Whamcloud - gitweb
LU-14699 mdd: proactive changelog garbage collection
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 MUNLINK=${MUNLINK:-munlink}
23 SOCKETSERVER=${SOCKETSERVER:-socketserver}
24 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
25 MEMHOG=${MEMHOG:-memhog}
26 DIRECTIO=${DIRECTIO:-directio}
27 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
28 DEF_STRIPE_COUNT=-1
29 CHECK_GRANT=${CHECK_GRANT:-"yes"}
30 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
31 export PARALLEL=${PARALLEL:-"no"}
32
33 TRACE=${TRACE:-""}
34 LUSTRE=${LUSTRE:-$(dirname $0)/..}
35 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
36 . $LUSTRE/tests/test-framework.sh
37 init_test_env $@
38
39 init_logging
40
41 ALWAYS_EXCEPT="$SANITY_EXCEPT "
42 # bug number for skipped test: LU-9693 LU-6493 LU-9693
43 ALWAYS_EXCEPT+="               42a     42b     42c "
44 # bug number:    LU-8411 LU-9054
45 ALWAYS_EXCEPT+=" 407     312"
46
47 if $SHARED_KEY; then
48         # bug number:    LU-14181 LU-14181
49         ALWAYS_EXCEPT+=" 64e      64f"
50 fi
51
52 selinux_status=$(getenforce)
53 if [ "$selinux_status" != "Disabled" ]; then
54         # bug number:
55         ALWAYS_EXCEPT+=""
56 fi
57
58 # skip the grant tests for ARM until they are fixed
59 if [[ $(uname -m) = aarch64 ]]; then
60         # bug number:    LU-11596
61         ALWAYS_EXCEPT+=" $GRANT_CHECK_LIST"
62         # bug number:    LU-11671
63         ALWAYS_EXCEPT+=" 45"
64         # bug number:    LU-14067 LU-14067
65         ALWAYS_EXCEPT+=" 400a     400b"
66 fi
67
68 # skip nfs tests on kernels >= 4.12.0 until they are fixed
69 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
70         # bug number:   LU-12661
71         ALWAYS_EXCEPT+=" 817"
72 fi
73 # skip cgroup tests on RHEL8.1 kernels until they are fixed
74 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
75       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
76         # bug number:   LU-13063
77         ALWAYS_EXCEPT+=" 411"
78 fi
79
80 #                                  5              12     8   12  15   (min)"
81 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 60i 64b 68 71 115 135 136 230d 300o"
82
83 if [ "$mds1_FSTYPE" = "zfs" ]; then
84         # bug number for skipped test:
85         ALWAYS_EXCEPT+="              "
86         #                                               13    (min)"
87         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
88 fi
89
90 if [ "$ost1_FSTYPE" = "zfs" ]; then
91         # bug number for skipped test:  LU-1941  LU-1941  LU-1941  LU-1941
92         ALWAYS_EXCEPT+="                130a 130b 130c 130d 130e 130f 130g"
93 fi
94
95 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
96
97 # Get the SLES distro version
98 #
99 # Returns a version string that should only be used in comparing
100 # strings returned by version_code()
101 sles_version_code()
102 {
103         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
104
105         # All SuSE Linux versions have one decimal. version_code expects two
106         local sles_version=$version.0
107         version_code $sles_version
108 }
109
110 # Check if we are running on Ubuntu or SLES so we can make decisions on
111 # what tests to run
112 if [ -r /etc/SuSE-release ]; then
113         sles_version=$(sles_version_code)
114         [ $sles_version -lt $(version_code 11.4.0) ] &&
115                 # bug number for skipped test: LU-4341
116                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
117         [ $sles_version -lt $(version_code 12.0.0) ] &&
118                 # bug number for skipped test: LU-3703
119                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
120 elif [ -r /etc/os-release ]; then
121         if grep -qi ubuntu /etc/os-release; then
122                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
123                                                 -e 's/^VERSION=//p' \
124                                                 /etc/os-release |
125                                                 awk '{ print $1 }'))
126
127                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
128                         # bug number for skipped test:
129                         #                LU-10334 LU-10366
130                         ALWAYS_EXCEPT+=" 103a     410"
131                 fi
132         fi
133 fi
134
135 build_test_filter
136 FAIL_ON_ERROR=false
137
138 cleanup() {
139         echo -n "cln.."
140         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
141         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
142 }
143 setup() {
144         echo -n "mnt.."
145         load_modules
146         setupall || exit 10
147         echo "done"
148 }
149
150 check_swap_layouts_support()
151 {
152         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
153                 skip "Does not support layout lock."
154 }
155
156 check_swap_layout_no_dom()
157 {
158         local FOLDER=$1
159         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
160         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
161 }
162
163 check_and_setup_lustre
164 DIR=${DIR:-$MOUNT}
165 assert_DIR
166
167 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
168
169 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
170 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
171 rm -rf $DIR/[Rdfs][0-9]*
172
173 # $RUNAS_ID may get set incorrectly somewhere else
174 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
175         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
176
177 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
178
179 if [ "${ONLY}" = "MOUNT" ] ; then
180         echo "Lustre is up, please go on"
181         exit
182 fi
183
184 echo "preparing for tests involving mounts"
185 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
186 touch $EXT2_DEV
187 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
188 echo # add a newline after mke2fs.
189
190 umask 077
191
192 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
193 lctl set_param debug=-1 2> /dev/null || true
194 test_0a() {
195         touch $DIR/$tfile
196         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
197         rm $DIR/$tfile
198         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
199 }
200 run_test 0a "touch; rm ====================="
201
202 test_0b() {
203         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
204         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
205 }
206 run_test 0b "chmod 0755 $DIR ============================="
207
208 test_0c() {
209         $LCTL get_param mdc.*.import | grep "state: FULL" ||
210                 error "import not FULL"
211         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
212                 error "bad target"
213 }
214 run_test 0c "check import proc"
215
216 test_0d() { # LU-3397
217         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
218                 skip "proc exports not supported before 2.10.57"
219
220         local mgs_exp="mgs.MGS.exports"
221         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
222         local exp_client_nid
223         local exp_client_version
224         local exp_val
225         local imp_val
226         local temp_imp=$DIR/$tfile.import
227         local temp_exp=$DIR/$tfile.export
228
229         # save mgc import file to $temp_imp
230         $LCTL get_param mgc.*.import | tee $temp_imp
231         # Check if client uuid is found in MGS export
232         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
233                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
234                         $client_uuid ] &&
235                         break;
236         done
237         # save mgs export file to $temp_exp
238         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
239
240         # Compare the value of field "connect_flags"
241         imp_val=$(grep "connect_flags" $temp_imp)
242         exp_val=$(grep "connect_flags" $temp_exp)
243         [ "$exp_val" == "$imp_val" ] ||
244                 error "export flags '$exp_val' != import flags '$imp_val'"
245
246         # Compare client versions.  Only compare top-3 fields for compatibility
247         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
248         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
249         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
250         [ "$exp_val" == "$imp_val" ] ||
251                 error "exp version '$exp_client_version'($exp_val) != " \
252                         "'$(lustre_build_version client)'($imp_val)"
253 }
254 run_test 0d "check export proc ============================="
255
256 test_0e() { # LU-13417
257         (( $MDSCOUNT > 1 )) ||
258                 skip "We need at least 2 MDTs for this test"
259
260         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
261                 skip "Need server version at least 2.14.51"
262
263         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
264         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
265
266         [ $default_lmv_count -eq 1 ] ||
267                 error "$MOUNT default stripe count $default_lmv_count"
268
269         [ $default_lmv_index -eq -1 ] ||
270                 error "$MOUNT default stripe index $default_lmv_index"
271
272         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
273         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
274
275         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
276         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
277
278         [ $mdt_index1 -eq $mdt_index2 ] &&
279                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
280
281         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
282 }
283 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
284
285 test_1() {
286         test_mkdir $DIR/$tdir
287         test_mkdir $DIR/$tdir/d2
288         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
289         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
290         rmdir $DIR/$tdir/d2
291         rmdir $DIR/$tdir
292         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
293 }
294 run_test 1 "mkdir; remkdir; rmdir"
295
296 test_2() {
297         test_mkdir $DIR/$tdir
298         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
299         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
300         rm -r $DIR/$tdir
301         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
302 }
303 run_test 2 "mkdir; touch; rmdir; check file"
304
305 test_3() {
306         test_mkdir $DIR/$tdir
307         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
308         touch $DIR/$tdir/$tfile
309         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
310         rm -r $DIR/$tdir
311         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
312 }
313 run_test 3 "mkdir; touch; rmdir; check dir"
314
315 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
316 test_4() {
317         test_mkdir -i 1 $DIR/$tdir
318
319         touch $DIR/$tdir/$tfile ||
320                 error "Create file under remote directory failed"
321
322         rmdir $DIR/$tdir &&
323                 error "Expect error removing in-use dir $DIR/$tdir"
324
325         test -d $DIR/$tdir || error "Remote directory disappeared"
326
327         rm -rf $DIR/$tdir || error "remove remote dir error"
328 }
329 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
330
331 test_5() {
332         test_mkdir $DIR/$tdir
333         test_mkdir $DIR/$tdir/d2
334         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
335         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
336         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
337 }
338 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
339
340 test_6a() {
341         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
342         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
343         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
344                 error "$tfile does not have perm 0666 or UID $UID"
345         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
346         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
347                 error "$tfile should be 0666 and owned by UID $UID"
348 }
349 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
350
351 test_6c() {
352         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
353
354         touch $DIR/$tfile
355         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
356         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
357                 error "$tfile should be owned by UID $RUNAS_ID"
358         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
359         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
360                 error "$tfile should be owned by UID $RUNAS_ID"
361 }
362 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
363
364 test_6e() {
365         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
366
367         touch $DIR/$tfile
368         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
369         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
370                 error "$tfile should be owned by GID $UID"
371         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
372         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
373                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
374 }
375 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
376
377 test_6g() {
378         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
379
380         test_mkdir $DIR/$tdir
381         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
382         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
383         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
384         test_mkdir $DIR/$tdir/d/subdir
385         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
386                 error "$tdir/d/subdir should be GID $RUNAS_GID"
387         if [[ $MDSCOUNT -gt 1 ]]; then
388                 # check remote dir sgid inherite
389                 $LFS mkdir -i 0 $DIR/$tdir.local ||
390                         error "mkdir $tdir.local failed"
391                 chmod g+s $DIR/$tdir.local ||
392                         error "chmod $tdir.local failed"
393                 chgrp $RUNAS_GID $DIR/$tdir.local ||
394                         error "chgrp $tdir.local failed"
395                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
396                         error "mkdir $tdir.remote failed"
397                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
398                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
399                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
400                         error "$tdir.remote should be mode 02755"
401         fi
402 }
403 run_test 6g "verify new dir in sgid dir inherits group"
404
405 test_6h() { # bug 7331
406         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
407
408         touch $DIR/$tfile || error "touch failed"
409         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
410         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
411                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
412         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
413                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
414 }
415 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
416
417 test_7a() {
418         test_mkdir $DIR/$tdir
419         $MCREATE $DIR/$tdir/$tfile
420         chmod 0666 $DIR/$tdir/$tfile
421         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
422                 error "$tdir/$tfile should be mode 0666"
423 }
424 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
425
426 test_7b() {
427         if [ ! -d $DIR/$tdir ]; then
428                 test_mkdir $DIR/$tdir
429         fi
430         $MCREATE $DIR/$tdir/$tfile
431         echo -n foo > $DIR/$tdir/$tfile
432         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
433         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
434 }
435 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
436
437 test_8() {
438         test_mkdir $DIR/$tdir
439         touch $DIR/$tdir/$tfile
440         chmod 0666 $DIR/$tdir/$tfile
441         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
442                 error "$tfile mode not 0666"
443 }
444 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
445
446 test_9() {
447         test_mkdir $DIR/$tdir
448         test_mkdir $DIR/$tdir/d2
449         test_mkdir $DIR/$tdir/d2/d3
450         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
451 }
452 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
453
454 test_10() {
455         test_mkdir $DIR/$tdir
456         test_mkdir $DIR/$tdir/d2
457         touch $DIR/$tdir/d2/$tfile
458         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
459                 error "$tdir/d2/$tfile not a file"
460 }
461 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
462
463 test_11() {
464         test_mkdir $DIR/$tdir
465         test_mkdir $DIR/$tdir/d2
466         chmod 0666 $DIR/$tdir/d2
467         chmod 0705 $DIR/$tdir/d2
468         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
469                 error "$tdir/d2 mode not 0705"
470 }
471 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
472
473 test_12() {
474         test_mkdir $DIR/$tdir
475         touch $DIR/$tdir/$tfile
476         chmod 0666 $DIR/$tdir/$tfile
477         chmod 0654 $DIR/$tdir/$tfile
478         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
479                 error "$tdir/d2 mode not 0654"
480 }
481 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
482
483 test_13() {
484         test_mkdir $DIR/$tdir
485         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
486         >  $DIR/$tdir/$tfile
487         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
488                 error "$tdir/$tfile size not 0 after truncate"
489 }
490 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
491
492 test_14() {
493         test_mkdir $DIR/$tdir
494         touch $DIR/$tdir/$tfile
495         rm $DIR/$tdir/$tfile
496         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
497 }
498 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
499
500 test_15() {
501         test_mkdir $DIR/$tdir
502         touch $DIR/$tdir/$tfile
503         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
504         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
505                 error "$tdir/${tfile_2} not a file after rename"
506         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
507 }
508 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
509
510 test_16() {
511         test_mkdir $DIR/$tdir
512         touch $DIR/$tdir/$tfile
513         rm -rf $DIR/$tdir/$tfile
514         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
515 }
516 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
517
518 test_17a() {
519         test_mkdir $DIR/$tdir
520         touch $DIR/$tdir/$tfile
521         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
522         ls -l $DIR/$tdir
523         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
524                 error "$tdir/l-exist not a symlink"
525         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
526                 error "$tdir/l-exist not referencing a file"
527         rm -f $DIR/$tdir/l-exist
528         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
529 }
530 run_test 17a "symlinks: create, remove (real)"
531
532 test_17b() {
533         test_mkdir $DIR/$tdir
534         ln -s no-such-file $DIR/$tdir/l-dangle
535         ls -l $DIR/$tdir
536         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
537                 error "$tdir/l-dangle not referencing no-such-file"
538         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
539                 error "$tdir/l-dangle not referencing non-existent file"
540         rm -f $DIR/$tdir/l-dangle
541         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
542 }
543 run_test 17b "symlinks: create, remove (dangling)"
544
545 test_17c() { # bug 3440 - don't save failed open RPC for replay
546         test_mkdir $DIR/$tdir
547         ln -s foo $DIR/$tdir/$tfile
548         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
549 }
550 run_test 17c "symlinks: open dangling (should return error)"
551
552 test_17d() {
553         test_mkdir $DIR/$tdir
554         ln -s foo $DIR/$tdir/$tfile
555         touch $DIR/$tdir/$tfile || error "creating to new symlink"
556 }
557 run_test 17d "symlinks: create dangling"
558
559 test_17e() {
560         test_mkdir $DIR/$tdir
561         local foo=$DIR/$tdir/$tfile
562         ln -s $foo $foo || error "create symlink failed"
563         ls -l $foo || error "ls -l failed"
564         ls $foo && error "ls not failed" || true
565 }
566 run_test 17e "symlinks: create recursive symlink (should return error)"
567
568 test_17f() {
569         test_mkdir $DIR/$tdir
570         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
571         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
572         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
573         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
574         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
575         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
576         ls -l  $DIR/$tdir
577 }
578 run_test 17f "symlinks: long and very long symlink name"
579
580 # str_repeat(S, N) generate a string that is string S repeated N times
581 str_repeat() {
582         local s=$1
583         local n=$2
584         local ret=''
585         while [ $((n -= 1)) -ge 0 ]; do
586                 ret=$ret$s
587         done
588         echo $ret
589 }
590
591 # Long symlinks and LU-2241
592 test_17g() {
593         test_mkdir $DIR/$tdir
594         local TESTS="59 60 61 4094 4095"
595
596         # Fix for inode size boundary in 2.1.4
597         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
598                 TESTS="4094 4095"
599
600         # Patch not applied to 2.2 or 2.3 branches
601         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
602         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
603                 TESTS="4094 4095"
604
605         for i in $TESTS; do
606                 local SYMNAME=$(str_repeat 'x' $i)
607                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
608                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
609         done
610 }
611 run_test 17g "symlinks: really long symlink name and inode boundaries"
612
613 test_17h() { #bug 17378
614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
615         remote_mds_nodsh && skip "remote MDS with nodsh"
616
617         local mdt_idx
618
619         test_mkdir $DIR/$tdir
620         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
621         $LFS setstripe -c -1 $DIR/$tdir
622         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
623         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
624         touch $DIR/$tdir/$tfile || true
625 }
626 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
627
628 test_17i() { #bug 20018
629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
630         remote_mds_nodsh && skip "remote MDS with nodsh"
631
632         local foo=$DIR/$tdir/$tfile
633         local mdt_idx
634
635         test_mkdir -c1 $DIR/$tdir
636         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
637         ln -s $foo $foo || error "create symlink failed"
638 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
639         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
640         ls -l $foo && error "error not detected"
641         return 0
642 }
643 run_test 17i "don't panic on short symlink (should return error)"
644
645 test_17k() { #bug 22301
646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
647         [[ -z "$(which rsync 2>/dev/null)" ]] &&
648                 skip "no rsync command"
649         rsync --help | grep -q xattr ||
650                 skip_env "$(rsync --version | head -n1) does not support xattrs"
651         test_mkdir $DIR/$tdir
652         test_mkdir $DIR/$tdir.new
653         touch $DIR/$tdir/$tfile
654         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
655         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
656                 error "rsync failed with xattrs enabled"
657 }
658 run_test 17k "symlinks: rsync with xattrs enabled"
659
660 test_17l() { # LU-279
661         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
662                 skip "no getfattr command"
663
664         test_mkdir $DIR/$tdir
665         touch $DIR/$tdir/$tfile
666         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
667         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
668                 # -h to not follow symlinks. -m '' to list all the xattrs.
669                 # grep to remove first line: '# file: $path'.
670                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
671                 do
672                         lgetxattr_size_check $path $xattr ||
673                                 error "lgetxattr_size_check $path $xattr failed"
674                 done
675         done
676 }
677 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
678
679 # LU-1540
680 test_17m() {
681         [ $PARALLEL == "yes" ] && skip "skip parallel run"
682         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
683         remote_mds_nodsh && skip "remote MDS with nodsh"
684         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
685         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
686                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
687
688         local short_sym="0123456789"
689         local wdir=$DIR/$tdir
690         local i
691
692         test_mkdir $wdir
693         long_sym=$short_sym
694         # create a long symlink file
695         for ((i = 0; i < 4; ++i)); do
696                 long_sym=${long_sym}${long_sym}
697         done
698
699         echo "create 512 short and long symlink files under $wdir"
700         for ((i = 0; i < 256; ++i)); do
701                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
702                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
703         done
704
705         echo "erase them"
706         rm -f $wdir/*
707         sync
708         wait_delete_completed
709
710         echo "recreate the 512 symlink files with a shorter string"
711         for ((i = 0; i < 512; ++i)); do
712                 # rewrite the symlink file with a shorter string
713                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
714                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
715         done
716
717         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
718         local devname=$(mdsdevname $mds_index)
719
720         echo "stop and checking mds${mds_index}:"
721         # e2fsck should not return error
722         stop mds${mds_index}
723         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
724         rc=$?
725
726         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
727                 error "start mds${mds_index} failed"
728         df $MOUNT > /dev/null 2>&1
729         [ $rc -eq 0 ] ||
730                 error "e2fsck detected error for short/long symlink: rc=$rc"
731         rm -f $wdir/*
732 }
733 run_test 17m "run e2fsck against MDT which contains short/long symlink"
734
735 check_fs_consistency_17n() {
736         local mdt_index
737         local rc=0
738
739         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
740         # so it only check MDT1/MDT2 instead of all of MDTs.
741         for mdt_index in 1 2; do
742                 local devname=$(mdsdevname $mdt_index)
743                 # e2fsck should not return error
744                 stop mds${mdt_index}
745                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
746                         rc=$((rc + $?))
747
748                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
749                         error "mount mds$mdt_index failed"
750                 df $MOUNT > /dev/null 2>&1
751         done
752         return $rc
753 }
754
755 test_17n() {
756         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
757         [ $PARALLEL == "yes" ] && skip "skip parallel run"
758         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
759         remote_mds_nodsh && skip "remote MDS with nodsh"
760         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
761         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
762                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
763
764         local i
765
766         test_mkdir $DIR/$tdir
767         for ((i=0; i<10; i++)); do
768                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
769                         error "create remote dir error $i"
770                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
771                         error "create files under remote dir failed $i"
772         done
773
774         check_fs_consistency_17n ||
775                 error "e2fsck report error after create files under remote dir"
776
777         for ((i = 0; i < 10; i++)); do
778                 rm -rf $DIR/$tdir/remote_dir_${i} ||
779                         error "destroy remote dir error $i"
780         done
781
782         check_fs_consistency_17n ||
783                 error "e2fsck report error after unlink files under remote dir"
784
785         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
786                 skip "lustre < 2.4.50 does not support migrate mv"
787
788         for ((i = 0; i < 10; i++)); do
789                 mkdir -p $DIR/$tdir/remote_dir_${i}
790                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
791                         error "create files under remote dir failed $i"
792                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
793                         error "migrate remote dir error $i"
794         done
795         check_fs_consistency_17n || error "e2fsck report error after migration"
796
797         for ((i = 0; i < 10; i++)); do
798                 rm -rf $DIR/$tdir/remote_dir_${i} ||
799                         error "destroy remote dir error $i"
800         done
801
802         check_fs_consistency_17n || error "e2fsck report error after unlink"
803 }
804 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
805
806 test_17o() {
807         remote_mds_nodsh && skip "remote MDS with nodsh"
808         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
809                 skip "Need MDS version at least 2.3.64"
810
811         local wdir=$DIR/${tdir}o
812         local mdt_index
813         local rc=0
814
815         test_mkdir $wdir
816         touch $wdir/$tfile
817         mdt_index=$($LFS getstripe -m $wdir/$tfile)
818         mdt_index=$((mdt_index + 1))
819
820         cancel_lru_locks mdc
821         #fail mds will wait the failover finish then set
822         #following fail_loc to avoid interfer the recovery process.
823         fail mds${mdt_index}
824
825         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
826         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
827         ls -l $wdir/$tfile && rc=1
828         do_facet mds${mdt_index} lctl set_param fail_loc=0
829         [[ $rc -eq 0 ]] || error "stat file should fail"
830 }
831 run_test 17o "stat file with incompat LMA feature"
832
833 test_18() {
834         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
835         ls $DIR || error "Failed to ls $DIR: $?"
836 }
837 run_test 18 "touch .../f ; ls ... =============================="
838
839 test_19a() {
840         touch $DIR/$tfile
841         ls -l $DIR
842         rm $DIR/$tfile
843         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
844 }
845 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
846
847 test_19b() {
848         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
849 }
850 run_test 19b "ls -l .../f19 (should return error) =============="
851
852 test_19c() {
853         [ $RUNAS_ID -eq $UID ] &&
854                 skip_env "RUNAS_ID = UID = $UID -- skipping"
855
856         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
857 }
858 run_test 19c "$RUNAS touch .../f19 (should return error) =="
859
860 test_19d() {
861         cat $DIR/f19 && error || true
862 }
863 run_test 19d "cat .../f19 (should return error) =============="
864
865 test_20() {
866         touch $DIR/$tfile
867         rm $DIR/$tfile
868         touch $DIR/$tfile
869         rm $DIR/$tfile
870         touch $DIR/$tfile
871         rm $DIR/$tfile
872         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
873 }
874 run_test 20 "touch .../f ; ls -l ..."
875
876 test_21() {
877         test_mkdir $DIR/$tdir
878         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
879         ln -s dangle $DIR/$tdir/link
880         echo foo >> $DIR/$tdir/link
881         cat $DIR/$tdir/dangle
882         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
883         $CHECKSTAT -f -t file $DIR/$tdir/link ||
884                 error "$tdir/link not linked to a file"
885 }
886 run_test 21 "write to dangling link"
887
888 test_22() {
889         local wdir=$DIR/$tdir
890         test_mkdir $wdir
891         chown $RUNAS_ID:$RUNAS_GID $wdir
892         (cd $wdir || error "cd $wdir failed";
893                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
894                 $RUNAS tar xf -)
895         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
896         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
897         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
898                 error "checkstat -u failed"
899 }
900 run_test 22 "unpack tar archive as non-root user"
901
902 # was test_23
903 test_23a() {
904         test_mkdir $DIR/$tdir
905         local file=$DIR/$tdir/$tfile
906
907         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
908         openfile -f O_CREAT:O_EXCL $file &&
909                 error "$file recreate succeeded" || true
910 }
911 run_test 23a "O_CREAT|O_EXCL in subdir"
912
913 test_23b() { # bug 18988
914         test_mkdir $DIR/$tdir
915         local file=$DIR/$tdir/$tfile
916
917         rm -f $file
918         echo foo > $file || error "write filed"
919         echo bar >> $file || error "append filed"
920         $CHECKSTAT -s 8 $file || error "wrong size"
921         rm $file
922 }
923 run_test 23b "O_APPEND check"
924
925 # LU-9409, size with O_APPEND and tiny writes
926 test_23c() {
927         local file=$DIR/$tfile
928
929         # single dd
930         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
931         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
932         rm -f $file
933
934         # racing tiny writes
935         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
936         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
937         wait
938         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
939         rm -f $file
940
941         #racing tiny & normal writes
942         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
943         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
944         wait
945         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
946         rm -f $file
947
948         #racing tiny & normal writes 2, ugly numbers
949         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
950         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
951         wait
952         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
953         rm -f $file
954 }
955 run_test 23c "O_APPEND size checks for tiny writes"
956
957 # LU-11069 file offset is correct after appending writes
958 test_23d() {
959         local file=$DIR/$tfile
960         local offset
961
962         echo CentaurHauls > $file
963         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
964         if ((offset != 26)); then
965                 error "wrong offset, expected 26, got '$offset'"
966         fi
967 }
968 run_test 23d "file offset is correct after appending writes"
969
970 # rename sanity
971 test_24a() {
972         echo '-- same directory rename'
973         test_mkdir $DIR/$tdir
974         touch $DIR/$tdir/$tfile.1
975         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
976         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
977 }
978 run_test 24a "rename file to non-existent target"
979
980 test_24b() {
981         test_mkdir $DIR/$tdir
982         touch $DIR/$tdir/$tfile.{1,2}
983         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
984         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
985         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
986 }
987 run_test 24b "rename file to existing target"
988
989 test_24c() {
990         test_mkdir $DIR/$tdir
991         test_mkdir $DIR/$tdir/d$testnum.1
992         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
993         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
994         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
995 }
996 run_test 24c "rename directory to non-existent target"
997
998 test_24d() {
999         test_mkdir -c1 $DIR/$tdir
1000         test_mkdir -c1 $DIR/$tdir/d$testnum.1
1001         test_mkdir -c1 $DIR/$tdir/d$testnum.2
1002         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
1003         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
1004         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
1005 }
1006 run_test 24d "rename directory to existing target"
1007
1008 test_24e() {
1009         echo '-- cross directory renames --'
1010         test_mkdir $DIR/R5a
1011         test_mkdir $DIR/R5b
1012         touch $DIR/R5a/f
1013         mv $DIR/R5a/f $DIR/R5b/g
1014         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
1015         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
1016 }
1017 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
1018
1019 test_24f() {
1020         test_mkdir $DIR/R6a
1021         test_mkdir $DIR/R6b
1022         touch $DIR/R6a/f $DIR/R6b/g
1023         mv $DIR/R6a/f $DIR/R6b/g
1024         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1025         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1026 }
1027 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1028
1029 test_24g() {
1030         test_mkdir $DIR/R7a
1031         test_mkdir $DIR/R7b
1032         test_mkdir $DIR/R7a/d
1033         mv $DIR/R7a/d $DIR/R7b/e
1034         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1035         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1036 }
1037 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1038
1039 test_24h() {
1040         test_mkdir -c1 $DIR/R8a
1041         test_mkdir -c1 $DIR/R8b
1042         test_mkdir -c1 $DIR/R8a/d
1043         test_mkdir -c1 $DIR/R8b/e
1044         mrename $DIR/R8a/d $DIR/R8b/e
1045         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1046         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1047 }
1048 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1049
1050 test_24i() {
1051         echo "-- rename error cases"
1052         test_mkdir $DIR/R9
1053         test_mkdir $DIR/R9/a
1054         touch $DIR/R9/f
1055         mrename $DIR/R9/f $DIR/R9/a
1056         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1057         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1058         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1059 }
1060 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1061
1062 test_24j() {
1063         test_mkdir $DIR/R10
1064         mrename $DIR/R10/f $DIR/R10/g
1065         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1066         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1067         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1068 }
1069 run_test 24j "source does not exist ============================"
1070
1071 test_24k() {
1072         test_mkdir $DIR/R11a
1073         test_mkdir $DIR/R11a/d
1074         touch $DIR/R11a/f
1075         mv $DIR/R11a/f $DIR/R11a/d
1076         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1077         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1078 }
1079 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1080
1081 # bug 2429 - rename foo foo foo creates invalid file
1082 test_24l() {
1083         f="$DIR/f24l"
1084         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1085 }
1086 run_test 24l "Renaming a file to itself ========================"
1087
1088 test_24m() {
1089         f="$DIR/f24m"
1090         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1091         # on ext3 this does not remove either the source or target files
1092         # though the "expected" operation would be to remove the source
1093         $CHECKSTAT -t file ${f} || error "${f} missing"
1094         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1095 }
1096 run_test 24m "Renaming a file to a hard link to itself ========="
1097
1098 test_24n() {
1099     f="$DIR/f24n"
1100     # this stats the old file after it was renamed, so it should fail
1101     touch ${f}
1102     $CHECKSTAT ${f} || error "${f} missing"
1103     mv ${f} ${f}.rename
1104     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1105     $CHECKSTAT -a ${f} || error "${f} exists"
1106 }
1107 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1108
1109 test_24o() {
1110         test_mkdir $DIR/$tdir
1111         rename_many -s random -v -n 10 $DIR/$tdir
1112 }
1113 run_test 24o "rename of files during htree split"
1114
1115 test_24p() {
1116         test_mkdir $DIR/R12a
1117         test_mkdir $DIR/R12b
1118         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1119         mrename $DIR/R12a $DIR/R12b
1120         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1121         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1122         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1123         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1124 }
1125 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1126
1127 cleanup_multiop_pause() {
1128         trap 0
1129         kill -USR1 $MULTIPID
1130 }
1131
1132 test_24q() {
1133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1134
1135         test_mkdir $DIR/R13a
1136         test_mkdir $DIR/R13b
1137         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1138         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1139         MULTIPID=$!
1140
1141         trap cleanup_multiop_pause EXIT
1142         mrename $DIR/R13a $DIR/R13b
1143         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1144         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1145         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1146         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1147         cleanup_multiop_pause
1148         wait $MULTIPID || error "multiop close failed"
1149 }
1150 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1151
1152 test_24r() { #bug 3789
1153         test_mkdir $DIR/R14a
1154         test_mkdir $DIR/R14a/b
1155         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1156         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1157         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1158 }
1159 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1160
1161 test_24s() {
1162         test_mkdir $DIR/R15a
1163         test_mkdir $DIR/R15a/b
1164         test_mkdir $DIR/R15a/b/c
1165         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1166         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1167         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1168 }
1169 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1170 test_24t() {
1171         test_mkdir $DIR/R16a
1172         test_mkdir $DIR/R16a/b
1173         test_mkdir $DIR/R16a/b/c
1174         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1175         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1176         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1177 }
1178 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1179
1180 test_24u() { # bug12192
1181         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1182         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1183 }
1184 run_test 24u "create stripe file"
1185
1186 simple_cleanup_common() {
1187         local rc=0
1188         trap 0
1189         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1190
1191         local start=$SECONDS
1192         rm -rf $DIR/$tdir
1193         rc=$?
1194         wait_delete_completed
1195         echo "cleanup time $((SECONDS - start))"
1196         return $rc
1197 }
1198
1199 max_pages_per_rpc() {
1200         local mdtname="$(printf "MDT%04x" ${1:-0})"
1201         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1202 }
1203
1204 test_24v() {
1205         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1206
1207         local nrfiles=${COUNT:-100000}
1208         local fname="$DIR/$tdir/$tfile"
1209
1210         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1211         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1212
1213         test_mkdir "$(dirname $fname)"
1214         # assume MDT0000 has the fewest inodes
1215         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1216         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1217         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1218
1219         trap simple_cleanup_common EXIT
1220
1221         createmany -m "$fname" $nrfiles
1222
1223         cancel_lru_locks mdc
1224         lctl set_param mdc.*.stats clear
1225
1226         # was previously test_24D: LU-6101
1227         # readdir() returns correct number of entries after cursor reload
1228         local num_ls=$(ls $DIR/$tdir | wc -l)
1229         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1230         local num_all=$(ls -a $DIR/$tdir | wc -l)
1231         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1232                 [ $num_all -ne $((nrfiles + 2)) ]; then
1233                         error "Expected $nrfiles files, got $num_ls " \
1234                                 "($num_uniq unique $num_all .&..)"
1235         fi
1236         # LU-5 large readdir
1237         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1238         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1239         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1240         # take into account of overhead in lu_dirpage header and end mark in
1241         # each page, plus one in rpc_num calculation.
1242         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1243         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1244         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1245         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1246         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1247         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1248         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1249         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1250                 error "large readdir doesn't take effect: " \
1251                       "$mds_readpage should be about $rpc_max"
1252
1253         simple_cleanup_common
1254 }
1255 run_test 24v "list large directory (test hash collision, b=17560)"
1256
1257 test_24w() { # bug21506
1258         SZ1=234852
1259         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1260         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1261         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1262         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1263         [[ "$SZ1" -eq "$SZ2" ]] ||
1264                 error "Error reading at the end of the file $tfile"
1265 }
1266 run_test 24w "Reading a file larger than 4Gb"
1267
1268 test_24x() {
1269         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1271         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1272                 skip "Need MDS version at least 2.7.56"
1273
1274         local MDTIDX=1
1275         local remote_dir=$DIR/$tdir/remote_dir
1276
1277         test_mkdir $DIR/$tdir
1278         $LFS mkdir -i $MDTIDX $remote_dir ||
1279                 error "create remote directory failed"
1280
1281         test_mkdir $DIR/$tdir/src_dir
1282         touch $DIR/$tdir/src_file
1283         test_mkdir $remote_dir/tgt_dir
1284         touch $remote_dir/tgt_file
1285
1286         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1287                 error "rename dir cross MDT failed!"
1288
1289         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1290                 error "rename file cross MDT failed!"
1291
1292         touch $DIR/$tdir/ln_file
1293         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1294                 error "ln file cross MDT failed"
1295
1296         rm -rf $DIR/$tdir || error "Can not delete directories"
1297 }
1298 run_test 24x "cross MDT rename/link"
1299
1300 test_24y() {
1301         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1302         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1303
1304         local remote_dir=$DIR/$tdir/remote_dir
1305         local mdtidx=1
1306
1307         test_mkdir $DIR/$tdir
1308         $LFS mkdir -i $mdtidx $remote_dir ||
1309                 error "create remote directory failed"
1310
1311         test_mkdir $remote_dir/src_dir
1312         touch $remote_dir/src_file
1313         test_mkdir $remote_dir/tgt_dir
1314         touch $remote_dir/tgt_file
1315
1316         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1317                 error "rename subdir in the same remote dir failed!"
1318
1319         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1320                 error "rename files in the same remote dir failed!"
1321
1322         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1323                 error "link files in the same remote dir failed!"
1324
1325         rm -rf $DIR/$tdir || error "Can not delete directories"
1326 }
1327 run_test 24y "rename/link on the same dir should succeed"
1328
1329 test_24z() {
1330         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1331         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1332                 skip "Need MDS version at least 2.12.51"
1333
1334         local index
1335
1336         for index in 0 1; do
1337                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1338                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1339         done
1340
1341         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1342
1343         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1344         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1345
1346         local mdts=$(comma_list $(mdts_nodes))
1347
1348         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1349         stack_trap "do_nodes $mdts $LCTL \
1350                 set_param mdt.*.enable_remote_rename=1" EXIT
1351
1352         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1353
1354         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1355         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1356 }
1357 run_test 24z "cross-MDT rename is done as cp"
1358
1359 test_24A() { # LU-3182
1360         local NFILES=5000
1361
1362         rm -rf $DIR/$tdir
1363         test_mkdir $DIR/$tdir
1364         trap simple_cleanup_common EXIT
1365         createmany -m $DIR/$tdir/$tfile $NFILES
1366         local t=$(ls $DIR/$tdir | wc -l)
1367         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1368         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1369         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1370            [ $v -ne $((NFILES + 2)) ] ; then
1371                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1372         fi
1373
1374         simple_cleanup_common || error "Can not delete directories"
1375 }
1376 run_test 24A "readdir() returns correct number of entries."
1377
1378 test_24B() { # LU-4805
1379         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1380
1381         local count
1382
1383         test_mkdir $DIR/$tdir
1384         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1385                 error "create striped dir failed"
1386
1387         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1388         [ $count -eq 2 ] || error "Expected 2, got $count"
1389
1390         touch $DIR/$tdir/striped_dir/a
1391
1392         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1393         [ $count -eq 3 ] || error "Expected 3, got $count"
1394
1395         touch $DIR/$tdir/striped_dir/.f
1396
1397         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1398         [ $count -eq 4 ] || error "Expected 4, got $count"
1399
1400         rm -rf $DIR/$tdir || error "Can not delete directories"
1401 }
1402 run_test 24B "readdir for striped dir return correct number of entries"
1403
1404 test_24C() {
1405         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1406
1407         mkdir $DIR/$tdir
1408         mkdir $DIR/$tdir/d0
1409         mkdir $DIR/$tdir/d1
1410
1411         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1412                 error "create striped dir failed"
1413
1414         cd $DIR/$tdir/d0/striped_dir
1415
1416         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1417         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1418         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1419
1420         [ "$d0_ino" = "$parent_ino" ] ||
1421                 error ".. wrong, expect $d0_ino, get $parent_ino"
1422
1423         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1424                 error "mv striped dir failed"
1425
1426         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1427
1428         [ "$d1_ino" = "$parent_ino" ] ||
1429                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1430 }
1431 run_test 24C "check .. in striped dir"
1432
1433 test_24E() {
1434         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1436
1437         mkdir -p $DIR/$tdir
1438         mkdir $DIR/$tdir/src_dir
1439         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1440                 error "create remote source failed"
1441
1442         touch $DIR/$tdir/src_dir/src_child/a
1443
1444         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1445                 error "create remote target dir failed"
1446
1447         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1448                 error "create remote target child failed"
1449
1450         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1451                 error "rename dir cross MDT failed!"
1452
1453         find $DIR/$tdir
1454
1455         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1456                 error "src_child still exists after rename"
1457
1458         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1459                 error "missing file(a) after rename"
1460
1461         rm -rf $DIR/$tdir || error "Can not delete directories"
1462 }
1463 run_test 24E "cross MDT rename/link"
1464
1465 test_24F () {
1466         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1467
1468         local repeats=1000
1469         [ "$SLOW" = "no" ] && repeats=100
1470
1471         mkdir -p $DIR/$tdir
1472
1473         echo "$repeats repeats"
1474         for ((i = 0; i < repeats; i++)); do
1475                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1476                 touch $DIR/$tdir/test/a || error "touch fails"
1477                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1478                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1479         done
1480
1481         true
1482 }
1483 run_test 24F "hash order vs readdir (LU-11330)"
1484
1485 test_24G () {
1486         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1487
1488         local ino1
1489         local ino2
1490
1491         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1492         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1493         touch $DIR/$tdir-0/f1 || error "touch f1"
1494         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1495         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1496         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1497         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1498         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1499 }
1500 run_test 24G "migrate symlink in rename"
1501
1502 test_25a() {
1503         echo '== symlink sanity ============================================='
1504
1505         test_mkdir $DIR/d25
1506         ln -s d25 $DIR/s25
1507         touch $DIR/s25/foo ||
1508                 error "File creation in symlinked directory failed"
1509 }
1510 run_test 25a "create file in symlinked directory ==============="
1511
1512 test_25b() {
1513         [ ! -d $DIR/d25 ] && test_25a
1514         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1515 }
1516 run_test 25b "lookup file in symlinked directory ==============="
1517
1518 test_26a() {
1519         test_mkdir $DIR/d26
1520         test_mkdir $DIR/d26/d26-2
1521         ln -s d26/d26-2 $DIR/s26
1522         touch $DIR/s26/foo || error "File creation failed"
1523 }
1524 run_test 26a "multiple component symlink ======================="
1525
1526 test_26b() {
1527         test_mkdir -p $DIR/$tdir/d26-2
1528         ln -s $tdir/d26-2/foo $DIR/s26-2
1529         touch $DIR/s26-2 || error "File creation failed"
1530 }
1531 run_test 26b "multiple component symlink at end of lookup ======"
1532
1533 test_26c() {
1534         test_mkdir $DIR/d26.2
1535         touch $DIR/d26.2/foo
1536         ln -s d26.2 $DIR/s26.2-1
1537         ln -s s26.2-1 $DIR/s26.2-2
1538         ln -s s26.2-2 $DIR/s26.2-3
1539         chmod 0666 $DIR/s26.2-3/foo
1540 }
1541 run_test 26c "chain of symlinks"
1542
1543 # recursive symlinks (bug 439)
1544 test_26d() {
1545         ln -s d26-3/foo $DIR/d26-3
1546 }
1547 run_test 26d "create multiple component recursive symlink"
1548
1549 test_26e() {
1550         [ ! -h $DIR/d26-3 ] && test_26d
1551         rm $DIR/d26-3
1552 }
1553 run_test 26e "unlink multiple component recursive symlink"
1554
1555 # recursive symlinks (bug 7022)
1556 test_26f() {
1557         test_mkdir $DIR/$tdir
1558         test_mkdir $DIR/$tdir/$tfile
1559         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1560         test_mkdir -p lndir/bar1
1561         test_mkdir $DIR/$tdir/$tfile/$tfile
1562         cd $tfile                || error "cd $tfile failed"
1563         ln -s .. dotdot          || error "ln dotdot failed"
1564         ln -s dotdot/lndir lndir || error "ln lndir failed"
1565         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1566         output=`ls $tfile/$tfile/lndir/bar1`
1567         [ "$output" = bar1 ] && error "unexpected output"
1568         rm -r $tfile             || error "rm $tfile failed"
1569         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1570 }
1571 run_test 26f "rm -r of a directory which has recursive symlink"
1572
1573 test_27a() {
1574         test_mkdir $DIR/$tdir
1575         $LFS getstripe $DIR/$tdir
1576         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1577         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1578         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1579 }
1580 run_test 27a "one stripe file"
1581
1582 test_27b() {
1583         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1584
1585         test_mkdir $DIR/$tdir
1586         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1587         $LFS getstripe -c $DIR/$tdir/$tfile
1588         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1589                 error "two-stripe file doesn't have two stripes"
1590
1591         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1592 }
1593 run_test 27b "create and write to two stripe file"
1594
1595 # 27c family tests specific striping, setstripe -o
1596 test_27ca() {
1597         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1598         test_mkdir -p $DIR/$tdir
1599         local osts="1"
1600
1601         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1602         $LFS getstripe -i $DIR/$tdir/$tfile
1603         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1604                 error "stripe not on specified OST"
1605
1606         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1607 }
1608 run_test 27ca "one stripe on specified OST"
1609
1610 test_27cb() {
1611         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1612         test_mkdir -p $DIR/$tdir
1613         local osts="1,0"
1614         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1615         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1616         echo "$getstripe"
1617
1618         # Strip getstripe output to a space separated list of OSTs
1619         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1620                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1621         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1622                 error "stripes not on specified OSTs"
1623
1624         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1625 }
1626 run_test 27cb "two stripes on specified OSTs"
1627
1628 test_27cc() {
1629         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1630         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1631                 skip "server does not support overstriping"
1632
1633         test_mkdir -p $DIR/$tdir
1634         local osts="0,0"
1635         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1636         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1637         echo "$getstripe"
1638
1639         # Strip getstripe output to a space separated list of OSTs
1640         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1641                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1642         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1643                 error "stripes not on specified OSTs"
1644
1645         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1646 }
1647 run_test 27cc "two stripes on the same OST"
1648
1649 test_27cd() {
1650         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1651         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1652                 skip "server does not support overstriping"
1653         test_mkdir -p $DIR/$tdir
1654         local osts="0,1,1,0"
1655         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1656         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1657         echo "$getstripe"
1658
1659         # Strip getstripe output to a space separated list of OSTs
1660         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1661                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1662         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1663                 error "stripes not on specified OSTs"
1664
1665         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1666 }
1667 run_test 27cd "four stripes on two OSTs"
1668
1669 test_27ce() {
1670         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1671                 skip_env "too many osts, skipping"
1672         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1673                 skip "server does not support overstriping"
1674         # We do one more stripe than we have OSTs
1675         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1676                 skip_env "ea_inode feature disabled"
1677
1678         test_mkdir -p $DIR/$tdir
1679         local osts=""
1680         for i in $(seq 0 $OSTCOUNT);
1681         do
1682                 osts=$osts"0"
1683                 if [ $i -ne $OSTCOUNT ]; then
1684                         osts=$osts","
1685                 fi
1686         done
1687         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1688         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1689         echo "$getstripe"
1690
1691         # Strip getstripe output to a space separated list of OSTs
1692         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1693                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1694         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1695                 error "stripes not on specified OSTs"
1696
1697         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1698 }
1699 run_test 27ce "more stripes than OSTs with -o"
1700
1701 test_27cf() {
1702         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1703         local pid=0
1704
1705         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1706         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1707         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1708         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1709                 error "failed to set $osp_proc=0"
1710
1711         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1712         pid=$!
1713         sleep 1
1714         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1715         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1716                 error "failed to set $osp_proc=1"
1717         wait $pid
1718         [[ $pid -ne 0 ]] ||
1719                 error "should return error due to $osp_proc=0"
1720 }
1721 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1722
1723 test_27d() {
1724         test_mkdir $DIR/$tdir
1725         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1726                 error "setstripe failed"
1727         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1728         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1729 }
1730 run_test 27d "create file with default settings"
1731
1732 test_27e() {
1733         # LU-5839 adds check for existed layout before setting it
1734         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1735                 skip "Need MDS version at least 2.7.56"
1736
1737         test_mkdir $DIR/$tdir
1738         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1739         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1740         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1741 }
1742 run_test 27e "setstripe existing file (should return error)"
1743
1744 test_27f() {
1745         test_mkdir $DIR/$tdir
1746         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1747                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1748         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1749                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1750         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1751         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1752 }
1753 run_test 27f "setstripe with bad stripe size (should return error)"
1754
1755 test_27g() {
1756         test_mkdir $DIR/$tdir
1757         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1758         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1759                 error "$DIR/$tdir/$tfile has object"
1760 }
1761 run_test 27g "$LFS getstripe with no objects"
1762
1763 test_27ga() {
1764         test_mkdir $DIR/$tdir
1765         touch $DIR/$tdir/$tfile || error "touch failed"
1766         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1767         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1768         local rc=$?
1769         (( rc == 2 )) || error "getstripe did not return ENOENT"
1770 }
1771 run_test 27ga "$LFS getstripe with missing file (should return error)"
1772
1773 test_27i() {
1774         test_mkdir $DIR/$tdir
1775         touch $DIR/$tdir/$tfile || error "touch failed"
1776         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1777                 error "missing objects"
1778 }
1779 run_test 27i "$LFS getstripe with some objects"
1780
1781 test_27j() {
1782         test_mkdir $DIR/$tdir
1783         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1784                 error "setstripe failed" || true
1785 }
1786 run_test 27j "setstripe with bad stripe offset (should return error)"
1787
1788 test_27k() { # bug 2844
1789         test_mkdir $DIR/$tdir
1790         local file=$DIR/$tdir/$tfile
1791         local ll_max_blksize=$((4 * 1024 * 1024))
1792         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1793         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1794         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1795         dd if=/dev/zero of=$file bs=4k count=1
1796         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1797         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1798 }
1799 run_test 27k "limit i_blksize for broken user apps"
1800
1801 test_27l() {
1802         mcreate $DIR/$tfile || error "creating file"
1803         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1804                 error "setstripe should have failed" || true
1805 }
1806 run_test 27l "check setstripe permissions (should return error)"
1807
1808 test_27m() {
1809         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1810
1811         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1812                 skip_env "multiple clients -- skipping"
1813
1814         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1815                    head -n1)
1816         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1817                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1818         fi
1819         trap simple_cleanup_common EXIT
1820         test_mkdir $DIR/$tdir
1821         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1822         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1823                 error "dd should fill OST0"
1824         i=2
1825         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1826                 i=$((i + 1))
1827                 [ $i -gt 256 ] && break
1828         done
1829         i=$((i + 1))
1830         touch $DIR/$tdir/$tfile.$i
1831         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1832             awk '{print $1}'| grep -w "0") ] &&
1833                 error "OST0 was full but new created file still use it"
1834         i=$((i + 1))
1835         touch $DIR/$tdir/$tfile.$i
1836         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1837             awk '{print $1}'| grep -w "0") ] &&
1838                 error "OST0 was full but new created file still use it"
1839         simple_cleanup_common
1840 }
1841 run_test 27m "create file while OST0 was full"
1842
1843 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1844 # if the OST isn't full anymore.
1845 reset_enospc() {
1846         local ostidx=${1:-""}
1847         local delay
1848         local ready
1849         local get_prealloc
1850
1851         local list=$(comma_list $(osts_nodes))
1852         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1853
1854         do_nodes $list lctl set_param fail_loc=0
1855         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1856         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1857                 awk '{print $1 * 2;exit;}')
1858         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1859                         grep -v \"^0$\""
1860         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1861 }
1862
1863 test_27n() {
1864         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1865         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1866         remote_mds_nodsh && skip "remote MDS with nodsh"
1867         remote_ost_nodsh && skip "remote OST with nodsh"
1868
1869         reset_enospc
1870         rm -f $DIR/$tdir/$tfile
1871         exhaust_precreations 0 0x80000215
1872         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1873         touch $DIR/$tdir/$tfile || error "touch failed"
1874         $LFS getstripe $DIR/$tdir/$tfile
1875         reset_enospc
1876 }
1877 run_test 27n "create file with some full OSTs"
1878
1879 test_27o() {
1880         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1882         remote_mds_nodsh && skip "remote MDS with nodsh"
1883         remote_ost_nodsh && skip "remote OST with nodsh"
1884
1885         reset_enospc
1886         rm -f $DIR/$tdir/$tfile
1887         exhaust_all_precreations 0x215
1888
1889         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1890
1891         reset_enospc
1892         rm -rf $DIR/$tdir/*
1893 }
1894 run_test 27o "create file with all full OSTs (should error)"
1895
1896 function create_and_checktime() {
1897         local fname=$1
1898         local loops=$2
1899         local i
1900
1901         for ((i=0; i < $loops; i++)); do
1902                 local start=$SECONDS
1903                 multiop $fname-$i Oc
1904                 ((SECONDS-start < TIMEOUT)) ||
1905                         error "creation took " $((SECONDS-$start)) && return 1
1906         done
1907 }
1908
1909 test_27oo() {
1910         local mdts=$(comma_list $(mdts_nodes))
1911
1912         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1913                 skip "Need MDS version at least 2.13.57"
1914
1915         local f0=$DIR/${tfile}-0
1916         local f1=$DIR/${tfile}-1
1917
1918         wait_delete_completed
1919
1920         # refill precreated objects
1921         $LFS setstripe -i0 -c1 $f0
1922
1923         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1924         # force QoS allocation policy
1925         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1926         stack_trap "do_nodes $mdts $LCTL set_param \
1927                 lov.*.qos_threshold_rr=$saved" EXIT
1928         sleep_maxage
1929
1930         # one OST is unavailable, but still have few objects preallocated
1931         stop ost1
1932         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1933                 rm -rf $f1 $DIR/$tdir*" EXIT
1934
1935         for ((i=0; i < 7; i++)); do
1936                 mkdir $DIR/$tdir$i || error "can't create dir"
1937                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1938                         error "can't set striping"
1939         done
1940         for ((i=0; i < 7; i++)); do
1941                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1942         done
1943         wait
1944 }
1945 run_test 27oo "don't let few threads to reserve too many objects"
1946
1947 test_27p() {
1948         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1950         remote_mds_nodsh && skip "remote MDS with nodsh"
1951         remote_ost_nodsh && skip "remote OST with nodsh"
1952
1953         reset_enospc
1954         rm -f $DIR/$tdir/$tfile
1955         test_mkdir $DIR/$tdir
1956
1957         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1958         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1959         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1960
1961         exhaust_precreations 0 0x80000215
1962         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1963         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1964         $LFS getstripe $DIR/$tdir/$tfile
1965
1966         reset_enospc
1967 }
1968 run_test 27p "append to a truncated file with some full OSTs"
1969
1970 test_27q() {
1971         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1973         remote_mds_nodsh && skip "remote MDS with nodsh"
1974         remote_ost_nodsh && skip "remote OST with nodsh"
1975
1976         reset_enospc
1977         rm -f $DIR/$tdir/$tfile
1978
1979         mkdir_on_mdt0 $DIR/$tdir
1980         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1981         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1982                 error "truncate $DIR/$tdir/$tfile failed"
1983         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1984
1985         exhaust_all_precreations 0x215
1986
1987         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1988         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1989
1990         reset_enospc
1991 }
1992 run_test 27q "append to truncated file with all OSTs full (should error)"
1993
1994 test_27r() {
1995         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1997         remote_mds_nodsh && skip "remote MDS with nodsh"
1998         remote_ost_nodsh && skip "remote OST with nodsh"
1999
2000         reset_enospc
2001         rm -f $DIR/$tdir/$tfile
2002         exhaust_precreations 0 0x80000215
2003
2004         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2005
2006         reset_enospc
2007 }
2008 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2009
2010 test_27s() { # bug 10725
2011         test_mkdir $DIR/$tdir
2012         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2013         local stripe_count=0
2014         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2015         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2016                 error "stripe width >= 2^32 succeeded" || true
2017
2018 }
2019 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2020
2021 test_27t() { # bug 10864
2022         WDIR=$(pwd)
2023         WLFS=$(which lfs)
2024         cd $DIR
2025         touch $tfile
2026         $WLFS getstripe $tfile
2027         cd $WDIR
2028 }
2029 run_test 27t "check that utils parse path correctly"
2030
2031 test_27u() { # bug 4900
2032         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2033         remote_mds_nodsh && skip "remote MDS with nodsh"
2034
2035         local index
2036         local list=$(comma_list $(mdts_nodes))
2037
2038 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2039         do_nodes $list $LCTL set_param fail_loc=0x139
2040         test_mkdir -p $DIR/$tdir
2041         trap simple_cleanup_common EXIT
2042         createmany -o $DIR/$tdir/t- 1000
2043         do_nodes $list $LCTL set_param fail_loc=0
2044
2045         TLOG=$TMP/$tfile.getstripe
2046         $LFS getstripe $DIR/$tdir > $TLOG
2047         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2048         unlinkmany $DIR/$tdir/t- 1000
2049         trap 0
2050         [[ $OBJS -gt 0 ]] &&
2051                 error "$OBJS objects created on OST-0. See $TLOG" ||
2052                 rm -f $TLOG
2053 }
2054 run_test 27u "skip object creation on OSC w/o objects"
2055
2056 test_27v() { # bug 4900
2057         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2059         remote_mds_nodsh && skip "remote MDS with nodsh"
2060         remote_ost_nodsh && skip "remote OST with nodsh"
2061
2062         exhaust_all_precreations 0x215
2063         reset_enospc
2064
2065         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2066
2067         touch $DIR/$tdir/$tfile
2068         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2069         # all except ost1
2070         for (( i=1; i < OSTCOUNT; i++ )); do
2071                 do_facet ost$i lctl set_param fail_loc=0x705
2072         done
2073         local START=`date +%s`
2074         createmany -o $DIR/$tdir/$tfile 32
2075
2076         local FINISH=`date +%s`
2077         local TIMEOUT=`lctl get_param -n timeout`
2078         local PROCESS=$((FINISH - START))
2079         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2080                error "$FINISH - $START >= $TIMEOUT / 2"
2081         sleep $((TIMEOUT / 2 - PROCESS))
2082         reset_enospc
2083 }
2084 run_test 27v "skip object creation on slow OST"
2085
2086 test_27w() { # bug 10997
2087         test_mkdir $DIR/$tdir
2088         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2089         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2090                 error "stripe size $size != 65536" || true
2091         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2092                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2093 }
2094 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2095
2096 test_27wa() {
2097         [[ $OSTCOUNT -lt 2 ]] &&
2098                 skip_env "skipping multiple stripe count/offset test"
2099
2100         test_mkdir $DIR/$tdir
2101         for i in $(seq 1 $OSTCOUNT); do
2102                 offset=$((i - 1))
2103                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2104                         error "setstripe -c $i -i $offset failed"
2105                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2106                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2107                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2108                 [ $index -ne $offset ] &&
2109                         error "stripe offset $index != $offset" || true
2110         done
2111 }
2112 run_test 27wa "check $LFS setstripe -c -i options"
2113
2114 test_27x() {
2115         remote_ost_nodsh && skip "remote OST with nodsh"
2116         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2117         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2118
2119         OFFSET=$(($OSTCOUNT - 1))
2120         OSTIDX=0
2121         local OST=$(ostname_from_index $OSTIDX)
2122
2123         test_mkdir $DIR/$tdir
2124         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2125         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2126         sleep_maxage
2127         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2128         for i in $(seq 0 $OFFSET); do
2129                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2130                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2131                 error "OST0 was degraded but new created file still use it"
2132         done
2133         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2134 }
2135 run_test 27x "create files while OST0 is degraded"
2136
2137 test_27y() {
2138         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2139         remote_mds_nodsh && skip "remote MDS with nodsh"
2140         remote_ost_nodsh && skip "remote OST with nodsh"
2141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2142
2143         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2144         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2145                 osp.$mdtosc.prealloc_last_id)
2146         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2147                 osp.$mdtosc.prealloc_next_id)
2148         local fcount=$((last_id - next_id))
2149         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2150         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2151
2152         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2153                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2154         local OST_DEACTIVE_IDX=-1
2155         local OSC
2156         local OSTIDX
2157         local OST
2158
2159         for OSC in $MDS_OSCS; do
2160                 OST=$(osc_to_ost $OSC)
2161                 OSTIDX=$(index_from_ostuuid $OST)
2162                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2163                         OST_DEACTIVE_IDX=$OSTIDX
2164                 fi
2165                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2166                         echo $OSC "is Deactivated:"
2167                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2168                 fi
2169         done
2170
2171         OSTIDX=$(index_from_ostuuid $OST)
2172         test_mkdir $DIR/$tdir
2173         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2174
2175         for OSC in $MDS_OSCS; do
2176                 OST=$(osc_to_ost $OSC)
2177                 OSTIDX=$(index_from_ostuuid $OST)
2178                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2179                         echo $OST "is degraded:"
2180                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2181                                                 obdfilter.$OST.degraded=1
2182                 fi
2183         done
2184
2185         sleep_maxage
2186         createmany -o $DIR/$tdir/$tfile $fcount
2187
2188         for OSC in $MDS_OSCS; do
2189                 OST=$(osc_to_ost $OSC)
2190                 OSTIDX=$(index_from_ostuuid $OST)
2191                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2192                         echo $OST "is recovered from degraded:"
2193                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2194                                                 obdfilter.$OST.degraded=0
2195                 else
2196                         do_facet $SINGLEMDS lctl --device %$OSC activate
2197                 fi
2198         done
2199
2200         # all osp devices get activated, hence -1 stripe count restored
2201         local stripe_count=0
2202
2203         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2204         # devices get activated.
2205         sleep_maxage
2206         $LFS setstripe -c -1 $DIR/$tfile
2207         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2208         rm -f $DIR/$tfile
2209         [ $stripe_count -ne $OSTCOUNT ] &&
2210                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2211         return 0
2212 }
2213 run_test 27y "create files while OST0 is degraded and the rest inactive"
2214
2215 check_seq_oid()
2216 {
2217         log "check file $1"
2218
2219         lmm_count=$($LFS getstripe -c $1)
2220         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2221         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2222
2223         local old_ifs="$IFS"
2224         IFS=$'[:]'
2225         fid=($($LFS path2fid $1))
2226         IFS="$old_ifs"
2227
2228         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2229         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2230
2231         # compare lmm_seq and lu_fid->f_seq
2232         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2233         # compare lmm_object_id and lu_fid->oid
2234         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2235
2236         # check the trusted.fid attribute of the OST objects of the file
2237         local have_obdidx=false
2238         local stripe_nr=0
2239         $LFS getstripe $1 | while read obdidx oid hex seq; do
2240                 # skip lines up to and including "obdidx"
2241                 [ -z "$obdidx" ] && break
2242                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2243                 $have_obdidx || continue
2244
2245                 local ost=$((obdidx + 1))
2246                 local dev=$(ostdevname $ost)
2247                 local oid_hex
2248
2249                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2250
2251                 seq=$(echo $seq | sed -e "s/^0x//g")
2252                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2253                         oid_hex=$(echo $oid)
2254                 else
2255                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2256                 fi
2257                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2258
2259                 local ff=""
2260                 #
2261                 # Don't unmount/remount the OSTs if we don't need to do that.
2262                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2263                 # update too, until that use mount/ll_decode_filter_fid/mount.
2264                 # Re-enable when debugfs will understand new filter_fid.
2265                 #
2266                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2267                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2268                                 $dev 2>/dev/null" | grep "parent=")
2269                 fi
2270                 if [ -z "$ff" ]; then
2271                         stop ost$ost
2272                         mount_fstype ost$ost
2273                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2274                                 $(facet_mntpt ost$ost)/$obj_file)
2275                         unmount_fstype ost$ost
2276                         start ost$ost $dev $OST_MOUNT_OPTS
2277                         clients_up
2278                 fi
2279
2280                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2281
2282                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2283
2284                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2285                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2286                 #
2287                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2288                 #       stripe_size=1048576 component_id=1 component_start=0 \
2289                 #       component_end=33554432
2290                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2291                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2292                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2293                 local ff_pstripe
2294                 if grep -q 'stripe=' <<<$ff; then
2295                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2296                 else
2297                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2298                         # into f_ver in this case.  See comment on ff_parent.
2299                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2300                 fi
2301
2302                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2303                 [ $ff_pseq = $lmm_seq ] ||
2304                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2305                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2306                 [ $ff_poid = $lmm_oid ] ||
2307                         error "FF parent OID $ff_poid != $lmm_oid"
2308                 (($ff_pstripe == $stripe_nr)) ||
2309                         error "FF stripe $ff_pstripe != $stripe_nr"
2310
2311                 stripe_nr=$((stripe_nr + 1))
2312                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2313                         continue
2314                 if grep -q 'stripe_count=' <<<$ff; then
2315                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2316                                             -e 's/ .*//' <<<$ff)
2317                         [ $lmm_count = $ff_scnt ] ||
2318                                 error "FF stripe count $lmm_count != $ff_scnt"
2319                 fi
2320         done
2321 }
2322
2323 test_27z() {
2324         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2325         remote_ost_nodsh && skip "remote OST with nodsh"
2326
2327         test_mkdir $DIR/$tdir
2328         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2329                 { error "setstripe -c -1 failed"; return 1; }
2330         # We need to send a write to every object to get parent FID info set.
2331         # This _should_ also work for setattr, but does not currently.
2332         # touch $DIR/$tdir/$tfile-1 ||
2333         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2334                 { error "dd $tfile-1 failed"; return 2; }
2335         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2336                 { error "setstripe -c -1 failed"; return 3; }
2337         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2338                 { error "dd $tfile-2 failed"; return 4; }
2339
2340         # make sure write RPCs have been sent to OSTs
2341         sync; sleep 5; sync
2342
2343         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2344         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2345 }
2346 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2347
2348 test_27A() { # b=19102
2349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2350
2351         save_layout_restore_at_exit $MOUNT
2352         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2353         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2354                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2355         local default_size=$($LFS getstripe -S $MOUNT)
2356         local default_offset=$($LFS getstripe -i $MOUNT)
2357         local dsize=$(do_facet $SINGLEMDS \
2358                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2359         [ $default_size -eq $dsize ] ||
2360                 error "stripe size $default_size != $dsize"
2361         [ $default_offset -eq -1 ] ||
2362                 error "stripe offset $default_offset != -1"
2363 }
2364 run_test 27A "check filesystem-wide default LOV EA values"
2365
2366 test_27B() { # LU-2523
2367         test_mkdir $DIR/$tdir
2368         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2369         touch $DIR/$tdir/f0
2370         # open f1 with O_LOV_DELAY_CREATE
2371         # rename f0 onto f1
2372         # call setstripe ioctl on open file descriptor for f1
2373         # close
2374         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2375                 $DIR/$tdir/f0
2376
2377         rm -f $DIR/$tdir/f1
2378         # open f1 with O_LOV_DELAY_CREATE
2379         # unlink f1
2380         # call setstripe ioctl on open file descriptor for f1
2381         # close
2382         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2383
2384         # Allow multiop to fail in imitation of NFS's busted semantics.
2385         true
2386 }
2387 run_test 27B "call setstripe on open unlinked file/rename victim"
2388
2389 # 27C family tests full striping and overstriping
2390 test_27Ca() { #LU-2871
2391         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2392
2393         declare -a ost_idx
2394         local index
2395         local found
2396         local i
2397         local j
2398
2399         test_mkdir $DIR/$tdir
2400         cd $DIR/$tdir
2401         for i in $(seq 0 $((OSTCOUNT - 1))); do
2402                 # set stripe across all OSTs starting from OST$i
2403                 $LFS setstripe -i $i -c -1 $tfile$i
2404                 # get striping information
2405                 ost_idx=($($LFS getstripe $tfile$i |
2406                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2407                 echo ${ost_idx[@]}
2408
2409                 # check the layout
2410                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2411                         error "${#ost_idx[@]} != $OSTCOUNT"
2412
2413                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2414                         found=0
2415                         for j in $(echo ${ost_idx[@]}); do
2416                                 if [ $index -eq $j ]; then
2417                                         found=1
2418                                         break
2419                                 fi
2420                         done
2421                         [ $found = 1 ] ||
2422                                 error "Can not find $index in ${ost_idx[@]}"
2423                 done
2424         done
2425 }
2426 run_test 27Ca "check full striping across all OSTs"
2427
2428 test_27Cb() {
2429         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2430                 skip "server does not support overstriping"
2431         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2432                 skip_env "too many osts, skipping"
2433
2434         test_mkdir -p $DIR/$tdir
2435         local setcount=$(($OSTCOUNT * 2))
2436         [ $setcount -lt 160 ] || large_xattr_enabled ||
2437                 skip_env "ea_inode feature disabled"
2438
2439         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2440                 error "setstripe failed"
2441
2442         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2443         [ $count -eq $setcount ] ||
2444                 error "stripe count $count, should be $setcount"
2445
2446         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2447                 error "overstriped should be set in pattern"
2448
2449         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2450                 error "dd failed"
2451 }
2452 run_test 27Cb "more stripes than OSTs with -C"
2453
2454 test_27Cc() {
2455         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2456                 skip "server does not support overstriping"
2457         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2458
2459         test_mkdir -p $DIR/$tdir
2460         local setcount=$(($OSTCOUNT - 1))
2461
2462         [ $setcount -lt 160 ] || large_xattr_enabled ||
2463                 skip_env "ea_inode feature disabled"
2464
2465         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2466                 error "setstripe failed"
2467
2468         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2469         [ $count -eq $setcount ] ||
2470                 error "stripe count $count, should be $setcount"
2471
2472         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2473                 error "overstriped should not be set in pattern"
2474
2475         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2476                 error "dd failed"
2477 }
2478 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2479
2480 test_27Cd() {
2481         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2482                 skip "server does not support overstriping"
2483         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2484         large_xattr_enabled || skip_env "ea_inode feature disabled"
2485
2486         test_mkdir -p $DIR/$tdir
2487         local setcount=$LOV_MAX_STRIPE_COUNT
2488
2489         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2490                 error "setstripe failed"
2491
2492         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2493         [ $count -eq $setcount ] ||
2494                 error "stripe count $count, should be $setcount"
2495
2496         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2497                 error "overstriped should be set in pattern"
2498
2499         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2500                 error "dd failed"
2501
2502         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2503 }
2504 run_test 27Cd "test maximum stripe count"
2505
2506 test_27Ce() {
2507         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2508                 skip "server does not support overstriping"
2509         test_mkdir -p $DIR/$tdir
2510
2511         pool_add $TESTNAME || error "Pool creation failed"
2512         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2513
2514         local setcount=8
2515
2516         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2517                 error "setstripe failed"
2518
2519         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2520         [ $count -eq $setcount ] ||
2521                 error "stripe count $count, should be $setcount"
2522
2523         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2524                 error "overstriped should be set in pattern"
2525
2526         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2527                 error "dd failed"
2528
2529         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2530 }
2531 run_test 27Ce "test pool with overstriping"
2532
2533 test_27Cf() {
2534         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2535                 skip "server does not support overstriping"
2536         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2537                 skip_env "too many osts, skipping"
2538
2539         test_mkdir -p $DIR/$tdir
2540
2541         local setcount=$(($OSTCOUNT * 2))
2542         [ $setcount -lt 160 ] || large_xattr_enabled ||
2543                 skip_env "ea_inode feature disabled"
2544
2545         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2546                 error "setstripe failed"
2547
2548         echo 1 > $DIR/$tdir/$tfile
2549
2550         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2551         [ $count -eq $setcount ] ||
2552                 error "stripe count $count, should be $setcount"
2553
2554         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2555                 error "overstriped should be set in pattern"
2556
2557         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2558                 error "dd failed"
2559
2560         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2561 }
2562 run_test 27Cf "test default inheritance with overstriping"
2563
2564 test_27D() {
2565         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2566         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2567         remote_mds_nodsh && skip "remote MDS with nodsh"
2568
2569         local POOL=${POOL:-testpool}
2570         local first_ost=0
2571         local last_ost=$(($OSTCOUNT - 1))
2572         local ost_step=1
2573         local ost_list=$(seq $first_ost $ost_step $last_ost)
2574         local ost_range="$first_ost $last_ost $ost_step"
2575
2576         test_mkdir $DIR/$tdir
2577         pool_add $POOL || error "pool_add failed"
2578         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2579
2580         local skip27D
2581         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2582                 skip27D+="-s 29"
2583         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2584                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2585                         skip27D+=" -s 30,31"
2586         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2587           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2588                 skip27D+=" -s 32,33"
2589         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2590                 skip27D+=" -s 34"
2591         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2592                 error "llapi_layout_test failed"
2593
2594         destroy_test_pools || error "destroy test pools failed"
2595 }
2596 run_test 27D "validate llapi_layout API"
2597
2598 # Verify that default_easize is increased from its initial value after
2599 # accessing a widely striped file.
2600 test_27E() {
2601         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2602         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2603                 skip "client does not have LU-3338 fix"
2604
2605         # 72 bytes is the minimum space required to store striping
2606         # information for a file striped across one OST:
2607         # (sizeof(struct lov_user_md_v3) +
2608         #  sizeof(struct lov_user_ost_data_v1))
2609         local min_easize=72
2610         $LCTL set_param -n llite.*.default_easize $min_easize ||
2611                 error "lctl set_param failed"
2612         local easize=$($LCTL get_param -n llite.*.default_easize)
2613
2614         [ $easize -eq $min_easize ] ||
2615                 error "failed to set default_easize"
2616
2617         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2618                 error "setstripe failed"
2619         # In order to ensure stat() call actually talks to MDS we need to
2620         # do something drastic to this file to shake off all lock, e.g.
2621         # rename it (kills lookup lock forcing cache cleaning)
2622         mv $DIR/$tfile $DIR/${tfile}-1
2623         ls -l $DIR/${tfile}-1
2624         rm $DIR/${tfile}-1
2625
2626         easize=$($LCTL get_param -n llite.*.default_easize)
2627
2628         [ $easize -gt $min_easize ] ||
2629                 error "default_easize not updated"
2630 }
2631 run_test 27E "check that default extended attribute size properly increases"
2632
2633 test_27F() { # LU-5346/LU-7975
2634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2635         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2636         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2637                 skip "Need MDS version at least 2.8.51"
2638         remote_ost_nodsh && skip "remote OST with nodsh"
2639
2640         test_mkdir $DIR/$tdir
2641         rm -f $DIR/$tdir/f0
2642         $LFS setstripe -c 2 $DIR/$tdir
2643
2644         # stop all OSTs to reproduce situation for LU-7975 ticket
2645         for num in $(seq $OSTCOUNT); do
2646                 stop ost$num
2647         done
2648
2649         # open/create f0 with O_LOV_DELAY_CREATE
2650         # truncate f0 to a non-0 size
2651         # close
2652         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2653
2654         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2655         # open/write it again to force delayed layout creation
2656         cat /etc/hosts > $DIR/$tdir/f0 &
2657         catpid=$!
2658
2659         # restart OSTs
2660         for num in $(seq $OSTCOUNT); do
2661                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2662                         error "ost$num failed to start"
2663         done
2664
2665         wait $catpid || error "cat failed"
2666
2667         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2668         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2669                 error "wrong stripecount"
2670
2671 }
2672 run_test 27F "Client resend delayed layout creation with non-zero size"
2673
2674 test_27G() { #LU-10629
2675         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2676                 skip "Need MDS version at least 2.11.51"
2677         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2678         remote_mds_nodsh && skip "remote MDS with nodsh"
2679         local POOL=${POOL:-testpool}
2680         local ostrange="0 0 1"
2681
2682         test_mkdir $DIR/$tdir
2683         touch $DIR/$tdir/$tfile.nopool
2684         pool_add $POOL || error "pool_add failed"
2685         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2686         $LFS setstripe -p $POOL $DIR/$tdir
2687
2688         local pool=$($LFS getstripe -p $DIR/$tdir)
2689
2690         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2691         touch $DIR/$tdir/$tfile.default
2692         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2693         $LFS find $DIR/$tdir -type f --pool $POOL
2694         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2695         [[ "$found" == "2" ]] ||
2696                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2697
2698         $LFS setstripe -d $DIR/$tdir
2699
2700         pool=$($LFS getstripe -p -d $DIR/$tdir)
2701
2702         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2703 }
2704 run_test 27G "Clear OST pool from stripe"
2705
2706 test_27H() {
2707         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2708                 skip "Need MDS version newer than 2.11.54"
2709         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2710         test_mkdir $DIR/$tdir
2711         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2712         touch $DIR/$tdir/$tfile
2713         $LFS getstripe -c $DIR/$tdir/$tfile
2714         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2715                 error "two-stripe file doesn't have two stripes"
2716
2717         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2718         $LFS getstripe -y $DIR/$tdir/$tfile
2719         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2720              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2721                 error "expected l_ost_idx: [02]$ not matched"
2722
2723         # make sure ost list has been cleared
2724         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2725         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2726                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2727         touch $DIR/$tdir/f3
2728         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2729 }
2730 run_test 27H "Set specific OSTs stripe"
2731
2732 test_27I() {
2733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2734         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2735         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2736                 skip "Need MDS version newer than 2.12.52"
2737         local pool=$TESTNAME
2738         local ostrange="1 1 1"
2739
2740         save_layout_restore_at_exit $MOUNT
2741         $LFS setstripe -c 2 -i 0 $MOUNT
2742         pool_add $pool || error "pool_add failed"
2743         pool_add_targets $pool $ostrange ||
2744                 error "pool_add_targets failed"
2745         test_mkdir $DIR/$tdir
2746         $LFS setstripe -p $pool $DIR/$tdir
2747         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2748         $LFS getstripe $DIR/$tdir/$tfile
2749 }
2750 run_test 27I "check that root dir striping does not break parent dir one"
2751
2752 test_27J() {
2753         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2754                 skip "Need MDS version newer than 2.12.51"
2755
2756         test_mkdir $DIR/$tdir
2757         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2758         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2759
2760         # create foreign file (raw way)
2761         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2762                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2763
2764         ! $LFS setstripe --foreign --flags foo \
2765                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2766                         error "creating $tfile with '--flags foo' should fail"
2767
2768         ! $LFS setstripe --foreign --flags 0xffffffff \
2769                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2770                         error "creating $tfile w/ 0xffffffff flags should fail"
2771
2772         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2773                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2774
2775         # verify foreign file (raw way)
2776         parse_foreign_file -f $DIR/$tdir/$tfile |
2777                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2778                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2779         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2780                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2781         parse_foreign_file -f $DIR/$tdir/$tfile |
2782                 grep "lov_foreign_size: 73" ||
2783                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2784         parse_foreign_file -f $DIR/$tdir/$tfile |
2785                 grep "lov_foreign_type: 1" ||
2786                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2787         parse_foreign_file -f $DIR/$tdir/$tfile |
2788                 grep "lov_foreign_flags: 0x0000DA08" ||
2789                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2790         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2791                 grep "lov_foreign_value: 0x" |
2792                 sed -e 's/lov_foreign_value: 0x//')
2793         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2794         [[ $lov = ${lov2// /} ]] ||
2795                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2796
2797         # create foreign file (lfs + API)
2798         $LFS setstripe --foreign=none --flags 0xda08 \
2799                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2800                 error "$DIR/$tdir/${tfile}2: create failed"
2801
2802         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2803                 grep "lfm_magic:.*0x0BD70BD0" ||
2804                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2805         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2806         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2807                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2808         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2809                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2810         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2811                 grep "lfm_flags:.*0x0000DA08" ||
2812                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2813         $LFS getstripe $DIR/$tdir/${tfile}2 |
2814                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2815                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2816
2817         # modify striping should fail
2818         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2819                 error "$DIR/$tdir/$tfile: setstripe should fail"
2820         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2821                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2822
2823         # R/W should fail
2824         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2825         cat $DIR/$tdir/${tfile}2 &&
2826                 error "$DIR/$tdir/${tfile}2: read should fail"
2827         cat /etc/passwd > $DIR/$tdir/$tfile &&
2828                 error "$DIR/$tdir/$tfile: write should fail"
2829         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2830                 error "$DIR/$tdir/${tfile}2: write should fail"
2831
2832         # chmod should work
2833         chmod 222 $DIR/$tdir/$tfile ||
2834                 error "$DIR/$tdir/$tfile: chmod failed"
2835         chmod 222 $DIR/$tdir/${tfile}2 ||
2836                 error "$DIR/$tdir/${tfile}2: chmod failed"
2837
2838         # chown should work
2839         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2840                 error "$DIR/$tdir/$tfile: chown failed"
2841         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2842                 error "$DIR/$tdir/${tfile}2: chown failed"
2843
2844         # rename should work
2845         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2846                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2847         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2848                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2849
2850         #remove foreign file
2851         rm $DIR/$tdir/${tfile}.new ||
2852                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2853         rm $DIR/$tdir/${tfile}2.new ||
2854                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2855 }
2856 run_test 27J "basic ops on file with foreign LOV"
2857
2858 test_27K() {
2859         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2860                 skip "Need MDS version newer than 2.12.49"
2861
2862         test_mkdir $DIR/$tdir
2863         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2864         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2865
2866         # create foreign dir (raw way)
2867         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2868                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2869
2870         ! $LFS setdirstripe --foreign --flags foo \
2871                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2872                         error "creating $tdir with '--flags foo' should fail"
2873
2874         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2875                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2876                         error "creating $tdir w/ 0xffffffff flags should fail"
2877
2878         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2879                 error "create_foreign_dir FAILED"
2880
2881         # verify foreign dir (raw way)
2882         parse_foreign_dir -d $DIR/$tdir/$tdir |
2883                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2884                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2885         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2886                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2887         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2888                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2889         parse_foreign_dir -d $DIR/$tdir/$tdir |
2890                 grep "lmv_foreign_flags: 55813$" ||
2891                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2892         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2893                 grep "lmv_foreign_value: 0x" |
2894                 sed 's/lmv_foreign_value: 0x//')
2895         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2896                 sed 's/ //g')
2897         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2898
2899         # create foreign dir (lfs + API)
2900         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2901                 $DIR/$tdir/${tdir}2 ||
2902                 error "$DIR/$tdir/${tdir}2: create failed"
2903
2904         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2905                 grep "lfm_magic:.*0x0CD50CD0" ||
2906                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2907         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2908         # - sizeof(lfm_type) - sizeof(lfm_flags)
2909         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2910                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2911         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2912                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2913         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2914                 grep "lfm_flags:.*0x0000DA05" ||
2915                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2916         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2917                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2918                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2919
2920         # file create in dir should fail
2921         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2922         touch $DIR/$tdir/${tdir}2/$tfile &&
2923                 "$DIR/${tdir}2: file create should fail"
2924
2925         # chmod should work
2926         chmod 777 $DIR/$tdir/$tdir ||
2927                 error "$DIR/$tdir: chmod failed"
2928         chmod 777 $DIR/$tdir/${tdir}2 ||
2929                 error "$DIR/${tdir}2: chmod failed"
2930
2931         # chown should work
2932         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2933                 error "$DIR/$tdir: chown failed"
2934         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2935                 error "$DIR/${tdir}2: chown failed"
2936
2937         # rename should work
2938         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2939                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2940         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2941                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2942
2943         #remove foreign dir
2944         rmdir $DIR/$tdir/${tdir}.new ||
2945                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2946         rmdir $DIR/$tdir/${tdir}2.new ||
2947                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2948 }
2949 run_test 27K "basic ops on dir with foreign LMV"
2950
2951 test_27L() {
2952         remote_mds_nodsh && skip "remote MDS with nodsh"
2953
2954         local POOL=${POOL:-$TESTNAME}
2955
2956         pool_add $POOL || error "pool_add failed"
2957
2958         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2959                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2960                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2961 }
2962 run_test 27L "lfs pool_list gives correct pool name"
2963
2964 test_27M() {
2965         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2966                 skip "Need MDS version >= than 2.12.57"
2967         remote_mds_nodsh && skip "remote MDS with nodsh"
2968         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2969
2970         test_mkdir $DIR/$tdir
2971
2972         # Set default striping on directory
2973         local setcount=4
2974         local stripe_opt
2975
2976         # if we run against a 2.12 server which lacks overstring support
2977         # then the connect_flag will not report overstriping, even if client
2978         # is 2.14+
2979         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
2980                 stripe_opt="-C $setcount"
2981         elif (( $OSTCOUNT >= $setcount )); then
2982                 stripe_opt="-c $setcount"
2983         else
2984                 skip "server does not support overstriping"
2985         fi
2986         $LFS setstripe $stripe_opt $DIR/$tdir
2987
2988         echo 1 > $DIR/$tdir/${tfile}.1
2989         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2990         [ $count -eq $setcount ] ||
2991                 error "(1) stripe count $count, should be $setcount"
2992
2993         # Capture existing append_stripe_count setting for restore
2994         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2995         local mdts=$(comma_list $(mdts_nodes))
2996         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2997
2998         local appendcount=$orig_count
2999         echo 1 >> $DIR/$tdir/${tfile}.2_append
3000         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3001         [ $count -eq $appendcount ] ||
3002                 error "(2)stripe count $count, should be $appendcount for append"
3003
3004         # Disable O_APPEND striping, verify it works
3005         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3006
3007         # Should now get the default striping, which is 4
3008         setcount=4
3009         echo 1 >> $DIR/$tdir/${tfile}.3_append
3010         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3011         [ $count -eq $setcount ] ||
3012                 error "(3) stripe count $count, should be $setcount"
3013
3014         # Try changing the stripe count for append files
3015         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3016
3017         # Append striping is now 2 (directory default is still 4)
3018         appendcount=2
3019         echo 1 >> $DIR/$tdir/${tfile}.4_append
3020         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3021         [ $count -eq $appendcount ] ||
3022                 error "(4) stripe count $count, should be $appendcount for append"
3023
3024         # Test append stripe count of -1
3025         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3026         appendcount=$OSTCOUNT
3027         echo 1 >> $DIR/$tdir/${tfile}.5
3028         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3029         [ $count -eq $appendcount ] ||
3030                 error "(5) stripe count $count, should be $appendcount for append"
3031
3032         # Set append striping back to default of 1
3033         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3034
3035         # Try a new default striping, PFL + DOM
3036         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3037
3038         # Create normal DOM file, DOM returns stripe count == 0
3039         setcount=0
3040         touch $DIR/$tdir/${tfile}.6
3041         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3042         [ $count -eq $setcount ] ||
3043                 error "(6) stripe count $count, should be $setcount"
3044
3045         # Show
3046         appendcount=1
3047         echo 1 >> $DIR/$tdir/${tfile}.7_append
3048         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3049         [ $count -eq $appendcount ] ||
3050                 error "(7) stripe count $count, should be $appendcount for append"
3051
3052         # Clean up DOM layout
3053         $LFS setstripe -d $DIR/$tdir
3054
3055         save_layout_restore_at_exit $MOUNT
3056         # Now test that append striping works when layout is from root
3057         $LFS setstripe -c 2 $MOUNT
3058         # Make a special directory for this
3059         mkdir $DIR/${tdir}/${tdir}.2
3060
3061         # Verify for normal file
3062         setcount=2
3063         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3064         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3065         [ $count -eq $setcount ] ||
3066                 error "(8) stripe count $count, should be $setcount"
3067
3068         appendcount=1
3069         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3070         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3071         [ $count -eq $appendcount ] ||
3072                 error "(9) stripe count $count, should be $appendcount for append"
3073
3074         # Now test O_APPEND striping with pools
3075         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3076         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
3077
3078         # Create the pool
3079         pool_add $TESTNAME || error "pool creation failed"
3080         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3081
3082         echo 1 >> $DIR/$tdir/${tfile}.10_append
3083
3084         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3085         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3086
3087         # Check that count is still correct
3088         appendcount=1
3089         echo 1 >> $DIR/$tdir/${tfile}.11_append
3090         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3091         [ $count -eq $appendcount ] ||
3092                 error "(11) stripe count $count, should be $appendcount for append"
3093
3094         # Disable O_APPEND stripe count, verify pool works separately
3095         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3096
3097         echo 1 >> $DIR/$tdir/${tfile}.12_append
3098
3099         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3100         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3101
3102         # Remove pool setting, verify it's not applied
3103         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3104
3105         echo 1 >> $DIR/$tdir/${tfile}.13_append
3106
3107         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3108         [ "$pool" = "" ] || error "(13) pool found: $pool"
3109 }
3110 run_test 27M "test O_APPEND striping"
3111
3112 test_27N() {
3113         combined_mgs_mds && skip "needs separate MGS/MDT"
3114
3115         pool_add $TESTNAME || error "pool_add failed"
3116         do_facet mgs "$LCTL pool_list $FSNAME" |
3117                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3118                 error "lctl pool_list on MGS failed"
3119 }
3120 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3121
3122 clean_foreign_symlink() {
3123         trap 0
3124         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3125         for i in $DIR/$tdir/* ; do
3126                 $LFS unlink_foreign $i || true
3127         done
3128 }
3129
3130 test_27O() {
3131         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3132                 skip "Need MDS version newer than 2.12.51"
3133
3134         test_mkdir $DIR/$tdir
3135         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3136         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3137
3138         trap clean_foreign_symlink EXIT
3139
3140         # enable foreign_symlink behaviour
3141         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3142
3143         # foreign symlink LOV format is a partial path by default
3144
3145         # create foreign file (lfs + API)
3146         $LFS setstripe --foreign=symlink --flags 0xda05 \
3147                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3148                 error "$DIR/$tdir/${tfile}: create failed"
3149
3150         $LFS getstripe -v $DIR/$tdir/${tfile} |
3151                 grep "lfm_magic:.*0x0BD70BD0" ||
3152                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3153         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3154                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3155         $LFS getstripe -v $DIR/$tdir/${tfile} |
3156                 grep "lfm_flags:.*0x0000DA05" ||
3157                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3158         $LFS getstripe $DIR/$tdir/${tfile} |
3159                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3160                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3161
3162         # modify striping should fail
3163         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3164                 error "$DIR/$tdir/$tfile: setstripe should fail"
3165
3166         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3167         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3168         cat /etc/passwd > $DIR/$tdir/$tfile &&
3169                 error "$DIR/$tdir/$tfile: write should fail"
3170
3171         # rename should succeed
3172         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3173                 error "$DIR/$tdir/$tfile: rename has failed"
3174
3175         #remove foreign_symlink file should fail
3176         rm $DIR/$tdir/${tfile}.new &&
3177                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3178
3179         #test fake symlink
3180         mkdir /tmp/${uuid1} ||
3181                 error "/tmp/${uuid1}: mkdir has failed"
3182         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3183                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3184         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3185         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3186                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3187         #read should succeed now
3188         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3189                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3190         #write should succeed now
3191         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3192                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3193         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3194                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3195         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3196                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3197
3198         #check that getstripe still works
3199         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3200                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3201
3202         # chmod should still succeed
3203         chmod 644 $DIR/$tdir/${tfile}.new ||
3204                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3205
3206         # chown should still succeed
3207         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3208                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3209
3210         # rename should still succeed
3211         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3212                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3213
3214         #remove foreign_symlink file should still fail
3215         rm $DIR/$tdir/${tfile} &&
3216                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3217
3218         #use special ioctl() to unlink foreign_symlink file
3219         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3220                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3221
3222 }
3223 run_test 27O "basic ops on foreign file of symlink type"
3224
3225 test_27P() {
3226         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3227                 skip "Need MDS version newer than 2.12.49"
3228
3229         test_mkdir $DIR/$tdir
3230         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3231         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3232
3233         trap clean_foreign_symlink EXIT
3234
3235         # enable foreign_symlink behaviour
3236         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3237
3238         # foreign symlink LMV format is a partial path by default
3239
3240         # create foreign dir (lfs + API)
3241         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3242                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3243                 error "$DIR/$tdir/${tdir}: create failed"
3244
3245         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3246                 grep "lfm_magic:.*0x0CD50CD0" ||
3247                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3248         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3249                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3250         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3251                 grep "lfm_flags:.*0x0000DA05" ||
3252                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3253         $LFS getdirstripe $DIR/$tdir/${tdir} |
3254                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3255                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3256
3257         # file create in dir should fail
3258         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3259         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
3260
3261         # rename should succeed
3262         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3263                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3264
3265         #remove foreign_symlink dir should fail
3266         rmdir $DIR/$tdir/${tdir}.new &&
3267                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3268
3269         #test fake symlink
3270         mkdir -p /tmp/${uuid1}/${uuid2} ||
3271                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3272         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3273                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3274         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3275         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3276                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3277         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3278                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3279
3280         #check that getstripe fails now that foreign_symlink enabled
3281         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3282                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3283
3284         # file create in dir should work now
3285         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3286                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3287         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3288                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3289         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3290                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3291
3292         # chmod should still succeed
3293         chmod 755 $DIR/$tdir/${tdir}.new ||
3294                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3295
3296         # chown should still succeed
3297         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3298                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3299
3300         # rename should still succeed
3301         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3302                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3303
3304         #remove foreign_symlink dir should still fail
3305         rmdir $DIR/$tdir/${tdir} &&
3306                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3307
3308         #use special ioctl() to unlink foreign_symlink file
3309         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3310                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3311
3312         #created file should still exist
3313         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3314                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3315         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3316                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3317 }
3318 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3319
3320 test_27Q() {
3321         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3322         stack_trap "rm -f $TMP/$tfile*"
3323
3324         test_mkdir $DIR/$tdir-1
3325         test_mkdir $DIR/$tdir-2
3326
3327         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3328         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3329
3330         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3331         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3332
3333         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3334         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3335
3336         # Create some bad symlinks and ensure that we don't loop
3337         # forever or something. These should return ELOOP (40) and
3338         # ENOENT (2) but I don't want to test for that because there's
3339         # always some weirdo architecture that needs to ruin
3340         # everything by defining these error numbers differently.
3341
3342         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3343         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3344
3345         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3346         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3347
3348         return 0
3349 }
3350 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3351
3352 test_27R() {
3353         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3354                 skip "need MDS 2.14.55 or later"
3355         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3356
3357         local testdir="$DIR/$tdir"
3358         test_mkdir -p $testdir
3359         stack_trap "rm -rf $testdir"
3360         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3361
3362         local f1="$testdir/f1"
3363         touch $f1 || error "failed to touch $f1"
3364         local count=$($LFS getstripe -c $f1)
3365         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3366
3367         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3368         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3369
3370         local maxcount=$(($OSTCOUNT - 1))
3371         local mdts=$(comma_list $(mdts_nodes))
3372         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3373         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3374
3375         local f2="$testdir/f2"
3376         touch $f2 || error "failed to touch $f2"
3377         local count=$($LFS getstripe -c $f2)
3378         (( $count == $maxcount )) || error "wrong stripe count"
3379 }
3380 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3381
3382 # createtest also checks that device nodes are created and
3383 # then visible correctly (#2091)
3384 test_28() { # bug 2091
3385         test_mkdir $DIR/d28
3386         $CREATETEST $DIR/d28/ct || error "createtest failed"
3387 }
3388 run_test 28 "create/mknod/mkdir with bad file types ============"
3389
3390 test_29() {
3391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3392
3393         sync; sleep 1; sync # flush out any dirty pages from previous tests
3394         cancel_lru_locks
3395         test_mkdir $DIR/d29
3396         touch $DIR/d29/foo
3397         log 'first d29'
3398         ls -l $DIR/d29
3399
3400         declare -i LOCKCOUNTORIG=0
3401         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3402                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3403         done
3404         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3405
3406         declare -i LOCKUNUSEDCOUNTORIG=0
3407         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3408                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3409         done
3410
3411         log 'second d29'
3412         ls -l $DIR/d29
3413         log 'done'
3414
3415         declare -i LOCKCOUNTCURRENT=0
3416         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3417                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3418         done
3419
3420         declare -i LOCKUNUSEDCOUNTCURRENT=0
3421         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3422                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3423         done
3424
3425         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3426                 $LCTL set_param -n ldlm.dump_namespaces ""
3427                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3428                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3429                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3430                 return 2
3431         fi
3432         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3433                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3434                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3435                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3436                 return 3
3437         fi
3438 }
3439 run_test 29 "IT_GETATTR regression  ============================"
3440
3441 test_30a() { # was test_30
3442         cp $(which ls) $DIR || cp /bin/ls $DIR
3443         $DIR/ls / || error "Can't execute binary from lustre"
3444         rm $DIR/ls
3445 }
3446 run_test 30a "execute binary from Lustre (execve) =============="
3447
3448 test_30b() {
3449         cp `which ls` $DIR || cp /bin/ls $DIR
3450         chmod go+rx $DIR/ls
3451         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3452         rm $DIR/ls
3453 }
3454 run_test 30b "execute binary from Lustre as non-root ==========="
3455
3456 test_30c() { # b=22376
3457         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3458
3459         cp $(which ls) $DIR || cp /bin/ls $DIR
3460         chmod a-rw $DIR/ls
3461         cancel_lru_locks mdc
3462         cancel_lru_locks osc
3463         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3464         rm -f $DIR/ls
3465 }
3466 run_test 30c "execute binary from Lustre without read perms ===="
3467
3468 test_30d() {
3469         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3470
3471         for i in {1..10}; do
3472                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3473                 local PID=$!
3474                 sleep 1
3475                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3476                 wait $PID || error "executing dd from Lustre failed"
3477                 rm -f $DIR/$tfile
3478         done
3479
3480         rm -f $DIR/dd
3481 }
3482 run_test 30d "execute binary from Lustre while clear locks"
3483
3484 test_31a() {
3485         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3486         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3487 }
3488 run_test 31a "open-unlink file =================================="
3489
3490 test_31b() {
3491         touch $DIR/f31 || error "touch $DIR/f31 failed"
3492         ln $DIR/f31 $DIR/f31b || error "ln failed"
3493         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3494         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3495 }
3496 run_test 31b "unlink file with multiple links while open ======="
3497
3498 test_31c() {
3499         touch $DIR/f31 || error "touch $DIR/f31 failed"
3500         ln $DIR/f31 $DIR/f31c || error "ln failed"
3501         multiop_bg_pause $DIR/f31 O_uc ||
3502                 error "multiop_bg_pause for $DIR/f31 failed"
3503         MULTIPID=$!
3504         $MULTIOP $DIR/f31c Ouc
3505         kill -USR1 $MULTIPID
3506         wait $MULTIPID
3507 }
3508 run_test 31c "open-unlink file with multiple links ============="
3509
3510 test_31d() {
3511         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3512         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3513 }
3514 run_test 31d "remove of open directory ========================="
3515
3516 test_31e() { # bug 2904
3517         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3518 }
3519 run_test 31e "remove of open non-empty directory ==============="
3520
3521 test_31f() { # bug 4554
3522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3523
3524         set -vx
3525         test_mkdir $DIR/d31f
3526         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3527         cp /etc/hosts $DIR/d31f
3528         ls -l $DIR/d31f
3529         $LFS getstripe $DIR/d31f/hosts
3530         multiop_bg_pause $DIR/d31f D_c || return 1
3531         MULTIPID=$!
3532
3533         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3534         test_mkdir $DIR/d31f
3535         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3536         cp /etc/hosts $DIR/d31f
3537         ls -l $DIR/d31f
3538         $LFS getstripe $DIR/d31f/hosts
3539         multiop_bg_pause $DIR/d31f D_c || return 1
3540         MULTIPID2=$!
3541
3542         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3543         wait $MULTIPID || error "first opendir $MULTIPID failed"
3544
3545         sleep 6
3546
3547         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3548         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3549         set +vx
3550 }
3551 run_test 31f "remove of open directory with open-unlink file ==="
3552
3553 test_31g() {
3554         echo "-- cross directory link --"
3555         test_mkdir -c1 $DIR/${tdir}ga
3556         test_mkdir -c1 $DIR/${tdir}gb
3557         touch $DIR/${tdir}ga/f
3558         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3559         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3560         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3561         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3562         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3563 }
3564 run_test 31g "cross directory link==============="
3565
3566 test_31h() {
3567         echo "-- cross directory link --"
3568         test_mkdir -c1 $DIR/${tdir}
3569         test_mkdir -c1 $DIR/${tdir}/dir
3570         touch $DIR/${tdir}/f
3571         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3572         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3573         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3574         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3575         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3576 }
3577 run_test 31h "cross directory link under child==============="
3578
3579 test_31i() {
3580         echo "-- cross directory link --"
3581         test_mkdir -c1 $DIR/$tdir
3582         test_mkdir -c1 $DIR/$tdir/dir
3583         touch $DIR/$tdir/dir/f
3584         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3585         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3586         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3587         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3588         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3589 }
3590 run_test 31i "cross directory link under parent==============="
3591
3592 test_31j() {
3593         test_mkdir -c1 -p $DIR/$tdir
3594         test_mkdir -c1 -p $DIR/$tdir/dir1
3595         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3596         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3597         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3598         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3599         return 0
3600 }
3601 run_test 31j "link for directory==============="
3602
3603 test_31k() {
3604         test_mkdir -c1 -p $DIR/$tdir
3605         touch $DIR/$tdir/s
3606         touch $DIR/$tdir/exist
3607         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3608         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3609         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3610         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3611         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3612         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3613         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3614         return 0
3615 }
3616 run_test 31k "link to file: the same, non-existing, dir==============="
3617
3618 test_31m() {
3619         mkdir $DIR/d31m
3620         touch $DIR/d31m/s
3621         mkdir $DIR/d31m2
3622         touch $DIR/d31m2/exist
3623         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3624         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3625         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3626         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3627         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3628         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3629         return 0
3630 }
3631 run_test 31m "link to file: the same, non-existing, dir==============="
3632
3633 test_31n() {
3634         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3635         nlink=$(stat --format=%h $DIR/$tfile)
3636         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3637         local fd=$(free_fd)
3638         local cmd="exec $fd<$DIR/$tfile"
3639         eval $cmd
3640         cmd="exec $fd<&-"
3641         trap "eval $cmd" EXIT
3642         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3643         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3644         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3645         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3646         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3647         eval $cmd
3648 }
3649 run_test 31n "check link count of unlinked file"
3650
3651 link_one() {
3652         local tempfile=$(mktemp $1_XXXXXX)
3653         mlink $tempfile $1 2> /dev/null &&
3654                 echo "$BASHPID: link $tempfile to $1 succeeded"
3655         munlink $tempfile
3656 }
3657
3658 test_31o() { # LU-2901
3659         test_mkdir $DIR/$tdir
3660         for LOOP in $(seq 100); do
3661                 rm -f $DIR/$tdir/$tfile*
3662                 for THREAD in $(seq 8); do
3663                         link_one $DIR/$tdir/$tfile.$LOOP &
3664                 done
3665                 wait
3666                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3667                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3668                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3669                         break || true
3670         done
3671 }
3672 run_test 31o "duplicate hard links with same filename"
3673
3674 test_31p() {
3675         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3676
3677         test_mkdir $DIR/$tdir
3678         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3679         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3680
3681         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3682                 error "open unlink test1 failed"
3683         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3684                 error "open unlink test2 failed"
3685
3686         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3687                 error "test1 still exists"
3688         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3689                 error "test2 still exists"
3690 }
3691 run_test 31p "remove of open striped directory"
3692
3693 test_31q() {
3694         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3695
3696         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3697         index=$($LFS getdirstripe -i $DIR/$tdir)
3698         [ $index -eq 3 ] || error "first stripe index $index != 3"
3699         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3700         [ $index -eq 1 ] || error "second stripe index $index != 1"
3701
3702         # when "-c <stripe_count>" is set, the number of MDTs specified after
3703         # "-i" should equal to the stripe count
3704         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3705 }
3706 run_test 31q "create striped directory on specific MDTs"
3707
3708 #LU-14949
3709 test_31r() {
3710         touch $DIR/$tfile.target
3711         touch $DIR/$tfile.source
3712
3713         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3714         $LCTL set_param fail_loc=0x1419 fail_val=3
3715         cat $DIR/$tfile.target &
3716         CATPID=$!
3717
3718         # Guarantee open is waiting before we get here
3719         sleep 1
3720         mv $DIR/$tfile.source $DIR/$tfile.target
3721
3722         wait $CATPID
3723         RC=$?
3724         if [[ $RC -ne 0 ]]; then
3725                 error "open with cat failed, rc=$RC"
3726         fi
3727 }
3728 run_test 31r "open-rename(replace) race"
3729
3730 cleanup_test32_mount() {
3731         local rc=0
3732         trap 0
3733         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3734         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3735         losetup -d $loopdev || true
3736         rm -rf $DIR/$tdir
3737         return $rc
3738 }
3739
3740 test_32a() {
3741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3742
3743         echo "== more mountpoints and symlinks ================="
3744         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3745         trap cleanup_test32_mount EXIT
3746         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3747         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3748                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3749         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3750                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3751         cleanup_test32_mount
3752 }
3753 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3754
3755 test_32b() {
3756         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3757
3758         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3759         trap cleanup_test32_mount EXIT
3760         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3761         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3762                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3763         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3764                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3765         cleanup_test32_mount
3766 }
3767 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3768
3769 test_32c() {
3770         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3771
3772         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3773         trap cleanup_test32_mount EXIT
3774         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3775         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3776                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3777         test_mkdir -p $DIR/$tdir/d2/test_dir
3778         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3779                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3780         cleanup_test32_mount
3781 }
3782 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3783
3784 test_32d() {
3785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3786
3787         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3788         trap cleanup_test32_mount EXIT
3789         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3790         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3791                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3792         test_mkdir -p $DIR/$tdir/d2/test_dir
3793         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3794                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3795         cleanup_test32_mount
3796 }
3797 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3798
3799 test_32e() {
3800         rm -fr $DIR/$tdir
3801         test_mkdir -p $DIR/$tdir/tmp
3802         local tmp_dir=$DIR/$tdir/tmp
3803         ln -s $DIR/$tdir $tmp_dir/symlink11
3804         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3805         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3806         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3807 }
3808 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3809
3810 test_32f() {
3811         rm -fr $DIR/$tdir
3812         test_mkdir -p $DIR/$tdir/tmp
3813         local tmp_dir=$DIR/$tdir/tmp
3814         ln -s $DIR/$tdir $tmp_dir/symlink11
3815         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3816         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3817         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3818 }
3819 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3820
3821 test_32g() {
3822         local tmp_dir=$DIR/$tdir/tmp
3823         test_mkdir -p $tmp_dir
3824         test_mkdir $DIR/${tdir}2
3825         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3826         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3827         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3828         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3829         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3830         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3831 }
3832 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3833
3834 test_32h() {
3835         rm -fr $DIR/$tdir $DIR/${tdir}2
3836         tmp_dir=$DIR/$tdir/tmp
3837         test_mkdir -p $tmp_dir
3838         test_mkdir $DIR/${tdir}2
3839         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3840         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3841         ls $tmp_dir/symlink12 || error "listing symlink12"
3842         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3843 }
3844 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3845
3846 test_32i() {
3847         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3848
3849         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3850         trap cleanup_test32_mount EXIT
3851         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3852         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3853                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3854         touch $DIR/$tdir/test_file
3855         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3856                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3857         cleanup_test32_mount
3858 }
3859 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3860
3861 test_32j() {
3862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3863
3864         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3865         trap cleanup_test32_mount EXIT
3866         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3867         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3868                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3869         touch $DIR/$tdir/test_file
3870         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3871                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3872         cleanup_test32_mount
3873 }
3874 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3875
3876 test_32k() {
3877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3878
3879         rm -fr $DIR/$tdir
3880         trap cleanup_test32_mount EXIT
3881         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3882         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3883                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3884         test_mkdir -p $DIR/$tdir/d2
3885         touch $DIR/$tdir/d2/test_file || error "touch failed"
3886         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3887                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3888         cleanup_test32_mount
3889 }
3890 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3891
3892 test_32l() {
3893         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3894
3895         rm -fr $DIR/$tdir
3896         trap cleanup_test32_mount EXIT
3897         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3898         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3899                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3900         test_mkdir -p $DIR/$tdir/d2
3901         touch $DIR/$tdir/d2/test_file || error "touch failed"
3902         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3903                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3904         cleanup_test32_mount
3905 }
3906 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3907
3908 test_32m() {
3909         rm -fr $DIR/d32m
3910         test_mkdir -p $DIR/d32m/tmp
3911         TMP_DIR=$DIR/d32m/tmp
3912         ln -s $DIR $TMP_DIR/symlink11
3913         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3914         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3915                 error "symlink11 not a link"
3916         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3917                 error "symlink01 not a link"
3918 }
3919 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3920
3921 test_32n() {
3922         rm -fr $DIR/d32n
3923         test_mkdir -p $DIR/d32n/tmp
3924         TMP_DIR=$DIR/d32n/tmp
3925         ln -s $DIR $TMP_DIR/symlink11
3926         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3927         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3928         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3929 }
3930 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3931
3932 test_32o() {
3933         touch $DIR/$tfile
3934         test_mkdir -p $DIR/d32o/tmp
3935         TMP_DIR=$DIR/d32o/tmp
3936         ln -s $DIR/$tfile $TMP_DIR/symlink12
3937         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3938         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3939                 error "symlink12 not a link"
3940         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3941         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3942                 error "$DIR/d32o/tmp/symlink12 not file type"
3943         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3944                 error "$DIR/d32o/symlink02 not file type"
3945 }
3946 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3947
3948 test_32p() {
3949         log 32p_1
3950         rm -fr $DIR/d32p
3951         log 32p_2
3952         rm -f $DIR/$tfile
3953         log 32p_3
3954         touch $DIR/$tfile
3955         log 32p_4
3956         test_mkdir -p $DIR/d32p/tmp
3957         log 32p_5
3958         TMP_DIR=$DIR/d32p/tmp
3959         log 32p_6
3960         ln -s $DIR/$tfile $TMP_DIR/symlink12
3961         log 32p_7
3962         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3963         log 32p_8
3964         cat $DIR/d32p/tmp/symlink12 ||
3965                 error "Can't open $DIR/d32p/tmp/symlink12"
3966         log 32p_9
3967         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3968         log 32p_10
3969 }
3970 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3971
3972 test_32q() {
3973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3974
3975         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3976         trap cleanup_test32_mount EXIT
3977         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3978         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3979         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3980                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3981         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3982         cleanup_test32_mount
3983 }
3984 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3985
3986 test_32r() {
3987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3988
3989         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3990         trap cleanup_test32_mount EXIT
3991         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3992         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3993         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3994                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3995         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3996         cleanup_test32_mount
3997 }
3998 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3999
4000 test_33aa() {
4001         rm -f $DIR/$tfile
4002         touch $DIR/$tfile
4003         chmod 444 $DIR/$tfile
4004         chown $RUNAS_ID $DIR/$tfile
4005         log 33_1
4006         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4007         log 33_2
4008 }
4009 run_test 33aa "write file with mode 444 (should return error)"
4010
4011 test_33a() {
4012         rm -fr $DIR/$tdir
4013         test_mkdir $DIR/$tdir
4014         chown $RUNAS_ID $DIR/$tdir
4015         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4016                 error "$RUNAS create $tdir/$tfile failed"
4017         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4018                 error "open RDWR" || true
4019 }
4020 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4021
4022 test_33b() {
4023         rm -fr $DIR/$tdir
4024         test_mkdir $DIR/$tdir
4025         chown $RUNAS_ID $DIR/$tdir
4026         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4027 }
4028 run_test 33b "test open file with malformed flags (No panic)"
4029
4030 test_33c() {
4031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4032         remote_ost_nodsh && skip "remote OST with nodsh"
4033
4034         local ostnum
4035         local ostname
4036         local write_bytes
4037         local all_zeros
4038
4039         all_zeros=true
4040         test_mkdir $DIR/$tdir
4041         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4042
4043         sync
4044         for ostnum in $(seq $OSTCOUNT); do
4045                 # test-framework's OST numbering is one-based, while Lustre's
4046                 # is zero-based
4047                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4048                 # check if at least some write_bytes stats are counted
4049                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4050                               obdfilter.$ostname.stats |
4051                               awk '/^write_bytes/ {print $7}' )
4052                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4053                 if (( ${write_bytes:-0} > 0 )); then
4054                         all_zeros=false
4055                         break
4056                 fi
4057         done
4058
4059         $all_zeros || return 0
4060
4061         # Write four bytes
4062         echo foo > $DIR/$tdir/bar
4063         # Really write them
4064         sync
4065
4066         # Total up write_bytes after writing.  We'd better find non-zeros.
4067         for ostnum in $(seq $OSTCOUNT); do
4068                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4069                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4070                               obdfilter/$ostname/stats |
4071                               awk '/^write_bytes/ {print $7}' )
4072                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4073                 if (( ${write_bytes:-0} > 0 )); then
4074                         all_zeros=false
4075                         break
4076                 fi
4077         done
4078
4079         if $all_zeros; then
4080                 for ostnum in $(seq $OSTCOUNT); do
4081                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4082                         echo "Check write_bytes is in obdfilter.*.stats:"
4083                         do_facet ost$ostnum lctl get_param -n \
4084                                 obdfilter.$ostname.stats
4085                 done
4086                 error "OST not keeping write_bytes stats (b=22312)"
4087         fi
4088 }
4089 run_test 33c "test write_bytes stats"
4090
4091 test_33d() {
4092         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4094
4095         local MDTIDX=1
4096         local remote_dir=$DIR/$tdir/remote_dir
4097
4098         test_mkdir $DIR/$tdir
4099         $LFS mkdir -i $MDTIDX $remote_dir ||
4100                 error "create remote directory failed"
4101
4102         touch $remote_dir/$tfile
4103         chmod 444 $remote_dir/$tfile
4104         chown $RUNAS_ID $remote_dir/$tfile
4105
4106         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4107
4108         chown $RUNAS_ID $remote_dir
4109         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4110                                         error "create" || true
4111         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4112                                     error "open RDWR" || true
4113         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4114 }
4115 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4116
4117 test_33e() {
4118         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4119
4120         mkdir $DIR/$tdir
4121
4122         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4123         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4124         mkdir $DIR/$tdir/local_dir
4125
4126         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4127         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4128         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4129
4130         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4131                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4132
4133         rmdir $DIR/$tdir/* || error "rmdir failed"
4134
4135         umask 777
4136         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4137         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4138         mkdir $DIR/$tdir/local_dir
4139
4140         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4141         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4142         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4143
4144         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4145                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4146
4147         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4148
4149         umask 000
4150         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4151         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4152         mkdir $DIR/$tdir/local_dir
4153
4154         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4155         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4156         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4157
4158         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4159                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4160 }
4161 run_test 33e "mkdir and striped directory should have same mode"
4162
4163 cleanup_33f() {
4164         trap 0
4165         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4166 }
4167
4168 test_33f() {
4169         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4170         remote_mds_nodsh && skip "remote MDS with nodsh"
4171
4172         mkdir $DIR/$tdir
4173         chmod go+rwx $DIR/$tdir
4174         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4175         trap cleanup_33f EXIT
4176
4177         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4178                 error "cannot create striped directory"
4179
4180         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4181                 error "cannot create files in striped directory"
4182
4183         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4184                 error "cannot remove files in striped directory"
4185
4186         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4187                 error "cannot remove striped directory"
4188
4189         cleanup_33f
4190 }
4191 run_test 33f "nonroot user can create, access, and remove a striped directory"
4192
4193 test_33g() {
4194         mkdir -p $DIR/$tdir/dir2
4195
4196         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4197         echo $err
4198         [[ $err =~ "exists" ]] || error "Not exists error"
4199 }
4200 run_test 33g "nonroot user create already existing root created file"
4201
4202 test_33h() {
4203         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4204         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
4205                 skip "Need MDS version at least 2.13.50"
4206
4207         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
4208                 error "mkdir $tdir failed"
4209         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4210
4211         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4212         local index2
4213
4214         for fname in $DIR/$tdir/$tfile.bak \
4215                      $DIR/$tdir/$tfile.SAV \
4216                      $DIR/$tdir/$tfile.orig \
4217                      $DIR/$tdir/$tfile~; do
4218                 touch $fname  || error "touch $fname failed"
4219                 index2=$($LFS getstripe -m $fname)
4220                 [ $index -eq $index2 ] ||
4221                         error "$fname MDT index mismatch $index != $index2"
4222         done
4223
4224         local failed=0
4225         for i in {1..250}; do
4226                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
4227                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
4228                         touch $fname  || error "touch $fname failed"
4229                         index2=$($LFS getstripe -m $fname)
4230                         if [[ $index != $index2 ]]; then
4231                                 failed=$((failed + 1))
4232                                 echo "$fname MDT index mismatch $index != $index2"
4233                         fi
4234                 done
4235         done
4236         echo "$failed MDT index mismatches"
4237         (( failed < 20 )) || error "MDT index mismatch $failed times"
4238
4239 }
4240 run_test 33h "temp file is located on the same MDT as target"
4241
4242 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4243 test_34a() {
4244         rm -f $DIR/f34
4245         $MCREATE $DIR/f34 || error "mcreate failed"
4246         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4247                 error "getstripe failed"
4248         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4249         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4250                 error "getstripe failed"
4251         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4252                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4253 }
4254 run_test 34a "truncate file that has not been opened ==========="
4255
4256 test_34b() {
4257         [ ! -f $DIR/f34 ] && test_34a
4258         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4259                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4260         $OPENFILE -f O_RDONLY $DIR/f34
4261         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4262                 error "getstripe failed"
4263         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4264                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4265 }
4266 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4267
4268 test_34c() {
4269         [ ! -f $DIR/f34 ] && test_34a
4270         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4271                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4272         $OPENFILE -f O_RDWR $DIR/f34
4273         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4274                 error "$LFS getstripe failed"
4275         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4276                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4277 }
4278 run_test 34c "O_RDWR opening file-with-size works =============="
4279
4280 test_34d() {
4281         [ ! -f $DIR/f34 ] && test_34a
4282         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4283                 error "dd failed"
4284         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4285                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4286         rm $DIR/f34
4287 }
4288 run_test 34d "write to sparse file ============================="
4289
4290 test_34e() {
4291         rm -f $DIR/f34e
4292         $MCREATE $DIR/f34e || error "mcreate failed"
4293         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4294         $CHECKSTAT -s 1000 $DIR/f34e ||
4295                 error "Size of $DIR/f34e not equal to 1000 bytes"
4296         $OPENFILE -f O_RDWR $DIR/f34e
4297         $CHECKSTAT -s 1000 $DIR/f34e ||
4298                 error "Size of $DIR/f34e not equal to 1000 bytes"
4299 }
4300 run_test 34e "create objects, some with size and some without =="
4301
4302 test_34f() { # bug 6242, 6243
4303         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4304
4305         SIZE34F=48000
4306         rm -f $DIR/f34f
4307         $MCREATE $DIR/f34f || error "mcreate failed"
4308         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4309         dd if=$DIR/f34f of=$TMP/f34f
4310         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4311         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4312         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4313         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4314         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4315 }
4316 run_test 34f "read from a file with no objects until EOF ======="
4317
4318 test_34g() {
4319         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4320
4321         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4322                 error "dd failed"
4323         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4324         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4325                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4326         cancel_lru_locks osc
4327         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4328                 error "wrong size after lock cancel"
4329
4330         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4331         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4332                 error "expanding truncate failed"
4333         cancel_lru_locks osc
4334         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4335                 error "wrong expanded size after lock cancel"
4336 }
4337 run_test 34g "truncate long file ==============================="
4338
4339 test_34h() {
4340         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4341
4342         local gid=10
4343         local sz=1000
4344
4345         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4346         sync # Flush the cache so that multiop below does not block on cache
4347              # flush when getting the group lock
4348         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4349         MULTIPID=$!
4350
4351         # Since just timed wait is not good enough, let's do a sync write
4352         # that way we are sure enough time for a roundtrip + processing
4353         # passed + 2 seconds of extra margin.
4354         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4355         rm $DIR/${tfile}-1
4356         sleep 2
4357
4358         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4359                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4360                 kill -9 $MULTIPID
4361         fi
4362         wait $MULTIPID
4363         local nsz=`stat -c %s $DIR/$tfile`
4364         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4365 }
4366 run_test 34h "ftruncate file under grouplock should not block"
4367
4368 test_35a() {
4369         cp /bin/sh $DIR/f35a
4370         chmod 444 $DIR/f35a
4371         chown $RUNAS_ID $DIR/f35a
4372         $RUNAS $DIR/f35a && error || true
4373         rm $DIR/f35a
4374 }
4375 run_test 35a "exec file with mode 444 (should return and not leak)"
4376
4377 test_36a() {
4378         rm -f $DIR/f36
4379         utime $DIR/f36 || error "utime failed for MDS"
4380 }
4381 run_test 36a "MDS utime check (mknod, utime)"
4382
4383 test_36b() {
4384         echo "" > $DIR/f36
4385         utime $DIR/f36 || error "utime failed for OST"
4386 }
4387 run_test 36b "OST utime check (open, utime)"
4388
4389 test_36c() {
4390         rm -f $DIR/d36/f36
4391         test_mkdir $DIR/d36
4392         chown $RUNAS_ID $DIR/d36
4393         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4394 }
4395 run_test 36c "non-root MDS utime check (mknod, utime)"
4396
4397 test_36d() {
4398         [ ! -d $DIR/d36 ] && test_36c
4399         echo "" > $DIR/d36/f36
4400         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4401 }
4402 run_test 36d "non-root OST utime check (open, utime)"
4403
4404 test_36e() {
4405         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4406
4407         test_mkdir $DIR/$tdir
4408         touch $DIR/$tdir/$tfile
4409         $RUNAS utime $DIR/$tdir/$tfile &&
4410                 error "utime worked, expected failure" || true
4411 }
4412 run_test 36e "utime on non-owned file (should return error)"
4413
4414 subr_36fh() {
4415         local fl="$1"
4416         local LANG_SAVE=$LANG
4417         local LC_LANG_SAVE=$LC_LANG
4418         export LANG=C LC_LANG=C # for date language
4419
4420         DATESTR="Dec 20  2000"
4421         test_mkdir $DIR/$tdir
4422         lctl set_param fail_loc=$fl
4423         date; date +%s
4424         cp /etc/hosts $DIR/$tdir/$tfile
4425         sync & # write RPC generated with "current" inode timestamp, but delayed
4426         sleep 1
4427         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4428         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4429         cancel_lru_locks $OSC
4430         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4431         date; date +%s
4432         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4433                 echo "BEFORE: $LS_BEFORE" && \
4434                 echo "AFTER : $LS_AFTER" && \
4435                 echo "WANT  : $DATESTR" && \
4436                 error "$DIR/$tdir/$tfile timestamps changed" || true
4437
4438         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4439 }
4440
4441 test_36f() {
4442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4443
4444         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4445         subr_36fh "0x80000214"
4446 }
4447 run_test 36f "utime on file racing with OST BRW write =========="
4448
4449 test_36g() {
4450         remote_ost_nodsh && skip "remote OST with nodsh"
4451         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4452         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4453                 skip "Need MDS version at least 2.12.51"
4454
4455         local fmd_max_age
4456         local fmd
4457         local facet="ost1"
4458         local tgt="obdfilter"
4459
4460         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4461
4462         test_mkdir $DIR/$tdir
4463         fmd_max_age=$(do_facet $facet \
4464                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4465                 head -n 1")
4466
4467         echo "FMD max age: ${fmd_max_age}s"
4468         touch $DIR/$tdir/$tfile
4469         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4470                 gawk '{cnt=cnt+$1}  END{print cnt}')
4471         echo "FMD before: $fmd"
4472         [[ $fmd == 0 ]] &&
4473                 error "FMD wasn't create by touch"
4474         sleep $((fmd_max_age + 12))
4475         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4476                 gawk '{cnt=cnt+$1}  END{print cnt}')
4477         echo "FMD after: $fmd"
4478         [[ $fmd == 0 ]] ||
4479                 error "FMD wasn't expired by ping"
4480 }
4481 run_test 36g "FMD cache expiry ====================="
4482
4483 test_36h() {
4484         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4485
4486         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4487         subr_36fh "0x80000227"
4488 }
4489 run_test 36h "utime on file racing with OST BRW write =========="
4490
4491 test_36i() {
4492         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4493
4494         test_mkdir $DIR/$tdir
4495         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4496
4497         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4498         local new_mtime=$((mtime + 200))
4499
4500         #change Modify time of striped dir
4501         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4502                         error "change mtime failed"
4503
4504         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4505
4506         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4507 }
4508 run_test 36i "change mtime on striped directory"
4509
4510 # test_37 - duplicate with tests 32q 32r
4511
4512 test_38() {
4513         local file=$DIR/$tfile
4514         touch $file
4515         openfile -f O_DIRECTORY $file
4516         local RC=$?
4517         local ENOTDIR=20
4518         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4519         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4520 }
4521 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4522
4523 test_39a() { # was test_39
4524         touch $DIR/$tfile
4525         touch $DIR/${tfile}2
4526 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4527 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4528 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4529         sleep 2
4530         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4531         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4532                 echo "mtime"
4533                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4534                 echo "atime"
4535                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4536                 echo "ctime"
4537                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4538                 error "O_TRUNC didn't change timestamps"
4539         fi
4540 }
4541 run_test 39a "mtime changed on create"
4542
4543 test_39b() {
4544         test_mkdir -c1 $DIR/$tdir
4545         cp -p /etc/passwd $DIR/$tdir/fopen
4546         cp -p /etc/passwd $DIR/$tdir/flink
4547         cp -p /etc/passwd $DIR/$tdir/funlink
4548         cp -p /etc/passwd $DIR/$tdir/frename
4549         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4550
4551         sleep 1
4552         echo "aaaaaa" >> $DIR/$tdir/fopen
4553         echo "aaaaaa" >> $DIR/$tdir/flink
4554         echo "aaaaaa" >> $DIR/$tdir/funlink
4555         echo "aaaaaa" >> $DIR/$tdir/frename
4556
4557         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4558         local link_new=`stat -c %Y $DIR/$tdir/flink`
4559         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4560         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4561
4562         cat $DIR/$tdir/fopen > /dev/null
4563         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4564         rm -f $DIR/$tdir/funlink2
4565         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4566
4567         for (( i=0; i < 2; i++ )) ; do
4568                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4569                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4570                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4571                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4572
4573                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4574                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4575                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4576                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4577
4578                 cancel_lru_locks $OSC
4579                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4580         done
4581 }
4582 run_test 39b "mtime change on open, link, unlink, rename  ======"
4583
4584 # this should be set to past
4585 TEST_39_MTIME=`date -d "1 year ago" +%s`
4586
4587 # bug 11063
4588 test_39c() {
4589         touch $DIR1/$tfile
4590         sleep 2
4591         local mtime0=`stat -c %Y $DIR1/$tfile`
4592
4593         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4594         local mtime1=`stat -c %Y $DIR1/$tfile`
4595         [ "$mtime1" = $TEST_39_MTIME ] || \
4596                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4597
4598         local d1=`date +%s`
4599         echo hello >> $DIR1/$tfile
4600         local d2=`date +%s`
4601         local mtime2=`stat -c %Y $DIR1/$tfile`
4602         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4603                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4604
4605         mv $DIR1/$tfile $DIR1/$tfile-1
4606
4607         for (( i=0; i < 2; i++ )) ; do
4608                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4609                 [ "$mtime2" = "$mtime3" ] || \
4610                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4611
4612                 cancel_lru_locks $OSC
4613                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4614         done
4615 }
4616 run_test 39c "mtime change on rename ==========================="
4617
4618 # bug 21114
4619 test_39d() {
4620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4621
4622         touch $DIR1/$tfile
4623         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4624
4625         for (( i=0; i < 2; i++ )) ; do
4626                 local mtime=`stat -c %Y $DIR1/$tfile`
4627                 [ $mtime = $TEST_39_MTIME ] || \
4628                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4629
4630                 cancel_lru_locks $OSC
4631                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4632         done
4633 }
4634 run_test 39d "create, utime, stat =============================="
4635
4636 # bug 21114
4637 test_39e() {
4638         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4639
4640         touch $DIR1/$tfile
4641         local mtime1=`stat -c %Y $DIR1/$tfile`
4642
4643         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4644
4645         for (( i=0; i < 2; i++ )) ; do
4646                 local mtime2=`stat -c %Y $DIR1/$tfile`
4647                 [ $mtime2 = $TEST_39_MTIME ] || \
4648                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4649
4650                 cancel_lru_locks $OSC
4651                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4652         done
4653 }
4654 run_test 39e "create, stat, utime, stat ========================"
4655
4656 # bug 21114
4657 test_39f() {
4658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4659
4660         touch $DIR1/$tfile
4661         mtime1=`stat -c %Y $DIR1/$tfile`
4662
4663         sleep 2
4664         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4665
4666         for (( i=0; i < 2; i++ )) ; do
4667                 local mtime2=`stat -c %Y $DIR1/$tfile`
4668                 [ $mtime2 = $TEST_39_MTIME ] || \
4669                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4670
4671                 cancel_lru_locks $OSC
4672                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4673         done
4674 }
4675 run_test 39f "create, stat, sleep, utime, stat ================="
4676
4677 # bug 11063
4678 test_39g() {
4679         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4680
4681         echo hello >> $DIR1/$tfile
4682         local mtime1=`stat -c %Y $DIR1/$tfile`
4683
4684         sleep 2
4685         chmod o+r $DIR1/$tfile
4686
4687         for (( i=0; i < 2; i++ )) ; do
4688                 local mtime2=`stat -c %Y $DIR1/$tfile`
4689                 [ "$mtime1" = "$mtime2" ] || \
4690                         error "lost mtime: $mtime2, should be $mtime1"
4691
4692                 cancel_lru_locks $OSC
4693                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4694         done
4695 }
4696 run_test 39g "write, chmod, stat ==============================="
4697
4698 # bug 11063
4699 test_39h() {
4700         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4701
4702         touch $DIR1/$tfile
4703         sleep 1
4704
4705         local d1=`date`
4706         echo hello >> $DIR1/$tfile
4707         local mtime1=`stat -c %Y $DIR1/$tfile`
4708
4709         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4710         local d2=`date`
4711         if [ "$d1" != "$d2" ]; then
4712                 echo "write and touch not within one second"
4713         else
4714                 for (( i=0; i < 2; i++ )) ; do
4715                         local mtime2=`stat -c %Y $DIR1/$tfile`
4716                         [ "$mtime2" = $TEST_39_MTIME ] || \
4717                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4718
4719                         cancel_lru_locks $OSC
4720                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4721                 done
4722         fi
4723 }
4724 run_test 39h "write, utime within one second, stat ============="
4725
4726 test_39i() {
4727         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4728
4729         touch $DIR1/$tfile
4730         sleep 1
4731
4732         echo hello >> $DIR1/$tfile
4733         local mtime1=`stat -c %Y $DIR1/$tfile`
4734
4735         mv $DIR1/$tfile $DIR1/$tfile-1
4736
4737         for (( i=0; i < 2; i++ )) ; do
4738                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4739
4740                 [ "$mtime1" = "$mtime2" ] || \
4741                         error "lost mtime: $mtime2, should be $mtime1"
4742
4743                 cancel_lru_locks $OSC
4744                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4745         done
4746 }
4747 run_test 39i "write, rename, stat =============================="
4748
4749 test_39j() {
4750         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4751
4752         start_full_debug_logging
4753         touch $DIR1/$tfile
4754         sleep 1
4755
4756         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4757         lctl set_param fail_loc=0x80000412
4758         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4759                 error "multiop failed"
4760         local multipid=$!
4761         local mtime1=`stat -c %Y $DIR1/$tfile`
4762
4763         mv $DIR1/$tfile $DIR1/$tfile-1
4764
4765         kill -USR1 $multipid
4766         wait $multipid || error "multiop close failed"
4767
4768         for (( i=0; i < 2; i++ )) ; do
4769                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4770                 [ "$mtime1" = "$mtime2" ] ||
4771                         error "mtime is lost on close: $mtime2, " \
4772                               "should be $mtime1"
4773
4774                 cancel_lru_locks
4775                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4776         done
4777         lctl set_param fail_loc=0
4778         stop_full_debug_logging
4779 }
4780 run_test 39j "write, rename, close, stat ======================="
4781
4782 test_39k() {
4783         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4784
4785         touch $DIR1/$tfile
4786         sleep 1
4787
4788         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4789         local multipid=$!
4790         local mtime1=`stat -c %Y $DIR1/$tfile`
4791
4792         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4793
4794         kill -USR1 $multipid
4795         wait $multipid || error "multiop close failed"
4796
4797         for (( i=0; i < 2; i++ )) ; do
4798                 local mtime2=`stat -c %Y $DIR1/$tfile`
4799
4800                 [ "$mtime2" = $TEST_39_MTIME ] || \
4801                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4802
4803                 cancel_lru_locks
4804                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4805         done
4806 }
4807 run_test 39k "write, utime, close, stat ========================"
4808
4809 # this should be set to future
4810 TEST_39_ATIME=`date -d "1 year" +%s`
4811
4812 test_39l() {
4813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4814         remote_mds_nodsh && skip "remote MDS with nodsh"
4815
4816         local atime_diff=$(do_facet $SINGLEMDS \
4817                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4818         rm -rf $DIR/$tdir
4819         mkdir_on_mdt0 $DIR/$tdir
4820
4821         # test setting directory atime to future
4822         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4823         local atime=$(stat -c %X $DIR/$tdir)
4824         [ "$atime" = $TEST_39_ATIME ] ||
4825                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4826
4827         # test setting directory atime from future to now
4828         local now=$(date +%s)
4829         touch -a -d @$now $DIR/$tdir
4830
4831         atime=$(stat -c %X $DIR/$tdir)
4832         [ "$atime" -eq "$now"  ] ||
4833                 error "atime is not updated from future: $atime, $now"
4834
4835         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4836         sleep 3
4837
4838         # test setting directory atime when now > dir atime + atime_diff
4839         local d1=$(date +%s)
4840         ls $DIR/$tdir
4841         local d2=$(date +%s)
4842         cancel_lru_locks mdc
4843         atime=$(stat -c %X $DIR/$tdir)
4844         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4845                 error "atime is not updated  : $atime, should be $d2"
4846
4847         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4848         sleep 3
4849
4850         # test not setting directory atime when now < dir atime + atime_diff
4851         ls $DIR/$tdir
4852         cancel_lru_locks mdc
4853         atime=$(stat -c %X $DIR/$tdir)
4854         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4855                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4856
4857         do_facet $SINGLEMDS \
4858                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4859 }
4860 run_test 39l "directory atime update ==========================="
4861
4862 test_39m() {
4863         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4864
4865         touch $DIR1/$tfile
4866         sleep 2
4867         local far_past_mtime=$(date -d "May 29 1953" +%s)
4868         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4869
4870         touch -m -d @$far_past_mtime $DIR1/$tfile
4871         touch -a -d @$far_past_atime $DIR1/$tfile
4872
4873         for (( i=0; i < 2; i++ )) ; do
4874                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4875                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4876                         error "atime or mtime set incorrectly"
4877
4878                 cancel_lru_locks $OSC
4879                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4880         done
4881 }
4882 run_test 39m "test atime and mtime before 1970"
4883
4884 test_39n() { # LU-3832
4885         remote_mds_nodsh && skip "remote MDS with nodsh"
4886
4887         local atime_diff=$(do_facet $SINGLEMDS \
4888                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4889         local atime0
4890         local atime1
4891         local atime2
4892
4893         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4894
4895         rm -rf $DIR/$tfile
4896         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4897         atime0=$(stat -c %X $DIR/$tfile)
4898
4899         sleep 5
4900         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4901         atime1=$(stat -c %X $DIR/$tfile)
4902
4903         sleep 5
4904         cancel_lru_locks mdc
4905         cancel_lru_locks osc
4906         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4907         atime2=$(stat -c %X $DIR/$tfile)
4908
4909         do_facet $SINGLEMDS \
4910                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4911
4912         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4913         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4914 }
4915 run_test 39n "check that O_NOATIME is honored"
4916
4917 test_39o() {
4918         TESTDIR=$DIR/$tdir/$tfile
4919         [ -e $TESTDIR ] && rm -rf $TESTDIR
4920         mkdir -p $TESTDIR
4921         cd $TESTDIR
4922         links1=2
4923         ls
4924         mkdir a b
4925         ls
4926         links2=$(stat -c %h .)
4927         [ $(($links1 + 2)) != $links2 ] &&
4928                 error "wrong links count $(($links1 + 2)) != $links2"
4929         rmdir b
4930         links3=$(stat -c %h .)
4931         [ $(($links1 + 1)) != $links3 ] &&
4932                 error "wrong links count $links1 != $links3"
4933         return 0
4934 }
4935 run_test 39o "directory cached attributes updated after create"
4936
4937 test_39p() {
4938         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4939
4940         local MDTIDX=1
4941         TESTDIR=$DIR/$tdir/$tdir
4942         [ -e $TESTDIR ] && rm -rf $TESTDIR
4943         test_mkdir -p $TESTDIR
4944         cd $TESTDIR
4945         links1=2
4946         ls
4947         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4948         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4949         ls
4950         links2=$(stat -c %h .)
4951         [ $(($links1 + 2)) != $links2 ] &&
4952                 error "wrong links count $(($links1 + 2)) != $links2"
4953         rmdir remote_dir2
4954         links3=$(stat -c %h .)
4955         [ $(($links1 + 1)) != $links3 ] &&
4956                 error "wrong links count $links1 != $links3"
4957         return 0
4958 }
4959 run_test 39p "remote directory cached attributes updated after create ========"
4960
4961 test_39r() {
4962         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4963                 skip "no atime update on old OST"
4964         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4965                 skip_env "ldiskfs only test"
4966         fi
4967
4968         local saved_adiff
4969         saved_adiff=$(do_facet ost1 \
4970                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4971         stack_trap "do_facet ost1 \
4972                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4973
4974         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4975
4976         $LFS setstripe -i 0 $DIR/$tfile
4977         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4978                 error "can't write initial file"
4979         cancel_lru_locks osc
4980
4981         # exceed atime_diff and access file
4982         sleep 6
4983         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
4984                 error "can't udpate atime"
4985
4986         local atime_cli=$(stat -c %X $DIR/$tfile)
4987         echo "client atime: $atime_cli"
4988         # allow atime update to be written to device
4989         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4990         sleep 5
4991
4992         local ostdev=$(ostdevname 1)
4993         local fid=($(lfs getstripe -y $DIR/$tfile |
4994                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4995         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4996         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4997
4998         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4999         local atime_ost=$(do_facet ost1 "$cmd" |&
5000                           awk -F'[: ]' '/atime:/ { print $4 }')
5001         (( atime_cli == atime_ost )) ||
5002                 error "atime on client $atime_cli != ost $atime_ost"
5003 }
5004 run_test 39r "lazy atime update on OST"
5005
5006 test_39q() { # LU-8041
5007         local testdir=$DIR/$tdir
5008         mkdir -p $testdir
5009         multiop_bg_pause $testdir D_c || error "multiop failed"
5010         local multipid=$!
5011         cancel_lru_locks mdc
5012         kill -USR1 $multipid
5013         local atime=$(stat -c %X $testdir)
5014         [ "$atime" -ne 0 ] || error "atime is zero"
5015 }
5016 run_test 39q "close won't zero out atime"
5017
5018 test_40() {
5019         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5020         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5021                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5022         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5023                 error "$tfile is not 4096 bytes in size"
5024 }
5025 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5026
5027 test_41() {
5028         # bug 1553
5029         small_write $DIR/f41 18
5030 }
5031 run_test 41 "test small file write + fstat ====================="
5032
5033 count_ost_writes() {
5034         lctl get_param -n ${OSC}.*.stats |
5035                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5036                         END { printf("%0.0f", writes) }'
5037 }
5038
5039 # decent default
5040 WRITEBACK_SAVE=500
5041 DIRTY_RATIO_SAVE=40
5042 MAX_DIRTY_RATIO=50
5043 BG_DIRTY_RATIO_SAVE=10
5044 MAX_BG_DIRTY_RATIO=25
5045
5046 start_writeback() {
5047         trap 0
5048         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5049         # dirty_ratio, dirty_background_ratio
5050         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5051                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5052                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5053                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5054         else
5055                 # if file not here, we are a 2.4 kernel
5056                 kill -CONT `pidof kupdated`
5057         fi
5058 }
5059
5060 stop_writeback() {
5061         # setup the trap first, so someone cannot exit the test at the
5062         # exact wrong time and mess up a machine
5063         trap start_writeback EXIT
5064         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5065         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5066                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5067                 sysctl -w vm.dirty_writeback_centisecs=0
5068                 sysctl -w vm.dirty_writeback_centisecs=0
5069                 # save and increase /proc/sys/vm/dirty_ratio
5070                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5071                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5072                 # save and increase /proc/sys/vm/dirty_background_ratio
5073                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5074                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5075         else
5076                 # if file not here, we are a 2.4 kernel
5077                 kill -STOP `pidof kupdated`
5078         fi
5079 }
5080
5081 # ensure that all stripes have some grant before we test client-side cache
5082 setup_test42() {
5083         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5084                 dd if=/dev/zero of=$i bs=4k count=1
5085                 rm $i
5086         done
5087 }
5088
5089 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5090 # file truncation, and file removal.
5091 test_42a() {
5092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5093
5094         setup_test42
5095         cancel_lru_locks $OSC
5096         stop_writeback
5097         sync; sleep 1; sync # just to be safe
5098         BEFOREWRITES=`count_ost_writes`
5099         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5100         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5101         AFTERWRITES=`count_ost_writes`
5102         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5103                 error "$BEFOREWRITES < $AFTERWRITES"
5104         start_writeback
5105 }
5106 run_test 42a "ensure that we don't flush on close"
5107
5108 test_42b() {
5109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5110
5111         setup_test42
5112         cancel_lru_locks $OSC
5113         stop_writeback
5114         sync
5115         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5116         BEFOREWRITES=$(count_ost_writes)
5117         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5118         AFTERWRITES=$(count_ost_writes)
5119         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5120                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5121         fi
5122         BEFOREWRITES=$(count_ost_writes)
5123         sync || error "sync: $?"
5124         AFTERWRITES=$(count_ost_writes)
5125         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5126                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5127         fi
5128         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5129         start_writeback
5130         return 0
5131 }
5132 run_test 42b "test destroy of file with cached dirty data ======"
5133
5134 # if these tests just want to test the effect of truncation,
5135 # they have to be very careful.  consider:
5136 # - the first open gets a {0,EOF}PR lock
5137 # - the first write conflicts and gets a {0, count-1}PW
5138 # - the rest of the writes are under {count,EOF}PW
5139 # - the open for truncate tries to match a {0,EOF}PR
5140 #   for the filesize and cancels the PWs.
5141 # any number of fixes (don't get {0,EOF} on open, match
5142 # composite locks, do smarter file size management) fix
5143 # this, but for now we want these tests to verify that
5144 # the cancellation with truncate intent works, so we
5145 # start the file with a full-file pw lock to match against
5146 # until the truncate.
5147 trunc_test() {
5148         test=$1
5149         file=$DIR/$test
5150         offset=$2
5151         cancel_lru_locks $OSC
5152         stop_writeback
5153         # prime the file with 0,EOF PW to match
5154         touch $file
5155         $TRUNCATE $file 0
5156         sync; sync
5157         # now the real test..
5158         dd if=/dev/zero of=$file bs=1024 count=100
5159         BEFOREWRITES=`count_ost_writes`
5160         $TRUNCATE $file $offset
5161         cancel_lru_locks $OSC
5162         AFTERWRITES=`count_ost_writes`
5163         start_writeback
5164 }
5165
5166 test_42c() {
5167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5168
5169         trunc_test 42c 1024
5170         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5171                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5172         rm $file
5173 }
5174 run_test 42c "test partial truncate of file with cached dirty data"
5175
5176 test_42d() {
5177         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5178
5179         trunc_test 42d 0
5180         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5181                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5182         rm $file
5183 }
5184 run_test 42d "test complete truncate of file with cached dirty data"
5185
5186 test_42e() { # bug22074
5187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5188
5189         local TDIR=$DIR/${tdir}e
5190         local pages=16 # hardcoded 16 pages, don't change it.
5191         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5192         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5193         local max_dirty_mb
5194         local warmup_files
5195
5196         test_mkdir $DIR/${tdir}e
5197         $LFS setstripe -c 1 $TDIR
5198         createmany -o $TDIR/f $files
5199
5200         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5201
5202         # we assume that with $OSTCOUNT files, at least one of them will
5203         # be allocated on OST0.
5204         warmup_files=$((OSTCOUNT * max_dirty_mb))
5205         createmany -o $TDIR/w $warmup_files
5206
5207         # write a large amount of data into one file and sync, to get good
5208         # avail_grant number from OST.
5209         for ((i=0; i<$warmup_files; i++)); do
5210                 idx=$($LFS getstripe -i $TDIR/w$i)
5211                 [ $idx -ne 0 ] && continue
5212                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5213                 break
5214         done
5215         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5216         sync
5217         $LCTL get_param $proc_osc0/cur_dirty_bytes
5218         $LCTL get_param $proc_osc0/cur_grant_bytes
5219
5220         # create as much dirty pages as we can while not to trigger the actual
5221         # RPCs directly. but depends on the env, VFS may trigger flush during this
5222         # period, hopefully we are good.
5223         for ((i=0; i<$warmup_files; i++)); do
5224                 idx=$($LFS getstripe -i $TDIR/w$i)
5225                 [ $idx -ne 0 ] && continue
5226                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5227         done
5228         $LCTL get_param $proc_osc0/cur_dirty_bytes
5229         $LCTL get_param $proc_osc0/cur_grant_bytes
5230
5231         # perform the real test
5232         $LCTL set_param $proc_osc0/rpc_stats 0
5233         for ((;i<$files; i++)); do
5234                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5235                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5236         done
5237         sync
5238         $LCTL get_param $proc_osc0/rpc_stats
5239
5240         local percent=0
5241         local have_ppr=false
5242         $LCTL get_param $proc_osc0/rpc_stats |
5243                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5244                         # skip lines until we are at the RPC histogram data
5245                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5246                         $have_ppr || continue
5247
5248                         # we only want the percent stat for < 16 pages
5249                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5250
5251                         percent=$((percent + WPCT))
5252                         if [[ $percent -gt 15 ]]; then
5253                                 error "less than 16-pages write RPCs" \
5254                                       "$percent% > 15%"
5255                                 break
5256                         fi
5257                 done
5258         rm -rf $TDIR
5259 }
5260 run_test 42e "verify sub-RPC writes are not done synchronously"
5261
5262 test_43A() { # was test_43
5263         test_mkdir $DIR/$tdir
5264         cp -p /bin/ls $DIR/$tdir/$tfile
5265         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5266         pid=$!
5267         # give multiop a chance to open
5268         sleep 1
5269
5270         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5271         kill -USR1 $pid
5272         # Wait for multiop to exit
5273         wait $pid
5274 }
5275 run_test 43A "execution of file opened for write should return -ETXTBSY"
5276
5277 test_43a() {
5278         test_mkdir $DIR/$tdir
5279         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5280         $DIR/$tdir/sleep 60 &
5281         SLEEP_PID=$!
5282         # Make sure exec of $tdir/sleep wins race with truncate
5283         sleep 1
5284         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5285         kill $SLEEP_PID
5286 }
5287 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5288
5289 test_43b() {
5290         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5291
5292         test_mkdir $DIR/$tdir
5293         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5294         $DIR/$tdir/sleep 60 &
5295         SLEEP_PID=$!
5296         # Make sure exec of $tdir/sleep wins race with truncate
5297         sleep 1
5298         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5299         kill $SLEEP_PID
5300 }
5301 run_test 43b "truncate of file being executed should return -ETXTBSY"
5302
5303 test_43c() {
5304         local testdir="$DIR/$tdir"
5305         test_mkdir $testdir
5306         cp $SHELL $testdir/
5307         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5308                 ( cd $testdir && md5sum -c )
5309 }
5310 run_test 43c "md5sum of copy into lustre"
5311
5312 test_44A() { # was test_44
5313         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5314
5315         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5316         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5317 }
5318 run_test 44A "zero length read from a sparse stripe"
5319
5320 test_44a() {
5321         local nstripe=$($LFS getstripe -c -d $DIR)
5322         [ -z "$nstripe" ] && skip "can't get stripe info"
5323         [[ $nstripe -gt $OSTCOUNT ]] &&
5324                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5325
5326         local stride=$($LFS getstripe -S -d $DIR)
5327         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5328                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5329         fi
5330
5331         OFFSETS="0 $((stride/2)) $((stride-1))"
5332         for offset in $OFFSETS; do
5333                 for i in $(seq 0 $((nstripe-1))); do
5334                         local GLOBALOFFSETS=""
5335                         # size in Bytes
5336                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5337                         local myfn=$DIR/d44a-$size
5338                         echo "--------writing $myfn at $size"
5339                         ll_sparseness_write $myfn $size ||
5340                                 error "ll_sparseness_write"
5341                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5342                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5343                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5344
5345                         for j in $(seq 0 $((nstripe-1))); do
5346                                 # size in Bytes
5347                                 size=$((((j + $nstripe )*$stride + $offset)))
5348                                 ll_sparseness_write $myfn $size ||
5349                                         error "ll_sparseness_write"
5350                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5351                         done
5352                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5353                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5354                         rm -f $myfn
5355                 done
5356         done
5357 }
5358 run_test 44a "test sparse pwrite ==============================="
5359
5360 dirty_osc_total() {
5361         tot=0
5362         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5363                 tot=$(($tot + $d))
5364         done
5365         echo $tot
5366 }
5367 do_dirty_record() {
5368         before=`dirty_osc_total`
5369         echo executing "\"$*\""
5370         eval $*
5371         after=`dirty_osc_total`
5372         echo before $before, after $after
5373 }
5374 test_45() {
5375         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5376
5377         f="$DIR/f45"
5378         # Obtain grants from OST if it supports it
5379         echo blah > ${f}_grant
5380         stop_writeback
5381         sync
5382         do_dirty_record "echo blah > $f"
5383         [[ $before -eq $after ]] && error "write wasn't cached"
5384         do_dirty_record "> $f"
5385         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5386         do_dirty_record "echo blah > $f"
5387         [[ $before -eq $after ]] && error "write wasn't cached"
5388         do_dirty_record "sync"
5389         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5390         do_dirty_record "echo blah > $f"
5391         [[ $before -eq $after ]] && error "write wasn't cached"
5392         do_dirty_record "cancel_lru_locks osc"
5393         [[ $before -gt $after ]] ||
5394                 error "lock cancellation didn't lower dirty count"
5395         start_writeback
5396 }
5397 run_test 45 "osc io page accounting ============================"
5398
5399 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5400 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5401 # objects offset and an assert hit when an rpc was built with 1023's mapped
5402 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5403 test_46() {
5404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5405
5406         f="$DIR/f46"
5407         stop_writeback
5408         sync
5409         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5410         sync
5411         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5412         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5413         sync
5414         start_writeback
5415 }
5416 run_test 46 "dirtying a previously written page ================"
5417
5418 # test_47 is removed "Device nodes check" is moved to test_28
5419
5420 test_48a() { # bug 2399
5421         [ "$mds1_FSTYPE" = "zfs" ] &&
5422         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5423                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5424
5425         test_mkdir $DIR/$tdir
5426         cd $DIR/$tdir
5427         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5428         test_mkdir $DIR/$tdir
5429         touch foo || error "'touch foo' failed after recreating cwd"
5430         test_mkdir bar
5431         touch .foo || error "'touch .foo' failed after recreating cwd"
5432         test_mkdir .bar
5433         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5434         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5435         cd . || error "'cd .' failed after recreating cwd"
5436         mkdir . && error "'mkdir .' worked after recreating cwd"
5437         rmdir . && error "'rmdir .' worked after recreating cwd"
5438         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5439         cd .. || error "'cd ..' failed after recreating cwd"
5440 }
5441 run_test 48a "Access renamed working dir (should return errors)="
5442
5443 test_48b() { # bug 2399
5444         rm -rf $DIR/$tdir
5445         test_mkdir $DIR/$tdir
5446         cd $DIR/$tdir
5447         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5448         touch foo && error "'touch foo' worked after removing cwd"
5449         mkdir foo && error "'mkdir foo' worked after removing cwd"
5450         touch .foo && error "'touch .foo' worked after removing cwd"
5451         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5452         ls . > /dev/null && error "'ls .' worked after removing cwd"
5453         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5454         mkdir . && error "'mkdir .' worked after removing cwd"
5455         rmdir . && error "'rmdir .' worked after removing cwd"
5456         ln -s . foo && error "'ln -s .' worked after removing cwd"
5457         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5458 }
5459 run_test 48b "Access removed working dir (should return errors)="
5460
5461 test_48c() { # bug 2350
5462         #lctl set_param debug=-1
5463         #set -vx
5464         rm -rf $DIR/$tdir
5465         test_mkdir -p $DIR/$tdir/dir
5466         cd $DIR/$tdir/dir
5467         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5468         $TRACE touch foo && error "touch foo worked after removing cwd"
5469         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5470         touch .foo && error "touch .foo worked after removing cwd"
5471         mkdir .foo && error "mkdir .foo worked after removing cwd"
5472         $TRACE ls . && error "'ls .' worked after removing cwd"
5473         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5474         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5475         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5476         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5477         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5478 }
5479 run_test 48c "Access removed working subdir (should return errors)"
5480
5481 test_48d() { # bug 2350
5482         #lctl set_param debug=-1
5483         #set -vx
5484         rm -rf $DIR/$tdir
5485         test_mkdir -p $DIR/$tdir/dir
5486         cd $DIR/$tdir/dir
5487         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5488         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5489         $TRACE touch foo && error "'touch foo' worked after removing parent"
5490         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5491         touch .foo && error "'touch .foo' worked after removing parent"
5492         mkdir .foo && error "mkdir .foo worked after removing parent"
5493         $TRACE ls . && error "'ls .' worked after removing parent"
5494         $TRACE ls .. && error "'ls ..' worked after removing parent"
5495         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5496         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5497         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5498         true
5499 }
5500 run_test 48d "Access removed parent subdir (should return errors)"
5501
5502 test_48e() { # bug 4134
5503         #lctl set_param debug=-1
5504         #set -vx
5505         rm -rf $DIR/$tdir
5506         test_mkdir -p $DIR/$tdir/dir
5507         cd $DIR/$tdir/dir
5508         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5509         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5510         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5511         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5512         # On a buggy kernel addition of "touch foo" after cd .. will
5513         # produce kernel oops in lookup_hash_it
5514         touch ../foo && error "'cd ..' worked after recreate parent"
5515         cd $DIR
5516         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5517 }
5518 run_test 48e "Access to recreated parent subdir (should return errors)"
5519
5520 test_48f() {
5521         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5522                 skip "need MDS >= 2.13.55"
5523         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5524         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5525                 skip "needs different host for mdt1 mdt2"
5526         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5527
5528         $LFS mkdir -i0 $DIR/$tdir
5529         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5530
5531         for d in sub1 sub2 sub3; do
5532                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5533                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5534                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5535         done
5536
5537         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5538 }
5539 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5540
5541 test_49() { # LU-1030
5542         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5543         remote_ost_nodsh && skip "remote OST with nodsh"
5544
5545         # get ost1 size - $FSNAME-OST0000
5546         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5547                 awk '{ print $4 }')
5548         # write 800M at maximum
5549         [[ $ost1_size -lt 2 ]] && ost1_size=2
5550         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5551
5552         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5553         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5554         local dd_pid=$!
5555
5556         # change max_pages_per_rpc while writing the file
5557         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5558         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5559         # loop until dd process exits
5560         while ps ax -opid | grep -wq $dd_pid; do
5561                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5562                 sleep $((RANDOM % 5 + 1))
5563         done
5564         # restore original max_pages_per_rpc
5565         $LCTL set_param $osc1_mppc=$orig_mppc
5566         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5567 }
5568 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5569
5570 test_50() {
5571         # bug 1485
5572         test_mkdir $DIR/$tdir
5573         cd $DIR/$tdir
5574         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5575 }
5576 run_test 50 "special situations: /proc symlinks  ==============="
5577
5578 test_51a() {    # was test_51
5579         # bug 1516 - create an empty entry right after ".." then split dir
5580         test_mkdir -c1 $DIR/$tdir
5581         touch $DIR/$tdir/foo
5582         $MCREATE $DIR/$tdir/bar
5583         rm $DIR/$tdir/foo
5584         createmany -m $DIR/$tdir/longfile 201
5585         FNUM=202
5586         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5587                 $MCREATE $DIR/$tdir/longfile$FNUM
5588                 FNUM=$(($FNUM + 1))
5589                 echo -n "+"
5590         done
5591         echo
5592         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5593 }
5594 run_test 51a "special situations: split htree with empty entry =="
5595
5596 cleanup_print_lfs_df () {
5597         trap 0
5598         $LFS df
5599         $LFS df -i
5600 }
5601
5602 test_51b() {
5603         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5604
5605         local dir=$DIR/$tdir
5606         local nrdirs=$((65536 + 100))
5607
5608         # cleanup the directory
5609         rm -fr $dir
5610
5611         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5612
5613         $LFS df
5614         $LFS df -i
5615         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5616         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5617         [[ $numfree -lt $nrdirs ]] &&
5618                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5619
5620         # need to check free space for the directories as well
5621         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5622         numfree=$(( blkfree / $(fs_inode_ksize) ))
5623         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5624
5625         trap cleanup_print_lfs_df EXIT
5626
5627         # create files
5628         createmany -d $dir/d $nrdirs || {
5629                 unlinkmany $dir/d $nrdirs
5630                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5631         }
5632
5633         # really created :
5634         nrdirs=$(ls -U $dir | wc -l)
5635
5636         # unlink all but 100 subdirectories, then check it still works
5637         local left=100
5638         local delete=$((nrdirs - left))
5639
5640         $LFS df
5641         $LFS df -i
5642
5643         # for ldiskfs the nlink count should be 1, but this is OSD specific
5644         # and so this is listed for informational purposes only
5645         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5646         unlinkmany -d $dir/d $delete ||
5647                 error "unlink of first $delete subdirs failed"
5648
5649         echo "nlink between: $(stat -c %h $dir)"
5650         local found=$(ls -U $dir | wc -l)
5651         [ $found -ne $left ] &&
5652                 error "can't find subdirs: found only $found, expected $left"
5653
5654         unlinkmany -d $dir/d $delete $left ||
5655                 error "unlink of second $left subdirs failed"
5656         # regardless of whether the backing filesystem tracks nlink accurately
5657         # or not, the nlink count shouldn't be more than "." and ".." here
5658         local after=$(stat -c %h $dir)
5659         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5660                 echo "nlink after: $after"
5661
5662         cleanup_print_lfs_df
5663 }
5664 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5665
5666 test_51d() {
5667         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5668         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5669         local qos_old
5670
5671         test_mkdir $DIR/$tdir
5672         $LFS setstripe -c $OSTCOUNT $DIR/$tdir
5673
5674         qos_old=$(do_facet mds1 \
5675                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
5676         do_nodes $(comma_list $(mdts_nodes)) \
5677                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
5678         stack_trap "do_nodes $(comma_list $(mdts_nodes)) \
5679                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
5680
5681         createmany -o $DIR/$tdir/t- 1000
5682         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5683         for ((n = 0; n < $OSTCOUNT; n++)); do
5684                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
5685                            END { printf("%0.0f", objs) }' $TMP/$tfile)
5686                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5687                             '($1 == '$n') { objs += 1 } \
5688                             END { printf("%0.0f", objs) }')
5689                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
5690         done
5691         unlinkmany $DIR/$tdir/t- 1000
5692
5693         nlast=0
5694         for ((n = 0; n < $OSTCOUNT; n++)); do
5695                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
5696                         { $LFS df && $LFS df -i &&
5697                         error "OST $n has fewer objects vs. OST $nlast" \
5698                               " (${objs[$n]} < ${objs[$nlast]}"; }
5699                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
5700                         { $LFS df && $LFS df -i &&
5701                         error "OST $n has fewer objects vs. OST $nlast" \
5702                               " (${objs[$n]} < ${objs[$nlast]}"; }
5703
5704                 (( ${objs0[$n]} > ${objs0[$nlast]} * 4 / 5 )) ||
5705                         { $LFS df && $LFS df -i &&
5706                         error "OST $n has fewer #0 objects vs. OST $nlast" \
5707                               " (${objs0[$n]} < ${objs0[$nlast]}"; }
5708                 (( ${objs0[$n]} < ${objs0[$nlast]} * 5 / 4 )) ||
5709                         { $LFS df && $LFS df -i &&
5710                         error "OST $n has fewer #0 objects vs. OST $nlast" \
5711                               " (${objs0[$n]} < ${objs0[$nlast]}"; }
5712                 nlast=$n
5713         done
5714 }
5715 run_test 51d "check object distribution"
5716
5717 test_51e() {
5718         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5719                 skip_env "ldiskfs only test"
5720         fi
5721
5722         test_mkdir -c1 $DIR/$tdir
5723         test_mkdir -c1 $DIR/$tdir/d0
5724
5725         touch $DIR/$tdir/d0/foo
5726         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5727                 error "file exceed 65000 nlink limit!"
5728         unlinkmany $DIR/$tdir/d0/f- 65001
5729         return 0
5730 }
5731 run_test 51e "check file nlink limit"
5732
5733 test_51f() {
5734         test_mkdir $DIR/$tdir
5735
5736         local max=100000
5737         local ulimit_old=$(ulimit -n)
5738         local spare=20 # number of spare fd's for scripts/libraries, etc.
5739         local mdt=$($LFS getstripe -m $DIR/$tdir)
5740         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5741
5742         echo "MDT$mdt numfree=$numfree, max=$max"
5743         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5744         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5745                 while ! ulimit -n $((numfree + spare)); do
5746                         numfree=$((numfree * 3 / 4))
5747                 done
5748                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5749         else
5750                 echo "left ulimit at $ulimit_old"
5751         fi
5752
5753         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5754                 unlinkmany $DIR/$tdir/f $numfree
5755                 error "create+open $numfree files in $DIR/$tdir failed"
5756         }
5757         ulimit -n $ulimit_old
5758
5759         # if createmany exits at 120s there will be fewer than $numfree files
5760         unlinkmany $DIR/$tdir/f $numfree || true
5761 }
5762 run_test 51f "check many open files limit"
5763
5764 test_52a() {
5765         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5766         test_mkdir $DIR/$tdir
5767         touch $DIR/$tdir/foo
5768         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5769         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5770         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5771         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5772         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5773                                         error "link worked"
5774         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5775         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5776         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5777                                                      error "lsattr"
5778         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5779         cp -r $DIR/$tdir $TMP/
5780         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5781 }
5782 run_test 52a "append-only flag test (should return errors)"
5783
5784 test_52b() {
5785         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5786         test_mkdir $DIR/$tdir
5787         touch $DIR/$tdir/foo
5788         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5789         cat test > $DIR/$tdir/foo && error "cat test worked"
5790         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5791         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5792         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5793                                         error "link worked"
5794         echo foo >> $DIR/$tdir/foo && error "echo worked"
5795         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5796         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5797         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5798         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5799                                                         error "lsattr"
5800         chattr -i $DIR/$tdir/foo || error "chattr failed"
5801
5802         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5803 }
5804 run_test 52b "immutable flag test (should return errors) ======="
5805
5806 test_53() {
5807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5808         remote_mds_nodsh && skip "remote MDS with nodsh"
5809         remote_ost_nodsh && skip "remote OST with nodsh"
5810
5811         local param
5812         local param_seq
5813         local ostname
5814         local mds_last
5815         local mds_last_seq
5816         local ost_last
5817         local ost_last_seq
5818         local ost_last_id
5819         local ostnum
5820         local node
5821         local found=false
5822         local support_last_seq=true
5823
5824         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5825                 support_last_seq=false
5826
5827         # only test MDT0000
5828         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5829         local value
5830         for value in $(do_facet $SINGLEMDS \
5831                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5832                 param=$(echo ${value[0]} | cut -d "=" -f1)
5833                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5834
5835                 if $support_last_seq; then
5836                         param_seq=$(echo $param |
5837                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5838                         mds_last_seq=$(do_facet $SINGLEMDS \
5839                                        $LCTL get_param -n $param_seq)
5840                 fi
5841                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5842
5843                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5844                 node=$(facet_active_host ost$((ostnum+1)))
5845                 param="obdfilter.$ostname.last_id"
5846                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5847                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5848                         ost_last_id=$ost_last
5849
5850                         if $support_last_seq; then
5851                                 ost_last_id=$(echo $ost_last |
5852                                               awk -F':' '{print $2}' |
5853                                               sed -e "s/^0x//g")
5854                                 ost_last_seq=$(echo $ost_last |
5855                                                awk -F':' '{print $1}')
5856                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5857                         fi
5858
5859                         if [[ $ost_last_id != $mds_last ]]; then
5860                                 error "$ost_last_id != $mds_last"
5861                         else
5862                                 found=true
5863                                 break
5864                         fi
5865                 done
5866         done
5867         $found || error "can not match last_seq/last_id for $mdtosc"
5868         return 0
5869 }
5870 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5871
5872 test_54a() {
5873         perl -MSocket -e ';' || skip "no Socket perl module installed"
5874
5875         $SOCKETSERVER $DIR/socket ||
5876                 error "$SOCKETSERVER $DIR/socket failed: $?"
5877         $SOCKETCLIENT $DIR/socket ||
5878                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5879         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5880 }
5881 run_test 54a "unix domain socket test =========================="
5882
5883 test_54b() {
5884         f="$DIR/f54b"
5885         mknod $f c 1 3
5886         chmod 0666 $f
5887         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5888 }
5889 run_test 54b "char device works in lustre ======================"
5890
5891 find_loop_dev() {
5892         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5893         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5894         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5895
5896         for i in $(seq 3 7); do
5897                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5898                 LOOPDEV=$LOOPBASE$i
5899                 LOOPNUM=$i
5900                 break
5901         done
5902 }
5903
5904 cleanup_54c() {
5905         local rc=0
5906         loopdev="$DIR/loop54c"
5907
5908         trap 0
5909         $UMOUNT $DIR/$tdir || rc=$?
5910         losetup -d $loopdev || true
5911         losetup -d $LOOPDEV || true
5912         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5913         return $rc
5914 }
5915
5916 test_54c() {
5917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5918
5919         loopdev="$DIR/loop54c"
5920
5921         find_loop_dev
5922         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5923         trap cleanup_54c EXIT
5924         mknod $loopdev b 7 $LOOPNUM
5925         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5926         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5927         losetup $loopdev $DIR/$tfile ||
5928                 error "can't set up $loopdev for $DIR/$tfile"
5929         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5930         test_mkdir $DIR/$tdir
5931         mount -t ext2 $loopdev $DIR/$tdir ||
5932                 error "error mounting $loopdev on $DIR/$tdir"
5933         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5934                 error "dd write"
5935         df $DIR/$tdir
5936         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5937                 error "dd read"
5938         cleanup_54c
5939 }
5940 run_test 54c "block device works in lustre ====================="
5941
5942 test_54d() {
5943         f="$DIR/f54d"
5944         string="aaaaaa"
5945         mknod $f p
5946         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5947 }
5948 run_test 54d "fifo device works in lustre ======================"
5949
5950 test_54e() {
5951         f="$DIR/f54e"
5952         string="aaaaaa"
5953         cp -aL /dev/console $f
5954         echo $string > $f || error "echo $string to $f failed"
5955 }
5956 run_test 54e "console/tty device works in lustre ======================"
5957
5958 test_56a() {
5959         local numfiles=3
5960         local numdirs=2
5961         local dir=$DIR/$tdir
5962
5963         rm -rf $dir
5964         test_mkdir -p $dir/dir
5965         for i in $(seq $numfiles); do
5966                 touch $dir/file$i
5967                 touch $dir/dir/file$i
5968         done
5969
5970         local numcomp=$($LFS getstripe --component-count $dir)
5971
5972         [[ $numcomp == 0 ]] && numcomp=1
5973
5974         # test lfs getstripe with --recursive
5975         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5976
5977         [[ $filenum -eq $((numfiles * 2)) ]] ||
5978                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5979         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5980         [[ $filenum -eq $numfiles ]] ||
5981                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5982         echo "$LFS getstripe showed obdidx or l_ost_idx"
5983
5984         # test lfs getstripe with file instead of dir
5985         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5986         [[ $filenum -eq 1 ]] ||
5987                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5988         echo "$LFS getstripe file1 passed"
5989
5990         #test lfs getstripe with --verbose
5991         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5992         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5993                 error "$LFS getstripe --verbose $dir: "\
5994                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5995         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5996                 error "$LFS getstripe $dir: showed lmm_magic"
5997
5998         #test lfs getstripe with -v prints lmm_fid
5999         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6000         local countfids=$((numdirs + numfiles * numcomp))
6001         [[ $filenum -eq $countfids ]] ||
6002                 error "$LFS getstripe -v $dir: "\
6003                       "got $filenum want $countfids lmm_fid"
6004         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6005                 error "$LFS getstripe $dir: showed lmm_fid by default"
6006         echo "$LFS getstripe --verbose passed"
6007
6008         #check for FID information
6009         local fid1=$($LFS getstripe --fid $dir/file1)
6010         local fid2=$($LFS getstripe --verbose $dir/file1 |
6011                      awk '/lmm_fid: / { print $2; exit; }')
6012         local fid3=$($LFS path2fid $dir/file1)
6013
6014         [ "$fid1" != "$fid2" ] &&
6015                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6016         [ "$fid1" != "$fid3" ] &&
6017                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6018         echo "$LFS getstripe --fid passed"
6019
6020         #test lfs getstripe with --obd
6021         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6022                 error "$LFS getstripe --obd wrong_uuid: should return error"
6023
6024         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6025
6026         local ostidx=1
6027         local obduuid=$(ostuuid_from_index $ostidx)
6028         local found=$($LFS getstripe -r --obd $obduuid $dir |
6029                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6030
6031         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6032         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6033                 ((filenum--))
6034         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6035                 ((filenum--))
6036
6037         [[ $found -eq $filenum ]] ||
6038                 error "$LFS getstripe --obd: found $found expect $filenum"
6039         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6040                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6041                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6042                 error "$LFS getstripe --obd: should not show file on other obd"
6043         echo "$LFS getstripe --obd passed"
6044 }
6045 run_test 56a "check $LFS getstripe"
6046
6047 test_56b() {
6048         local dir=$DIR/$tdir
6049         local numdirs=3
6050
6051         test_mkdir $dir
6052         for i in $(seq $numdirs); do
6053                 test_mkdir $dir/dir$i
6054         done
6055
6056         # test lfs getdirstripe default mode is non-recursion, which is
6057         # different from lfs getstripe
6058         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6059
6060         [[ $dircnt -eq 1 ]] ||
6061                 error "$LFS getdirstripe: found $dircnt, not 1"
6062         dircnt=$($LFS getdirstripe --recursive $dir |
6063                 grep -c lmv_stripe_count)
6064         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6065                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6066 }
6067 run_test 56b "check $LFS getdirstripe"
6068
6069 test_56c() {
6070         remote_ost_nodsh && skip "remote OST with nodsh"
6071
6072         local ost_idx=0
6073         local ost_name=$(ostname_from_index $ost_idx)
6074         local old_status=$(ost_dev_status $ost_idx)
6075         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6076
6077         [[ -z "$old_status" ]] ||
6078                 skip_env "OST $ost_name is in $old_status status"
6079
6080         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6081         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6082                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6083         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6084                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6085                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6086         fi
6087
6088         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6089                 error "$LFS df -v showing inactive devices"
6090         sleep_maxage
6091
6092         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6093
6094         [[ "$new_status" =~ "D" ]] ||
6095                 error "$ost_name status is '$new_status', missing 'D'"
6096         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6097                 [[ "$new_status" =~ "N" ]] ||
6098                         error "$ost_name status is '$new_status', missing 'N'"
6099         fi
6100         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6101                 [[ "$new_status" =~ "f" ]] ||
6102                         error "$ost_name status is '$new_status', missing 'f'"
6103         fi
6104
6105         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6106         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6107                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6108         [[ -z "$p" ]] && restore_lustre_params < $p || true
6109         sleep_maxage
6110
6111         new_status=$(ost_dev_status $ost_idx)
6112         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6113                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6114         # can't check 'f' as devices may actually be on flash
6115 }
6116 run_test 56c "check 'lfs df' showing device status"
6117
6118 test_56d() {
6119         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6120         local osts=$($LFS df -v $MOUNT | grep -c OST)
6121
6122         $LFS df $MOUNT
6123
6124         (( mdts == MDSCOUNT )) ||
6125                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6126         (( osts == OSTCOUNT )) ||
6127                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6128 }
6129 run_test 56d "'lfs df -v' prints only configured devices"
6130
6131 test_56e() {
6132         err_enoent=2 # No such file or directory
6133         err_eopnotsupp=95 # Operation not supported
6134
6135         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6136         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6137
6138         # Check for handling of path not exists
6139         output=$($LFS df $enoent_mnt 2>&1)
6140         ret=$?
6141
6142         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6143         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6144                 error "expect failure $err_enoent, not $ret"
6145
6146         # Check for handling of non-Lustre FS
6147         output=$($LFS df $notsup_mnt)
6148         ret=$?
6149
6150         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6151         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6152                 error "expect success $err_eopnotsupp, not $ret"
6153
6154         # Check for multiple LustreFS argument
6155         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6156         ret=$?
6157
6158         [[ $output -eq 3 && $ret -eq 0 ]] ||
6159                 error "expect success 3, not $output, rc = $ret"
6160
6161         # Check for correct non-Lustre FS handling among multiple
6162         # LustreFS argument
6163         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6164                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6165         ret=$?
6166
6167         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6168                 error "expect success 2, not $output, rc = $ret"
6169 }
6170 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6171
6172 NUMFILES=3
6173 NUMDIRS=3
6174 setup_56() {
6175         local local_tdir="$1"
6176         local local_numfiles="$2"
6177         local local_numdirs="$3"
6178         local dir_params="$4"
6179         local dir_stripe_params="$5"
6180
6181         if [ ! -d "$local_tdir" ] ; then
6182                 test_mkdir -p $dir_stripe_params $local_tdir
6183                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6184                 for i in $(seq $local_numfiles) ; do
6185                         touch $local_tdir/file$i
6186                 done
6187                 for i in $(seq $local_numdirs) ; do
6188                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6189                         for j in $(seq $local_numfiles) ; do
6190                                 touch $local_tdir/dir$i/file$j
6191                         done
6192                 done
6193         fi
6194 }
6195
6196 setup_56_special() {
6197         local local_tdir=$1
6198         local local_numfiles=$2
6199         local local_numdirs=$3
6200
6201         setup_56 $local_tdir $local_numfiles $local_numdirs
6202
6203         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6204                 for i in $(seq $local_numfiles) ; do
6205                         mknod $local_tdir/loop${i}b b 7 $i
6206                         mknod $local_tdir/null${i}c c 1 3
6207                         ln -s $local_tdir/file1 $local_tdir/link${i}
6208                 done
6209                 for i in $(seq $local_numdirs) ; do
6210                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6211                         mknod $local_tdir/dir$i/null${i}c c 1 3
6212                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6213                 done
6214         fi
6215 }
6216
6217 test_56g() {
6218         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6219         local expected=$(($NUMDIRS + 2))
6220
6221         setup_56 $dir $NUMFILES $NUMDIRS
6222
6223         # test lfs find with -name
6224         for i in $(seq $NUMFILES) ; do
6225                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6226
6227                 [ $nums -eq $expected ] ||
6228                         error "lfs find -name '*$i' $dir wrong: "\
6229                               "found $nums, expected $expected"
6230         done
6231 }
6232 run_test 56g "check lfs find -name"
6233
6234 test_56h() {
6235         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6236         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6237
6238         setup_56 $dir $NUMFILES $NUMDIRS
6239
6240         # test lfs find with ! -name
6241         for i in $(seq $NUMFILES) ; do
6242                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6243
6244                 [ $nums -eq $expected ] ||
6245                         error "lfs find ! -name '*$i' $dir wrong: "\
6246                               "found $nums, expected $expected"
6247         done
6248 }
6249 run_test 56h "check lfs find ! -name"
6250
6251 test_56i() {
6252         local dir=$DIR/$tdir
6253
6254         test_mkdir $dir
6255
6256         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6257         local out=$($cmd)
6258
6259         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6260 }
6261 run_test 56i "check 'lfs find -ost UUID' skips directories"
6262
6263 test_56j() {
6264         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6265
6266         setup_56_special $dir $NUMFILES $NUMDIRS
6267
6268         local expected=$((NUMDIRS + 1))
6269         local cmd="$LFS find -type d $dir"
6270         local nums=$($cmd | wc -l)
6271
6272         [ $nums -eq $expected ] ||
6273                 error "'$cmd' wrong: found $nums, expected $expected"
6274 }
6275 run_test 56j "check lfs find -type d"
6276
6277 test_56k() {
6278         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6279
6280         setup_56_special $dir $NUMFILES $NUMDIRS
6281
6282         local expected=$(((NUMDIRS + 1) * NUMFILES))
6283         local cmd="$LFS find -type f $dir"
6284         local nums=$($cmd | wc -l)
6285
6286         [ $nums -eq $expected ] ||
6287                 error "'$cmd' wrong: found $nums, expected $expected"
6288 }
6289 run_test 56k "check lfs find -type f"
6290
6291 test_56l() {
6292         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6293
6294         setup_56_special $dir $NUMFILES $NUMDIRS
6295
6296         local expected=$((NUMDIRS + NUMFILES))
6297         local cmd="$LFS find -type b $dir"
6298         local nums=$($cmd | wc -l)
6299
6300         [ $nums -eq $expected ] ||
6301                 error "'$cmd' wrong: found $nums, expected $expected"
6302 }
6303 run_test 56l "check lfs find -type b"
6304
6305 test_56m() {
6306         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6307
6308         setup_56_special $dir $NUMFILES $NUMDIRS
6309
6310         local expected=$((NUMDIRS + NUMFILES))
6311         local cmd="$LFS find -type c $dir"
6312         local nums=$($cmd | wc -l)
6313         [ $nums -eq $expected ] ||
6314                 error "'$cmd' wrong: found $nums, expected $expected"
6315 }
6316 run_test 56m "check lfs find -type c"
6317
6318 test_56n() {
6319         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6320         setup_56_special $dir $NUMFILES $NUMDIRS
6321
6322         local expected=$((NUMDIRS + NUMFILES))
6323         local cmd="$LFS find -type l $dir"
6324         local nums=$($cmd | wc -l)
6325
6326         [ $nums -eq $expected ] ||
6327                 error "'$cmd' wrong: found $nums, expected $expected"
6328 }
6329 run_test 56n "check lfs find -type l"
6330
6331 test_56o() {
6332         local dir=$DIR/$tdir
6333
6334         setup_56 $dir $NUMFILES $NUMDIRS
6335         utime $dir/file1 > /dev/null || error "utime (1)"
6336         utime $dir/file2 > /dev/null || error "utime (2)"
6337         utime $dir/dir1 > /dev/null || error "utime (3)"
6338         utime $dir/dir2 > /dev/null || error "utime (4)"
6339         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6340         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6341
6342         local expected=4
6343         local nums=$($LFS find -mtime +0 $dir | wc -l)
6344
6345         [ $nums -eq $expected ] ||
6346                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6347
6348         expected=12
6349         cmd="$LFS find -mtime 0 $dir"
6350         nums=$($cmd | wc -l)
6351         [ $nums -eq $expected ] ||
6352                 error "'$cmd' wrong: found $nums, expected $expected"
6353 }
6354 run_test 56o "check lfs find -mtime for old files"
6355
6356 test_56ob() {
6357         local dir=$DIR/$tdir
6358         local expected=1
6359         local count=0
6360
6361         # just to make sure there is something that won't be found
6362         test_mkdir $dir
6363         touch $dir/$tfile.now
6364
6365         for age in year week day hour min; do
6366                 count=$((count + 1))
6367
6368                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6369                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6370                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6371
6372                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6373                 local nums=$($cmd | wc -l)
6374                 [ $nums -eq $expected ] ||
6375                         error "'$cmd' wrong: found $nums, expected $expected"
6376
6377                 cmd="$LFS find $dir -atime $count${age:0:1}"
6378                 nums=$($cmd | wc -l)
6379                 [ $nums -eq $expected ] ||
6380                         error "'$cmd' wrong: found $nums, expected $expected"
6381         done
6382
6383         sleep 2
6384         cmd="$LFS find $dir -ctime +1s -type f"
6385         nums=$($cmd | wc -l)
6386         (( $nums == $count * 2 + 1)) ||
6387                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6388 }
6389 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6390
6391 test_newerXY_base() {
6392         local x=$1
6393         local y=$2
6394         local dir=$DIR/$tdir
6395         local ref
6396         local negref
6397
6398         if [ $y == "t" ]; then
6399                 if [ $x == "b" ]; then
6400                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6401                 else
6402                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6403                 fi
6404         else
6405                 ref=$DIR/$tfile.newer.$x$y
6406                 touch $ref || error "touch $ref failed"
6407         fi
6408
6409         echo "before = $ref"
6410         sleep 2
6411         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6412         sleep 2
6413         if [ $y == "t" ]; then
6414                 if [ $x == "b" ]; then
6415                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6416                 else
6417                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6418                 fi
6419         else
6420                 negref=$DIR/$tfile.negnewer.$x$y
6421                 touch $negref || error "touch $negref failed"
6422         fi
6423
6424         echo "after = $negref"
6425         local cmd="$LFS find $dir -newer$x$y $ref"
6426         local nums=$(eval $cmd | wc -l)
6427         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6428
6429         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6430                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6431
6432         cmd="$LFS find $dir ! -newer$x$y $negref"
6433         nums=$(eval $cmd | wc -l)
6434         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6435                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6436
6437         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6438         nums=$(eval $cmd | wc -l)
6439         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6440                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6441
6442         rm -rf $DIR/*
6443 }
6444
6445 test_56oc() {
6446         test_newerXY_base "a" "a"
6447         test_newerXY_base "a" "m"
6448         test_newerXY_base "a" "c"
6449         test_newerXY_base "m" "a"
6450         test_newerXY_base "m" "m"
6451         test_newerXY_base "m" "c"
6452         test_newerXY_base "c" "a"
6453         test_newerXY_base "c" "m"
6454         test_newerXY_base "c" "c"
6455
6456         [[ -n "$sles_version" ]] &&
6457                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6458
6459         test_newerXY_base "a" "t"
6460         test_newerXY_base "m" "t"
6461         test_newerXY_base "c" "t"
6462
6463         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6464            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6465                 ! btime_supported && echo "btime unsupported" && return 0
6466
6467         test_newerXY_base "b" "b"
6468         test_newerXY_base "b" "t"
6469 }
6470 run_test 56oc "check lfs find -newerXY work"
6471
6472 btime_supported() {
6473         local dir=$DIR/$tdir
6474         local rc
6475
6476         mkdir -p $dir
6477         touch $dir/$tfile
6478         $LFS find $dir -btime -1d -type f
6479         rc=$?
6480         rm -rf $dir
6481         return $rc
6482 }
6483
6484 test_56od() {
6485         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6486                 ! btime_supported && skip "btime unsupported on MDS"
6487
6488         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6489                 ! btime_supported && skip "btime unsupported on clients"
6490
6491         local dir=$DIR/$tdir
6492         local ref=$DIR/$tfile.ref
6493         local negref=$DIR/$tfile.negref
6494
6495         mkdir $dir || error "mkdir $dir failed"
6496         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6497         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6498         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6499         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6500         touch $ref || error "touch $ref failed"
6501         # sleep 3 seconds at least
6502         sleep 3
6503
6504         local before=$(do_facet mds1 date +%s)
6505         local skew=$(($(date +%s) - before + 1))
6506
6507         if (( skew < 0 && skew > -5 )); then
6508                 sleep $((0 - skew + 1))
6509                 skew=0
6510         fi
6511
6512         # Set the dir stripe params to limit files all on MDT0,
6513         # otherwise we need to calc the max clock skew between
6514         # the client and MDTs.
6515         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6516         sleep 2
6517         touch $negref || error "touch $negref failed"
6518
6519         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6520         local nums=$($cmd | wc -l)
6521         local expected=$(((NUMFILES + 1) * NUMDIRS))
6522
6523         [ $nums -eq $expected ] ||
6524                 error "'$cmd' wrong: found $nums, expected $expected"
6525
6526         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6527         nums=$($cmd | wc -l)
6528         expected=$((NUMFILES + 1))
6529         [ $nums -eq $expected ] ||
6530                 error "'$cmd' wrong: found $nums, expected $expected"
6531
6532         [ $skew -lt 0 ] && return
6533
6534         local after=$(do_facet mds1 date +%s)
6535         local age=$((after - before + 1 + skew))
6536
6537         cmd="$LFS find $dir -btime -${age}s -type f"
6538         nums=$($cmd | wc -l)
6539         expected=$(((NUMFILES + 1) * NUMDIRS))
6540
6541         echo "Clock skew between client and server: $skew, age:$age"
6542         [ $nums -eq $expected ] ||
6543                 error "'$cmd' wrong: found $nums, expected $expected"
6544
6545         expected=$(($NUMDIRS + 1))
6546         cmd="$LFS find $dir -btime -${age}s -type d"
6547         nums=$($cmd | wc -l)
6548         [ $nums -eq $expected ] ||
6549                 error "'$cmd' wrong: found $nums, expected $expected"
6550         rm -f $ref $negref || error "Failed to remove $ref $negref"
6551 }
6552 run_test 56od "check lfs find -btime with units"
6553
6554 test_56p() {
6555         [ $RUNAS_ID -eq $UID ] &&
6556                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6557
6558         local dir=$DIR/$tdir
6559
6560         setup_56 $dir $NUMFILES $NUMDIRS
6561         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6562
6563         local expected=$NUMFILES
6564         local cmd="$LFS find -uid $RUNAS_ID $dir"
6565         local nums=$($cmd | wc -l)
6566
6567         [ $nums -eq $expected ] ||
6568                 error "'$cmd' wrong: found $nums, expected $expected"
6569
6570         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6571         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6572         nums=$($cmd | wc -l)
6573         [ $nums -eq $expected ] ||
6574                 error "'$cmd' wrong: found $nums, expected $expected"
6575 }
6576 run_test 56p "check lfs find -uid and ! -uid"
6577
6578 test_56q() {
6579         [ $RUNAS_ID -eq $UID ] &&
6580                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6581
6582         local dir=$DIR/$tdir
6583
6584         setup_56 $dir $NUMFILES $NUMDIRS
6585         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6586
6587         local expected=$NUMFILES
6588         local cmd="$LFS find -gid $RUNAS_GID $dir"
6589         local nums=$($cmd | wc -l)
6590
6591         [ $nums -eq $expected ] ||
6592                 error "'$cmd' wrong: found $nums, expected $expected"
6593
6594         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6595         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6596         nums=$($cmd | wc -l)
6597         [ $nums -eq $expected ] ||
6598                 error "'$cmd' wrong: found $nums, expected $expected"
6599 }
6600 run_test 56q "check lfs find -gid and ! -gid"
6601
6602 test_56r() {
6603         local dir=$DIR/$tdir
6604
6605         setup_56 $dir $NUMFILES $NUMDIRS
6606
6607         local expected=12
6608         local cmd="$LFS find -size 0 -type f -lazy $dir"
6609         local nums=$($cmd | wc -l)
6610
6611         [ $nums -eq $expected ] ||
6612                 error "'$cmd' wrong: found $nums, expected $expected"
6613         cmd="$LFS find -size 0 -type f $dir"
6614         nums=$($cmd | wc -l)
6615         [ $nums -eq $expected ] ||
6616                 error "'$cmd' wrong: found $nums, expected $expected"
6617
6618         expected=0
6619         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6620         nums=$($cmd | wc -l)
6621         [ $nums -eq $expected ] ||
6622                 error "'$cmd' wrong: found $nums, expected $expected"
6623         cmd="$LFS find ! -size 0 -type f $dir"
6624         nums=$($cmd | wc -l)
6625         [ $nums -eq $expected ] ||
6626                 error "'$cmd' wrong: found $nums, expected $expected"
6627
6628         echo "test" > $dir/$tfile
6629         echo "test2" > $dir/$tfile.2 && sync
6630         expected=1
6631         cmd="$LFS find -size 5 -type f -lazy $dir"
6632         nums=$($cmd | wc -l)
6633         [ $nums -eq $expected ] ||
6634                 error "'$cmd' wrong: found $nums, expected $expected"
6635         cmd="$LFS find -size 5 -type f $dir"
6636         nums=$($cmd | wc -l)
6637         [ $nums -eq $expected ] ||
6638                 error "'$cmd' wrong: found $nums, expected $expected"
6639
6640         expected=1
6641         cmd="$LFS find -size +5 -type f -lazy $dir"
6642         nums=$($cmd | wc -l)
6643         [ $nums -eq $expected ] ||
6644                 error "'$cmd' wrong: found $nums, expected $expected"
6645         cmd="$LFS find -size +5 -type f $dir"
6646         nums=$($cmd | wc -l)
6647         [ $nums -eq $expected ] ||
6648                 error "'$cmd' wrong: found $nums, expected $expected"
6649
6650         expected=2
6651         cmd="$LFS find -size +0 -type f -lazy $dir"
6652         nums=$($cmd | wc -l)
6653         [ $nums -eq $expected ] ||
6654                 error "'$cmd' wrong: found $nums, expected $expected"
6655         cmd="$LFS find -size +0 -type f $dir"
6656         nums=$($cmd | wc -l)
6657         [ $nums -eq $expected ] ||
6658                 error "'$cmd' wrong: found $nums, expected $expected"
6659
6660         expected=2
6661         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6662         nums=$($cmd | wc -l)
6663         [ $nums -eq $expected ] ||
6664                 error "'$cmd' wrong: found $nums, expected $expected"
6665         cmd="$LFS find ! -size -5 -type f $dir"
6666         nums=$($cmd | wc -l)
6667         [ $nums -eq $expected ] ||
6668                 error "'$cmd' wrong: found $nums, expected $expected"
6669
6670         expected=12
6671         cmd="$LFS find -size -5 -type f -lazy $dir"
6672         nums=$($cmd | wc -l)
6673         [ $nums -eq $expected ] ||
6674                 error "'$cmd' wrong: found $nums, expected $expected"
6675         cmd="$LFS find -size -5 -type f $dir"
6676         nums=$($cmd | wc -l)
6677         [ $nums -eq $expected ] ||
6678                 error "'$cmd' wrong: found $nums, expected $expected"
6679 }
6680 run_test 56r "check lfs find -size works"
6681
6682 test_56ra_sub() {
6683         local expected=$1
6684         local glimpses=$2
6685         local cmd="$3"
6686
6687         cancel_lru_locks $OSC
6688
6689         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6690         local nums=$($cmd | wc -l)
6691
6692         [ $nums -eq $expected ] ||
6693                 error "'$cmd' wrong: found $nums, expected $expected"
6694
6695         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6696
6697         if (( rpcs_before + glimpses != rpcs_after )); then
6698                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6699                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6700
6701                 if [[ $glimpses == 0 ]]; then
6702                         error "'$cmd' should not send glimpse RPCs to OST"
6703                 else
6704                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6705                 fi
6706         fi
6707 }
6708
6709 test_56ra() {
6710         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6711                 skip "MDS < 2.12.58 doesn't return LSOM data"
6712         local dir=$DIR/$tdir
6713         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6714
6715         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6716
6717         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6718         $LCTL set_param -n llite.*.statahead_agl=0
6719         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6720
6721         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6722         # open and close all files to ensure LSOM is updated
6723         cancel_lru_locks $OSC
6724         find $dir -type f | xargs cat > /dev/null
6725
6726         #   expect_found  glimpse_rpcs  command_to_run
6727         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6728         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6729         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6730         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6731
6732         echo "test" > $dir/$tfile
6733         echo "test2" > $dir/$tfile.2 && sync
6734         cancel_lru_locks $OSC
6735         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6736
6737         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6738         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6739         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6740         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6741
6742         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6743         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6744         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6745         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6746         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6747         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6748 }
6749 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6750
6751 test_56rb() {
6752         local dir=$DIR/$tdir
6753         local tmp=$TMP/$tfile.log
6754         local mdt_idx;
6755
6756         test_mkdir -p $dir || error "failed to mkdir $dir"
6757         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6758                 error "failed to setstripe $dir/$tfile"
6759         mdt_idx=$($LFS getdirstripe -i $dir)
6760         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6761
6762         stack_trap "rm -f $tmp" EXIT
6763         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6764         ! grep -q obd_uuid $tmp ||
6765                 error "failed to find --size +100K --ost 0 $dir"
6766         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6767         ! grep -q obd_uuid $tmp ||
6768                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6769 }
6770 run_test 56rb "check lfs find --size --ost/--mdt works"
6771
6772 test_56rc() {
6773         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
6774         local dir=$DIR/$tdir
6775         local found
6776
6777         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
6778         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
6779         (( $MDSCOUNT > 2 )) &&
6780                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
6781         mkdir $dir/$tdir-{1..10}
6782         touch $dir/$tfile-{1..10}
6783
6784         found=$($LFS find $dir --mdt-count 2 | wc -l)
6785         expect=11
6786         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
6787
6788         found=$($LFS find $dir -T +1 | wc -l)
6789         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
6790         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
6791
6792         found=$($LFS find $dir --mdt-hash all_char | wc -l)
6793         expect=11
6794         (( $found == $expect )) || error "found $found all_char, expect $expect"
6795
6796         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
6797         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
6798         (( $found == $expect )) || error "found $found all_char, expect $expect"
6799 }
6800 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
6801
6802 test_56s() { # LU-611 #LU-9369
6803         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6804
6805         local dir=$DIR/$tdir
6806         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6807
6808         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6809         for i in $(seq $NUMDIRS); do
6810                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6811         done
6812
6813         local expected=$NUMDIRS
6814         local cmd="$LFS find -c $OSTCOUNT $dir"
6815         local nums=$($cmd | wc -l)
6816
6817         [ $nums -eq $expected ] || {
6818                 $LFS getstripe -R $dir
6819                 error "'$cmd' wrong: found $nums, expected $expected"
6820         }
6821
6822         expected=$((NUMDIRS + onestripe))
6823         cmd="$LFS find -stripe-count +0 -type f $dir"
6824         nums=$($cmd | wc -l)
6825         [ $nums -eq $expected ] || {
6826                 $LFS getstripe -R $dir
6827                 error "'$cmd' wrong: found $nums, expected $expected"
6828         }
6829
6830         expected=$onestripe
6831         cmd="$LFS find -stripe-count 1 -type f $dir"
6832         nums=$($cmd | wc -l)
6833         [ $nums -eq $expected ] || {
6834                 $LFS getstripe -R $dir
6835                 error "'$cmd' wrong: found $nums, expected $expected"
6836         }
6837
6838         cmd="$LFS find -stripe-count -2 -type f $dir"
6839         nums=$($cmd | wc -l)
6840         [ $nums -eq $expected ] || {
6841                 $LFS getstripe -R $dir
6842                 error "'$cmd' wrong: found $nums, expected $expected"
6843         }
6844
6845         expected=0
6846         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6847         nums=$($cmd | wc -l)
6848         [ $nums -eq $expected ] || {
6849                 $LFS getstripe -R $dir
6850                 error "'$cmd' wrong: found $nums, expected $expected"
6851         }
6852 }
6853 run_test 56s "check lfs find -stripe-count works"
6854
6855 test_56t() { # LU-611 #LU-9369
6856         local dir=$DIR/$tdir
6857
6858         setup_56 $dir 0 $NUMDIRS
6859         for i in $(seq $NUMDIRS); do
6860                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6861         done
6862
6863         local expected=$NUMDIRS
6864         local cmd="$LFS find -S 8M $dir"
6865         local nums=$($cmd | wc -l)
6866
6867         [ $nums -eq $expected ] || {
6868                 $LFS getstripe -R $dir
6869                 error "'$cmd' wrong: found $nums, expected $expected"
6870         }
6871         rm -rf $dir
6872
6873         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6874
6875         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6876
6877         expected=$(((NUMDIRS + 1) * NUMFILES))
6878         cmd="$LFS find -stripe-size 512k -type f $dir"
6879         nums=$($cmd | wc -l)
6880         [ $nums -eq $expected ] ||
6881                 error "'$cmd' wrong: found $nums, expected $expected"
6882
6883         cmd="$LFS find -stripe-size +320k -type f $dir"
6884         nums=$($cmd | wc -l)
6885         [ $nums -eq $expected ] ||
6886                 error "'$cmd' wrong: found $nums, expected $expected"
6887
6888         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6889         cmd="$LFS find -stripe-size +200k -type f $dir"
6890         nums=$($cmd | wc -l)
6891         [ $nums -eq $expected ] ||
6892                 error "'$cmd' wrong: found $nums, expected $expected"
6893
6894         cmd="$LFS find -stripe-size -640k -type f $dir"
6895         nums=$($cmd | wc -l)
6896         [ $nums -eq $expected ] ||
6897                 error "'$cmd' wrong: found $nums, expected $expected"
6898
6899         expected=4
6900         cmd="$LFS find -stripe-size 256k -type f $dir"
6901         nums=$($cmd | wc -l)
6902         [ $nums -eq $expected ] ||
6903                 error "'$cmd' wrong: found $nums, expected $expected"
6904
6905         cmd="$LFS find -stripe-size -320k -type f $dir"
6906         nums=$($cmd | wc -l)
6907         [ $nums -eq $expected ] ||
6908                 error "'$cmd' wrong: found $nums, expected $expected"
6909
6910         expected=0
6911         cmd="$LFS find -stripe-size 1024k -type f $dir"
6912         nums=$($cmd | wc -l)
6913         [ $nums -eq $expected ] ||
6914                 error "'$cmd' wrong: found $nums, expected $expected"
6915 }
6916 run_test 56t "check lfs find -stripe-size works"
6917
6918 test_56u() { # LU-611
6919         local dir=$DIR/$tdir
6920
6921         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6922
6923         if [[ $OSTCOUNT -gt 1 ]]; then
6924                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6925                 onestripe=4
6926         else
6927                 onestripe=0
6928         fi
6929
6930         local expected=$(((NUMDIRS + 1) * NUMFILES))
6931         local cmd="$LFS find -stripe-index 0 -type f $dir"
6932         local nums=$($cmd | wc -l)
6933
6934         [ $nums -eq $expected ] ||
6935                 error "'$cmd' wrong: found $nums, expected $expected"
6936
6937         expected=$onestripe
6938         cmd="$LFS find -stripe-index 1 -type f $dir"
6939         nums=$($cmd | wc -l)
6940         [ $nums -eq $expected ] ||
6941                 error "'$cmd' wrong: found $nums, expected $expected"
6942
6943         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6944         nums=$($cmd | wc -l)
6945         [ $nums -eq $expected ] ||
6946                 error "'$cmd' wrong: found $nums, expected $expected"
6947
6948         expected=0
6949         # This should produce an error and not return any files
6950         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6951         nums=$($cmd 2>/dev/null | wc -l)
6952         [ $nums -eq $expected ] ||
6953                 error "'$cmd' wrong: found $nums, expected $expected"
6954
6955         if [[ $OSTCOUNT -gt 1 ]]; then
6956                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6957                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6958                 nums=$($cmd | wc -l)
6959                 [ $nums -eq $expected ] ||
6960                         error "'$cmd' wrong: found $nums, expected $expected"
6961         fi
6962 }
6963 run_test 56u "check lfs find -stripe-index works"
6964
6965 test_56v() {
6966         local mdt_idx=0
6967         local dir=$DIR/$tdir
6968
6969         setup_56 $dir $NUMFILES $NUMDIRS
6970
6971         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6972         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6973
6974         for file in $($LFS find -m $UUID $dir); do
6975                 file_midx=$($LFS getstripe -m $file)
6976                 [ $file_midx -eq $mdt_idx ] ||
6977                         error "lfs find -m $UUID != getstripe -m $file_midx"
6978         done
6979 }
6980 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6981
6982 test_56w() {
6983         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6985
6986         local dir=$DIR/$tdir
6987
6988         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6989
6990         local stripe_size=$($LFS getstripe -S -d $dir) ||
6991                 error "$LFS getstripe -S -d $dir failed"
6992         stripe_size=${stripe_size%% *}
6993
6994         local file_size=$((stripe_size * OSTCOUNT))
6995         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6996         local required_space=$((file_num * file_size))
6997         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6998                            head -n1)
6999         [[ $free_space -le $((required_space / 1024)) ]] &&
7000                 skip_env "need $required_space, have $free_space kbytes"
7001
7002         local dd_bs=65536
7003         local dd_count=$((file_size / dd_bs))
7004
7005         # write data into the files
7006         local i
7007         local j
7008         local file
7009
7010         for i in $(seq $NUMFILES); do
7011                 file=$dir/file$i
7012                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7013                         error "write data into $file failed"
7014         done
7015         for i in $(seq $NUMDIRS); do
7016                 for j in $(seq $NUMFILES); do
7017                         file=$dir/dir$i/file$j
7018                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7019                                 error "write data into $file failed"
7020                 done
7021         done
7022
7023         # $LFS_MIGRATE will fail if hard link migration is unsupported
7024         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
7025                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7026                         error "creating links to $dir/dir1/file1 failed"
7027         fi
7028
7029         local expected=-1
7030
7031         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
7032
7033         # lfs_migrate file
7034         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7035
7036         echo "$cmd"
7037         eval $cmd || error "$cmd failed"
7038
7039         check_stripe_count $dir/file1 $expected
7040
7041         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
7042         then
7043                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7044                 # OST 1 if it is on OST 0. This file is small enough to
7045                 # be on only one stripe.
7046                 file=$dir/migr_1_ost
7047                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7048                         error "write data into $file failed"
7049                 local obdidx=$($LFS getstripe -i $file)
7050                 local oldmd5=$(md5sum $file)
7051                 local newobdidx=0
7052
7053                 [[ $obdidx -eq 0 ]] && newobdidx=1
7054                 cmd="$LFS migrate -i $newobdidx $file"
7055                 echo $cmd
7056                 eval $cmd || error "$cmd failed"
7057
7058                 local realobdix=$($LFS getstripe -i $file)
7059                 local newmd5=$(md5sum $file)
7060
7061                 [[ $newobdidx -ne $realobdix ]] &&
7062                         error "new OST is different (was=$obdidx, "\
7063                               "wanted=$newobdidx, got=$realobdix)"
7064                 [[ "$oldmd5" != "$newmd5" ]] &&
7065                         error "md5sum differ: $oldmd5, $newmd5"
7066         fi
7067
7068         # lfs_migrate dir
7069         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7070         echo "$cmd"
7071         eval $cmd || error "$cmd failed"
7072
7073         for j in $(seq $NUMFILES); do
7074                 check_stripe_count $dir/dir1/file$j $expected
7075         done
7076
7077         # lfs_migrate works with lfs find
7078         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7079              $LFS_MIGRATE -y -c $expected"
7080         echo "$cmd"
7081         eval $cmd || error "$cmd failed"
7082
7083         for i in $(seq 2 $NUMFILES); do
7084                 check_stripe_count $dir/file$i $expected
7085         done
7086         for i in $(seq 2 $NUMDIRS); do
7087                 for j in $(seq $NUMFILES); do
7088                 check_stripe_count $dir/dir$i/file$j $expected
7089                 done
7090         done
7091 }
7092 run_test 56w "check lfs_migrate -c stripe_count works"
7093
7094 test_56wb() {
7095         local file1=$DIR/$tdir/file1
7096         local create_pool=false
7097         local initial_pool=$($LFS getstripe -p $DIR)
7098         local pool_list=()
7099         local pool=""
7100
7101         echo -n "Creating test dir..."
7102         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7103         echo "done."
7104
7105         echo -n "Creating test file..."
7106         touch $file1 || error "cannot create file"
7107         echo "done."
7108
7109         echo -n "Detecting existing pools..."
7110         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7111
7112         if [ ${#pool_list[@]} -gt 0 ]; then
7113                 echo "${pool_list[@]}"
7114                 for thispool in "${pool_list[@]}"; do
7115                         if [[ -z "$initial_pool" ||
7116                               "$initial_pool" != "$thispool" ]]; then
7117                                 pool="$thispool"
7118                                 echo "Using existing pool '$pool'"
7119                                 break
7120                         fi
7121                 done
7122         else
7123                 echo "none detected."
7124         fi
7125         if [ -z "$pool" ]; then
7126                 pool=${POOL:-testpool}
7127                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7128                 echo -n "Creating pool '$pool'..."
7129                 create_pool=true
7130                 pool_add $pool &> /dev/null ||
7131                         error "pool_add failed"
7132                 echo "done."
7133
7134                 echo -n "Adding target to pool..."
7135                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7136                         error "pool_add_targets failed"
7137                 echo "done."
7138         fi
7139
7140         echo -n "Setting pool using -p option..."
7141         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7142                 error "migrate failed rc = $?"
7143         echo "done."
7144
7145         echo -n "Verifying test file is in pool after migrating..."
7146         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7147                 error "file was not migrated to pool $pool"
7148         echo "done."
7149
7150         echo -n "Removing test file from pool '$pool'..."
7151         # "lfs migrate $file" won't remove the file from the pool
7152         # until some striping information is changed.
7153         $LFS migrate -c 1 $file1 &> /dev/null ||
7154                 error "cannot remove from pool"
7155         [ "$($LFS getstripe -p $file1)" ] &&
7156                 error "pool still set"
7157         echo "done."
7158
7159         echo -n "Setting pool using --pool option..."
7160         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7161                 error "migrate failed rc = $?"
7162         echo "done."
7163
7164         # Clean up
7165         rm -f $file1
7166         if $create_pool; then
7167                 destroy_test_pools 2> /dev/null ||
7168                         error "destroy test pools failed"
7169         fi
7170 }
7171 run_test 56wb "check lfs_migrate pool support"
7172
7173 test_56wc() {
7174         local file1="$DIR/$tdir/file1"
7175         local parent_ssize
7176         local parent_scount
7177         local cur_ssize
7178         local cur_scount
7179         local orig_ssize
7180
7181         echo -n "Creating test dir..."
7182         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7183         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7184                 error "cannot set stripe by '-S 1M -c 1'"
7185         echo "done"
7186
7187         echo -n "Setting initial stripe for test file..."
7188         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7189                 error "cannot set stripe"
7190         cur_ssize=$($LFS getstripe -S "$file1")
7191         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7192         echo "done."
7193
7194         # File currently set to -S 512K -c 1
7195
7196         # Ensure -c and -S options are rejected when -R is set
7197         echo -n "Verifying incompatible options are detected..."
7198         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7199                 error "incompatible -c and -R options not detected"
7200         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7201                 error "incompatible -S and -R options not detected"
7202         echo "done."
7203
7204         # Ensure unrecognized options are passed through to 'lfs migrate'
7205         echo -n "Verifying -S option is passed through to lfs migrate..."
7206         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7207                 error "migration failed"
7208         cur_ssize=$($LFS getstripe -S "$file1")
7209         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7210         echo "done."
7211
7212         # File currently set to -S 1M -c 1
7213
7214         # Ensure long options are supported
7215         echo -n "Verifying long options supported..."
7216         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7217                 error "long option without argument not supported"
7218         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7219                 error "long option with argument not supported"
7220         cur_ssize=$($LFS getstripe -S "$file1")
7221         [ $cur_ssize -eq 524288 ] ||
7222                 error "migrate --stripe-size $cur_ssize != 524288"
7223         echo "done."
7224
7225         # File currently set to -S 512K -c 1
7226
7227         if [ "$OSTCOUNT" -gt 1 ]; then
7228                 echo -n "Verifying explicit stripe count can be set..."
7229                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7230                         error "migrate failed"
7231                 cur_scount=$($LFS getstripe -c "$file1")
7232                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7233                 echo "done."
7234         fi
7235
7236         # File currently set to -S 512K -c 1 or -S 512K -c 2
7237
7238         # Ensure parent striping is used if -R is set, and no stripe
7239         # count or size is specified
7240         echo -n "Setting stripe for parent directory..."
7241         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7242                 error "cannot set stripe '-S 2M -c 1'"
7243         echo "done."
7244
7245         echo -n "Verifying restripe option uses parent stripe settings..."
7246         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7247         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7248         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7249                 error "migrate failed"
7250         cur_ssize=$($LFS getstripe -S "$file1")
7251         [ $cur_ssize -eq $parent_ssize ] ||
7252                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7253         cur_scount=$($LFS getstripe -c "$file1")
7254         [ $cur_scount -eq $parent_scount ] ||
7255                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7256         echo "done."
7257
7258         # File currently set to -S 1M -c 1
7259
7260         # Ensure striping is preserved if -R is not set, and no stripe
7261         # count or size is specified
7262         echo -n "Verifying striping size preserved when not specified..."
7263         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7264         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7265                 error "cannot set stripe on parent directory"
7266         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7267                 error "migrate failed"
7268         cur_ssize=$($LFS getstripe -S "$file1")
7269         [ $cur_ssize -eq $orig_ssize ] ||
7270                 error "migrate by default $cur_ssize != $orig_ssize"
7271         echo "done."
7272
7273         # Ensure file name properly detected when final option has no argument
7274         echo -n "Verifying file name properly detected..."
7275         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7276                 error "file name interpreted as option argument"
7277         echo "done."
7278
7279         # Clean up
7280         rm -f "$file1"
7281 }
7282 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7283
7284 test_56wd() {
7285         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7286
7287         local file1=$DIR/$tdir/file1
7288
7289         echo -n "Creating test dir..."
7290         test_mkdir $DIR/$tdir || error "cannot create dir"
7291         echo "done."
7292
7293         echo -n "Creating test file..."
7294         touch $file1
7295         echo "done."
7296
7297         # Ensure 'lfs migrate' will fail by using a non-existent option,
7298         # and make sure rsync is not called to recover
7299         echo -n "Make sure --no-rsync option works..."
7300         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7301                 grep -q 'refusing to fall back to rsync' ||
7302                 error "rsync was called with --no-rsync set"
7303         echo "done."
7304
7305         # Ensure rsync is called without trying 'lfs migrate' first
7306         echo -n "Make sure --rsync option works..."
7307         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7308                 grep -q 'falling back to rsync' &&
7309                 error "lfs migrate was called with --rsync set"
7310         echo "done."
7311
7312         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7313         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7314                 grep -q 'at the same time' ||
7315                 error "--rsync and --no-rsync accepted concurrently"
7316         echo "done."
7317
7318         # Clean up
7319         rm -f $file1
7320 }
7321 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7322
7323 test_56we() {
7324         local td=$DIR/$tdir
7325         local tf=$td/$tfile
7326
7327         test_mkdir $td || error "cannot create $td"
7328         touch $tf || error "cannot touch $tf"
7329
7330         echo -n "Make sure --non-direct|-D works..."
7331         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7332                 grep -q "lfs migrate --non-direct" ||
7333                 error "--non-direct option cannot work correctly"
7334         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7335                 grep -q "lfs migrate -D" ||
7336                 error "-D option cannot work correctly"
7337         echo "done."
7338 }
7339 run_test 56we "check lfs_migrate --non-direct|-D support"
7340
7341 test_56x() {
7342         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7343         check_swap_layouts_support
7344
7345         local dir=$DIR/$tdir
7346         local ref1=/etc/passwd
7347         local file1=$dir/file1
7348
7349         test_mkdir $dir || error "creating dir $dir"
7350         $LFS setstripe -c 2 $file1
7351         cp $ref1 $file1
7352         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7353         stripe=$($LFS getstripe -c $file1)
7354         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7355         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7356
7357         # clean up
7358         rm -f $file1
7359 }
7360 run_test 56x "lfs migration support"
7361
7362 test_56xa() {
7363         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7364         check_swap_layouts_support
7365
7366         local dir=$DIR/$tdir/$testnum
7367
7368         test_mkdir -p $dir
7369
7370         local ref1=/etc/passwd
7371         local file1=$dir/file1
7372
7373         $LFS setstripe -c 2 $file1
7374         cp $ref1 $file1
7375         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7376
7377         local stripe=$($LFS getstripe -c $file1)
7378
7379         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7380         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7381
7382         # clean up
7383         rm -f $file1
7384 }
7385 run_test 56xa "lfs migration --block support"
7386
7387 check_migrate_links() {
7388         local dir="$1"
7389         local file1="$dir/file1"
7390         local begin="$2"
7391         local count="$3"
7392         local runas="$4"
7393         local total_count=$(($begin + $count - 1))
7394         local symlink_count=10
7395         local uniq_count=10
7396
7397         if [ ! -f "$file1" ]; then
7398                 echo -n "creating initial file..."
7399                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7400                         error "cannot setstripe initial file"
7401                 echo "done"
7402
7403                 echo -n "creating symlinks..."
7404                 for s in $(seq 1 $symlink_count); do
7405                         ln -s "$file1" "$dir/slink$s" ||
7406                                 error "cannot create symlinks"
7407                 done
7408                 echo "done"
7409
7410                 echo -n "creating nonlinked files..."
7411                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7412                         error "cannot create nonlinked files"
7413                 echo "done"
7414         fi
7415
7416         # create hard links
7417         if [ ! -f "$dir/file$total_count" ]; then
7418                 echo -n "creating hard links $begin:$total_count..."
7419                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7420                         /dev/null || error "cannot create hard links"
7421                 echo "done"
7422         fi
7423
7424         echo -n "checking number of hard links listed in xattrs..."
7425         local fid=$($LFS getstripe -F "$file1")
7426         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7427
7428         echo "${#paths[*]}"
7429         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7430                         skip "hard link list has unexpected size, skipping test"
7431         fi
7432         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7433                         error "link names should exceed xattrs size"
7434         fi
7435
7436         echo -n "migrating files..."
7437         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7438         local rc=$?
7439         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7440         echo "done"
7441
7442         # make sure all links have been properly migrated
7443         echo -n "verifying files..."
7444         fid=$($LFS getstripe -F "$file1") ||
7445                 error "cannot get fid for file $file1"
7446         for i in $(seq 2 $total_count); do
7447                 local fid2=$($LFS getstripe -F $dir/file$i)
7448
7449                 [ "$fid2" == "$fid" ] ||
7450                         error "migrated hard link has mismatched FID"
7451         done
7452
7453         # make sure hard links were properly detected, and migration was
7454         # performed only once for the entire link set; nonlinked files should
7455         # also be migrated
7456         local actual=$(grep -c 'done' <<< "$migrate_out")
7457         local expected=$(($uniq_count + 1))
7458
7459         [ "$actual" -eq  "$expected" ] ||
7460                 error "hard links individually migrated ($actual != $expected)"
7461
7462         # make sure the correct number of hard links are present
7463         local hardlinks=$(stat -c '%h' "$file1")
7464
7465         [ $hardlinks -eq $total_count ] ||
7466                 error "num hard links $hardlinks != $total_count"
7467         echo "done"
7468
7469         return 0
7470 }
7471
7472 test_56xb() {
7473         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7474                 skip "Need MDS version at least 2.10.55"
7475
7476         local dir="$DIR/$tdir"
7477
7478         test_mkdir "$dir" || error "cannot create dir $dir"
7479
7480         echo "testing lfs migrate mode when all links fit within xattrs"
7481         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7482
7483         echo "testing rsync mode when all links fit within xattrs"
7484         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7485
7486         echo "testing lfs migrate mode when all links do not fit within xattrs"
7487         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7488
7489         echo "testing rsync mode when all links do not fit within xattrs"
7490         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7491
7492         chown -R $RUNAS_ID $dir
7493         echo "testing non-root lfs migrate mode when not all links are in xattr"
7494         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7495
7496         # clean up
7497         rm -rf $dir
7498 }
7499 run_test 56xb "lfs migration hard link support"
7500
7501 test_56xc() {
7502         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7503
7504         local dir="$DIR/$tdir"
7505
7506         test_mkdir "$dir" || error "cannot create dir $dir"
7507
7508         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7509         echo -n "Setting initial stripe for 20MB test file..."
7510         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7511                 error "cannot setstripe 20MB file"
7512         echo "done"
7513         echo -n "Sizing 20MB test file..."
7514         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7515         echo "done"
7516         echo -n "Verifying small file autostripe count is 1..."
7517         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7518                 error "cannot migrate 20MB file"
7519         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7520                 error "cannot get stripe for $dir/20mb"
7521         [ $stripe_count -eq 1 ] ||
7522                 error "unexpected stripe count $stripe_count for 20MB file"
7523         rm -f "$dir/20mb"
7524         echo "done"
7525
7526         # Test 2: File is small enough to fit within the available space on
7527         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7528         # have at least an additional 1KB for each desired stripe for test 3
7529         echo -n "Setting stripe for 1GB test file..."
7530         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7531         echo "done"
7532         echo -n "Sizing 1GB test file..."
7533         # File size is 1GB + 3KB
7534         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7535         echo "done"
7536
7537         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7538         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7539         if (( avail > 524288 * OSTCOUNT )); then
7540                 echo -n "Migrating 1GB file..."
7541                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7542                         error "cannot migrate 1GB file"
7543                 echo "done"
7544                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7545                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7546                         error "cannot getstripe for 1GB file"
7547                 [ $stripe_count -eq 2 ] ||
7548                         error "unexpected stripe count $stripe_count != 2"
7549                 echo "done"
7550         fi
7551
7552         # Test 3: File is too large to fit within the available space on
7553         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7554         if [ $OSTCOUNT -ge 3 ]; then
7555                 # The required available space is calculated as
7556                 # file size (1GB + 3KB) / OST count (3).
7557                 local kb_per_ost=349526
7558
7559                 echo -n "Migrating 1GB file with limit..."
7560                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7561                         error "cannot migrate 1GB file with limit"
7562                 echo "done"
7563
7564                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7565                 echo -n "Verifying 1GB autostripe count with limited space..."
7566                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7567                         error "unexpected stripe count $stripe_count (min 3)"
7568                 echo "done"
7569         fi
7570
7571         # clean up
7572         rm -rf $dir
7573 }
7574 run_test 56xc "lfs migration autostripe"
7575
7576 test_56xd() {
7577         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7578
7579         local dir=$DIR/$tdir
7580         local f_mgrt=$dir/$tfile.mgrt
7581         local f_yaml=$dir/$tfile.yaml
7582         local f_copy=$dir/$tfile.copy
7583         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7584         local layout_copy="-c 2 -S 2M -i 1"
7585         local yamlfile=$dir/yamlfile
7586         local layout_before;
7587         local layout_after;
7588
7589         test_mkdir "$dir" || error "cannot create dir $dir"
7590         $LFS setstripe $layout_yaml $f_yaml ||
7591                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7592         $LFS getstripe --yaml $f_yaml > $yamlfile
7593         $LFS setstripe $layout_copy $f_copy ||
7594                 error "cannot setstripe $f_copy with layout $layout_copy"
7595         touch $f_mgrt
7596         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7597
7598         # 1. test option --yaml
7599         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7600                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7601         layout_before=$(get_layout_param $f_yaml)
7602         layout_after=$(get_layout_param $f_mgrt)
7603         [ "$layout_after" == "$layout_before" ] ||
7604                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7605
7606         # 2. test option --copy
7607         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7608                 error "cannot migrate $f_mgrt with --copy $f_copy"
7609         layout_before=$(get_layout_param $f_copy)
7610         layout_after=$(get_layout_param $f_mgrt)
7611         [ "$layout_after" == "$layout_before" ] ||
7612                 error "lfs_migrate --copy: $layout_after != $layout_before"
7613 }
7614 run_test 56xd "check lfs_migrate --yaml and --copy support"
7615
7616 test_56xe() {
7617         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7618
7619         local dir=$DIR/$tdir
7620         local f_comp=$dir/$tfile
7621         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7622         local layout_before=""
7623         local layout_after=""
7624
7625         test_mkdir "$dir" || error "cannot create dir $dir"
7626         $LFS setstripe $layout $f_comp ||
7627                 error "cannot setstripe $f_comp with layout $layout"
7628         layout_before=$(get_layout_param $f_comp)
7629         dd if=/dev/zero of=$f_comp bs=1M count=4
7630
7631         # 1. migrate a comp layout file by lfs_migrate
7632         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7633         layout_after=$(get_layout_param $f_comp)
7634         [ "$layout_before" == "$layout_after" ] ||
7635                 error "lfs_migrate: $layout_before != $layout_after"
7636
7637         # 2. migrate a comp layout file by lfs migrate
7638         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7639         layout_after=$(get_layout_param $f_comp)
7640         [ "$layout_before" == "$layout_after" ] ||
7641                 error "lfs migrate: $layout_before != $layout_after"
7642 }
7643 run_test 56xe "migrate a composite layout file"
7644
7645 test_56xf() {
7646         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7647
7648         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7649                 skip "Need server version at least 2.13.53"
7650
7651         local dir=$DIR/$tdir
7652         local f_comp=$dir/$tfile
7653         local layout="-E 1M -c1 -E -1 -c2"
7654         local fid_before=""
7655         local fid_after=""
7656
7657         test_mkdir "$dir" || error "cannot create dir $dir"
7658         $LFS setstripe $layout $f_comp ||
7659                 error "cannot setstripe $f_comp with layout $layout"
7660         fid_before=$($LFS getstripe --fid $f_comp)
7661         dd if=/dev/zero of=$f_comp bs=1M count=4
7662
7663         # 1. migrate a comp layout file to a comp layout
7664         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7665         fid_after=$($LFS getstripe --fid $f_comp)
7666         [ "$fid_before" == "$fid_after" ] ||
7667                 error "comp-to-comp migrate: $fid_before != $fid_after"
7668
7669         # 2. migrate a comp layout file to a plain layout
7670         $LFS migrate -c2 $f_comp ||
7671                 error "cannot migrate $f_comp by lfs migrate"
7672         fid_after=$($LFS getstripe --fid $f_comp)
7673         [ "$fid_before" == "$fid_after" ] ||
7674                 error "comp-to-plain migrate: $fid_before != $fid_after"
7675
7676         # 3. migrate a plain layout file to a comp layout
7677         $LFS migrate $layout $f_comp ||
7678                 error "cannot migrate $f_comp by lfs migrate"
7679         fid_after=$($LFS getstripe --fid $f_comp)
7680         [ "$fid_before" == "$fid_after" ] ||
7681                 error "plain-to-comp migrate: $fid_before != $fid_after"
7682 }
7683 run_test 56xf "FID is not lost during migration of a composite layout file"
7684
7685 check_file_ost_range() {
7686         local file="$1"
7687         shift
7688         local range="$*"
7689         local -a file_range
7690         local idx
7691
7692         file_range=($($LFS getstripe -y "$file" |
7693                 awk '/l_ost_idx:/ { print $NF }'))
7694
7695         if [[ "${#file_range[@]}" = 0 ]]; then
7696                 echo "No osts found for $file"
7697                 return 1
7698         fi
7699
7700         for idx in "${file_range[@]}"; do
7701                 [[ " $range " =~ " $idx " ]] ||
7702                         return 1
7703         done
7704
7705         return 0
7706 }
7707
7708 sub_test_56xg() {
7709         local stripe_opt="$1"
7710         local pool="$2"
7711         shift 2
7712         local pool_ostidx="$(seq $* | tr '\n' ' ')"
7713
7714         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
7715                 error "Fail to migrate $tfile on $pool"
7716         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
7717                 error "$tfile is not in pool $pool"
7718         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
7719                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
7720 }
7721
7722 test_56xg() {
7723         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7724         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
7725         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
7726                 skip "Need MDS version newer than 2.14.52"
7727
7728         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
7729         local -a pool_ranges=("0 0" "1 1" "0 1")
7730
7731         # init pools
7732         for i in "${!pool_names[@]}"; do
7733                 pool_add ${pool_names[$i]} ||
7734                         error "pool_add failed (pool: ${pool_names[$i]})"
7735                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
7736                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
7737         done
7738
7739         # init the file to migrate
7740         $LFS setstripe -c1 -i1 $DIR/$tfile ||
7741                 error "Unable to create $tfile on OST1"
7742         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
7743                 error "Unable to write on $tfile"
7744
7745         echo "1. migrate $tfile on pool ${pool_names[0]}"
7746         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
7747
7748         echo "2. migrate $tfile on pool ${pool_names[2]}"
7749         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
7750
7751         echo "3. migrate $tfile on pool ${pool_names[1]}"
7752         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
7753
7754         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
7755         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
7756         echo
7757
7758         # Clean pools
7759         destroy_test_pools ||
7760                 error "pool_destroy failed"
7761 }
7762 run_test 56xg "lfs migrate pool support"
7763
7764 test_56y() {
7765         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7766                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7767
7768         local res=""
7769         local dir=$DIR/$tdir
7770         local f1=$dir/file1
7771         local f2=$dir/file2
7772
7773         test_mkdir -p $dir || error "creating dir $dir"
7774         touch $f1 || error "creating std file $f1"
7775         $MULTIOP $f2 H2c || error "creating released file $f2"
7776
7777         # a directory can be raid0, so ask only for files
7778         res=$($LFS find $dir -L raid0 -type f | wc -l)
7779         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7780
7781         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7782         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7783
7784         # only files can be released, so no need to force file search
7785         res=$($LFS find $dir -L released)
7786         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7787
7788         res=$($LFS find $dir -type f \! -L released)
7789         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7790 }
7791 run_test 56y "lfs find -L raid0|released"
7792
7793 test_56z() { # LU-4824
7794         # This checks to make sure 'lfs find' continues after errors
7795         # There are two classes of errors that should be caught:
7796         # - If multiple paths are provided, all should be searched even if one
7797         #   errors out
7798         # - If errors are encountered during the search, it should not terminate
7799         #   early
7800         local dir=$DIR/$tdir
7801         local i
7802
7803         test_mkdir $dir
7804         for i in d{0..9}; do
7805                 test_mkdir $dir/$i
7806                 touch $dir/$i/$tfile
7807         done
7808         $LFS find $DIR/non_existent_dir $dir &&
7809                 error "$LFS find did not return an error"
7810         # Make a directory unsearchable. This should NOT be the last entry in
7811         # directory order.  Arbitrarily pick the 6th entry
7812         chmod 700 $($LFS find $dir -type d | sed '6!d')
7813
7814         $RUNAS $LFS find $DIR/non_existent $dir
7815         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7816
7817         # The user should be able to see 10 directories and 9 files
7818         (( count == 19 )) ||
7819                 error "$LFS find found $count != 19 entries after error"
7820 }
7821 run_test 56z "lfs find should continue after an error"
7822
7823 test_56aa() { # LU-5937
7824         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7825
7826         local dir=$DIR/$tdir
7827
7828         mkdir $dir
7829         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7830
7831         createmany -o $dir/striped_dir/${tfile}- 1024
7832         local dirs=$($LFS find --size +8k $dir/)
7833
7834         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7835 }
7836 run_test 56aa "lfs find --size under striped dir"
7837
7838 test_56ab() { # LU-10705
7839         test_mkdir $DIR/$tdir
7840         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7841         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7842         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7843         # Flush writes to ensure valid blocks.  Need to be more thorough for
7844         # ZFS, since blocks are not allocated/returned to client immediately.
7845         sync_all_data
7846         wait_zfs_commit ost1 2
7847         cancel_lru_locks osc
7848         ls -ls $DIR/$tdir
7849
7850         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7851
7852         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7853
7854         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7855         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7856
7857         rm -f $DIR/$tdir/$tfile.[123]
7858 }
7859 run_test 56ab "lfs find --blocks"
7860
7861 # LU-11188
7862 test_56aca() {
7863         local dir="$DIR/$tdir"
7864         local perms=(001 002 003 004 005 006 007
7865                      010 020 030 040 050 060 070
7866                      100 200 300 400 500 600 700
7867                      111 222 333 444 555 666 777)
7868         local perm_minus=(8 8 4 8 4 4 2
7869                           8 8 4 8 4 4 2
7870                           8 8 4 8 4 4 2
7871                           4 4 2 4 2 2 1)
7872         local perm_slash=(8  8 12  8 12 12 14
7873                           8  8 12  8 12 12 14
7874                           8  8 12  8 12 12 14
7875                          16 16 24 16 24 24 28)
7876
7877         test_mkdir "$dir"
7878         for perm in ${perms[*]}; do
7879                 touch "$dir/$tfile.$perm"
7880                 chmod $perm "$dir/$tfile.$perm"
7881         done
7882
7883         for ((i = 0; i < ${#perms[*]}; i++)); do
7884                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
7885                 (( $num == 1 )) ||
7886                         error "lfs find -perm ${perms[i]}:"\
7887                               "$num != 1"
7888
7889                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
7890                 (( $num == ${perm_minus[i]} )) ||
7891                         error "lfs find -perm -${perms[i]}:"\
7892                               "$num != ${perm_minus[i]}"
7893
7894                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
7895                 (( $num == ${perm_slash[i]} )) ||
7896                         error "lfs find -perm /${perms[i]}:"\
7897                               "$num != ${perm_slash[i]}"
7898         done
7899 }
7900 run_test 56aca "check lfs find -perm with octal representation"
7901
7902 test_56acb() {
7903         local dir=$DIR/$tdir
7904         # p is the permission of write and execute for user, group and other
7905         # without the umask. It is used to test +wx.
7906         local p=$(printf "%o" "$((0333 & ~$(umask)))")
7907         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
7908         local symbolic=(+t  a+t u+t g+t o+t
7909                         g+s u+s o+s +s o+sr
7910                         o=r,ug+o,u+w
7911                         u+ g+ o+ a+ ugo+
7912                         u- g- o- a- ugo-
7913                         u= g= o= a= ugo=
7914                         o=r,ug+o,u+w u=r,a+u,u+w
7915                         g=r,ugo=g,u+w u+x,+X +X
7916                         u+x,u+X u+X u+x,g+X o+r,+X
7917                         u+x,go+X +wx +rwx)
7918
7919         test_mkdir $dir
7920         for perm in ${perms[*]}; do
7921                 touch "$dir/$tfile.$perm"
7922                 chmod $perm "$dir/$tfile.$perm"
7923         done
7924
7925         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
7926                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
7927
7928                 (( $num == 1 )) ||
7929                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
7930         done
7931 }
7932 run_test 56acb "check lfs find -perm with symbolic representation"
7933
7934 test_56acc() {
7935         local dir=$DIR/$tdir
7936         local tests="17777 787 789 abcd
7937                 ug=uu ug=a ug=gu uo=ou urw
7938                 u+xg+x a=r,u+x,"
7939
7940         test_mkdir $dir
7941         for err in $tests; do
7942                 if $LFS find $dir -perm $err 2>/dev/null; then
7943                         error "lfs find -perm $err: parsing should have failed"
7944                 fi
7945         done
7946 }
7947 run_test 56acc "check parsing error for lfs find -perm"
7948
7949 test_56ba() {
7950         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7951                 skip "Need MDS version at least 2.10.50"
7952
7953         # Create composite files with one component
7954         local dir=$DIR/$tdir
7955
7956         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7957         # Create composite files with three components
7958         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7959         # Create non-composite files
7960         createmany -o $dir/${tfile}- 10
7961
7962         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7963
7964         [[ $nfiles == 10 ]] ||
7965                 error "lfs find -E 1M found $nfiles != 10 files"
7966
7967         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7968         [[ $nfiles == 25 ]] ||
7969                 error "lfs find ! -E 1M found $nfiles != 25 files"
7970
7971         # All files have a component that starts at 0
7972         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7973         [[ $nfiles == 35 ]] ||
7974                 error "lfs find --component-start 0 - $nfiles != 35 files"
7975
7976         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7977         [[ $nfiles == 15 ]] ||
7978                 error "lfs find --component-start 2M - $nfiles != 15 files"
7979
7980         # All files created here have a componenet that does not starts at 2M
7981         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7982         [[ $nfiles == 35 ]] ||
7983                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7984
7985         # Find files with a specified number of components
7986         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7987         [[ $nfiles == 15 ]] ||
7988                 error "lfs find --component-count 3 - $nfiles != 15 files"
7989
7990         # Remember non-composite files have a component count of zero
7991         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7992         [[ $nfiles == 10 ]] ||
7993                 error "lfs find --component-count 0 - $nfiles != 10 files"
7994
7995         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7996         [[ $nfiles == 20 ]] ||
7997                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7998
7999         # All files have a flag called "init"
8000         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8001         [[ $nfiles == 35 ]] ||
8002                 error "lfs find --component-flags init - $nfiles != 35 files"
8003
8004         # Multi-component files will have a component not initialized
8005         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8006         [[ $nfiles == 15 ]] ||
8007                 error "lfs find !--component-flags init - $nfiles != 15 files"
8008
8009         rm -rf $dir
8010
8011 }
8012 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8013
8014 test_56ca() {
8015         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8016                 skip "Need MDS version at least 2.10.57"
8017
8018         local td=$DIR/$tdir
8019         local tf=$td/$tfile
8020         local dir
8021         local nfiles
8022         local cmd
8023         local i
8024         local j
8025
8026         # create mirrored directories and mirrored files
8027         mkdir $td || error "mkdir $td failed"
8028         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8029         createmany -o $tf- 10 || error "create $tf- failed"
8030
8031         for i in $(seq 2); do
8032                 dir=$td/dir$i
8033                 mkdir $dir || error "mkdir $dir failed"
8034                 $LFS mirror create -N$((3 + i)) $dir ||
8035                         error "create mirrored dir $dir failed"
8036                 createmany -o $dir/$tfile- 10 ||
8037                         error "create $dir/$tfile- failed"
8038         done
8039
8040         # change the states of some mirrored files
8041         echo foo > $tf-6
8042         for i in $(seq 2); do
8043                 dir=$td/dir$i
8044                 for j in $(seq 4 9); do
8045                         echo foo > $dir/$tfile-$j
8046                 done
8047         done
8048
8049         # find mirrored files with specific mirror count
8050         cmd="$LFS find --mirror-count 3 --type f $td"
8051         nfiles=$($cmd | wc -l)
8052         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8053
8054         cmd="$LFS find ! --mirror-count 3 --type f $td"
8055         nfiles=$($cmd | wc -l)
8056         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8057
8058         cmd="$LFS find --mirror-count +2 --type f $td"
8059         nfiles=$($cmd | wc -l)
8060         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8061
8062         cmd="$LFS find --mirror-count -6 --type f $td"
8063         nfiles=$($cmd | wc -l)
8064         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8065
8066         # find mirrored files with specific file state
8067         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8068         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8069
8070         cmd="$LFS find --mirror-state=ro --type f $td"
8071         nfiles=$($cmd | wc -l)
8072         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8073
8074         cmd="$LFS find ! --mirror-state=ro --type f $td"
8075         nfiles=$($cmd | wc -l)
8076         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8077
8078         cmd="$LFS find --mirror-state=wp --type f $td"
8079         nfiles=$($cmd | wc -l)
8080         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8081
8082         cmd="$LFS find ! --mirror-state=sp --type f $td"
8083         nfiles=$($cmd | wc -l)
8084         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8085 }
8086 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8087
8088 test_56da() { # LU-14179
8089         local path=$DIR/$tdir
8090
8091         test_mkdir $path
8092         cd $path
8093
8094         local longdir=$(str_repeat 'a' 255)
8095
8096         for i in {1..15}; do
8097                 path=$path/$longdir
8098                 test_mkdir $longdir
8099                 cd $longdir
8100         done
8101
8102         local len=${#path}
8103         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8104
8105         test_mkdir $lastdir
8106         cd $lastdir
8107         # PATH_MAX-1
8108         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8109
8110         # NAME_MAX
8111         touch $(str_repeat 'f' 255)
8112
8113         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8114                 error "lfs find reported an error"
8115
8116         rm -rf $DIR/$tdir
8117 }
8118 run_test 56da "test lfs find with long paths"
8119
8120 test_57a() {
8121         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8122         # note test will not do anything if MDS is not local
8123         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8124                 skip_env "ldiskfs only test"
8125         fi
8126         remote_mds_nodsh && skip "remote MDS with nodsh"
8127
8128         local MNTDEV="osd*.*MDT*.mntdev"
8129         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8130         [ -z "$DEV" ] && error "can't access $MNTDEV"
8131         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8132                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8133                         error "can't access $DEV"
8134                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8135                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8136                 rm $TMP/t57a.dump
8137         done
8138 }
8139 run_test 57a "verify MDS filesystem created with large inodes =="
8140
8141 test_57b() {
8142         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8143         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8144                 skip_env "ldiskfs only test"
8145         fi
8146         remote_mds_nodsh && skip "remote MDS with nodsh"
8147
8148         local dir=$DIR/$tdir
8149         local filecount=100
8150         local file1=$dir/f1
8151         local fileN=$dir/f$filecount
8152
8153         rm -rf $dir || error "removing $dir"
8154         test_mkdir -c1 $dir
8155         local mdtidx=$($LFS getstripe -m $dir)
8156         local mdtname=MDT$(printf %04x $mdtidx)
8157         local facet=mds$((mdtidx + 1))
8158
8159         echo "mcreating $filecount files"
8160         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8161
8162         # verify that files do not have EAs yet
8163         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8164                 error "$file1 has an EA"
8165         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8166                 error "$fileN has an EA"
8167
8168         sync
8169         sleep 1
8170         df $dir  #make sure we get new statfs data
8171         local mdsfree=$(do_facet $facet \
8172                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8173         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8174         local file
8175
8176         echo "opening files to create objects/EAs"
8177         for file in $(seq -f $dir/f%g 1 $filecount); do
8178                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8179                         error "opening $file"
8180         done
8181
8182         # verify that files have EAs now
8183         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8184         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8185
8186         sleep 1  #make sure we get new statfs data
8187         df $dir
8188         local mdsfree2=$(do_facet $facet \
8189                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8190         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8191
8192         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8193                 if [ "$mdsfree" != "$mdsfree2" ]; then
8194                         error "MDC before $mdcfree != after $mdcfree2"
8195                 else
8196                         echo "MDC before $mdcfree != after $mdcfree2"
8197                         echo "unable to confirm if MDS has large inodes"
8198                 fi
8199         fi
8200         rm -rf $dir
8201 }
8202 run_test 57b "default LOV EAs are stored inside large inodes ==="
8203
8204 test_58() {
8205         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8206         [ -z "$(which wiretest 2>/dev/null)" ] &&
8207                         skip_env "could not find wiretest"
8208
8209         wiretest
8210 }
8211 run_test 58 "verify cross-platform wire constants =============="
8212
8213 test_59() {
8214         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8215
8216         echo "touch 130 files"
8217         createmany -o $DIR/f59- 130
8218         echo "rm 130 files"
8219         unlinkmany $DIR/f59- 130
8220         sync
8221         # wait for commitment of removal
8222         wait_delete_completed
8223 }
8224 run_test 59 "verify cancellation of llog records async ========="
8225
8226 TEST60_HEAD="test_60 run $RANDOM"
8227 test_60a() {
8228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8229         remote_mgs_nodsh && skip "remote MGS with nodsh"
8230         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8231                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8232                         skip_env "missing subtest run-llog.sh"
8233
8234         log "$TEST60_HEAD - from kernel mode"
8235         do_facet mgs "$LCTL dk > /dev/null"
8236         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8237         do_facet mgs $LCTL dk > $TMP/$tfile
8238
8239         # LU-6388: test llog_reader
8240         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8241         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8242         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8243                         skip_env "missing llog_reader"
8244         local fstype=$(facet_fstype mgs)
8245         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8246                 skip_env "Only for ldiskfs or zfs type mgs"
8247
8248         local mntpt=$(facet_mntpt mgs)
8249         local mgsdev=$(mgsdevname 1)
8250         local fid_list
8251         local fid
8252         local rec_list
8253         local rec
8254         local rec_type
8255         local obj_file
8256         local path
8257         local seq
8258         local oid
8259         local pass=true
8260
8261         #get fid and record list
8262         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8263                 tail -n 4))
8264         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8265                 tail -n 4))
8266         #remount mgs as ldiskfs or zfs type
8267         stop mgs || error "stop mgs failed"
8268         mount_fstype mgs || error "remount mgs failed"
8269         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8270                 fid=${fid_list[i]}
8271                 rec=${rec_list[i]}
8272                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8273                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8274                 oid=$((16#$oid))
8275
8276                 case $fstype in
8277                         ldiskfs )
8278                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8279                         zfs )
8280                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8281                 esac
8282                 echo "obj_file is $obj_file"
8283                 do_facet mgs $llog_reader $obj_file
8284
8285                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8286                         awk '{ print $3 }' | sed -e "s/^type=//g")
8287                 if [ $rec_type != $rec ]; then
8288                         echo "FAILED test_60a wrong record type $rec_type," \
8289                               "should be $rec"
8290                         pass=false
8291                         break
8292                 fi
8293
8294                 #check obj path if record type is LLOG_LOGID_MAGIC
8295                 if [ "$rec" == "1064553b" ]; then
8296                         path=$(do_facet mgs $llog_reader $obj_file |
8297                                 grep "path=" | awk '{ print $NF }' |
8298                                 sed -e "s/^path=//g")
8299                         if [ $obj_file != $mntpt/$path ]; then
8300                                 echo "FAILED test_60a wrong obj path" \
8301                                       "$montpt/$path, should be $obj_file"
8302                                 pass=false
8303                                 break
8304                         fi
8305                 fi
8306         done
8307         rm -f $TMP/$tfile
8308         #restart mgs before "error", otherwise it will block the next test
8309         stop mgs || error "stop mgs failed"
8310         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8311         $pass || error "test failed, see FAILED test_60a messages for specifics"
8312 }
8313 run_test 60a "llog_test run from kernel module and test llog_reader"
8314
8315 test_60b() { # bug 6411
8316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8317
8318         dmesg > $DIR/$tfile
8319         LLOG_COUNT=$(do_facet mgs dmesg |
8320                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8321                           /llog_[a-z]*.c:[0-9]/ {
8322                                 if (marker)
8323                                         from_marker++
8324                                 from_begin++
8325                           }
8326                           END {
8327                                 if (marker)
8328                                         print from_marker
8329                                 else
8330                                         print from_begin
8331                           }")
8332
8333         [[ $LLOG_COUNT -gt 120 ]] &&
8334                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8335 }
8336 run_test 60b "limit repeated messages from CERROR/CWARN"
8337
8338 test_60c() {
8339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8340
8341         echo "create 5000 files"
8342         createmany -o $DIR/f60c- 5000
8343 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8344         lctl set_param fail_loc=0x80000137
8345         unlinkmany $DIR/f60c- 5000
8346         lctl set_param fail_loc=0
8347 }
8348 run_test 60c "unlink file when mds full"
8349
8350 test_60d() {
8351         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8352
8353         SAVEPRINTK=$(lctl get_param -n printk)
8354         # verify "lctl mark" is even working"
8355         MESSAGE="test message ID $RANDOM $$"
8356         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8357         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8358
8359         lctl set_param printk=0 || error "set lnet.printk failed"
8360         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8361         MESSAGE="new test message ID $RANDOM $$"
8362         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8363         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8364         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8365
8366         lctl set_param -n printk="$SAVEPRINTK"
8367 }
8368 run_test 60d "test printk console message masking"
8369
8370 test_60e() {
8371         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8372         remote_mds_nodsh && skip "remote MDS with nodsh"
8373
8374         touch $DIR/$tfile
8375 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8376         do_facet mds1 lctl set_param fail_loc=0x15b
8377         rm $DIR/$tfile
8378 }
8379 run_test 60e "no space while new llog is being created"
8380
8381 test_60f() {
8382         local old_path=$($LCTL get_param -n debug_path)
8383
8384         stack_trap "$LCTL set_param debug_path=$old_path"
8385         stack_trap "rm -f $TMP/$tfile*"
8386         rm -f $TMP/$tfile* 2> /dev/null
8387         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8388         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8389         test_mkdir $DIR/$tdir
8390         # retry in case the open is cached and not released
8391         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8392                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8393                 sleep 0.1
8394         done
8395         ls $TMP/$tfile*
8396         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8397 }
8398 run_test 60f "change debug_path works"
8399
8400 test_60g() {
8401         local pid
8402         local i
8403
8404         test_mkdir -c $MDSCOUNT $DIR/$tdir
8405
8406         (
8407                 local index=0
8408                 while true; do
8409                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8410                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8411                                 2>/dev/null
8412                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8413                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8414                         index=$((index + 1))
8415                 done
8416         ) &
8417
8418         pid=$!
8419
8420         for i in {0..100}; do
8421                 # define OBD_FAIL_OSD_TXN_START    0x19a
8422                 local index=$((i % MDSCOUNT + 1))
8423
8424                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8425                         > /dev/null
8426                 sleep 0.01
8427         done
8428
8429         kill -9 $pid
8430
8431         for i in $(seq $MDSCOUNT); do
8432                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8433         done
8434
8435         mkdir $DIR/$tdir/new || error "mkdir failed"
8436         rmdir $DIR/$tdir/new || error "rmdir failed"
8437
8438         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8439                 -t namespace
8440         for i in $(seq $MDSCOUNT); do
8441                 wait_update_facet mds$i "$LCTL get_param -n \
8442                         mdd.$(facet_svc mds$i).lfsck_namespace |
8443                         awk '/^status/ { print \\\$2 }'" "completed"
8444         done
8445
8446         ls -R $DIR/$tdir || error "ls failed"
8447         rm -rf $DIR/$tdir || error "rmdir failed"
8448 }
8449 run_test 60g "transaction abort won't cause MDT hung"
8450
8451 test_60h() {
8452         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8453                 skip "Need MDS version at least 2.12.52"
8454         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8455
8456         local f
8457
8458         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8459         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8460         for fail_loc in 0x80000188 0x80000189; do
8461                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8462                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8463                         error "mkdir $dir-$fail_loc failed"
8464                 for i in {0..10}; do
8465                         # create may fail on missing stripe
8466                         echo $i > $DIR/$tdir-$fail_loc/$i
8467                 done
8468                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8469                         error "getdirstripe $tdir-$fail_loc failed"
8470                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8471                         error "migrate $tdir-$fail_loc failed"
8472                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8473                         error "getdirstripe $tdir-$fail_loc failed"
8474                 pushd $DIR/$tdir-$fail_loc
8475                 for f in *; do
8476                         echo $f | cmp $f - || error "$f data mismatch"
8477                 done
8478                 popd
8479                 rm -rf $DIR/$tdir-$fail_loc
8480         done
8481 }
8482 run_test 60h "striped directory with missing stripes can be accessed"
8483
8484 function t60i_load() {
8485         mkdir $DIR/$tdir
8486         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8487         $LCTL set_param fail_loc=0x131c fail_val=1
8488         for ((i=0; i<5000; i++)); do
8489                 touch $DIR/$tdir/f$i
8490         done
8491 }
8492
8493 test_60i() {
8494         changelog_register || error "changelog_register failed"
8495         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8496         changelog_users $SINGLEMDS | grep -q $cl_user ||
8497                 error "User $cl_user not found in changelog_users"
8498         changelog_chmask "ALL"
8499         t60i_load &
8500         local PID=$!
8501         for((i=0; i<100; i++)); do
8502                 changelog_dump >/dev/null ||
8503                         error "can't read changelog"
8504         done
8505         kill $PID
8506         wait $PID
8507         changelog_deregister || error "changelog_deregister failed"
8508         $LCTL set_param fail_loc=0
8509 }
8510 run_test 60i "llog: new record vs reader race"
8511
8512 test_61a() {
8513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8514
8515         f="$DIR/f61"
8516         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8517         cancel_lru_locks osc
8518         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8519         sync
8520 }
8521 run_test 61a "mmap() writes don't make sync hang ================"
8522
8523 test_61b() {
8524         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8525 }
8526 run_test 61b "mmap() of unstriped file is successful"
8527
8528 # bug 2330 - insufficient obd_match error checking causes LBUG
8529 test_62() {
8530         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8531
8532         f="$DIR/f62"
8533         echo foo > $f
8534         cancel_lru_locks osc
8535         lctl set_param fail_loc=0x405
8536         cat $f && error "cat succeeded, expect -EIO"
8537         lctl set_param fail_loc=0
8538 }
8539 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8540 # match every page all of the time.
8541 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8542
8543 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8544 # Though this test is irrelevant anymore, it helped to reveal some
8545 # other grant bugs (LU-4482), let's keep it.
8546 test_63a() {   # was test_63
8547         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8548
8549         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8550
8551         for i in `seq 10` ; do
8552                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8553                 sleep 5
8554                 kill $!
8555                 sleep 1
8556         done
8557
8558         rm -f $DIR/f63 || true
8559 }
8560 run_test 63a "Verify oig_wait interruption does not crash ======="
8561
8562 # bug 2248 - async write errors didn't return to application on sync
8563 # bug 3677 - async write errors left page locked
8564 test_63b() {
8565         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8566
8567         debugsave
8568         lctl set_param debug=-1
8569
8570         # ensure we have a grant to do async writes
8571         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8572         rm $DIR/$tfile
8573
8574         sync    # sync lest earlier test intercept the fail_loc
8575
8576         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8577         lctl set_param fail_loc=0x80000406
8578         $MULTIOP $DIR/$tfile Owy && \
8579                 error "sync didn't return ENOMEM"
8580         sync; sleep 2; sync     # do a real sync this time to flush page
8581         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8582                 error "locked page left in cache after async error" || true
8583         debugrestore
8584 }
8585 run_test 63b "async write errors should be returned to fsync ==="
8586
8587 test_64a () {
8588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8589
8590         lfs df $DIR
8591         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8592 }
8593 run_test 64a "verify filter grant calculations (in kernel) ====="
8594
8595 test_64b () {
8596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8597
8598         sh oos.sh $MOUNT || error "oos.sh failed: $?"
8599 }
8600 run_test 64b "check out-of-space detection on client"
8601
8602 test_64c() {
8603         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8604 }
8605 run_test 64c "verify grant shrink"
8606
8607 import_param() {
8608         local tgt=$1
8609         local param=$2
8610
8611         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8612 }
8613
8614 # this does exactly what osc_request.c:osc_announce_cached() does in
8615 # order to calculate max amount of grants to ask from server
8616 want_grant() {
8617         local tgt=$1
8618
8619         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8620         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8621
8622         ((rpc_in_flight++));
8623         nrpages=$((nrpages * rpc_in_flight))
8624
8625         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8626
8627         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8628
8629         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8630         local undirty=$((nrpages * PAGE_SIZE))
8631
8632         local max_extent_pages
8633         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8634         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8635         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8636         local grant_extent_tax
8637         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8638
8639         undirty=$((undirty + nrextents * grant_extent_tax))
8640
8641         echo $undirty
8642 }
8643
8644 # this is size of unit for grant allocation. It should be equal to
8645 # what tgt_grant.c:tgt_grant_chunk() calculates
8646 grant_chunk() {
8647         local tgt=$1
8648         local max_brw_size
8649         local grant_extent_tax
8650
8651         max_brw_size=$(import_param $tgt max_brw_size)
8652
8653         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8654
8655         echo $(((max_brw_size + grant_extent_tax) * 2))
8656 }
8657
8658 test_64d() {
8659         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8660                 skip "OST < 2.10.55 doesn't limit grants enough"
8661
8662         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8663
8664         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8665                 skip "no grant_param connect flag"
8666
8667         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8668
8669         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8670         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8671
8672
8673         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8674         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8675
8676         $LFS setstripe $DIR/$tfile -i 0 -c 1
8677         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8678         ddpid=$!
8679
8680         while kill -0 $ddpid; do
8681                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8682
8683                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8684                         kill $ddpid
8685                         error "cur_grant $cur_grant > $max_cur_granted"
8686                 fi
8687
8688                 sleep 1
8689         done
8690 }
8691 run_test 64d "check grant limit exceed"
8692
8693 check_grants() {
8694         local tgt=$1
8695         local expected=$2
8696         local msg=$3
8697         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8698
8699         ((cur_grants == expected)) ||
8700                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8701 }
8702
8703 round_up_p2() {
8704         echo $((($1 + $2 - 1) & ~($2 - 1)))
8705 }
8706
8707 test_64e() {
8708         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8709         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8710                 skip "Need OSS version at least 2.11.56"
8711
8712         # Remount client to reset grant
8713         remount_client $MOUNT || error "failed to remount client"
8714         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8715
8716         local init_grants=$(import_param $osc_tgt initial_grant)
8717
8718         check_grants $osc_tgt $init_grants "init grants"
8719
8720         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8721         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8722         local gbs=$(import_param $osc_tgt grant_block_size)
8723
8724         # write random number of bytes from max_brw_size / 4 to max_brw_size
8725         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8726         # align for direct io
8727         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8728         # round to grant consumption unit
8729         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8730
8731         local grants=$((wb_round_up + extent_tax))
8732
8733         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8734
8735         # define OBD_FAIL_TGT_NO_GRANT 0x725
8736         # make the server not grant more back
8737         do_facet ost1 $LCTL set_param fail_loc=0x725
8738         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8739
8740         do_facet ost1 $LCTL set_param fail_loc=0
8741
8742         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8743
8744         rm -f $DIR/$tfile || error "rm failed"
8745
8746         # Remount client to reset grant
8747         remount_client $MOUNT || error "failed to remount client"
8748         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8749
8750         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8751
8752         # define OBD_FAIL_TGT_NO_GRANT 0x725
8753         # make the server not grant more back
8754         do_facet ost1 $LCTL set_param fail_loc=0x725
8755         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8756         do_facet ost1 $LCTL set_param fail_loc=0
8757
8758         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8759 }
8760 run_test 64e "check grant consumption (no grant allocation)"
8761
8762 test_64f() {
8763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8764
8765         # Remount client to reset grant
8766         remount_client $MOUNT || error "failed to remount client"
8767         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8768
8769         local init_grants=$(import_param $osc_tgt initial_grant)
8770         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8771         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8772         local gbs=$(import_param $osc_tgt grant_block_size)
8773         local chunk=$(grant_chunk $osc_tgt)
8774
8775         # write random number of bytes from max_brw_size / 4 to max_brw_size
8776         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8777         # align for direct io
8778         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8779         # round to grant consumption unit
8780         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8781
8782         local grants=$((wb_round_up + extent_tax))
8783
8784         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8785         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8786                 error "error writing to $DIR/$tfile"
8787
8788         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8789                 "direct io with grant allocation"
8790
8791         rm -f $DIR/$tfile || error "rm failed"
8792
8793         # Remount client to reset grant
8794         remount_client $MOUNT || error "failed to remount client"
8795         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8796
8797         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8798
8799         local cmd="oO_WRONLY:w${write_bytes}_yc"
8800
8801         $MULTIOP $DIR/$tfile $cmd &
8802         MULTIPID=$!
8803         sleep 1
8804
8805         check_grants $osc_tgt $((init_grants - grants)) \
8806                 "buffered io, not write rpc"
8807
8808         kill -USR1 $MULTIPID
8809         wait
8810
8811         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8812                 "buffered io, one RPC"
8813 }
8814 run_test 64f "check grant consumption (with grant allocation)"
8815
8816 test_64g() {
8817         #[ $MDS1_VERSION -lt $(version_code 2.14.54) ] &&
8818         #       skip "Need MDS version at least 2.14.54"
8819
8820         local mdts=$(comma_list $(mdts_nodes))
8821
8822         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
8823                         tr '\n' ' ')
8824         stack_trap "$LCTL set_param $old"
8825
8826         # generate dirty pages and increase dirty granted on MDT
8827         stack_trap "rm -f $DIR/$tfile-*"
8828         for (( i = 0; i < 10; i++)); do
8829                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
8830                         error "can't set stripe"
8831                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
8832                         error "can't dd"
8833                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
8834                         $LFS getstripe $DIR/$tfile-$i
8835                         error "not DoM file"
8836                 }
8837         done
8838
8839         # flush dirty pages
8840         sync
8841
8842         # wait until grant shrink reset grant dirty on MDTs
8843         for ((i = 0; i < 120; i++)); do
8844                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
8845                         awk '{sum=sum+$1} END {print sum}')
8846                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
8847                 echo "$grant_dirty grants, $vm_dirty pages"
8848                 (( grant_dirty + vm_dirty == 0 )) && break
8849                 (( i == 3 )) && sync &&
8850                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
8851                 sleep 1
8852         done
8853
8854         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
8855                 awk '{sum=sum+$1} END {print sum}')
8856         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
8857 }
8858 run_test 64g "grant shrink on MDT"
8859
8860 test_64h() {
8861         local instance=$($LFS getname -i $DIR)
8862         local osc_tgt="$FSNAME-OST0000-osc-$instance"
8863         local num_exps=$(do_facet ost1 \
8864             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
8865         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8866         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
8867         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
8868
8869         # 10MiB is for file to be written, max_brw_size * 16 *
8870         # num_exps is space reserve so that tgt_grant_shrink() decided
8871         # to not shrink
8872         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
8873         (( avail * 1024 < expect )) &&
8874                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
8875
8876         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
8877         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
8878         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
8879         $LCTL set_param osc.*OST0000*.grant_shrink=1
8880         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
8881
8882         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8883         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
8884
8885         # drop cache so that coming read would do rpc
8886         cancel_lru_locks osc
8887
8888         # shrink interval is set to 10, pause for 7 seconds so that
8889         # grant thread did not wake up yet but coming read entered
8890         # shrink mode for rpc (osc_should_shrink_grant())
8891         sleep 7
8892
8893         declare -a cur_grant_bytes
8894         declare -a tot_granted
8895         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
8896         tot_granted[0]=$(do_facet ost1 \
8897             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
8898
8899         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
8900
8901         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
8902         tot_granted[1]=$(do_facet ost1 \
8903             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
8904
8905         # grant change should be equal on both sides
8906         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
8907                 tot_granted[0] - tot_granted[1])) ||
8908                 error "grant change mismatch, "                                \
8909                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
8910                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
8911 }
8912 run_test 64h "grant shrink on read"
8913
8914 test_64i() {
8915         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
8916                 skip "need OST at least 2.14.55 to avoid grant shrink on replay"
8917
8918         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8919         remote_ost_nodsh && skip "remote OSTs with nodsh"
8920
8921         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8922
8923         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
8924
8925         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
8926         local instance=$($LFS getname -i $DIR)
8927
8928         local osc_tgt="$FSNAME-OST0000-osc-$instance"
8929         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
8930
8931         # shrink grants and simulate rpc loss
8932         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
8933         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
8934         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
8935
8936         fail ost1
8937
8938         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
8939
8940         local testid=$(echo $TESTNAME | tr '_' ' ')
8941
8942         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
8943                 grep "GRANT, real grant" &&
8944                 error "client has more grants then it owns" || true
8945 }
8946 run_test 64i "shrink on reconnect"
8947
8948 # bug 1414 - set/get directories' stripe info
8949 test_65a() {
8950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8951
8952         test_mkdir $DIR/$tdir
8953         touch $DIR/$tdir/f1
8954         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8955 }
8956 run_test 65a "directory with no stripe info"
8957
8958 test_65b() {
8959         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8960
8961         test_mkdir $DIR/$tdir
8962         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8963
8964         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8965                                                 error "setstripe"
8966         touch $DIR/$tdir/f2
8967         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8968 }
8969 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8970
8971 test_65c() {
8972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8973         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8974
8975         test_mkdir $DIR/$tdir
8976         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8977
8978         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8979                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8980         touch $DIR/$tdir/f3
8981         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8982 }
8983 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8984
8985 test_65d() {
8986         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8987
8988         test_mkdir $DIR/$tdir
8989         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8990         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8991
8992         if [[ $STRIPECOUNT -le 0 ]]; then
8993                 sc=1
8994         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8995                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8996                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8997         else
8998                 sc=$(($STRIPECOUNT - 1))
8999         fi
9000         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9001         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9002         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9003                 error "lverify failed"
9004 }
9005 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9006
9007 test_65e() {
9008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9009
9010         test_mkdir $DIR/$tdir
9011
9012         $LFS setstripe $DIR/$tdir || error "setstripe"
9013         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9014                                         error "no stripe info failed"
9015         touch $DIR/$tdir/f6
9016         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9017 }
9018 run_test 65e "directory setstripe defaults"
9019
9020 test_65f() {
9021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9022
9023         test_mkdir $DIR/${tdir}f
9024         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9025                 error "setstripe succeeded" || true
9026 }
9027 run_test 65f "dir setstripe permission (should return error) ==="
9028
9029 test_65g() {
9030         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9031
9032         test_mkdir $DIR/$tdir
9033         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9034
9035         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9036                 error "setstripe -S failed"
9037         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9038         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9039                 error "delete default stripe failed"
9040 }
9041 run_test 65g "directory setstripe -d"
9042
9043 test_65h() {
9044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9045
9046         test_mkdir $DIR/$tdir
9047         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9048
9049         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9050                 error "setstripe -S failed"
9051         test_mkdir $DIR/$tdir/dd1
9052         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9053                 error "stripe info inherit failed"
9054 }
9055 run_test 65h "directory stripe info inherit ===================="
9056
9057 test_65i() {
9058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9059
9060         save_layout_restore_at_exit $MOUNT
9061
9062         # bug6367: set non-default striping on root directory
9063         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9064
9065         # bug12836: getstripe on -1 default directory striping
9066         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9067
9068         # bug12836: getstripe -v on -1 default directory striping
9069         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9070
9071         # bug12836: new find on -1 default directory striping
9072         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9073 }
9074 run_test 65i "various tests to set root directory striping"
9075
9076 test_65j() { # bug6367
9077         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9078
9079         sync; sleep 1
9080
9081         # if we aren't already remounting for each test, do so for this test
9082         if [ "$I_MOUNTED" = "yes" ]; then
9083                 cleanup || error "failed to unmount"
9084                 setup
9085         fi
9086
9087         save_layout_restore_at_exit $MOUNT
9088
9089         $LFS setstripe -d $MOUNT || error "setstripe failed"
9090 }
9091 run_test 65j "set default striping on root directory (bug 6367)="
9092
9093 cleanup_65k() {
9094         rm -rf $DIR/$tdir
9095         wait_delete_completed
9096         do_facet $SINGLEMDS "lctl set_param -n \
9097                 osp.$ost*MDT0000.max_create_count=$max_count"
9098         do_facet $SINGLEMDS "lctl set_param -n \
9099                 osp.$ost*MDT0000.create_count=$count"
9100         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9101         echo $INACTIVE_OSC "is Activate"
9102
9103         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9104 }
9105
9106 test_65k() { # bug11679
9107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9108         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9109         remote_mds_nodsh && skip "remote MDS with nodsh"
9110
9111         local disable_precreate=true
9112         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9113                 disable_precreate=false
9114
9115         echo "Check OST status: "
9116         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9117                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9118
9119         for OSC in $MDS_OSCS; do
9120                 echo $OSC "is active"
9121                 do_facet $SINGLEMDS lctl --device %$OSC activate
9122         done
9123
9124         for INACTIVE_OSC in $MDS_OSCS; do
9125                 local ost=$(osc_to_ost $INACTIVE_OSC)
9126                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9127                                lov.*md*.target_obd |
9128                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9129
9130                 mkdir -p $DIR/$tdir
9131                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9132                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9133
9134                 echo "Deactivate: " $INACTIVE_OSC
9135                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9136
9137                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9138                               osp.$ost*MDT0000.create_count")
9139                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9140                                   osp.$ost*MDT0000.max_create_count")
9141                 $disable_precreate &&
9142                         do_facet $SINGLEMDS "lctl set_param -n \
9143                                 osp.$ost*MDT0000.max_create_count=0"
9144
9145                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9146                         [ -f $DIR/$tdir/$idx ] && continue
9147                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9148                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9149                                 { cleanup_65k;
9150                                   error "setstripe $idx should succeed"; }
9151                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9152                 done
9153                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9154                 rmdir $DIR/$tdir
9155
9156                 do_facet $SINGLEMDS "lctl set_param -n \
9157                         osp.$ost*MDT0000.max_create_count=$max_count"
9158                 do_facet $SINGLEMDS "lctl set_param -n \
9159                         osp.$ost*MDT0000.create_count=$count"
9160                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9161                 echo $INACTIVE_OSC "is Activate"
9162
9163                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9164         done
9165 }
9166 run_test 65k "validate manual striping works properly with deactivated OSCs"
9167
9168 test_65l() { # bug 12836
9169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9170
9171         test_mkdir -p $DIR/$tdir/test_dir
9172         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9173         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9174 }
9175 run_test 65l "lfs find on -1 stripe dir ========================"
9176
9177 test_65m() {
9178         local layout=$(save_layout $MOUNT)
9179         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9180                 restore_layout $MOUNT $layout
9181                 error "setstripe should fail by non-root users"
9182         }
9183         true
9184 }
9185 run_test 65m "normal user can't set filesystem default stripe"
9186
9187 test_65n() {
9188         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9189         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9190                 skip "Need MDS version at least 2.12.50"
9191         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9192
9193         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9194         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9195         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9196
9197         save_layout_restore_at_exit $MOUNT
9198
9199         # new subdirectory under root directory should not inherit
9200         # the default layout from root
9201         local dir1=$MOUNT/$tdir-1
9202         mkdir $dir1 || error "mkdir $dir1 failed"
9203         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9204                 error "$dir1 shouldn't have LOV EA"
9205
9206         # delete the default layout on root directory
9207         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9208
9209         local dir2=$MOUNT/$tdir-2
9210         mkdir $dir2 || error "mkdir $dir2 failed"
9211         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9212                 error "$dir2 shouldn't have LOV EA"
9213
9214         # set a new striping pattern on root directory
9215         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9216         local new_def_stripe_size=$((def_stripe_size * 2))
9217         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9218                 error "set stripe size on $MOUNT failed"
9219
9220         # new file created in $dir2 should inherit the new stripe size from
9221         # the filesystem default
9222         local file2=$dir2/$tfile-2
9223         touch $file2 || error "touch $file2 failed"
9224
9225         local file2_stripe_size=$($LFS getstripe -S $file2)
9226         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9227         {
9228                 echo "file2_stripe_size: '$file2_stripe_size'"
9229                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9230                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9231         }
9232
9233         local dir3=$MOUNT/$tdir-3
9234         mkdir $dir3 || error "mkdir $dir3 failed"
9235         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9236         # the root layout, which is the actual default layout that will be used
9237         # when new files are created in $dir3.
9238         local dir3_layout=$(get_layout_param $dir3)
9239         local root_dir_layout=$(get_layout_param $MOUNT)
9240         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9241         {
9242                 echo "dir3_layout: '$dir3_layout'"
9243                 echo "root_dir_layout: '$root_dir_layout'"
9244                 error "$dir3 should show the default layout from $MOUNT"
9245         }
9246
9247         # set OST pool on root directory
9248         local pool=$TESTNAME
9249         pool_add $pool || error "add $pool failed"
9250         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9251                 error "add targets to $pool failed"
9252
9253         $LFS setstripe -p $pool $MOUNT ||
9254                 error "set OST pool on $MOUNT failed"
9255
9256         # new file created in $dir3 should inherit the pool from
9257         # the filesystem default
9258         local file3=$dir3/$tfile-3
9259         touch $file3 || error "touch $file3 failed"
9260
9261         local file3_pool=$($LFS getstripe -p $file3)
9262         [[ "$file3_pool" = "$pool" ]] ||
9263                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9264
9265         local dir4=$MOUNT/$tdir-4
9266         mkdir $dir4 || error "mkdir $dir4 failed"
9267         local dir4_layout=$(get_layout_param $dir4)
9268         root_dir_layout=$(get_layout_param $MOUNT)
9269         echo "$LFS getstripe -d $dir4"
9270         $LFS getstripe -d $dir4
9271         echo "$LFS getstripe -d $MOUNT"
9272         $LFS getstripe -d $MOUNT
9273         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9274         {
9275                 echo "dir4_layout: '$dir4_layout'"
9276                 echo "root_dir_layout: '$root_dir_layout'"
9277                 error "$dir4 should show the default layout from $MOUNT"
9278         }
9279
9280         # new file created in $dir4 should inherit the pool from
9281         # the filesystem default
9282         local file4=$dir4/$tfile-4
9283         touch $file4 || error "touch $file4 failed"
9284
9285         local file4_pool=$($LFS getstripe -p $file4)
9286         [[ "$file4_pool" = "$pool" ]] ||
9287                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9288
9289         # new subdirectory under non-root directory should inherit
9290         # the default layout from its parent directory
9291         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9292                 error "set directory layout on $dir4 failed"
9293
9294         local dir5=$dir4/$tdir-5
9295         mkdir $dir5 || error "mkdir $dir5 failed"
9296
9297         dir4_layout=$(get_layout_param $dir4)
9298         local dir5_layout=$(get_layout_param $dir5)
9299         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9300         {
9301                 echo "dir4_layout: '$dir4_layout'"
9302                 echo "dir5_layout: '$dir5_layout'"
9303                 error "$dir5 should inherit the default layout from $dir4"
9304         }
9305
9306         # though subdir under ROOT doesn't inherit default layout, but
9307         # its sub dir/file should be created with default layout.
9308         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9309         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9310                 skip "Need MDS version at least 2.12.59"
9311
9312         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9313         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9314         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9315
9316         if [ $default_lmv_hash == "none" ]; then
9317                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9318         else
9319                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9320                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9321         fi
9322
9323         $LFS setdirstripe -D -c 2 $MOUNT ||
9324                 error "setdirstripe -D -c 2 failed"
9325         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9326         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9327         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9328 }
9329 run_test 65n "don't inherit default layout from root for new subdirectories"
9330
9331 # bug 2543 - update blocks count on client
9332 test_66() {
9333         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9334
9335         COUNT=${COUNT:-8}
9336         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9337         sync; sync_all_data; sync; sync_all_data
9338         cancel_lru_locks osc
9339         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
9340         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9341 }
9342 run_test 66 "update inode blocks count on client ==============="
9343
9344 meminfo() {
9345         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9346 }
9347
9348 swap_used() {
9349         swapon -s | awk '($1 == "'$1'") { print $4 }'
9350 }
9351
9352 # bug5265, obdfilter oa2dentry return -ENOENT
9353 # #define OBD_FAIL_SRV_ENOENT 0x217
9354 test_69() {
9355         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9356         remote_ost_nodsh && skip "remote OST with nodsh"
9357
9358         f="$DIR/$tfile"
9359         $LFS setstripe -c 1 -i 0 $f
9360
9361         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9362
9363         do_facet ost1 lctl set_param fail_loc=0x217
9364         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9365         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9366
9367         do_facet ost1 lctl set_param fail_loc=0
9368         $DIRECTIO write $f 0 2 || error "write error"
9369
9370         cancel_lru_locks osc
9371         $DIRECTIO read $f 0 1 || error "read error"
9372
9373         do_facet ost1 lctl set_param fail_loc=0x217
9374         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9375
9376         do_facet ost1 lctl set_param fail_loc=0
9377         rm -f $f
9378 }
9379 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9380
9381 test_71() {
9382         test_mkdir $DIR/$tdir
9383         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9384         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9385 }
9386 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9387
9388 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9389         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9390         [ "$RUNAS_ID" = "$UID" ] &&
9391                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9392         # Check that testing environment is properly set up. Skip if not
9393         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9394                 skip_env "User $RUNAS_ID does not exist - skipping"
9395
9396         touch $DIR/$tfile
9397         chmod 777 $DIR/$tfile
9398         chmod ug+s $DIR/$tfile
9399         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9400                 error "$RUNAS dd $DIR/$tfile failed"
9401         # See if we are still setuid/sgid
9402         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9403                 error "S/gid is not dropped on write"
9404         # Now test that MDS is updated too
9405         cancel_lru_locks mdc
9406         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9407                 error "S/gid is not dropped on MDS"
9408         rm -f $DIR/$tfile
9409 }
9410 run_test 72a "Test that remove suid works properly (bug5695) ===="
9411
9412 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9413         local perm
9414
9415         [ "$RUNAS_ID" = "$UID" ] &&
9416                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9417         [ "$RUNAS_ID" -eq 0 ] &&
9418                 skip_env "RUNAS_ID = 0 -- skipping"
9419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9420         # Check that testing environment is properly set up. Skip if not
9421         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9422                 skip_env "User $RUNAS_ID does not exist - skipping"
9423
9424         touch $DIR/${tfile}-f{g,u}
9425         test_mkdir $DIR/${tfile}-dg
9426         test_mkdir $DIR/${tfile}-du
9427         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9428         chmod g+s $DIR/${tfile}-{f,d}g
9429         chmod u+s $DIR/${tfile}-{f,d}u
9430         for perm in 777 2777 4777; do
9431                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9432                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9433                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9434                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9435         done
9436         true
9437 }
9438 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9439
9440 # bug 3462 - multiple simultaneous MDC requests
9441 test_73() {
9442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9443
9444         test_mkdir $DIR/d73-1
9445         test_mkdir $DIR/d73-2
9446         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9447         pid1=$!
9448
9449         lctl set_param fail_loc=0x80000129
9450         $MULTIOP $DIR/d73-1/f73-2 Oc &
9451         sleep 1
9452         lctl set_param fail_loc=0
9453
9454         $MULTIOP $DIR/d73-2/f73-3 Oc &
9455         pid3=$!
9456
9457         kill -USR1 $pid1
9458         wait $pid1 || return 1
9459
9460         sleep 25
9461
9462         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9463         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9464         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9465
9466         rm -rf $DIR/d73-*
9467 }
9468 run_test 73 "multiple MDC requests (should not deadlock)"
9469
9470 test_74a() { # bug 6149, 6184
9471         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9472
9473         touch $DIR/f74a
9474         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9475         #
9476         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9477         # will spin in a tight reconnection loop
9478         $LCTL set_param fail_loc=0x8000030e
9479         # get any lock that won't be difficult - lookup works.
9480         ls $DIR/f74a
9481         $LCTL set_param fail_loc=0
9482         rm -f $DIR/f74a
9483         true
9484 }
9485 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9486
9487 test_74b() { # bug 13310
9488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9489
9490         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9491         #
9492         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9493         # will spin in a tight reconnection loop
9494         $LCTL set_param fail_loc=0x8000030e
9495         # get a "difficult" lock
9496         touch $DIR/f74b
9497         $LCTL set_param fail_loc=0
9498         rm -f $DIR/f74b
9499         true
9500 }
9501 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9502
9503 test_74c() {
9504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9505
9506         #define OBD_FAIL_LDLM_NEW_LOCK
9507         $LCTL set_param fail_loc=0x319
9508         touch $DIR/$tfile && error "touch successful"
9509         $LCTL set_param fail_loc=0
9510         true
9511 }
9512 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9513
9514 slab_lic=/sys/kernel/slab/lustre_inode_cache
9515 num_objects() {
9516         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9517         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9518                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9519 }
9520
9521 test_76a() { # Now for b=20433, added originally in b=1443
9522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9523
9524         cancel_lru_locks osc
9525         # there may be some slab objects cached per core
9526         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9527         local before=$(num_objects)
9528         local count=$((512 * cpus))
9529         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9530         local margin=$((count / 10))
9531         if [[ -f $slab_lic/aliases ]]; then
9532                 local aliases=$(cat $slab_lic/aliases)
9533                 (( aliases > 0 )) && margin=$((margin * aliases))
9534         fi
9535
9536         echo "before slab objects: $before"
9537         for i in $(seq $count); do
9538                 touch $DIR/$tfile
9539                 rm -f $DIR/$tfile
9540         done
9541         cancel_lru_locks osc
9542         local after=$(num_objects)
9543         echo "created: $count, after slab objects: $after"
9544         # shared slab counts are not very accurate, allow significant margin
9545         # the main goal is that the cache growth is not permanently > $count
9546         while (( after > before + margin )); do
9547                 sleep 1
9548                 after=$(num_objects)
9549                 wait=$((wait + 1))
9550                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9551                 if (( wait > 60 )); then
9552                         error "inode slab grew from $before+$margin to $after"
9553                 fi
9554         done
9555 }
9556 run_test 76a "confirm clients recycle inodes properly ===="
9557
9558 test_76b() {
9559         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9560         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9561
9562         local count=512
9563         local before=$(num_objects)
9564
9565         for i in $(seq $count); do
9566                 mkdir $DIR/$tdir
9567                 rmdir $DIR/$tdir
9568         done
9569
9570         local after=$(num_objects)
9571         local wait=0
9572
9573         while (( after > before )); do
9574                 sleep 1
9575                 after=$(num_objects)
9576                 wait=$((wait + 1))
9577                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9578                 if (( wait > 60 )); then
9579                         error "inode slab grew from $before to $after"
9580                 fi
9581         done
9582
9583         echo "slab objects before: $before, after: $after"
9584 }
9585 run_test 76b "confirm clients recycle directory inodes properly ===="
9586
9587 export ORIG_CSUM=""
9588 set_checksums()
9589 {
9590         # Note: in sptlrpc modes which enable its own bulk checksum, the
9591         # original crc32_le bulk checksum will be automatically disabled,
9592         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9593         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9594         # In this case set_checksums() will not be no-op, because sptlrpc
9595         # bulk checksum will be enabled all through the test.
9596
9597         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9598         lctl set_param -n osc.*.checksums $1
9599         return 0
9600 }
9601
9602 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9603                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9604 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9605                              tr -d [] | head -n1)}
9606 set_checksum_type()
9607 {
9608         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9609         rc=$?
9610         log "set checksum type to $1, rc = $rc"
9611         return $rc
9612 }
9613
9614 get_osc_checksum_type()
9615 {
9616         # arugment 1: OST name, like OST0000
9617         ost=$1
9618         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9619                         sed 's/.*\[\(.*\)\].*/\1/g')
9620         rc=$?
9621         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9622         echo $checksum_type
9623 }
9624
9625 F77_TMP=$TMP/f77-temp
9626 F77SZ=8
9627 setup_f77() {
9628         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9629                 error "error writing to $F77_TMP"
9630 }
9631
9632 test_77a() { # bug 10889
9633         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9634         $GSS && skip_env "could not run with gss"
9635
9636         [ ! -f $F77_TMP ] && setup_f77
9637         set_checksums 1
9638         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9639         set_checksums 0
9640         rm -f $DIR/$tfile
9641 }
9642 run_test 77a "normal checksum read/write operation"
9643
9644 test_77b() { # bug 10889
9645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9646         $GSS && skip_env "could not run with gss"
9647
9648         [ ! -f $F77_TMP ] && setup_f77
9649         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9650         $LCTL set_param fail_loc=0x80000409
9651         set_checksums 1
9652
9653         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9654                 error "dd error: $?"
9655         $LCTL set_param fail_loc=0
9656
9657         for algo in $CKSUM_TYPES; do
9658                 cancel_lru_locks osc
9659                 set_checksum_type $algo
9660                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9661                 $LCTL set_param fail_loc=0x80000408
9662                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9663                 $LCTL set_param fail_loc=0
9664         done
9665         set_checksums 0
9666         set_checksum_type $ORIG_CSUM_TYPE
9667         rm -f $DIR/$tfile
9668 }
9669 run_test 77b "checksum error on client write, read"
9670
9671 cleanup_77c() {
9672         trap 0
9673         set_checksums 0
9674         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9675         $check_ost &&
9676                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9677         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9678         $check_ost && [ -n "$ost_file_prefix" ] &&
9679                 do_facet ost1 rm -f ${ost_file_prefix}\*
9680 }
9681
9682 test_77c() {
9683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9684         $GSS && skip_env "could not run with gss"
9685         remote_ost_nodsh && skip "remote OST with nodsh"
9686
9687         local bad1
9688         local osc_file_prefix
9689         local osc_file
9690         local check_ost=false
9691         local ost_file_prefix
9692         local ost_file
9693         local orig_cksum
9694         local dump_cksum
9695         local fid
9696
9697         # ensure corruption will occur on first OSS/OST
9698         $LFS setstripe -i 0 $DIR/$tfile
9699
9700         [ ! -f $F77_TMP ] && setup_f77
9701         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9702                 error "dd write error: $?"
9703         fid=$($LFS path2fid $DIR/$tfile)
9704
9705         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9706         then
9707                 check_ost=true
9708                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9709                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9710         else
9711                 echo "OSS do not support bulk pages dump upon error"
9712         fi
9713
9714         osc_file_prefix=$($LCTL get_param -n debug_path)
9715         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9716
9717         trap cleanup_77c EXIT
9718
9719         set_checksums 1
9720         # enable bulk pages dump upon error on Client
9721         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9722         # enable bulk pages dump upon error on OSS
9723         $check_ost &&
9724                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9725
9726         # flush Client cache to allow next read to reach OSS
9727         cancel_lru_locks osc
9728
9729         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9730         $LCTL set_param fail_loc=0x80000408
9731         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9732         $LCTL set_param fail_loc=0
9733
9734         rm -f $DIR/$tfile
9735
9736         # check cksum dump on Client
9737         osc_file=$(ls ${osc_file_prefix}*)
9738         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9739         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9740         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9741         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9742         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9743                      cksum)
9744         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9745         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9746                 error "dump content does not match on Client"
9747
9748         $check_ost || skip "No need to check cksum dump on OSS"
9749
9750         # check cksum dump on OSS
9751         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9752         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9753         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9754         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9755         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9756                 error "dump content does not match on OSS"
9757
9758         cleanup_77c
9759 }
9760 run_test 77c "checksum error on client read with debug"
9761
9762 test_77d() { # bug 10889
9763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9764         $GSS && skip_env "could not run with gss"
9765
9766         stack_trap "rm -f $DIR/$tfile"
9767         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9768         $LCTL set_param fail_loc=0x80000409
9769         set_checksums 1
9770         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9771                 error "direct write: rc=$?"
9772         $LCTL set_param fail_loc=0
9773         set_checksums 0
9774
9775         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9776         $LCTL set_param fail_loc=0x80000408
9777         set_checksums 1
9778         cancel_lru_locks osc
9779         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9780                 error "direct read: rc=$?"
9781         $LCTL set_param fail_loc=0
9782         set_checksums 0
9783 }
9784 run_test 77d "checksum error on OST direct write, read"
9785
9786 test_77f() { # bug 10889
9787         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9788         $GSS && skip_env "could not run with gss"
9789
9790         set_checksums 1
9791         stack_trap "rm -f $DIR/$tfile"
9792         for algo in $CKSUM_TYPES; do
9793                 cancel_lru_locks osc
9794                 set_checksum_type $algo
9795                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9796                 $LCTL set_param fail_loc=0x409
9797                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9798                         error "direct write succeeded"
9799                 $LCTL set_param fail_loc=0
9800         done
9801         set_checksum_type $ORIG_CSUM_TYPE
9802         set_checksums 0
9803 }
9804 run_test 77f "repeat checksum error on write (expect error)"
9805
9806 test_77g() { # bug 10889
9807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9808         $GSS && skip_env "could not run with gss"
9809         remote_ost_nodsh && skip "remote OST with nodsh"
9810
9811         [ ! -f $F77_TMP ] && setup_f77
9812
9813         local file=$DIR/$tfile
9814         stack_trap "rm -f $file" EXIT
9815
9816         $LFS setstripe -c 1 -i 0 $file
9817         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9818         do_facet ost1 lctl set_param fail_loc=0x8000021a
9819         set_checksums 1
9820         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9821                 error "write error: rc=$?"
9822         do_facet ost1 lctl set_param fail_loc=0
9823         set_checksums 0
9824
9825         cancel_lru_locks osc
9826         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9827         do_facet ost1 lctl set_param fail_loc=0x8000021b
9828         set_checksums 1
9829         cmp $F77_TMP $file || error "file compare failed"
9830         do_facet ost1 lctl set_param fail_loc=0
9831         set_checksums 0
9832 }
9833 run_test 77g "checksum error on OST write, read"
9834
9835 test_77k() { # LU-10906
9836         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9837         $GSS && skip_env "could not run with gss"
9838
9839         local cksum_param="osc.$FSNAME*.checksums"
9840         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9841         local checksum
9842         local i
9843
9844         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9845         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9846         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9847
9848         for i in 0 1; do
9849                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9850                         error "failed to set checksum=$i on MGS"
9851                 wait_update $HOSTNAME "$get_checksum" $i
9852                 #remount
9853                 echo "remount client, checksum should be $i"
9854                 remount_client $MOUNT || error "failed to remount client"
9855                 checksum=$(eval $get_checksum)
9856                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9857         done
9858         # remove persistent param to avoid races with checksum mountopt below
9859         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9860                 error "failed to delete checksum on MGS"
9861
9862         for opt in "checksum" "nochecksum"; do
9863                 #remount with mount option
9864                 echo "remount client with option $opt, checksum should be $i"
9865                 umount_client $MOUNT || error "failed to umount client"
9866                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9867                         error "failed to mount client with option '$opt'"
9868                 checksum=$(eval $get_checksum)
9869                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9870                 i=$((i - 1))
9871         done
9872
9873         remount_client $MOUNT || error "failed to remount client"
9874 }
9875 run_test 77k "enable/disable checksum correctly"
9876
9877 test_77l() {
9878         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9879         $GSS && skip_env "could not run with gss"
9880
9881         set_checksums 1
9882         stack_trap "set_checksums $ORIG_CSUM" EXIT
9883         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9884
9885         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9886
9887         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9888         for algo in $CKSUM_TYPES; do
9889                 set_checksum_type $algo || error "fail to set checksum type $algo"
9890                 osc_algo=$(get_osc_checksum_type OST0000)
9891                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9892
9893                 # no locks, no reqs to let the connection idle
9894                 cancel_lru_locks osc
9895                 lru_resize_disable osc
9896                 wait_osc_import_state client ost1 IDLE
9897
9898                 # ensure ost1 is connected
9899                 stat $DIR/$tfile >/dev/null || error "can't stat"
9900                 wait_osc_import_state client ost1 FULL
9901
9902                 osc_algo=$(get_osc_checksum_type OST0000)
9903                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9904         done
9905         return 0
9906 }
9907 run_test 77l "preferred checksum type is remembered after reconnected"
9908
9909 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9910 rm -f $F77_TMP
9911 unset F77_TMP
9912
9913 test_77m() {
9914         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
9915                 skip "Need at least version 2.14.52"
9916         local param=checksum_speed
9917
9918         $LCTL get_param $param || error "reading $param failed"
9919
9920         csum_speeds=$($LCTL get_param -n $param)
9921
9922         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
9923                 error "known checksum types are missing"
9924 }
9925 run_test 77m "Verify checksum_speed is correctly read"
9926
9927 check_filefrag_77n() {
9928         local nr_ext=0
9929         local starts=()
9930         local ends=()
9931
9932         while read extidx a b start end rest; do
9933                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
9934                         nr_ext=$(( $nr_ext + 1 ))
9935                         starts+=( ${start%..} )
9936                         ends+=( ${end%:} )
9937                 fi
9938         done < <( filefrag -sv $1 )
9939
9940         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
9941         return 1
9942 }
9943
9944 test_77n() {
9945         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
9946
9947         touch $DIR/$tfile
9948         $TRUNCATE $DIR/$tfile 0
9949         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
9950         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
9951         check_filefrag_77n $DIR/$tfile ||
9952                 skip "$tfile blocks not contiguous around hole"
9953
9954         set_checksums 1
9955         stack_trap "set_checksums $ORIG_CSUM" EXIT
9956         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9957         stack_trap "rm -f $DIR/$tfile"
9958
9959         for algo in $CKSUM_TYPES; do
9960                 if [[ "$algo" =~ ^t10 ]]; then
9961                         set_checksum_type $algo ||
9962                                 error "fail to set checksum type $algo"
9963                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
9964                                 error "fail to read $tfile with $algo"
9965                 fi
9966         done
9967         rm -f $DIR/$tfile
9968         return 0
9969 }
9970 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
9971
9972 test_77o() {
9973         (( $CLIENT_VERSION >= $(version_code 2.14.54) )) ||
9974                 skip "Need at least version 2.14.54"
9975         local ofd=obdfilter
9976         local mdt=mdt
9977
9978         # print OST checksum_type
9979         echo "$ofd.$FSNAME-*.checksum_type:"
9980         do_nodes $(comma_list $(osts_nodes)) \
9981                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
9982
9983         # print MDT checksum_type
9984         echo "$mdt.$FSNAME-*.checksum_type:"
9985         do_nodes $(comma_list $(mdts_nodes)) \
9986                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
9987
9988         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
9989                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
9990
9991         (( $o_count == $OSTCOUNT )) ||
9992                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
9993
9994         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
9995                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
9996
9997         (( $m_count == $MDSCOUNT )) ||
9998                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
9999 }
10000 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10001
10002 cleanup_test_78() {
10003         trap 0
10004         rm -f $DIR/$tfile
10005 }
10006
10007 test_78() { # bug 10901
10008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10009         remote_ost || skip_env "local OST"
10010
10011         NSEQ=5
10012         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10013         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10014         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10015         echo "MemTotal: $MEMTOTAL"
10016
10017         # reserve 256MB of memory for the kernel and other running processes,
10018         # and then take 1/2 of the remaining memory for the read/write buffers.
10019         if [ $MEMTOTAL -gt 512 ] ;then
10020                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10021         else
10022                 # for those poor memory-starved high-end clusters...
10023                 MEMTOTAL=$((MEMTOTAL / 2))
10024         fi
10025         echo "Mem to use for directio: $MEMTOTAL"
10026
10027         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10028         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10029         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10030         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10031                 head -n1)
10032         echo "Smallest OST: $SMALLESTOST"
10033         [[ $SMALLESTOST -lt 10240 ]] &&
10034                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10035
10036         trap cleanup_test_78 EXIT
10037
10038         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10039                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10040
10041         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10042         echo "File size: $F78SIZE"
10043         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10044         for i in $(seq 1 $NSEQ); do
10045                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10046                 echo directIO rdwr round $i of $NSEQ
10047                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10048         done
10049
10050         cleanup_test_78
10051 }
10052 run_test 78 "handle large O_DIRECT writes correctly ============"
10053
10054 test_79() { # bug 12743
10055         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10056
10057         wait_delete_completed
10058
10059         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10060         BKFREE=$(calc_osc_kbytes kbytesfree)
10061         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10062
10063         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10064         DFTOTAL=`echo $STRING | cut -d, -f1`
10065         DFUSED=`echo $STRING  | cut -d, -f2`
10066         DFAVAIL=`echo $STRING | cut -d, -f3`
10067         DFFREE=$(($DFTOTAL - $DFUSED))
10068
10069         ALLOWANCE=$((64 * $OSTCOUNT))
10070
10071         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10072            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10073                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10074         fi
10075         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10076            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10077                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10078         fi
10079         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10080            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10081                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10082         fi
10083 }
10084 run_test 79 "df report consistency check ======================="
10085
10086 test_80() { # bug 10718
10087         remote_ost_nodsh && skip "remote OST with nodsh"
10088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10089
10090         # relax strong synchronous semantics for slow backends like ZFS
10091         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10092                 local soc="obdfilter.*.sync_lock_cancel"
10093                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10094
10095                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10096                 if [ -z "$save" ]; then
10097                         soc="obdfilter.*.sync_on_lock_cancel"
10098                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10099                 fi
10100
10101                 if [ "$save" != "never" ]; then
10102                         local hosts=$(comma_list $(osts_nodes))
10103
10104                         do_nodes $hosts $LCTL set_param $soc=never
10105                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10106                 fi
10107         fi
10108
10109         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10110         sync; sleep 1; sync
10111         local before=$(date +%s)
10112         cancel_lru_locks osc
10113         local after=$(date +%s)
10114         local diff=$((after - before))
10115         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10116
10117         rm -f $DIR/$tfile
10118 }
10119 run_test 80 "Page eviction is equally fast at high offsets too"
10120
10121 test_81a() { # LU-456
10122         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10123         remote_ost_nodsh && skip "remote OST with nodsh"
10124
10125         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10126         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10127         do_facet ost1 lctl set_param fail_loc=0x80000228
10128
10129         # write should trigger a retry and success
10130         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10131         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10132         RC=$?
10133         if [ $RC -ne 0 ] ; then
10134                 error "write should success, but failed for $RC"
10135         fi
10136 }
10137 run_test 81a "OST should retry write when get -ENOSPC ==============="
10138
10139 test_81b() { # LU-456
10140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10141         remote_ost_nodsh && skip "remote OST with nodsh"
10142
10143         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10144         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10145         do_facet ost1 lctl set_param fail_loc=0x228
10146
10147         # write should retry several times and return -ENOSPC finally
10148         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10149         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10150         RC=$?
10151         ENOSPC=28
10152         if [ $RC -ne $ENOSPC ] ; then
10153                 error "dd should fail for -ENOSPC, but succeed."
10154         fi
10155 }
10156 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10157
10158 test_99() {
10159         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10160
10161         test_mkdir $DIR/$tdir.cvsroot
10162         chown $RUNAS_ID $DIR/$tdir.cvsroot
10163
10164         cd $TMP
10165         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10166
10167         cd /etc/init.d
10168         # some versions of cvs import exit(1) when asked to import links or
10169         # files they can't read.  ignore those files.
10170         local toignore=$(find . -type l -printf '-I %f\n' -o \
10171                          ! -perm /4 -printf '-I %f\n')
10172         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10173                 $tdir.reposname vtag rtag
10174
10175         cd $DIR
10176         test_mkdir $DIR/$tdir.reposname
10177         chown $RUNAS_ID $DIR/$tdir.reposname
10178         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10179
10180         cd $DIR/$tdir.reposname
10181         $RUNAS touch foo99
10182         $RUNAS cvs add -m 'addmsg' foo99
10183         $RUNAS cvs update
10184         $RUNAS cvs commit -m 'nomsg' foo99
10185         rm -fr $DIR/$tdir.cvsroot
10186 }
10187 run_test 99 "cvs strange file/directory operations"
10188
10189 test_100() {
10190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10191         [[ "$NETTYPE" =~ tcp ]] ||
10192                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10193         remote_ost_nodsh && skip "remote OST with nodsh"
10194         remote_mds_nodsh && skip "remote MDS with nodsh"
10195         remote_servers ||
10196                 skip "useless for local single node setup"
10197
10198         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10199                 [ "$PROT" != "tcp" ] && continue
10200                 RPORT=$(echo $REMOTE | cut -d: -f2)
10201                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10202
10203                 rc=0
10204                 LPORT=`echo $LOCAL | cut -d: -f2`
10205                 if [ $LPORT -ge 1024 ]; then
10206                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10207                         netstat -tna
10208                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10209                 fi
10210         done
10211         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10212 }
10213 run_test 100 "check local port using privileged port ==========="
10214
10215 function get_named_value()
10216 {
10217     local tag=$1
10218
10219     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10220 }
10221
10222 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10223                    awk '/^max_cached_mb/ { print $2 }')
10224
10225 cleanup_101a() {
10226         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10227         trap 0
10228 }
10229
10230 test_101a() {
10231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10232
10233         local s
10234         local discard
10235         local nreads=10000
10236         local cache_limit=32
10237
10238         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10239         trap cleanup_101a EXIT
10240         $LCTL set_param -n llite.*.read_ahead_stats=0
10241         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10242
10243         #
10244         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10245         #
10246         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10247         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10248
10249         discard=0
10250         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10251                    get_named_value 'read.but.discarded'); do
10252                         discard=$(($discard + $s))
10253         done
10254         cleanup_101a
10255
10256         $LCTL get_param osc.*-osc*.rpc_stats
10257         $LCTL get_param llite.*.read_ahead_stats
10258
10259         # Discard is generally zero, but sometimes a few random reads line up
10260         # and trigger larger readahead, which is wasted & leads to discards.
10261         if [[ $(($discard)) -gt $nreads ]]; then
10262                 error "too many ($discard) discarded pages"
10263         fi
10264         rm -f $DIR/$tfile || true
10265 }
10266 run_test 101a "check read-ahead for random reads"
10267
10268 setup_test101bc() {
10269         test_mkdir $DIR/$tdir
10270         local ssize=$1
10271         local FILE_LENGTH=$2
10272         STRIPE_OFFSET=0
10273
10274         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10275
10276         local list=$(comma_list $(osts_nodes))
10277         set_osd_param $list '' read_cache_enable 0
10278         set_osd_param $list '' writethrough_cache_enable 0
10279
10280         trap cleanup_test101bc EXIT
10281         # prepare the read-ahead file
10282         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10283
10284         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10285                                 count=$FILE_SIZE_MB 2> /dev/null
10286
10287 }
10288
10289 cleanup_test101bc() {
10290         trap 0
10291         rm -rf $DIR/$tdir
10292         rm -f $DIR/$tfile
10293
10294         local list=$(comma_list $(osts_nodes))
10295         set_osd_param $list '' read_cache_enable 1
10296         set_osd_param $list '' writethrough_cache_enable 1
10297 }
10298
10299 calc_total() {
10300         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10301 }
10302
10303 ra_check_101() {
10304         local READ_SIZE=$1
10305         local STRIPE_SIZE=$2
10306         local FILE_LENGTH=$3
10307         local RA_INC=1048576
10308         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
10309         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
10310                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
10311         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
10312                   get_named_value 'read.but.discarded' | calc_total)
10313         if [[ $DISCARD -gt $discard_limit ]]; then
10314                 $LCTL get_param llite.*.read_ahead_stats
10315                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
10316         else
10317                 echo "Read-ahead success for size ${READ_SIZE}"
10318         fi
10319 }
10320
10321 test_101b() {
10322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10323         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10324
10325         local STRIPE_SIZE=1048576
10326         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10327
10328         if [ $SLOW == "yes" ]; then
10329                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10330         else
10331                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10332         fi
10333
10334         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10335
10336         # prepare the read-ahead file
10337         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10338         cancel_lru_locks osc
10339         for BIDX in 2 4 8 16 32 64 128 256
10340         do
10341                 local BSIZE=$((BIDX*4096))
10342                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10343                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10344                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10345                 $LCTL set_param -n llite.*.read_ahead_stats=0
10346                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10347                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10348                 cancel_lru_locks osc
10349                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10350         done
10351         cleanup_test101bc
10352         true
10353 }
10354 run_test 101b "check stride-io mode read-ahead ================="
10355
10356 test_101c() {
10357         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10358
10359         local STRIPE_SIZE=1048576
10360         local FILE_LENGTH=$((STRIPE_SIZE*100))
10361         local nreads=10000
10362         local rsize=65536
10363         local osc_rpc_stats
10364
10365         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10366
10367         cancel_lru_locks osc
10368         $LCTL set_param osc.*.rpc_stats=0
10369         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10370         $LCTL get_param osc.*.rpc_stats
10371         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10372                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10373                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10374                 local size
10375
10376                 if [ $lines -le 20 ]; then
10377                         echo "continue debug"
10378                         continue
10379                 fi
10380                 for size in 1 2 4 8; do
10381                         local rpc=$(echo "$stats" |
10382                                     awk '($1 == "'$size':") {print $2; exit; }')
10383                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10384                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10385                 done
10386                 echo "$osc_rpc_stats check passed!"
10387         done
10388         cleanup_test101bc
10389         true
10390 }
10391 run_test 101c "check stripe_size aligned read-ahead"
10392
10393 test_101d() {
10394         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10395
10396         local file=$DIR/$tfile
10397         local sz_MB=${FILESIZE_101d:-80}
10398         local ra_MB=${READAHEAD_MB:-40}
10399
10400         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10401         [ $free_MB -lt $sz_MB ] &&
10402                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10403
10404         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10405         $LFS setstripe -c -1 $file || error "setstripe failed"
10406
10407         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10408         echo Cancel LRU locks on lustre client to flush the client cache
10409         cancel_lru_locks osc
10410
10411         echo Disable read-ahead
10412         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10413         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10414         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10415         $LCTL get_param -n llite.*.max_read_ahead_mb
10416
10417         echo "Reading the test file $file with read-ahead disabled"
10418         local sz_KB=$((sz_MB * 1024 / 4))
10419         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10420         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10421         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10422                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10423
10424         echo "Cancel LRU locks on lustre client to flush the client cache"
10425         cancel_lru_locks osc
10426         echo Enable read-ahead with ${ra_MB}MB
10427         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10428
10429         echo "Reading the test file $file with read-ahead enabled"
10430         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10431                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10432
10433         echo "read-ahead disabled time read $raOFF"
10434         echo "read-ahead enabled time read $raON"
10435
10436         rm -f $file
10437         wait_delete_completed
10438
10439         # use awk for this check instead of bash because it handles decimals
10440         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10441                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10442 }
10443 run_test 101d "file read with and without read-ahead enabled"
10444
10445 test_101e() {
10446         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10447
10448         local file=$DIR/$tfile
10449         local size_KB=500  #KB
10450         local count=100
10451         local bsize=1024
10452
10453         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10454         local need_KB=$((count * size_KB))
10455         [[ $free_KB -le $need_KB ]] &&
10456                 skip_env "Need free space $need_KB, have $free_KB"
10457
10458         echo "Creating $count ${size_KB}K test files"
10459         for ((i = 0; i < $count; i++)); do
10460                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10461         done
10462
10463         echo "Cancel LRU locks on lustre client to flush the client cache"
10464         cancel_lru_locks $OSC
10465
10466         echo "Reset readahead stats"
10467         $LCTL set_param -n llite.*.read_ahead_stats=0
10468
10469         for ((i = 0; i < $count; i++)); do
10470                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10471         done
10472
10473         $LCTL get_param llite.*.max_cached_mb
10474         $LCTL get_param llite.*.read_ahead_stats
10475         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10476                      get_named_value 'misses' | calc_total)
10477
10478         for ((i = 0; i < $count; i++)); do
10479                 rm -rf $file.$i 2>/dev/null
10480         done
10481
10482         #10000 means 20% reads are missing in readahead
10483         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10484 }
10485 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10486
10487 test_101f() {
10488         which iozone || skip_env "no iozone installed"
10489
10490         local old_debug=$($LCTL get_param debug)
10491         old_debug=${old_debug#*=}
10492         $LCTL set_param debug="reada mmap"
10493
10494         # create a test file
10495         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10496
10497         echo Cancel LRU locks on lustre client to flush the client cache
10498         cancel_lru_locks osc
10499
10500         echo Reset readahead stats
10501         $LCTL set_param -n llite.*.read_ahead_stats=0
10502
10503         echo mmap read the file with small block size
10504         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10505                 > /dev/null 2>&1
10506
10507         echo checking missing pages
10508         $LCTL get_param llite.*.read_ahead_stats
10509         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10510                         get_named_value 'misses' | calc_total)
10511
10512         $LCTL set_param debug="$old_debug"
10513         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10514         rm -f $DIR/$tfile
10515 }
10516 run_test 101f "check mmap read performance"
10517
10518 test_101g_brw_size_test() {
10519         local mb=$1
10520         local pages=$((mb * 1048576 / PAGE_SIZE))
10521         local file=$DIR/$tfile
10522
10523         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10524                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10525         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10526                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10527                         return 2
10528         done
10529
10530         stack_trap "rm -f $file" EXIT
10531         $LCTL set_param -n osc.*.rpc_stats=0
10532
10533         # 10 RPCs should be enough for the test
10534         local count=10
10535         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10536                 { error "dd write ${mb} MB blocks failed"; return 3; }
10537         cancel_lru_locks osc
10538         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10539                 { error "dd write ${mb} MB blocks failed"; return 4; }
10540
10541         # calculate number of full-sized read and write RPCs
10542         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10543                 sed -n '/pages per rpc/,/^$/p' |
10544                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10545                 END { print reads,writes }'))
10546         # allow one extra full-sized read RPC for async readahead
10547         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10548                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10549         [[ ${rpcs[1]} == $count ]] ||
10550                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10551 }
10552
10553 test_101g() {
10554         remote_ost_nodsh && skip "remote OST with nodsh"
10555
10556         local rpcs
10557         local osts=$(get_facets OST)
10558         local list=$(comma_list $(osts_nodes))
10559         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10560         local brw_size="obdfilter.*.brw_size"
10561
10562         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10563
10564         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10565
10566         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10567                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10568                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10569            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10570                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10571                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10572
10573                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10574                         suffix="M"
10575
10576                 if [[ $orig_mb -lt 16 ]]; then
10577                         save_lustre_params $osts "$brw_size" > $p
10578                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10579                                 error "set 16MB RPC size failed"
10580
10581                         echo "remount client to enable new RPC size"
10582                         remount_client $MOUNT || error "remount_client failed"
10583                 fi
10584
10585                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10586                 # should be able to set brw_size=12, but no rpc_stats for that
10587                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10588         fi
10589
10590         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10591
10592         if [[ $orig_mb -lt 16 ]]; then
10593                 restore_lustre_params < $p
10594                 remount_client $MOUNT || error "remount_client restore failed"
10595         fi
10596
10597         rm -f $p $DIR/$tfile
10598 }
10599 run_test 101g "Big bulk(4/16 MiB) readahead"
10600
10601 test_101h() {
10602         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10603
10604         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10605                 error "dd 70M file failed"
10606         echo Cancel LRU locks on lustre client to flush the client cache
10607         cancel_lru_locks osc
10608
10609         echo "Reset readahead stats"
10610         $LCTL set_param -n llite.*.read_ahead_stats 0
10611
10612         echo "Read 10M of data but cross 64M bundary"
10613         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10614         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10615                      get_named_value 'misses' | calc_total)
10616         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10617         rm -f $p $DIR/$tfile
10618 }
10619 run_test 101h "Readahead should cover current read window"
10620
10621 test_101i() {
10622         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10623                 error "dd 10M file failed"
10624
10625         local max_per_file_mb=$($LCTL get_param -n \
10626                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10627         cancel_lru_locks osc
10628         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10629         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10630                 error "set max_read_ahead_per_file_mb to 1 failed"
10631
10632         echo "Reset readahead stats"
10633         $LCTL set_param llite.*.read_ahead_stats=0
10634
10635         dd if=$DIR/$tfile of=/dev/null bs=2M
10636
10637         $LCTL get_param llite.*.read_ahead_stats
10638         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10639                      awk '/misses/ { print $2 }')
10640         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10641         rm -f $DIR/$tfile
10642 }
10643 run_test 101i "allow current readahead to exceed reservation"
10644
10645 test_101j() {
10646         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10647                 error "setstripe $DIR/$tfile failed"
10648         local file_size=$((1048576 * 16))
10649         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10650         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10651
10652         echo Disable read-ahead
10653         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10654
10655         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10656         for blk in $PAGE_SIZE 1048576 $file_size; do
10657                 cancel_lru_locks osc
10658                 echo "Reset readahead stats"
10659                 $LCTL set_param -n llite.*.read_ahead_stats=0
10660                 local count=$(($file_size / $blk))
10661                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10662                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10663                              get_named_value 'failed.to.fast.read' | calc_total)
10664                 $LCTL get_param -n llite.*.read_ahead_stats
10665                 [ $miss -eq $count ] || error "expected $count got $miss"
10666         done
10667
10668         rm -f $p $DIR/$tfile
10669 }
10670 run_test 101j "A complete read block should be submitted when no RA"
10671
10672 setup_test102() {
10673         test_mkdir $DIR/$tdir
10674         chown $RUNAS_ID $DIR/$tdir
10675         STRIPE_SIZE=65536
10676         STRIPE_OFFSET=1
10677         STRIPE_COUNT=$OSTCOUNT
10678         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10679
10680         trap cleanup_test102 EXIT
10681         cd $DIR
10682         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10683         cd $DIR/$tdir
10684         for num in 1 2 3 4; do
10685                 for count in $(seq 1 $STRIPE_COUNT); do
10686                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10687                                 local size=`expr $STRIPE_SIZE \* $num`
10688                                 local file=file"$num-$idx-$count"
10689                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10690                         done
10691                 done
10692         done
10693
10694         cd $DIR
10695         $1 tar cf $TMP/f102.tar $tdir --xattrs
10696 }
10697
10698 cleanup_test102() {
10699         trap 0
10700         rm -f $TMP/f102.tar
10701         rm -rf $DIR/d0.sanity/d102
10702 }
10703
10704 test_102a() {
10705         [ "$UID" != 0 ] && skip "must run as root"
10706         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10707                 skip_env "must have user_xattr"
10708
10709         [ -z "$(which setfattr 2>/dev/null)" ] &&
10710                 skip_env "could not find setfattr"
10711
10712         local testfile=$DIR/$tfile
10713
10714         touch $testfile
10715         echo "set/get xattr..."
10716         setfattr -n trusted.name1 -v value1 $testfile ||
10717                 error "setfattr -n trusted.name1=value1 $testfile failed"
10718         getfattr -n trusted.name1 $testfile 2> /dev/null |
10719           grep "trusted.name1=.value1" ||
10720                 error "$testfile missing trusted.name1=value1"
10721
10722         setfattr -n user.author1 -v author1 $testfile ||
10723                 error "setfattr -n user.author1=author1 $testfile failed"
10724         getfattr -n user.author1 $testfile 2> /dev/null |
10725           grep "user.author1=.author1" ||
10726                 error "$testfile missing trusted.author1=author1"
10727
10728         echo "listxattr..."
10729         setfattr -n trusted.name2 -v value2 $testfile ||
10730                 error "$testfile unable to set trusted.name2"
10731         setfattr -n trusted.name3 -v value3 $testfile ||
10732                 error "$testfile unable to set trusted.name3"
10733         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10734             grep "trusted.name" | wc -l) -eq 3 ] ||
10735                 error "$testfile missing 3 trusted.name xattrs"
10736
10737         setfattr -n user.author2 -v author2 $testfile ||
10738                 error "$testfile unable to set user.author2"
10739         setfattr -n user.author3 -v author3 $testfile ||
10740                 error "$testfile unable to set user.author3"
10741         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10742             grep "user.author" | wc -l) -eq 3 ] ||
10743                 error "$testfile missing 3 user.author xattrs"
10744
10745         echo "remove xattr..."
10746         setfattr -x trusted.name1 $testfile ||
10747                 error "$testfile error deleting trusted.name1"
10748         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10749                 error "$testfile did not delete trusted.name1 xattr"
10750
10751         setfattr -x user.author1 $testfile ||
10752                 error "$testfile error deleting user.author1"
10753         echo "set lustre special xattr ..."
10754         $LFS setstripe -c1 $testfile
10755         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10756                 awk -F "=" '/trusted.lov/ { print $2 }' )
10757         setfattr -n "trusted.lov" -v $lovea $testfile ||
10758                 error "$testfile doesn't ignore setting trusted.lov again"
10759         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10760                 error "$testfile allow setting invalid trusted.lov"
10761         rm -f $testfile
10762 }
10763 run_test 102a "user xattr test =================================="
10764
10765 check_102b_layout() {
10766         local layout="$*"
10767         local testfile=$DIR/$tfile
10768
10769         echo "test layout '$layout'"
10770         $LFS setstripe $layout $testfile || error "setstripe failed"
10771         $LFS getstripe -y $testfile
10772
10773         echo "get/set/list trusted.lov xattr ..." # b=10930
10774         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10775         [[ "$value" =~ "trusted.lov" ]] ||
10776                 error "can't get trusted.lov from $testfile"
10777         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10778                 error "getstripe failed"
10779
10780         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10781
10782         value=$(cut -d= -f2 <<<$value)
10783         # LU-13168: truncated xattr should fail if short lov_user_md header
10784         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10785                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10786         for len in $lens; do
10787                 echo "setfattr $len $testfile.2"
10788                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10789                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10790         done
10791         local stripe_size=$($LFS getstripe -S $testfile.2)
10792         local stripe_count=$($LFS getstripe -c $testfile.2)
10793         [[ $stripe_size -eq 65536 ]] ||
10794                 error "stripe size $stripe_size != 65536"
10795         [[ $stripe_count -eq $stripe_count_orig ]] ||
10796                 error "stripe count $stripe_count != $stripe_count_orig"
10797         rm $testfile $testfile.2
10798 }
10799
10800 test_102b() {
10801         [ -z "$(which setfattr 2>/dev/null)" ] &&
10802                 skip_env "could not find setfattr"
10803         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10804
10805         # check plain layout
10806         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10807
10808         # and also check composite layout
10809         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10810
10811 }
10812 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10813
10814 test_102c() {
10815         [ -z "$(which setfattr 2>/dev/null)" ] &&
10816                 skip_env "could not find setfattr"
10817         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10818
10819         # b10930: get/set/list lustre.lov xattr
10820         echo "get/set/list lustre.lov xattr ..."
10821         test_mkdir $DIR/$tdir
10822         chown $RUNAS_ID $DIR/$tdir
10823         local testfile=$DIR/$tdir/$tfile
10824         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10825                 error "setstripe failed"
10826         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10827                 error "getstripe failed"
10828         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10829         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10830
10831         local testfile2=${testfile}2
10832         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10833                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10834
10835         $RUNAS $MCREATE $testfile2
10836         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10837         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10838         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10839         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10840         [ $stripe_count -eq $STRIPECOUNT ] ||
10841                 error "stripe count $stripe_count != $STRIPECOUNT"
10842 }
10843 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10844
10845 compare_stripe_info1() {
10846         local stripe_index_all_zero=true
10847
10848         for num in 1 2 3 4; do
10849                 for count in $(seq 1 $STRIPE_COUNT); do
10850                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10851                                 local size=$((STRIPE_SIZE * num))
10852                                 local file=file"$num-$offset-$count"
10853                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10854                                 [[ $stripe_size -ne $size ]] &&
10855                                     error "$file: size $stripe_size != $size"
10856                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10857                                 # allow fewer stripes to be created, ORI-601
10858                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10859                                     error "$file: count $stripe_count != $count"
10860                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10861                                 [[ $stripe_index -ne 0 ]] &&
10862                                         stripe_index_all_zero=false
10863                         done
10864                 done
10865         done
10866         $stripe_index_all_zero &&
10867                 error "all files are being extracted starting from OST index 0"
10868         return 0
10869 }
10870
10871 have_xattrs_include() {
10872         tar --help | grep -q xattrs-include &&
10873                 echo --xattrs-include="lustre.*"
10874 }
10875
10876 test_102d() {
10877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10878         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10879
10880         XINC=$(have_xattrs_include)
10881         setup_test102
10882         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10883         cd $DIR/$tdir/$tdir
10884         compare_stripe_info1
10885 }
10886 run_test 102d "tar restore stripe info from tarfile,not keep osts"
10887
10888 test_102f() {
10889         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10890         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10891
10892         XINC=$(have_xattrs_include)
10893         setup_test102
10894         test_mkdir $DIR/$tdir.restore
10895         cd $DIR
10896         tar cf - --xattrs $tdir | tar xf - \
10897                 -C $DIR/$tdir.restore --xattrs $XINC
10898         cd $DIR/$tdir.restore/$tdir
10899         compare_stripe_info1
10900 }
10901 run_test 102f "tar copy files, not keep osts"
10902
10903 grow_xattr() {
10904         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
10905                 skip "must have user_xattr"
10906         [ -z "$(which setfattr 2>/dev/null)" ] &&
10907                 skip_env "could not find setfattr"
10908         [ -z "$(which getfattr 2>/dev/null)" ] &&
10909                 skip_env "could not find getfattr"
10910
10911         local xsize=${1:-1024}  # in bytes
10912         local file=$DIR/$tfile
10913         local value="$(generate_string $xsize)"
10914         local xbig=trusted.big
10915         local toobig=$2
10916
10917         touch $file
10918         log "save $xbig on $file"
10919         if [ -z "$toobig" ]
10920         then
10921                 setfattr -n $xbig -v $value $file ||
10922                         error "saving $xbig on $file failed"
10923         else
10924                 setfattr -n $xbig -v $value $file &&
10925                         error "saving $xbig on $file succeeded"
10926                 return 0
10927         fi
10928
10929         local orig=$(get_xattr_value $xbig $file)
10930         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
10931
10932         local xsml=trusted.sml
10933         log "save $xsml on $file"
10934         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
10935
10936         local new=$(get_xattr_value $xbig $file)
10937         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
10938
10939         log "grow $xsml on $file"
10940         setfattr -n $xsml -v "$value" $file ||
10941                 error "growing $xsml on $file failed"
10942
10943         new=$(get_xattr_value $xbig $file)
10944         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
10945         log "$xbig still valid after growing $xsml"
10946
10947         rm -f $file
10948 }
10949
10950 test_102h() { # bug 15777
10951         grow_xattr 1024
10952 }
10953 run_test 102h "grow xattr from inside inode to external block"
10954
10955 test_102ha() {
10956         large_xattr_enabled || skip_env "ea_inode feature disabled"
10957
10958         echo "setting xattr of max xattr size: $(max_xattr_size)"
10959         grow_xattr $(max_xattr_size)
10960
10961         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10962         echo "This should fail:"
10963         grow_xattr $(($(max_xattr_size) + 10)) 1
10964 }
10965 run_test 102ha "grow xattr from inside inode to external inode"
10966
10967 test_102i() { # bug 17038
10968         [ -z "$(which getfattr 2>/dev/null)" ] &&
10969                 skip "could not find getfattr"
10970
10971         touch $DIR/$tfile
10972         ln -s $DIR/$tfile $DIR/${tfile}link
10973         getfattr -n trusted.lov $DIR/$tfile ||
10974                 error "lgetxattr on $DIR/$tfile failed"
10975         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10976                 grep -i "no such attr" ||
10977                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10978         rm -f $DIR/$tfile $DIR/${tfile}link
10979 }
10980 run_test 102i "lgetxattr test on symbolic link ============"
10981
10982 test_102j() {
10983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10984         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10985
10986         XINC=$(have_xattrs_include)
10987         setup_test102 "$RUNAS"
10988         chown $RUNAS_ID $DIR/$tdir
10989         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10990         cd $DIR/$tdir/$tdir
10991         compare_stripe_info1 "$RUNAS"
10992 }
10993 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10994
10995 test_102k() {
10996         [ -z "$(which setfattr 2>/dev/null)" ] &&
10997                 skip "could not find setfattr"
10998
10999         touch $DIR/$tfile
11000         # b22187 just check that does not crash for regular file.
11001         setfattr -n trusted.lov $DIR/$tfile
11002         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11003         local test_kdir=$DIR/$tdir
11004         test_mkdir $test_kdir
11005         local default_size=$($LFS getstripe -S $test_kdir)
11006         local default_count=$($LFS getstripe -c $test_kdir)
11007         local default_offset=$($LFS getstripe -i $test_kdir)
11008         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11009                 error 'dir setstripe failed'
11010         setfattr -n trusted.lov $test_kdir
11011         local stripe_size=$($LFS getstripe -S $test_kdir)
11012         local stripe_count=$($LFS getstripe -c $test_kdir)
11013         local stripe_offset=$($LFS getstripe -i $test_kdir)
11014         [ $stripe_size -eq $default_size ] ||
11015                 error "stripe size $stripe_size != $default_size"
11016         [ $stripe_count -eq $default_count ] ||
11017                 error "stripe count $stripe_count != $default_count"
11018         [ $stripe_offset -eq $default_offset ] ||
11019                 error "stripe offset $stripe_offset != $default_offset"
11020         rm -rf $DIR/$tfile $test_kdir
11021 }
11022 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11023
11024 test_102l() {
11025         [ -z "$(which getfattr 2>/dev/null)" ] &&
11026                 skip "could not find getfattr"
11027
11028         # LU-532 trusted. xattr is invisible to non-root
11029         local testfile=$DIR/$tfile
11030
11031         touch $testfile
11032
11033         echo "listxattr as user..."
11034         chown $RUNAS_ID $testfile
11035         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11036             grep -q "trusted" &&
11037                 error "$testfile trusted xattrs are user visible"
11038
11039         return 0;
11040 }
11041 run_test 102l "listxattr size test =================================="
11042
11043 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11044         local path=$DIR/$tfile
11045         touch $path
11046
11047         listxattr_size_check $path || error "listattr_size_check $path failed"
11048 }
11049 run_test 102m "Ensure listxattr fails on small bufffer ========"
11050
11051 cleanup_test102
11052
11053 getxattr() { # getxattr path name
11054         # Return the base64 encoding of the value of xattr name on path.
11055         local path=$1
11056         local name=$2
11057
11058         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11059         # file: $path
11060         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11061         #
11062         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11063
11064         getfattr --absolute-names --encoding=base64 --name=$name $path |
11065                 awk -F= -v name=$name '$1 == name {
11066                         print substr($0, index($0, "=") + 1);
11067         }'
11068 }
11069
11070 test_102n() { # LU-4101 mdt: protect internal xattrs
11071         [ -z "$(which setfattr 2>/dev/null)" ] &&
11072                 skip "could not find setfattr"
11073         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11074         then
11075                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11076         fi
11077
11078         local file0=$DIR/$tfile.0
11079         local file1=$DIR/$tfile.1
11080         local xattr0=$TMP/$tfile.0
11081         local xattr1=$TMP/$tfile.1
11082         local namelist="lov lma lmv link fid version som hsm"
11083         local name
11084         local value
11085
11086         rm -rf $file0 $file1 $xattr0 $xattr1
11087         touch $file0 $file1
11088
11089         # Get 'before' xattrs of $file1.
11090         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11091
11092         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11093                 namelist+=" lfsck_namespace"
11094         for name in $namelist; do
11095                 # Try to copy xattr from $file0 to $file1.
11096                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11097
11098                 setfattr --name=trusted.$name --value="$value" $file1 ||
11099                         error "setxattr 'trusted.$name' failed"
11100
11101                 # Try to set a garbage xattr.
11102                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11103
11104                 if [[ x$name == "xlov" ]]; then
11105                         setfattr --name=trusted.lov --value="$value" $file1 &&
11106                         error "setxattr invalid 'trusted.lov' success"
11107                 else
11108                         setfattr --name=trusted.$name --value="$value" $file1 ||
11109                                 error "setxattr invalid 'trusted.$name' failed"
11110                 fi
11111
11112                 # Try to remove the xattr from $file1. We don't care if this
11113                 # appears to succeed or fail, we just don't want there to be
11114                 # any changes or crashes.
11115                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11116         done
11117
11118         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11119         then
11120                 name="lfsck_ns"
11121                 # Try to copy xattr from $file0 to $file1.
11122                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11123
11124                 setfattr --name=trusted.$name --value="$value" $file1 ||
11125                         error "setxattr 'trusted.$name' failed"
11126
11127                 # Try to set a garbage xattr.
11128                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11129
11130                 setfattr --name=trusted.$name --value="$value" $file1 ||
11131                         error "setxattr 'trusted.$name' failed"
11132
11133                 # Try to remove the xattr from $file1. We don't care if this
11134                 # appears to succeed or fail, we just don't want there to be
11135                 # any changes or crashes.
11136                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11137         fi
11138
11139         # Get 'after' xattrs of file1.
11140         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11141
11142         if ! diff $xattr0 $xattr1; then
11143                 error "before and after xattrs of '$file1' differ"
11144         fi
11145
11146         rm -rf $file0 $file1 $xattr0 $xattr1
11147
11148         return 0
11149 }
11150 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11151
11152 test_102p() { # LU-4703 setxattr did not check ownership
11153         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11154                 skip "MDS needs to be at least 2.5.56"
11155
11156         local testfile=$DIR/$tfile
11157
11158         touch $testfile
11159
11160         echo "setfacl as user..."
11161         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11162         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11163
11164         echo "setfattr as user..."
11165         setfacl -m "u:$RUNAS_ID:---" $testfile
11166         $RUNAS setfattr -x system.posix_acl_access $testfile
11167         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11168 }
11169 run_test 102p "check setxattr(2) correctly fails without permission"
11170
11171 test_102q() {
11172         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11173                 skip "MDS needs to be at least 2.6.92"
11174
11175         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11176 }
11177 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11178
11179 test_102r() {
11180         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11181                 skip "MDS needs to be at least 2.6.93"
11182
11183         touch $DIR/$tfile || error "touch"
11184         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11185         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11186         rm $DIR/$tfile || error "rm"
11187
11188         #normal directory
11189         mkdir -p $DIR/$tdir || error "mkdir"
11190         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11191         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11192         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11193                 error "$testfile error deleting user.author1"
11194         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11195                 grep "user.$(basename $tdir)" &&
11196                 error "$tdir did not delete user.$(basename $tdir)"
11197         rmdir $DIR/$tdir || error "rmdir"
11198
11199         #striped directory
11200         test_mkdir $DIR/$tdir
11201         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11202         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11203         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11204                 error "$testfile error deleting user.author1"
11205         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11206                 grep "user.$(basename $tdir)" &&
11207                 error "$tdir did not delete user.$(basename $tdir)"
11208         rmdir $DIR/$tdir || error "rm striped dir"
11209 }
11210 run_test 102r "set EAs with empty values"
11211
11212 test_102s() {
11213         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11214                 skip "MDS needs to be at least 2.11.52"
11215
11216         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11217
11218         save_lustre_params client "llite.*.xattr_cache" > $save
11219
11220         for cache in 0 1; do
11221                 lctl set_param llite.*.xattr_cache=$cache
11222
11223                 rm -f $DIR/$tfile
11224                 touch $DIR/$tfile || error "touch"
11225                 for prefix in lustre security system trusted user; do
11226                         # Note getxattr() may fail with 'Operation not
11227                         # supported' or 'No such attribute' depending
11228                         # on prefix and cache.
11229                         getfattr -n $prefix.n102s $DIR/$tfile &&
11230                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11231                 done
11232         done
11233
11234         restore_lustre_params < $save
11235 }
11236 run_test 102s "getting nonexistent xattrs should fail"
11237
11238 test_102t() {
11239         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11240                 skip "MDS needs to be at least 2.11.52"
11241
11242         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11243
11244         save_lustre_params client "llite.*.xattr_cache" > $save
11245
11246         for cache in 0 1; do
11247                 lctl set_param llite.*.xattr_cache=$cache
11248
11249                 for buf_size in 0 256; do
11250                         rm -f $DIR/$tfile
11251                         touch $DIR/$tfile || error "touch"
11252                         setfattr -n user.multiop $DIR/$tfile
11253                         $MULTIOP $DIR/$tfile oa$buf_size ||
11254                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11255                 done
11256         done
11257
11258         restore_lustre_params < $save
11259 }
11260 run_test 102t "zero length xattr values handled correctly"
11261
11262 run_acl_subtest()
11263 {
11264     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
11265     return $?
11266 }
11267
11268 test_103a() {
11269         [ "$UID" != 0 ] && skip "must run as root"
11270         $GSS && skip_env "could not run under gss"
11271         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
11272                 skip_env "must have acl enabled"
11273         [ -z "$(which setfacl 2>/dev/null)" ] &&
11274                 skip_env "could not find setfacl"
11275         remote_mds_nodsh && skip "remote MDS with nodsh"
11276
11277         gpasswd -a daemon bin                           # LU-5641
11278         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
11279
11280         declare -a identity_old
11281
11282         for num in $(seq $MDSCOUNT); do
11283                 switch_identity $num true || identity_old[$num]=$?
11284         done
11285
11286         SAVE_UMASK=$(umask)
11287         umask 0022
11288         mkdir -p $DIR/$tdir
11289         cd $DIR/$tdir
11290
11291         echo "performing cp ..."
11292         run_acl_subtest cp || error "run_acl_subtest cp failed"
11293         echo "performing getfacl-noacl..."
11294         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
11295         echo "performing misc..."
11296         run_acl_subtest misc || error  "misc test failed"
11297         echo "performing permissions..."
11298         run_acl_subtest permissions || error "permissions failed"
11299         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
11300         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
11301                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
11302                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
11303         then
11304                 echo "performing permissions xattr..."
11305                 run_acl_subtest permissions_xattr ||
11306                         error "permissions_xattr failed"
11307         fi
11308         echo "performing setfacl..."
11309         run_acl_subtest setfacl || error  "setfacl test failed"
11310
11311         # inheritance test got from HP
11312         echo "performing inheritance..."
11313         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11314         chmod +x make-tree || error "chmod +x failed"
11315         run_acl_subtest inheritance || error "inheritance test failed"
11316         rm -f make-tree
11317
11318         echo "LU-974 ignore umask when acl is enabled..."
11319         run_acl_subtest 974 || error "LU-974 umask test failed"
11320         if [ $MDSCOUNT -ge 2 ]; then
11321                 run_acl_subtest 974_remote ||
11322                         error "LU-974 umask test failed under remote dir"
11323         fi
11324
11325         echo "LU-2561 newly created file is same size as directory..."
11326         if [ "$mds1_FSTYPE" != "zfs" ]; then
11327                 run_acl_subtest 2561 || error "LU-2561 test failed"
11328         else
11329                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
11330         fi
11331
11332         run_acl_subtest 4924 || error "LU-4924 test failed"
11333
11334         cd $SAVE_PWD
11335         umask $SAVE_UMASK
11336
11337         for num in $(seq $MDSCOUNT); do
11338                 if [ "${identity_old[$num]}" = 1 ]; then
11339                         switch_identity $num false || identity_old[$num]=$?
11340                 fi
11341         done
11342 }
11343 run_test 103a "acl test"
11344
11345 test_103b() {
11346         declare -a pids
11347         local U
11348
11349         for U in {0..511}; do
11350                 {
11351                 local O=$(printf "%04o" $U)
11352
11353                 umask $(printf "%04o" $((511 ^ $O)))
11354                 $LFS setstripe -c 1 $DIR/$tfile.s$O
11355                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
11356
11357                 (( $S == ($O & 0666) )) ||
11358                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11359
11360                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11361                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11362                 (( $S == ($O & 0666) )) ||
11363                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11364
11365                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11366                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11367                 (( $S == ($O & 0666) )) ||
11368                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11369                 rm -f $DIR/$tfile.[smp]$0
11370                 } &
11371                 local pid=$!
11372
11373                 # limit the concurrently running threads to 64. LU-11878
11374                 local idx=$((U % 64))
11375                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11376                 pids[idx]=$pid
11377         done
11378         wait
11379 }
11380 run_test 103b "umask lfs setstripe"
11381
11382 test_103c() {
11383         mkdir -p $DIR/$tdir
11384         cp -rp $DIR/$tdir $DIR/$tdir.bak
11385
11386         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11387                 error "$DIR/$tdir shouldn't contain default ACL"
11388         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11389                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11390         true
11391 }
11392 run_test 103c "'cp -rp' won't set empty acl"
11393
11394 test_103e() {
11395         local numacl
11396         local fileacl
11397         local saved_debug=$($LCTL get_param -n debug)
11398
11399         (( $MDS1_VERSION >= $(version_code 2.14.0) )) ||
11400                 skip "MDS needs to be at least 2.14.0"
11401
11402         large_xattr_enabled || skip_env "ea_inode feature disabled"
11403
11404         mkdir -p $DIR/$tdir
11405         # add big LOV EA to cause reply buffer overflow earlier
11406         $LFS setstripe -C 1000 $DIR/$tdir
11407         lctl set_param mdc.*-mdc*.stats=clear
11408
11409         $LCTL set_param debug=0
11410         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11411         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11412
11413         # add a large number of default ACLs (expect 8000+ for 2.13+)
11414         for U in {2..7000}; do
11415                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11416                         error "Able to add just $U default ACLs"
11417         done
11418         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11419         echo "$numacl default ACLs created"
11420
11421         stat $DIR/$tdir || error "Cannot stat directory"
11422         # check file creation
11423         touch $DIR/$tdir/$tfile ||
11424                 error "failed to create $tfile with $numacl default ACLs"
11425         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11426         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11427         echo "$fileacl ACLs were inherited"
11428         (( $fileacl == $numacl )) ||
11429                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11430         # check that new ACLs creation adds new ACLs to inherited ACLs
11431         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11432                 error "Cannot set new ACL"
11433         numacl=$((numacl + 1))
11434         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11435         (( $fileacl == $numacl )) ||
11436                 error "failed to add new ACL: $fileacl != $numacl as expected"
11437         # adds more ACLs to a file to reach their maximum at 8000+
11438         numacl=0
11439         for U in {20000..25000}; do
11440                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11441                 numacl=$((numacl + 1))
11442         done
11443         echo "Added $numacl more ACLs to the file"
11444         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11445         echo "Total $fileacl ACLs in file"
11446         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11447         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11448         rmdir $DIR/$tdir || error "Cannot remove directory"
11449 }
11450 run_test 103e "inheritance of big amount of default ACLs"
11451
11452 test_103f() {
11453         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11454                 skip "MDS needs to be at least 2.14.51"
11455
11456         large_xattr_enabled || skip_env "ea_inode feature disabled"
11457
11458         # enable changelog to consume more internal MDD buffers
11459         changelog_register
11460
11461         mkdir -p $DIR/$tdir
11462         # add big LOV EA
11463         $LFS setstripe -C 1000 $DIR/$tdir
11464         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11465         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11466         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11467         rmdir $DIR/$tdir || error "Cannot remove directory"
11468 }
11469 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11470
11471 test_104a() {
11472         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11473
11474         touch $DIR/$tfile
11475         lfs df || error "lfs df failed"
11476         lfs df -ih || error "lfs df -ih failed"
11477         lfs df -h $DIR || error "lfs df -h $DIR failed"
11478         lfs df -i $DIR || error "lfs df -i $DIR failed"
11479         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11480         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11481
11482         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11483         lctl --device %$OSC deactivate
11484         lfs df || error "lfs df with deactivated OSC failed"
11485         lctl --device %$OSC activate
11486         # wait the osc back to normal
11487         wait_osc_import_ready client ost
11488
11489         lfs df || error "lfs df with reactivated OSC failed"
11490         rm -f $DIR/$tfile
11491 }
11492 run_test 104a "lfs df [-ih] [path] test ========================="
11493
11494 test_104b() {
11495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11496         [ $RUNAS_ID -eq $UID ] &&
11497                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11498
11499         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11500                         grep "Permission denied" | wc -l)))
11501         if [ $denied_cnt -ne 0 ]; then
11502                 error "lfs check servers test failed"
11503         fi
11504 }
11505 run_test 104b "$RUNAS lfs check servers test ===================="
11506
11507 #
11508 # Verify $1 is within range of $2.
11509 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11510 # $1 is <= 2% of $2. Else Fail.
11511 #
11512 value_in_range() {
11513         # Strip all units (M, G, T)
11514         actual=$(echo $1 | tr -d A-Z)
11515         expect=$(echo $2 | tr -d A-Z)
11516
11517         expect_lo=$(($expect * 98 / 100)) # 2% below
11518         expect_hi=$(($expect * 102 / 100)) # 2% above
11519
11520         # permit 2% drift above and below
11521         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11522 }
11523
11524 test_104c() {
11525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11526         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11527
11528         local ost_param="osd-zfs.$FSNAME-OST0000."
11529         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11530         local ofacets=$(get_facets OST)
11531         local mfacets=$(get_facets MDS)
11532         local saved_ost_blocks=
11533         local saved_mdt_blocks=
11534
11535         echo "Before recordsize change"
11536         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11537         df=($(df -h | grep "/mnt/lustre"$))
11538
11539         # For checking.
11540         echo "lfs output : ${lfs_df[*]}"
11541         echo "df  output : ${df[*]}"
11542
11543         for facet in ${ofacets//,/ }; do
11544                 if [ -z $saved_ost_blocks ]; then
11545                         saved_ost_blocks=$(do_facet $facet \
11546                                 lctl get_param -n $ost_param.blocksize)
11547                         echo "OST Blocksize: $saved_ost_blocks"
11548                 fi
11549                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11550                 do_facet $facet zfs set recordsize=32768 $ost
11551         done
11552
11553         # BS too small. Sufficient for functional testing.
11554         for facet in ${mfacets//,/ }; do
11555                 if [ -z $saved_mdt_blocks ]; then
11556                         saved_mdt_blocks=$(do_facet $facet \
11557                                 lctl get_param -n $mdt_param.blocksize)
11558                         echo "MDT Blocksize: $saved_mdt_blocks"
11559                 fi
11560                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11561                 do_facet $facet zfs set recordsize=32768 $mdt
11562         done
11563
11564         # Give new values chance to reflect change
11565         sleep 2
11566
11567         echo "After recordsize change"
11568         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11569         df_after=($(df -h | grep "/mnt/lustre"$))
11570
11571         # For checking.
11572         echo "lfs output : ${lfs_df_after[*]}"
11573         echo "df  output : ${df_after[*]}"
11574
11575         # Verify lfs df
11576         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11577                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11578         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11579                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11580         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11581                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11582
11583         # Verify df
11584         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11585                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11586         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11587                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11588         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11589                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11590
11591         # Restore MDT recordize back to original
11592         for facet in ${mfacets//,/ }; do
11593                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11594                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11595         done
11596
11597         # Restore OST recordize back to original
11598         for facet in ${ofacets//,/ }; do
11599                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11600                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11601         done
11602
11603         return 0
11604 }
11605 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11606
11607 test_105a() {
11608         # doesn't work on 2.4 kernels
11609         touch $DIR/$tfile
11610         if $(flock_is_enabled); then
11611                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11612         else
11613                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11614         fi
11615         rm -f $DIR/$tfile
11616 }
11617 run_test 105a "flock when mounted without -o flock test ========"
11618
11619 test_105b() {
11620         touch $DIR/$tfile
11621         if $(flock_is_enabled); then
11622                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11623         else
11624                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11625         fi
11626         rm -f $DIR/$tfile
11627 }
11628 run_test 105b "fcntl when mounted without -o flock test ========"
11629
11630 test_105c() {
11631         touch $DIR/$tfile
11632         if $(flock_is_enabled); then
11633                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11634         else
11635                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11636         fi
11637         rm -f $DIR/$tfile
11638 }
11639 run_test 105c "lockf when mounted without -o flock test"
11640
11641 test_105d() { # bug 15924
11642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11643
11644         test_mkdir $DIR/$tdir
11645         flock_is_enabled || skip_env "mount w/o flock enabled"
11646         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11647         $LCTL set_param fail_loc=0x80000315
11648         flocks_test 2 $DIR/$tdir
11649 }
11650 run_test 105d "flock race (should not freeze) ========"
11651
11652 test_105e() { # bug 22660 && 22040
11653         flock_is_enabled || skip_env "mount w/o flock enabled"
11654
11655         touch $DIR/$tfile
11656         flocks_test 3 $DIR/$tfile
11657 }
11658 run_test 105e "Two conflicting flocks from same process"
11659
11660 test_106() { #bug 10921
11661         test_mkdir $DIR/$tdir
11662         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11663         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11664 }
11665 run_test 106 "attempt exec of dir followed by chown of that dir"
11666
11667 test_107() {
11668         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11669
11670         CDIR=`pwd`
11671         local file=core
11672
11673         cd $DIR
11674         rm -f $file
11675
11676         local save_pattern=$(sysctl -n kernel.core_pattern)
11677         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11678         sysctl -w kernel.core_pattern=$file
11679         sysctl -w kernel.core_uses_pid=0
11680
11681         ulimit -c unlimited
11682         sleep 60 &
11683         SLEEPPID=$!
11684
11685         sleep 1
11686
11687         kill -s 11 $SLEEPPID
11688         wait $SLEEPPID
11689         if [ -e $file ]; then
11690                 size=`stat -c%s $file`
11691                 [ $size -eq 0 ] && error "Fail to create core file $file"
11692         else
11693                 error "Fail to create core file $file"
11694         fi
11695         rm -f $file
11696         sysctl -w kernel.core_pattern=$save_pattern
11697         sysctl -w kernel.core_uses_pid=$save_uses_pid
11698         cd $CDIR
11699 }
11700 run_test 107 "Coredump on SIG"
11701
11702 test_110() {
11703         test_mkdir $DIR/$tdir
11704         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11705         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11706                 error "mkdir with 256 char should fail, but did not"
11707         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11708                 error "create with 255 char failed"
11709         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11710                 error "create with 256 char should fail, but did not"
11711
11712         ls -l $DIR/$tdir
11713         rm -rf $DIR/$tdir
11714 }
11715 run_test 110 "filename length checking"
11716
11717 #
11718 # Purpose: To verify dynamic thread (OSS) creation.
11719 #
11720 test_115() {
11721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11722         remote_ost_nodsh && skip "remote OST with nodsh"
11723
11724         # Lustre does not stop service threads once they are started.
11725         # Reset number of running threads to default.
11726         stopall
11727         setupall
11728
11729         local OSTIO_pre
11730         local save_params="$TMP/sanity-$TESTNAME.parameters"
11731
11732         # Get ll_ost_io count before I/O
11733         OSTIO_pre=$(do_facet ost1 \
11734                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
11735         # Exit if lustre is not running (ll_ost_io not running).
11736         [ -z "$OSTIO_pre" ] && error "no OSS threads"
11737
11738         echo "Starting with $OSTIO_pre threads"
11739         local thread_max=$((OSTIO_pre * 2))
11740         local rpc_in_flight=$((thread_max * 2))
11741         # Number of I/O Process proposed to be started.
11742         local nfiles
11743         local facets=$(get_facets OST)
11744
11745         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
11746         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
11747
11748         # Set in_flight to $rpc_in_flight
11749         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
11750                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
11751         nfiles=${rpc_in_flight}
11752         # Set ost thread_max to $thread_max
11753         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
11754
11755         # 5 Minutes should be sufficient for max number of OSS
11756         # threads(thread_max) to be created.
11757         local timeout=300
11758
11759         # Start I/O.
11760         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
11761         test_mkdir $DIR/$tdir
11762         for i in $(seq $nfiles); do
11763                 local file=$DIR/$tdir/${tfile}-$i
11764                 $LFS setstripe -c -1 -i 0 $file
11765                 ($WTL $file $timeout)&
11766         done
11767
11768         # I/O Started - Wait for thread_started to reach thread_max or report
11769         # error if thread_started is more than thread_max.
11770         echo "Waiting for thread_started to reach thread_max"
11771         local thread_started=0
11772         local end_time=$((SECONDS + timeout))
11773
11774         while [ $SECONDS -le $end_time ] ; do
11775                 echo -n "."
11776                 # Get ost i/o thread_started count.
11777                 thread_started=$(do_facet ost1 \
11778                         "$LCTL get_param \
11779                         ost.OSS.ost_io.threads_started | cut -d= -f2")
11780                 # Break out if thread_started is equal/greater than thread_max
11781                 if [[ $thread_started -ge $thread_max ]]; then
11782                         echo ll_ost_io thread_started $thread_started, \
11783                                 equal/greater than thread_max $thread_max
11784                         break
11785                 fi
11786                 sleep 1
11787         done
11788
11789         # Cleanup - We have the numbers, Kill i/o jobs if running.
11790         jobcount=($(jobs -p))
11791         for i in $(seq 0 $((${#jobcount[@]}-1)))
11792         do
11793                 kill -9 ${jobcount[$i]}
11794                 if [ $? -ne 0 ] ; then
11795                         echo Warning: \
11796                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
11797                 fi
11798         done
11799
11800         # Cleanup files left by WTL binary.
11801         for i in $(seq $nfiles); do
11802                 local file=$DIR/$tdir/${tfile}-$i
11803                 rm -rf $file
11804                 if [ $? -ne 0 ] ; then
11805                         echo "Warning: Failed to delete file $file"
11806                 fi
11807         done
11808
11809         restore_lustre_params <$save_params
11810         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
11811
11812         # Error out if no new thread has started or Thread started is greater
11813         # than thread max.
11814         if [[ $thread_started -le $OSTIO_pre ||
11815                         $thread_started -gt $thread_max ]]; then
11816                 error "ll_ost_io: thread_started $thread_started" \
11817                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
11818                       "No new thread started or thread started greater " \
11819                       "than thread_max."
11820         fi
11821 }
11822 run_test 115 "verify dynamic thread creation===================="
11823
11824 free_min_max () {
11825         wait_delete_completed
11826         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
11827         echo "OST kbytes available: ${AVAIL[@]}"
11828         MAXV=${AVAIL[0]}
11829         MAXI=0
11830         MINV=${AVAIL[0]}
11831         MINI=0
11832         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
11833                 #echo OST $i: ${AVAIL[i]}kb
11834                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
11835                         MAXV=${AVAIL[i]}
11836                         MAXI=$i
11837                 fi
11838                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
11839                         MINV=${AVAIL[i]}
11840                         MINI=$i
11841                 fi
11842         done
11843         echo "Min free space: OST $MINI: $MINV"
11844         echo "Max free space: OST $MAXI: $MAXV"
11845 }
11846
11847 test_116a() { # was previously test_116()
11848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11849         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11850         remote_mds_nodsh && skip "remote MDS with nodsh"
11851
11852         echo -n "Free space priority "
11853         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11854                 head -n1
11855         declare -a AVAIL
11856         free_min_max
11857
11858         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11859         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11860         trap simple_cleanup_common EXIT
11861
11862         # Check if we need to generate uneven OSTs
11863         test_mkdir -p $DIR/$tdir/OST${MINI}
11864         local FILL=$((MINV / 4))
11865         local DIFF=$((MAXV - MINV))
11866         local DIFF2=$((DIFF * 100 / MINV))
11867
11868         local threshold=$(do_facet $SINGLEMDS \
11869                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
11870         threshold=${threshold%%%}
11871         echo -n "Check for uneven OSTs: "
11872         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
11873
11874         if [[ $DIFF2 -gt $threshold ]]; then
11875                 echo "ok"
11876                 echo "Don't need to fill OST$MINI"
11877         else
11878                 # generate uneven OSTs. Write 2% over the QOS threshold value
11879                 echo "no"
11880                 DIFF=$((threshold - DIFF2 + 2))
11881                 DIFF2=$((MINV * DIFF / 100))
11882                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
11883                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
11884                         error "setstripe failed"
11885                 DIFF=$((DIFF2 / 2048))
11886                 i=0
11887                 while [ $i -lt $DIFF ]; do
11888                         i=$((i + 1))
11889                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
11890                                 bs=2M count=1 2>/dev/null
11891                         echo -n .
11892                 done
11893                 echo .
11894                 sync
11895                 sleep_maxage
11896                 free_min_max
11897         fi
11898
11899         DIFF=$((MAXV - MINV))
11900         DIFF2=$((DIFF * 100 / MINV))
11901         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
11902         if [ $DIFF2 -gt $threshold ]; then
11903                 echo "ok"
11904         else
11905                 echo "failed - QOS mode won't be used"
11906                 simple_cleanup_common
11907                 skip "QOS imbalance criteria not met"
11908         fi
11909
11910         MINI1=$MINI
11911         MINV1=$MINV
11912         MAXI1=$MAXI
11913         MAXV1=$MAXV
11914
11915         # now fill using QOS
11916         $LFS setstripe -c 1 $DIR/$tdir
11917         FILL=$((FILL / 200))
11918         if [ $FILL -gt 600 ]; then
11919                 FILL=600
11920         fi
11921         echo "writing $FILL files to QOS-assigned OSTs"
11922         i=0
11923         while [ $i -lt $FILL ]; do
11924                 i=$((i + 1))
11925                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
11926                         count=1 2>/dev/null
11927                 echo -n .
11928         done
11929         echo "wrote $i 200k files"
11930         sync
11931         sleep_maxage
11932
11933         echo "Note: free space may not be updated, so measurements might be off"
11934         free_min_max
11935         DIFF2=$((MAXV - MINV))
11936         echo "free space delta: orig $DIFF final $DIFF2"
11937         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
11938         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
11939         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
11940         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
11941         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
11942         if [[ $DIFF -gt 0 ]]; then
11943                 FILL=$((DIFF2 * 100 / DIFF - 100))
11944                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
11945         fi
11946
11947         # Figure out which files were written where
11948         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11949                awk '/'$MINI1': / {print $2; exit}')
11950         echo $UUID
11951         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11952         echo "$MINC files created on smaller OST $MINI1"
11953         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11954                awk '/'$MAXI1': / {print $2; exit}')
11955         echo $UUID
11956         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11957         echo "$MAXC files created on larger OST $MAXI1"
11958         if [[ $MINC -gt 0 ]]; then
11959                 FILL=$((MAXC * 100 / MINC - 100))
11960                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
11961         fi
11962         [[ $MAXC -gt $MINC ]] ||
11963                 error_ignore LU-9 "stripe QOS didn't balance free space"
11964         simple_cleanup_common
11965 }
11966 run_test 116a "stripe QOS: free space balance ==================="
11967
11968 test_116b() { # LU-2093
11969         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11970         remote_mds_nodsh && skip "remote MDS with nodsh"
11971
11972 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
11973         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
11974                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
11975         [ -z "$old_rr" ] && skip "no QOS"
11976         do_facet $SINGLEMDS lctl set_param \
11977                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
11978         mkdir -p $DIR/$tdir
11979         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
11980         createmany -o $DIR/$tdir/f- 20 || error "can't create"
11981         do_facet $SINGLEMDS lctl set_param fail_loc=0
11982         rm -rf $DIR/$tdir
11983         do_facet $SINGLEMDS lctl set_param \
11984                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
11985 }
11986 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
11987
11988 test_117() # bug 10891
11989 {
11990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11991
11992         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
11993         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
11994         lctl set_param fail_loc=0x21e
11995         > $DIR/$tfile || error "truncate failed"
11996         lctl set_param fail_loc=0
11997         echo "Truncate succeeded."
11998         rm -f $DIR/$tfile
11999 }
12000 run_test 117 "verify osd extend =========="
12001
12002 NO_SLOW_RESENDCOUNT=4
12003 export OLD_RESENDCOUNT=""
12004 set_resend_count () {
12005         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12006         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12007         lctl set_param -n $PROC_RESENDCOUNT $1
12008         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12009 }
12010
12011 # for reduce test_118* time (b=14842)
12012 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12013
12014 # Reset async IO behavior after error case
12015 reset_async() {
12016         FILE=$DIR/reset_async
12017
12018         # Ensure all OSCs are cleared
12019         $LFS setstripe -c -1 $FILE
12020         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12021         sync
12022         rm $FILE
12023 }
12024
12025 test_118a() #bug 11710
12026 {
12027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12028
12029         reset_async
12030
12031         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12032         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12033         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12034
12035         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12036                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12037                 return 1;
12038         fi
12039         rm -f $DIR/$tfile
12040 }
12041 run_test 118a "verify O_SYNC works =========="
12042
12043 test_118b()
12044 {
12045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12046         remote_ost_nodsh && skip "remote OST with nodsh"
12047
12048         reset_async
12049
12050         #define OBD_FAIL_SRV_ENOENT 0x217
12051         set_nodes_failloc "$(osts_nodes)" 0x217
12052         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12053         RC=$?
12054         set_nodes_failloc "$(osts_nodes)" 0
12055         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12056         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12057                     grep -c writeback)
12058
12059         if [[ $RC -eq 0 ]]; then
12060                 error "Must return error due to dropped pages, rc=$RC"
12061                 return 1;
12062         fi
12063
12064         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12065                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12066                 return 1;
12067         fi
12068
12069         echo "Dirty pages not leaked on ENOENT"
12070
12071         # Due to the above error the OSC will issue all RPCs syncronously
12072         # until a subsequent RPC completes successfully without error.
12073         $MULTIOP $DIR/$tfile Ow4096yc
12074         rm -f $DIR/$tfile
12075
12076         return 0
12077 }
12078 run_test 118b "Reclaim dirty pages on fatal error =========="
12079
12080 test_118c()
12081 {
12082         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12083
12084         # for 118c, restore the original resend count, LU-1940
12085         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12086                                 set_resend_count $OLD_RESENDCOUNT
12087         remote_ost_nodsh && skip "remote OST with nodsh"
12088
12089         reset_async
12090
12091         #define OBD_FAIL_OST_EROFS               0x216
12092         set_nodes_failloc "$(osts_nodes)" 0x216
12093
12094         # multiop should block due to fsync until pages are written
12095         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12096         MULTIPID=$!
12097         sleep 1
12098
12099         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12100                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12101         fi
12102
12103         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12104                     grep -c writeback)
12105         if [[ $WRITEBACK -eq 0 ]]; then
12106                 error "No page in writeback, writeback=$WRITEBACK"
12107         fi
12108
12109         set_nodes_failloc "$(osts_nodes)" 0
12110         wait $MULTIPID
12111         RC=$?
12112         if [[ $RC -ne 0 ]]; then
12113                 error "Multiop fsync failed, rc=$RC"
12114         fi
12115
12116         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12117         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12118                     grep -c writeback)
12119         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12120                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12121         fi
12122
12123         rm -f $DIR/$tfile
12124         echo "Dirty pages flushed via fsync on EROFS"
12125         return 0
12126 }
12127 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12128
12129 # continue to use small resend count to reduce test_118* time (b=14842)
12130 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12131
12132 test_118d()
12133 {
12134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12135         remote_ost_nodsh && skip "remote OST with nodsh"
12136
12137         reset_async
12138
12139         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12140         set_nodes_failloc "$(osts_nodes)" 0x214
12141         # multiop should block due to fsync until pages are written
12142         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12143         MULTIPID=$!
12144         sleep 1
12145
12146         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12147                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12148         fi
12149
12150         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12151                     grep -c writeback)
12152         if [[ $WRITEBACK -eq 0 ]]; then
12153                 error "No page in writeback, writeback=$WRITEBACK"
12154         fi
12155
12156         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12157         set_nodes_failloc "$(osts_nodes)" 0
12158
12159         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12160         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12161                     grep -c writeback)
12162         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12163                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12164         fi
12165
12166         rm -f $DIR/$tfile
12167         echo "Dirty pages gaurenteed flushed via fsync"
12168         return 0
12169 }
12170 run_test 118d "Fsync validation inject a delay of the bulk =========="
12171
12172 test_118f() {
12173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12174
12175         reset_async
12176
12177         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12178         lctl set_param fail_loc=0x8000040a
12179
12180         # Should simulate EINVAL error which is fatal
12181         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12182         RC=$?
12183         if [[ $RC -eq 0 ]]; then
12184                 error "Must return error due to dropped pages, rc=$RC"
12185         fi
12186
12187         lctl set_param fail_loc=0x0
12188
12189         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12190         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12191         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12192                     grep -c writeback)
12193         if [[ $LOCKED -ne 0 ]]; then
12194                 error "Locked pages remain in cache, locked=$LOCKED"
12195         fi
12196
12197         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12198                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12199         fi
12200
12201         rm -f $DIR/$tfile
12202         echo "No pages locked after fsync"
12203
12204         reset_async
12205         return 0
12206 }
12207 run_test 118f "Simulate unrecoverable OSC side error =========="
12208
12209 test_118g() {
12210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12211
12212         reset_async
12213
12214         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12215         lctl set_param fail_loc=0x406
12216
12217         # simulate local -ENOMEM
12218         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12219         RC=$?
12220
12221         lctl set_param fail_loc=0
12222         if [[ $RC -eq 0 ]]; then
12223                 error "Must return error due to dropped pages, rc=$RC"
12224         fi
12225
12226         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12227         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12228         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12229                         grep -c writeback)
12230         if [[ $LOCKED -ne 0 ]]; then
12231                 error "Locked pages remain in cache, locked=$LOCKED"
12232         fi
12233
12234         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12235                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12236         fi
12237
12238         rm -f $DIR/$tfile
12239         echo "No pages locked after fsync"
12240
12241         reset_async
12242         return 0
12243 }
12244 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12245
12246 test_118h() {
12247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12248         remote_ost_nodsh && skip "remote OST with nodsh"
12249
12250         reset_async
12251
12252         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12253         set_nodes_failloc "$(osts_nodes)" 0x20e
12254         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12255         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12256         RC=$?
12257
12258         set_nodes_failloc "$(osts_nodes)" 0
12259         if [[ $RC -eq 0 ]]; then
12260                 error "Must return error due to dropped pages, rc=$RC"
12261         fi
12262
12263         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12264         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12265         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12266                     grep -c writeback)
12267         if [[ $LOCKED -ne 0 ]]; then
12268                 error "Locked pages remain in cache, locked=$LOCKED"
12269         fi
12270
12271         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12272                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12273         fi
12274
12275         rm -f $DIR/$tfile
12276         echo "No pages locked after fsync"
12277
12278         return 0
12279 }
12280 run_test 118h "Verify timeout in handling recoverables errors  =========="
12281
12282 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12283
12284 test_118i() {
12285         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12286         remote_ost_nodsh && skip "remote OST with nodsh"
12287
12288         reset_async
12289
12290         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12291         set_nodes_failloc "$(osts_nodes)" 0x20e
12292
12293         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12294         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12295         PID=$!
12296         sleep 5
12297         set_nodes_failloc "$(osts_nodes)" 0
12298
12299         wait $PID
12300         RC=$?
12301         if [[ $RC -ne 0 ]]; then
12302                 error "got error, but should be not, rc=$RC"
12303         fi
12304
12305         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12306         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12307         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12308         if [[ $LOCKED -ne 0 ]]; then
12309                 error "Locked pages remain in cache, locked=$LOCKED"
12310         fi
12311
12312         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12313                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12314         fi
12315
12316         rm -f $DIR/$tfile
12317         echo "No pages locked after fsync"
12318
12319         return 0
12320 }
12321 run_test 118i "Fix error before timeout in recoverable error  =========="
12322
12323 [ "$SLOW" = "no" ] && set_resend_count 4
12324
12325 test_118j() {
12326         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12327         remote_ost_nodsh && skip "remote OST with nodsh"
12328
12329         reset_async
12330
12331         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12332         set_nodes_failloc "$(osts_nodes)" 0x220
12333
12334         # return -EIO from OST
12335         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12336         RC=$?
12337         set_nodes_failloc "$(osts_nodes)" 0x0
12338         if [[ $RC -eq 0 ]]; then
12339                 error "Must return error due to dropped pages, rc=$RC"
12340         fi
12341
12342         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12343         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12344         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12345         if [[ $LOCKED -ne 0 ]]; then
12346                 error "Locked pages remain in cache, locked=$LOCKED"
12347         fi
12348
12349         # in recoverable error on OST we want resend and stay until it finished
12350         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12351                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12352         fi
12353
12354         rm -f $DIR/$tfile
12355         echo "No pages locked after fsync"
12356
12357         return 0
12358 }
12359 run_test 118j "Simulate unrecoverable OST side error =========="
12360
12361 test_118k()
12362 {
12363         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12364         remote_ost_nodsh && skip "remote OSTs with nodsh"
12365
12366         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12367         set_nodes_failloc "$(osts_nodes)" 0x20e
12368         test_mkdir $DIR/$tdir
12369
12370         for ((i=0;i<10;i++)); do
12371                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12372                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12373                 SLEEPPID=$!
12374                 sleep 0.500s
12375                 kill $SLEEPPID
12376                 wait $SLEEPPID
12377         done
12378
12379         set_nodes_failloc "$(osts_nodes)" 0
12380         rm -rf $DIR/$tdir
12381 }
12382 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12383
12384 test_118l() # LU-646
12385 {
12386         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12387
12388         test_mkdir $DIR/$tdir
12389         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12390         rm -rf $DIR/$tdir
12391 }
12392 run_test 118l "fsync dir"
12393
12394 test_118m() # LU-3066
12395 {
12396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12397
12398         test_mkdir $DIR/$tdir
12399         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12400         rm -rf $DIR/$tdir
12401 }
12402 run_test 118m "fdatasync dir ========="
12403
12404 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12405
12406 test_118n()
12407 {
12408         local begin
12409         local end
12410
12411         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12412         remote_ost_nodsh && skip "remote OSTs with nodsh"
12413
12414         # Sleep to avoid a cached response.
12415         #define OBD_STATFS_CACHE_SECONDS 1
12416         sleep 2
12417
12418         # Inject a 10 second delay in the OST_STATFS handler.
12419         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12420         set_nodes_failloc "$(osts_nodes)" 0x242
12421
12422         begin=$SECONDS
12423         stat --file-system $MOUNT > /dev/null
12424         end=$SECONDS
12425
12426         set_nodes_failloc "$(osts_nodes)" 0
12427
12428         if ((end - begin > 20)); then
12429             error "statfs took $((end - begin)) seconds, expected 10"
12430         fi
12431 }
12432 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12433
12434 test_119a() # bug 11737
12435 {
12436         BSIZE=$((512 * 1024))
12437         directio write $DIR/$tfile 0 1 $BSIZE
12438         # We ask to read two blocks, which is more than a file size.
12439         # directio will indicate an error when requested and actual
12440         # sizes aren't equeal (a normal situation in this case) and
12441         # print actual read amount.
12442         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12443         if [ "$NOB" != "$BSIZE" ]; then
12444                 error "read $NOB bytes instead of $BSIZE"
12445         fi
12446         rm -f $DIR/$tfile
12447 }
12448 run_test 119a "Short directIO read must return actual read amount"
12449
12450 test_119b() # bug 11737
12451 {
12452         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12453
12454         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12455         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12456         sync
12457         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12458                 error "direct read failed"
12459         rm -f $DIR/$tfile
12460 }
12461 run_test 119b "Sparse directIO read must return actual read amount"
12462
12463 test_119c() # bug 13099
12464 {
12465         BSIZE=1048576
12466         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12467         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12468         rm -f $DIR/$tfile
12469 }
12470 run_test 119c "Testing for direct read hitting hole"
12471
12472 test_119d() # bug 15950
12473 {
12474         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12475
12476         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12477         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12478         BSIZE=1048576
12479         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12480         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12481         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12482         lctl set_param fail_loc=0x40d
12483         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12484         pid_dio=$!
12485         sleep 1
12486         cat $DIR/$tfile > /dev/null &
12487         lctl set_param fail_loc=0
12488         pid_reads=$!
12489         wait $pid_dio
12490         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12491         sleep 2
12492         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12493         error "the read rpcs have not completed in 2s"
12494         rm -f $DIR/$tfile
12495         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12496 }
12497 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12498
12499 test_120a() {
12500         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12501         remote_mds_nodsh && skip "remote MDS with nodsh"
12502         test_mkdir -i0 -c1 $DIR/$tdir
12503         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12504                 skip_env "no early lock cancel on server"
12505
12506         lru_resize_disable mdc
12507         lru_resize_disable osc
12508         cancel_lru_locks mdc
12509         # asynchronous object destroy at MDT could cause bl ast to client
12510         cancel_lru_locks osc
12511
12512         stat $DIR/$tdir > /dev/null
12513         can1=$(do_facet mds1 \
12514                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12515                awk '/ldlm_cancel/ {print $2}')
12516         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12517                awk '/ldlm_bl_callback/ {print $2}')
12518         test_mkdir -i0 -c1 $DIR/$tdir/d1
12519         can2=$(do_facet mds1 \
12520                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12521                awk '/ldlm_cancel/ {print $2}')
12522         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12523                awk '/ldlm_bl_callback/ {print $2}')
12524         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12525         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12526         lru_resize_enable mdc
12527         lru_resize_enable osc
12528 }
12529 run_test 120a "Early Lock Cancel: mkdir test"
12530
12531 test_120b() {
12532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12533         remote_mds_nodsh && skip "remote MDS with nodsh"
12534         test_mkdir $DIR/$tdir
12535         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12536                 skip_env "no early lock cancel on server"
12537
12538         lru_resize_disable mdc
12539         lru_resize_disable osc
12540         cancel_lru_locks mdc
12541         stat $DIR/$tdir > /dev/null
12542         can1=$(do_facet $SINGLEMDS \
12543                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12544                awk '/ldlm_cancel/ {print $2}')
12545         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12546                awk '/ldlm_bl_callback/ {print $2}')
12547         touch $DIR/$tdir/f1
12548         can2=$(do_facet $SINGLEMDS \
12549                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12550                awk '/ldlm_cancel/ {print $2}')
12551         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12552                awk '/ldlm_bl_callback/ {print $2}')
12553         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12554         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12555         lru_resize_enable mdc
12556         lru_resize_enable osc
12557 }
12558 run_test 120b "Early Lock Cancel: create test"
12559
12560 test_120c() {
12561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12562         remote_mds_nodsh && skip "remote MDS with nodsh"
12563         test_mkdir -i0 -c1 $DIR/$tdir
12564         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12565                 skip "no early lock cancel on server"
12566
12567         lru_resize_disable mdc
12568         lru_resize_disable osc
12569         test_mkdir -i0 -c1 $DIR/$tdir/d1
12570         test_mkdir -i0 -c1 $DIR/$tdir/d2
12571         touch $DIR/$tdir/d1/f1
12572         cancel_lru_locks mdc
12573         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12574         can1=$(do_facet mds1 \
12575                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12576                awk '/ldlm_cancel/ {print $2}')
12577         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12578                awk '/ldlm_bl_callback/ {print $2}')
12579         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12580         can2=$(do_facet mds1 \
12581                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12582                awk '/ldlm_cancel/ {print $2}')
12583         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12584                awk '/ldlm_bl_callback/ {print $2}')
12585         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12586         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12587         lru_resize_enable mdc
12588         lru_resize_enable osc
12589 }
12590 run_test 120c "Early Lock Cancel: link test"
12591
12592 test_120d() {
12593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12594         remote_mds_nodsh && skip "remote MDS with nodsh"
12595         test_mkdir -i0 -c1 $DIR/$tdir
12596         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12597                 skip_env "no early lock cancel on server"
12598
12599         lru_resize_disable mdc
12600         lru_resize_disable osc
12601         touch $DIR/$tdir
12602         cancel_lru_locks mdc
12603         stat $DIR/$tdir > /dev/null
12604         can1=$(do_facet mds1 \
12605                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12606                awk '/ldlm_cancel/ {print $2}')
12607         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12608                awk '/ldlm_bl_callback/ {print $2}')
12609         chmod a+x $DIR/$tdir
12610         can2=$(do_facet mds1 \
12611                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12612                awk '/ldlm_cancel/ {print $2}')
12613         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12614                awk '/ldlm_bl_callback/ {print $2}')
12615         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12616         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12617         lru_resize_enable mdc
12618         lru_resize_enable osc
12619 }
12620 run_test 120d "Early Lock Cancel: setattr test"
12621
12622 test_120e() {
12623         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12624         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12625                 skip_env "no early lock cancel on server"
12626         remote_mds_nodsh && skip "remote MDS with nodsh"
12627
12628         local dlmtrace_set=false
12629
12630         test_mkdir -i0 -c1 $DIR/$tdir
12631         lru_resize_disable mdc
12632         lru_resize_disable osc
12633         ! $LCTL get_param debug | grep -q dlmtrace &&
12634                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12635         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12636         cancel_lru_locks mdc
12637         cancel_lru_locks osc
12638         dd if=$DIR/$tdir/f1 of=/dev/null
12639         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12640         # XXX client can not do early lock cancel of OST lock
12641         # during unlink (LU-4206), so cancel osc lock now.
12642         sleep 2
12643         cancel_lru_locks osc
12644         can1=$(do_facet mds1 \
12645                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12646                awk '/ldlm_cancel/ {print $2}')
12647         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12648                awk '/ldlm_bl_callback/ {print $2}')
12649         unlink $DIR/$tdir/f1
12650         sleep 5
12651         can2=$(do_facet mds1 \
12652                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12653                awk '/ldlm_cancel/ {print $2}')
12654         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12655                awk '/ldlm_bl_callback/ {print $2}')
12656         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12657                 $LCTL dk $TMP/cancel.debug.txt
12658         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12659                 $LCTL dk $TMP/blocking.debug.txt
12660         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12661         lru_resize_enable mdc
12662         lru_resize_enable osc
12663 }
12664 run_test 120e "Early Lock Cancel: unlink test"
12665
12666 test_120f() {
12667         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12668         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12669                 skip_env "no early lock cancel on server"
12670         remote_mds_nodsh && skip "remote MDS with nodsh"
12671
12672         test_mkdir -i0 -c1 $DIR/$tdir
12673         lru_resize_disable mdc
12674         lru_resize_disable osc
12675         test_mkdir -i0 -c1 $DIR/$tdir/d1
12676         test_mkdir -i0 -c1 $DIR/$tdir/d2
12677         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12678         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12679         cancel_lru_locks mdc
12680         cancel_lru_locks osc
12681         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12682         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12683         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12684         # XXX client can not do early lock cancel of OST lock
12685         # during rename (LU-4206), so cancel osc lock now.
12686         sleep 2
12687         cancel_lru_locks osc
12688         can1=$(do_facet mds1 \
12689                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12690                awk '/ldlm_cancel/ {print $2}')
12691         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12692                awk '/ldlm_bl_callback/ {print $2}')
12693         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12694         sleep 5
12695         can2=$(do_facet mds1 \
12696                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12697                awk '/ldlm_cancel/ {print $2}')
12698         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12699                awk '/ldlm_bl_callback/ {print $2}')
12700         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12701         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12702         lru_resize_enable mdc
12703         lru_resize_enable osc
12704 }
12705 run_test 120f "Early Lock Cancel: rename test"
12706
12707 test_120g() {
12708         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12709         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12710                 skip_env "no early lock cancel on server"
12711         remote_mds_nodsh && skip "remote MDS with nodsh"
12712
12713         lru_resize_disable mdc
12714         lru_resize_disable osc
12715         count=10000
12716         echo create $count files
12717         test_mkdir $DIR/$tdir
12718         cancel_lru_locks mdc
12719         cancel_lru_locks osc
12720         t0=$(date +%s)
12721
12722         can0=$(do_facet $SINGLEMDS \
12723                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12724                awk '/ldlm_cancel/ {print $2}')
12725         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12726                awk '/ldlm_bl_callback/ {print $2}')
12727         createmany -o $DIR/$tdir/f $count
12728         sync
12729         can1=$(do_facet $SINGLEMDS \
12730                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12731                awk '/ldlm_cancel/ {print $2}')
12732         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12733                awk '/ldlm_bl_callback/ {print $2}')
12734         t1=$(date +%s)
12735         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
12736         echo rm $count files
12737         rm -r $DIR/$tdir
12738         sync
12739         can2=$(do_facet $SINGLEMDS \
12740                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12741                awk '/ldlm_cancel/ {print $2}')
12742         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12743                awk '/ldlm_bl_callback/ {print $2}')
12744         t2=$(date +%s)
12745         echo total: $count removes in $((t2-t1))
12746         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
12747         sleep 2
12748         # wait for commitment of removal
12749         lru_resize_enable mdc
12750         lru_resize_enable osc
12751 }
12752 run_test 120g "Early Lock Cancel: performance test"
12753
12754 test_121() { #bug #10589
12755         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12756
12757         rm -rf $DIR/$tfile
12758         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12759 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
12760         lctl set_param fail_loc=0x310
12761         cancel_lru_locks osc > /dev/null
12762         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
12763         lctl set_param fail_loc=0
12764         [[ $reads -eq $writes ]] ||
12765                 error "read $reads blocks, must be $writes blocks"
12766 }
12767 run_test 121 "read cancel race ========="
12768
12769 test_123a_base() { # was test 123, statahead(bug 11401)
12770         local lsx="$1"
12771
12772         SLOWOK=0
12773         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
12774                 log "testing UP system. Performance may be lower than expected."
12775                 SLOWOK=1
12776         fi
12777
12778         rm -rf $DIR/$tdir
12779         test_mkdir $DIR/$tdir
12780         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12781         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12782         MULT=10
12783         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12784                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12785
12786                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12787                 lctl set_param -n llite.*.statahead_max 0
12788                 lctl get_param llite.*.statahead_max
12789                 cancel_lru_locks mdc
12790                 cancel_lru_locks osc
12791                 stime=$(date +%s)
12792                 time $lsx $DIR/$tdir | wc -l
12793                 etime=$(date +%s)
12794                 delta=$((etime - stime))
12795                 log "$lsx $i files without statahead: $delta sec"
12796                 lctl set_param llite.*.statahead_max=$max
12797
12798                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12799                         grep "statahead wrong:" | awk '{print $3}')
12800                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
12801                 cancel_lru_locks mdc
12802                 cancel_lru_locks osc
12803                 stime=$(date +%s)
12804                 time $lsx $DIR/$tdir | wc -l
12805                 etime=$(date +%s)
12806                 delta_sa=$((etime - stime))
12807                 log "$lsx $i files with statahead: $delta_sa sec"
12808                 lctl get_param -n llite.*.statahead_stats
12809                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12810                         grep "statahead wrong:" | awk '{print $3}')
12811
12812                 [[ $swrong -lt $ewrong ]] &&
12813                         log "statahead was stopped, maybe too many locks held!"
12814                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12815
12816                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
12817                         max=$(lctl get_param -n llite.*.statahead_max |
12818                                 head -n 1)
12819                         lctl set_param -n llite.*.statahead_max 0
12820                         lctl get_param llite.*.statahead_max
12821                         cancel_lru_locks mdc
12822                         cancel_lru_locks osc
12823                         stime=$(date +%s)
12824                         time $lsx $DIR/$tdir | wc -l
12825                         etime=$(date +%s)
12826                         delta=$((etime - stime))
12827                         log "$lsx $i files again without statahead: $delta sec"
12828                         lctl set_param llite.*.statahead_max=$max
12829                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
12830                                 if [  $SLOWOK -eq 0 ]; then
12831                                         error "$lsx $i files is slower with statahead!"
12832                                 else
12833                                         log "$lsx $i files is slower with statahead!"
12834                                 fi
12835                                 break
12836                         fi
12837                 fi
12838
12839                 [ $delta -gt 20 ] && break
12840                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12841                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12842         done
12843         log "$lsx done"
12844
12845         stime=$(date +%s)
12846         rm -r $DIR/$tdir
12847         sync
12848         etime=$(date +%s)
12849         delta=$((etime - stime))
12850         log "rm -r $DIR/$tdir/: $delta seconds"
12851         log "rm done"
12852         lctl get_param -n llite.*.statahead_stats
12853 }
12854
12855 test_123aa() {
12856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12857
12858         test_123a_base "ls -l"
12859 }
12860 run_test 123aa "verify statahead work"
12861
12862 test_123ab() {
12863         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12864
12865         statx_supported || skip_env "Test must be statx() syscall supported"
12866
12867         test_123a_base "$STATX -l"
12868 }
12869 run_test 123ab "verify statahead work by using statx"
12870
12871 test_123ac() {
12872         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12873
12874         statx_supported || skip_env "Test must be statx() syscall supported"
12875
12876         local rpcs_before
12877         local rpcs_after
12878         local agl_before
12879         local agl_after
12880
12881         cancel_lru_locks $OSC
12882         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12883         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
12884                 awk '/agl.total:/ {print $3}')
12885         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
12886         test_123a_base "$STATX --cached=always -D"
12887         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
12888                 awk '/agl.total:/ {print $3}')
12889         [ $agl_before -eq $agl_after ] ||
12890                 error "Should not trigger AGL thread - $agl_before:$agl_after"
12891         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12892         [ $rpcs_after -eq $rpcs_before ] ||
12893                 error "$STATX should not send glimpse RPCs to $OSC"
12894 }
12895 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
12896
12897 test_123b () { # statahead(bug 15027)
12898         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12899
12900         test_mkdir $DIR/$tdir
12901         createmany -o $DIR/$tdir/$tfile-%d 1000
12902
12903         cancel_lru_locks mdc
12904         cancel_lru_locks osc
12905
12906 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
12907         lctl set_param fail_loc=0x80000803
12908         ls -lR $DIR/$tdir > /dev/null
12909         log "ls done"
12910         lctl set_param fail_loc=0x0
12911         lctl get_param -n llite.*.statahead_stats
12912         rm -r $DIR/$tdir
12913         sync
12914
12915 }
12916 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
12917
12918 test_123c() {
12919         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
12920
12921         test_mkdir -i 0 -c 1 $DIR/$tdir.0
12922         test_mkdir -i 1 -c 1 $DIR/$tdir.1
12923         touch $DIR/$tdir.1/{1..3}
12924         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
12925
12926         remount_client $MOUNT
12927
12928         $MULTIOP $DIR/$tdir.0 Q
12929
12930         # let statahead to complete
12931         ls -l $DIR/$tdir.0 > /dev/null
12932
12933         testid=$(echo $TESTNAME | tr '_' ' ')
12934         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
12935                 error "statahead warning" || true
12936 }
12937 run_test 123c "Can not initialize inode warning on DNE statahead"
12938
12939 test_124a() {
12940         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12941         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12942                 skip_env "no lru resize on server"
12943
12944         local NR=2000
12945
12946         test_mkdir $DIR/$tdir
12947
12948         log "create $NR files at $DIR/$tdir"
12949         createmany -o $DIR/$tdir/f $NR ||
12950                 error "failed to create $NR files in $DIR/$tdir"
12951
12952         cancel_lru_locks mdc
12953         ls -l $DIR/$tdir > /dev/null
12954
12955         local NSDIR=""
12956         local LRU_SIZE=0
12957         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
12958                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
12959                 LRU_SIZE=$($LCTL get_param -n $PARAM)
12960                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
12961                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
12962                         log "NSDIR=$NSDIR"
12963                         log "NS=$(basename $NSDIR)"
12964                         break
12965                 fi
12966         done
12967
12968         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
12969                 skip "Not enough cached locks created!"
12970         fi
12971         log "LRU=$LRU_SIZE"
12972
12973         local SLEEP=30
12974
12975         # We know that lru resize allows one client to hold $LIMIT locks
12976         # for 10h. After that locks begin to be killed by client.
12977         local MAX_HRS=10
12978         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
12979         log "LIMIT=$LIMIT"
12980         if [ $LIMIT -lt $LRU_SIZE ]; then
12981                 skip "Limit is too small $LIMIT"
12982         fi
12983
12984         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
12985         # killing locks. Some time was spent for creating locks. This means
12986         # that up to the moment of sleep finish we must have killed some of
12987         # them (10-100 locks). This depends on how fast ther were created.
12988         # Many of them were touched in almost the same moment and thus will
12989         # be killed in groups.
12990         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
12991
12992         # Use $LRU_SIZE_B here to take into account real number of locks
12993         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
12994         local LRU_SIZE_B=$LRU_SIZE
12995         log "LVF=$LVF"
12996         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
12997         log "OLD_LVF=$OLD_LVF"
12998         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
12999
13000         # Let's make sure that we really have some margin. Client checks
13001         # cached locks every 10 sec.
13002         SLEEP=$((SLEEP+20))
13003         log "Sleep ${SLEEP} sec"
13004         local SEC=0
13005         while ((SEC<$SLEEP)); do
13006                 echo -n "..."
13007                 sleep 5
13008                 SEC=$((SEC+5))
13009                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13010                 echo -n "$LRU_SIZE"
13011         done
13012         echo ""
13013         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13014         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13015
13016         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13017                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13018                 unlinkmany $DIR/$tdir/f $NR
13019                 return
13020         }
13021
13022         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13023         log "unlink $NR files at $DIR/$tdir"
13024         unlinkmany $DIR/$tdir/f $NR
13025 }
13026 run_test 124a "lru resize ======================================="
13027
13028 get_max_pool_limit()
13029 {
13030         local limit=$($LCTL get_param \
13031                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13032         local max=0
13033         for l in $limit; do
13034                 if [[ $l -gt $max ]]; then
13035                         max=$l
13036                 fi
13037         done
13038         echo $max
13039 }
13040
13041 test_124b() {
13042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13043         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13044                 skip_env "no lru resize on server"
13045
13046         LIMIT=$(get_max_pool_limit)
13047
13048         NR=$(($(default_lru_size)*20))
13049         if [[ $NR -gt $LIMIT ]]; then
13050                 log "Limit lock number by $LIMIT locks"
13051                 NR=$LIMIT
13052         fi
13053
13054         IFree=$(mdsrate_inodes_available)
13055         if [ $IFree -lt $NR ]; then
13056                 log "Limit lock number by $IFree inodes"
13057                 NR=$IFree
13058         fi
13059
13060         lru_resize_disable mdc
13061         test_mkdir -p $DIR/$tdir/disable_lru_resize
13062
13063         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13064         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13065         cancel_lru_locks mdc
13066         stime=`date +%s`
13067         PID=""
13068         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13069         PID="$PID $!"
13070         sleep 2
13071         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13072         PID="$PID $!"
13073         sleep 2
13074         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13075         PID="$PID $!"
13076         wait $PID
13077         etime=`date +%s`
13078         nolruresize_delta=$((etime-stime))
13079         log "ls -la time: $nolruresize_delta seconds"
13080         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13081         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13082
13083         lru_resize_enable mdc
13084         test_mkdir -p $DIR/$tdir/enable_lru_resize
13085
13086         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13087         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13088         cancel_lru_locks mdc
13089         stime=`date +%s`
13090         PID=""
13091         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13092         PID="$PID $!"
13093         sleep 2
13094         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13095         PID="$PID $!"
13096         sleep 2
13097         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13098         PID="$PID $!"
13099         wait $PID
13100         etime=`date +%s`
13101         lruresize_delta=$((etime-stime))
13102         log "ls -la time: $lruresize_delta seconds"
13103         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13104
13105         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13106                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13107         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13108                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13109         else
13110                 log "lru resize performs the same with no lru resize"
13111         fi
13112         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13113 }
13114 run_test 124b "lru resize (performance test) ======================="
13115
13116 test_124c() {
13117         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13118         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13119                 skip_env "no lru resize on server"
13120
13121         # cache ununsed locks on client
13122         local nr=100
13123         cancel_lru_locks mdc
13124         test_mkdir $DIR/$tdir
13125         createmany -o $DIR/$tdir/f $nr ||
13126                 error "failed to create $nr files in $DIR/$tdir"
13127         ls -l $DIR/$tdir > /dev/null
13128
13129         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13130         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13131         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13132         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13133         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13134
13135         # set lru_max_age to 1 sec
13136         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13137         echo "sleep $((recalc_p * 2)) seconds..."
13138         sleep $((recalc_p * 2))
13139
13140         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13141         # restore lru_max_age
13142         $LCTL set_param -n $nsdir.lru_max_age $max_age
13143         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13144         unlinkmany $DIR/$tdir/f $nr
13145 }
13146 run_test 124c "LRUR cancel very aged locks"
13147
13148 test_124d() {
13149         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13150         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13151                 skip_env "no lru resize on server"
13152
13153         # cache ununsed locks on client
13154         local nr=100
13155
13156         lru_resize_disable mdc
13157         stack_trap "lru_resize_enable mdc" EXIT
13158
13159         cancel_lru_locks mdc
13160
13161         # asynchronous object destroy at MDT could cause bl ast to client
13162         test_mkdir $DIR/$tdir
13163         createmany -o $DIR/$tdir/f $nr ||
13164                 error "failed to create $nr files in $DIR/$tdir"
13165         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13166
13167         ls -l $DIR/$tdir > /dev/null
13168
13169         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13170         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13171         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13172         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13173
13174         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13175
13176         # set lru_max_age to 1 sec
13177         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13178         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13179
13180         echo "sleep $((recalc_p * 2)) seconds..."
13181         sleep $((recalc_p * 2))
13182
13183         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13184
13185         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13186 }
13187 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13188
13189 test_125() { # 13358
13190         $LCTL get_param -n llite.*.client_type | grep -q local ||
13191                 skip "must run as local client"
13192         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13193                 skip_env "must have acl enabled"
13194         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13195
13196         test_mkdir $DIR/$tdir
13197         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13198         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
13199         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13200 }
13201 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13202
13203 test_126() { # bug 12829/13455
13204         $GSS && skip_env "must run as gss disabled"
13205         $LCTL get_param -n llite.*.client_type | grep -q local ||
13206                 skip "must run as local client"
13207         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13208
13209         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13210         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13211         rm -f $DIR/$tfile
13212         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13213 }
13214 run_test 126 "check that the fsgid provided by the client is taken into account"
13215
13216 test_127a() { # bug 15521
13217         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13218         local name count samp unit min max sum sumsq
13219
13220         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13221         echo "stats before reset"
13222         $LCTL get_param osc.*.stats
13223         $LCTL set_param osc.*.stats=0
13224         local fsize=$((2048 * 1024))
13225
13226         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13227         cancel_lru_locks osc
13228         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13229
13230         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
13231         stack_trap "rm -f $TMP/$tfile.tmp"
13232         while read name count samp unit min max sum sumsq; do
13233                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13234                 [ ! $min ] && error "Missing min value for $name proc entry"
13235                 eval $name=$count || error "Wrong proc format"
13236
13237                 case $name in
13238                 read_bytes|write_bytes)
13239                         [[ "$unit" =~ "bytes" ]] ||
13240                                 error "unit is not 'bytes': $unit"
13241                         (( $min >= 4096 )) || error "min is too small: $min"
13242                         (( $min <= $fsize )) || error "min is too big: $min"
13243                         (( $max >= 4096 )) || error "max is too small: $max"
13244                         (( $max <= $fsize )) || error "max is too big: $max"
13245                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13246                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13247                                 error "sumsquare is too small: $sumsq"
13248                         (( $sumsq <= $fsize * $fsize )) ||
13249                                 error "sumsquare is too big: $sumsq"
13250                         ;;
13251                 ost_read|ost_write)
13252                         [[ "$unit" =~ "usec" ]] ||
13253                                 error "unit is not 'usec': $unit"
13254                         ;;
13255                 *)      ;;
13256                 esac
13257         done < $DIR/$tfile.tmp
13258
13259         #check that we actually got some stats
13260         [ "$read_bytes" ] || error "Missing read_bytes stats"
13261         [ "$write_bytes" ] || error "Missing write_bytes stats"
13262         [ "$read_bytes" != 0 ] || error "no read done"
13263         [ "$write_bytes" != 0 ] || error "no write done"
13264 }
13265 run_test 127a "verify the client stats are sane"
13266
13267 test_127b() { # bug LU-333
13268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13269         local name count samp unit min max sum sumsq
13270
13271         echo "stats before reset"
13272         $LCTL get_param llite.*.stats
13273         $LCTL set_param llite.*.stats=0
13274
13275         # perform 2 reads and writes so MAX is different from SUM.
13276         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13277         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13278         cancel_lru_locks osc
13279         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13280         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13281
13282         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13283         stack_trap "rm -f $TMP/$tfile.tmp"
13284         while read name count samp unit min max sum sumsq; do
13285                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13286                 eval $name=$count || error "Wrong proc format"
13287
13288                 case $name in
13289                 read_bytes|write_bytes)
13290                         [[ "$unit" =~ "bytes" ]] ||
13291                                 error "unit is not 'bytes': $unit"
13292                         (( $count == 2 )) || error "count is not 2: $count"
13293                         (( $min == $PAGE_SIZE )) ||
13294                                 error "min is not $PAGE_SIZE: $min"
13295                         (( $max == $PAGE_SIZE )) ||
13296                                 error "max is not $PAGE_SIZE: $max"
13297                         (( $sum == $PAGE_SIZE * 2 )) ||
13298                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13299                         ;;
13300                 read|write)
13301                         [[ "$unit" =~ "usec" ]] ||
13302                                 error "unit is not 'usec': $unit"
13303                         ;;
13304                 *)      ;;
13305                 esac
13306         done < $TMP/$tfile.tmp
13307
13308         #check that we actually got some stats
13309         [ "$read_bytes" ] || error "Missing read_bytes stats"
13310         [ "$write_bytes" ] || error "Missing write_bytes stats"
13311         [ "$read_bytes" != 0 ] || error "no read done"
13312         [ "$write_bytes" != 0 ] || error "no write done"
13313 }
13314 run_test 127b "verify the llite client stats are sane"
13315
13316 test_127c() { # LU-12394
13317         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13318         local size
13319         local bsize
13320         local reads
13321         local writes
13322         local count
13323
13324         $LCTL set_param llite.*.extents_stats=1
13325         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13326
13327         # Use two stripes so there is enough space in default config
13328         $LFS setstripe -c 2 $DIR/$tfile
13329
13330         # Extent stats start at 0-4K and go in power of two buckets
13331         # LL_HIST_START = 12 --> 2^12 = 4K
13332         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13333         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13334         # small configs
13335         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13336                 do
13337                 # Write and read, 2x each, second time at a non-zero offset
13338                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13339                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13340                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13341                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13342                 rm -f $DIR/$tfile
13343         done
13344
13345         $LCTL get_param llite.*.extents_stats
13346
13347         count=2
13348         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13349                 do
13350                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13351                                 grep -m 1 $bsize)
13352                 reads=$(echo $bucket | awk '{print $5}')
13353                 writes=$(echo $bucket | awk '{print $9}')
13354                 [ "$reads" -eq $count ] ||
13355                         error "$reads reads in < $bsize bucket, expect $count"
13356                 [ "$writes" -eq $count ] ||
13357                         error "$writes writes in < $bsize bucket, expect $count"
13358         done
13359
13360         # Test mmap write and read
13361         $LCTL set_param llite.*.extents_stats=c
13362         size=512
13363         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13364         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13365         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13366
13367         $LCTL get_param llite.*.extents_stats
13368
13369         count=$(((size*1024) / PAGE_SIZE))
13370
13371         bsize=$((2 * PAGE_SIZE / 1024))K
13372
13373         bucket=$($LCTL get_param -n llite.*.extents_stats |
13374                         grep -m 1 $bsize)
13375         reads=$(echo $bucket | awk '{print $5}')
13376         writes=$(echo $bucket | awk '{print $9}')
13377         # mmap writes fault in the page first, creating an additonal read
13378         [ "$reads" -eq $((2 * count)) ] ||
13379                 error "$reads reads in < $bsize bucket, expect $count"
13380         [ "$writes" -eq $count ] ||
13381                 error "$writes writes in < $bsize bucket, expect $count"
13382 }
13383 run_test 127c "test llite extent stats with regular & mmap i/o"
13384
13385 test_128() { # bug 15212
13386         touch $DIR/$tfile
13387         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13388                 find $DIR/$tfile
13389                 find $DIR/$tfile
13390         EOF
13391
13392         result=$(grep error $TMP/$tfile.log)
13393         rm -f $DIR/$tfile $TMP/$tfile.log
13394         [ -z "$result" ] ||
13395                 error "consecutive find's under interactive lfs failed"
13396 }
13397 run_test 128 "interactive lfs for 2 consecutive find's"
13398
13399 set_dir_limits () {
13400         local mntdev
13401         local canondev
13402         local node
13403
13404         local ldproc=/proc/fs/ldiskfs
13405         local facets=$(get_facets MDS)
13406
13407         for facet in ${facets//,/ }; do
13408                 canondev=$(ldiskfs_canon \
13409                            *.$(convert_facet2label $facet).mntdev $facet)
13410                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13411                         ldproc=/sys/fs/ldiskfs
13412                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13413                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13414         done
13415 }
13416
13417 check_mds_dmesg() {
13418         local facets=$(get_facets MDS)
13419         for facet in ${facets//,/ }; do
13420                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13421         done
13422         return 1
13423 }
13424
13425 test_129() {
13426         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13427         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13428                 skip "Need MDS version with at least 2.5.56"
13429         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13430                 skip_env "ldiskfs only test"
13431         fi
13432         remote_mds_nodsh && skip "remote MDS with nodsh"
13433
13434         local ENOSPC=28
13435         local has_warning=false
13436
13437         rm -rf $DIR/$tdir
13438         mkdir -p $DIR/$tdir
13439
13440         # block size of mds1
13441         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13442         set_dir_limits $maxsize $((maxsize * 6 / 8))
13443         stack_trap "set_dir_limits 0 0"
13444         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13445         local dirsize=$(stat -c%s "$DIR/$tdir")
13446         local nfiles=0
13447         while (( $dirsize <= $maxsize )); do
13448                 $MCREATE $DIR/$tdir/file_base_$nfiles
13449                 rc=$?
13450                 # check two errors:
13451                 # ENOSPC for ext4 max_dir_size, which has been used since
13452                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13453                 if (( rc == ENOSPC )); then
13454                         set_dir_limits 0 0
13455                         echo "rc=$rc returned as expected after $nfiles files"
13456
13457                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13458                                 error "create failed w/o dir size limit"
13459
13460                         # messages may be rate limited if test is run repeatedly
13461                         check_mds_dmesg '"is approaching max"' ||
13462                                 echo "warning message should be output"
13463                         check_mds_dmesg '"has reached max"' ||
13464                                 echo "reached message should be output"
13465
13466                         dirsize=$(stat -c%s "$DIR/$tdir")
13467
13468                         [[ $dirsize -ge $maxsize ]] && return 0
13469                         error "dirsize $dirsize < $maxsize after $nfiles files"
13470                 elif (( rc != 0 )); then
13471                         break
13472                 fi
13473                 nfiles=$((nfiles + 1))
13474                 dirsize=$(stat -c%s "$DIR/$tdir")
13475         done
13476
13477         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13478 }
13479 run_test 129 "test directory size limit ========================"
13480
13481 OLDIFS="$IFS"
13482 cleanup_130() {
13483         trap 0
13484         IFS="$OLDIFS"
13485 }
13486
13487 test_130a() {
13488         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13489         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13490
13491         trap cleanup_130 EXIT RETURN
13492
13493         local fm_file=$DIR/$tfile
13494         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13495         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13496                 error "dd failed for $fm_file"
13497
13498         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13499         filefrag -ves $fm_file
13500         RC=$?
13501         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13502                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13503         [ $RC != 0 ] && error "filefrag $fm_file failed"
13504
13505         filefrag_op=$(filefrag -ve -k $fm_file |
13506                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13507         lun=$($LFS getstripe -i $fm_file)
13508
13509         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13510         IFS=$'\n'
13511         tot_len=0
13512         for line in $filefrag_op
13513         do
13514                 frag_lun=`echo $line | cut -d: -f5`
13515                 ext_len=`echo $line | cut -d: -f4`
13516                 if (( $frag_lun != $lun )); then
13517                         cleanup_130
13518                         error "FIEMAP on 1-stripe file($fm_file) failed"
13519                         return
13520                 fi
13521                 (( tot_len += ext_len ))
13522         done
13523
13524         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13525                 cleanup_130
13526                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13527                 return
13528         fi
13529
13530         cleanup_130
13531
13532         echo "FIEMAP on single striped file succeeded"
13533 }
13534 run_test 130a "FIEMAP (1-stripe file)"
13535
13536 test_130b() {
13537         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13538
13539         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13540         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13541
13542         trap cleanup_130 EXIT RETURN
13543
13544         local fm_file=$DIR/$tfile
13545         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13546                         error "setstripe on $fm_file"
13547         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13548                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13549
13550         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13551                 error "dd failed on $fm_file"
13552
13553         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13554         filefrag_op=$(filefrag -ve -k $fm_file |
13555                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13556
13557         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13558                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13559
13560         IFS=$'\n'
13561         tot_len=0
13562         num_luns=1
13563         for line in $filefrag_op
13564         do
13565                 frag_lun=$(echo $line | cut -d: -f5 |
13566                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13567                 ext_len=$(echo $line | cut -d: -f4)
13568                 if (( $frag_lun != $last_lun )); then
13569                         if (( tot_len != 1024 )); then
13570                                 cleanup_130
13571                                 error "FIEMAP on $fm_file failed; returned " \
13572                                 "len $tot_len for OST $last_lun instead of 1024"
13573                                 return
13574                         else
13575                                 (( num_luns += 1 ))
13576                                 tot_len=0
13577                         fi
13578                 fi
13579                 (( tot_len += ext_len ))
13580                 last_lun=$frag_lun
13581         done
13582         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13583                 cleanup_130
13584                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13585                         "luns or wrong len for OST $last_lun"
13586                 return
13587         fi
13588
13589         cleanup_130
13590
13591         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13592 }
13593 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13594
13595 test_130c() {
13596         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13597
13598         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13599         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13600
13601         trap cleanup_130 EXIT RETURN
13602
13603         local fm_file=$DIR/$tfile
13604         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13605         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13606                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13607
13608         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13609                         error "dd failed on $fm_file"
13610
13611         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13612         filefrag_op=$(filefrag -ve -k $fm_file |
13613                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13614
13615         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13616                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13617
13618         IFS=$'\n'
13619         tot_len=0
13620         num_luns=1
13621         for line in $filefrag_op
13622         do
13623                 frag_lun=$(echo $line | cut -d: -f5 |
13624                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13625                 ext_len=$(echo $line | cut -d: -f4)
13626                 if (( $frag_lun != $last_lun )); then
13627                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13628                         if (( logical != 512 )); then
13629                                 cleanup_130
13630                                 error "FIEMAP on $fm_file failed; returned " \
13631                                 "logical start for lun $logical instead of 512"
13632                                 return
13633                         fi
13634                         if (( tot_len != 512 )); then
13635                                 cleanup_130
13636                                 error "FIEMAP on $fm_file failed; returned " \
13637                                 "len $tot_len for OST $last_lun instead of 1024"
13638                                 return
13639                         else
13640                                 (( num_luns += 1 ))
13641                                 tot_len=0
13642                         fi
13643                 fi
13644                 (( tot_len += ext_len ))
13645                 last_lun=$frag_lun
13646         done
13647         if (( num_luns != 2 || tot_len != 512 )); then
13648                 cleanup_130
13649                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13650                         "luns or wrong len for OST $last_lun"
13651                 return
13652         fi
13653
13654         cleanup_130
13655
13656         echo "FIEMAP on 2-stripe file with hole succeeded"
13657 }
13658 run_test 130c "FIEMAP (2-stripe file with hole)"
13659
13660 test_130d() {
13661         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13662
13663         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13664         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13665
13666         trap cleanup_130 EXIT RETURN
13667
13668         local fm_file=$DIR/$tfile
13669         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13670                         error "setstripe on $fm_file"
13671         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13672                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13673
13674         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13675         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13676                 error "dd failed on $fm_file"
13677
13678         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13679         filefrag_op=$(filefrag -ve -k $fm_file |
13680                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13681
13682         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13683                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13684
13685         IFS=$'\n'
13686         tot_len=0
13687         num_luns=1
13688         for line in $filefrag_op
13689         do
13690                 frag_lun=$(echo $line | cut -d: -f5 |
13691                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13692                 ext_len=$(echo $line | cut -d: -f4)
13693                 if (( $frag_lun != $last_lun )); then
13694                         if (( tot_len != 1024 )); then
13695                                 cleanup_130
13696                                 error "FIEMAP on $fm_file failed; returned " \
13697                                 "len $tot_len for OST $last_lun instead of 1024"
13698                                 return
13699                         else
13700                                 (( num_luns += 1 ))
13701                                 tot_len=0
13702                         fi
13703                 fi
13704                 (( tot_len += ext_len ))
13705                 last_lun=$frag_lun
13706         done
13707         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13708                 cleanup_130
13709                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13710                         "luns or wrong len for OST $last_lun"
13711                 return
13712         fi
13713
13714         cleanup_130
13715
13716         echo "FIEMAP on N-stripe file succeeded"
13717 }
13718 run_test 130d "FIEMAP (N-stripe file)"
13719
13720 test_130e() {
13721         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13722
13723         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13724         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13725
13726         trap cleanup_130 EXIT RETURN
13727
13728         local fm_file=$DIR/$tfile
13729         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13730
13731         NUM_BLKS=512
13732         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13733         for ((i = 0; i < $NUM_BLKS; i++)); do
13734                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13735                         conv=notrunc > /dev/null 2>&1
13736         done
13737
13738         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13739         filefrag_op=$(filefrag -ve -k $fm_file |
13740                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13741
13742         last_lun=$(echo $filefrag_op | cut -d: -f5)
13743
13744         IFS=$'\n'
13745         tot_len=0
13746         num_luns=1
13747         for line in $filefrag_op; do
13748                 frag_lun=$(echo $line | cut -d: -f5)
13749                 ext_len=$(echo $line | cut -d: -f4)
13750                 if [[ "$frag_lun" != "$last_lun" ]]; then
13751                         if (( tot_len != $EXPECTED_LEN )); then
13752                                 cleanup_130
13753                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13754                         else
13755                                 (( num_luns += 1 ))
13756                                 tot_len=0
13757                         fi
13758                 fi
13759                 (( tot_len += ext_len ))
13760                 last_lun=$frag_lun
13761         done
13762         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
13763                 cleanup_130
13764                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
13765         fi
13766
13767         echo "FIEMAP with continuation calls succeeded"
13768 }
13769 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
13770
13771 test_130f() {
13772         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13773         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13774
13775         local fm_file=$DIR/$tfile
13776         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
13777                 error "multiop create with lov_delay_create on $fm_file"
13778
13779         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13780         filefrag_extents=$(filefrag -vek $fm_file |
13781                            awk '/extents? found/ { print $2 }')
13782         if [[ "$filefrag_extents" != "0" ]]; then
13783                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13784         fi
13785
13786         rm -f $fm_file
13787 }
13788 run_test 130f "FIEMAP (unstriped file)"
13789
13790 test_130g() {
13791         local file=$DIR/$tfile
13792         local nr=$((OSTCOUNT * 100))
13793
13794         $LFS setstripe -C $nr $file ||
13795                 error "failed to setstripe -C $nr $file"
13796
13797         dd if=/dev/zero of=$file count=$nr bs=1M
13798         sync
13799         nr=$($LFS getstripe -c $file)
13800
13801         local extents=$(filefrag -v $file |
13802                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13803
13804         echo "filefrag list $extents extents in file with stripecount $nr"
13805         if (( extents < nr )); then
13806                 $LFS getstripe $file
13807                 filefrag -v $file
13808                 error "filefrag printed $extents < $nr extents"
13809         fi
13810
13811         rm -f $file
13812 }
13813 run_test 130g "FIEMAP (overstripe file)"
13814
13815 # Test for writev/readv
13816 test_131a() {
13817         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
13818                 error "writev test failed"
13819         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
13820                 error "readv failed"
13821         rm -f $DIR/$tfile
13822 }
13823 run_test 131a "test iov's crossing stripe boundary for writev/readv"
13824
13825 test_131b() {
13826         local fsize=$((524288 + 1048576 + 1572864))
13827         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
13828                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13829                         error "append writev test failed"
13830
13831         ((fsize += 1572864 + 1048576))
13832         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13833                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13834                         error "append writev test failed"
13835         rm -f $DIR/$tfile
13836 }
13837 run_test 131b "test append writev"
13838
13839 test_131c() {
13840         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13841         error "NOT PASS"
13842 }
13843 run_test 131c "test read/write on file w/o objects"
13844
13845 test_131d() {
13846         rwv -f $DIR/$tfile -w -n 1 1572864
13847         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13848         if [ "$NOB" != 1572864 ]; then
13849                 error "Short read filed: read $NOB bytes instead of 1572864"
13850         fi
13851         rm -f $DIR/$tfile
13852 }
13853 run_test 131d "test short read"
13854
13855 test_131e() {
13856         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13857         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13858         error "read hitting hole failed"
13859         rm -f $DIR/$tfile
13860 }
13861 run_test 131e "test read hitting hole"
13862
13863 check_stats() {
13864         local facet=$1
13865         local op=$2
13866         local want=${3:-0}
13867         local res
13868
13869         case $facet in
13870         mds*) res=$(do_facet $facet \
13871                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
13872                  ;;
13873         ost*) res=$(do_facet $facet \
13874                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
13875                  ;;
13876         *) error "Wrong facet '$facet'" ;;
13877         esac
13878         [ "$res" ] || error "The counter for $op on $facet was not incremented"
13879         # if the argument $3 is zero, it means any stat increment is ok.
13880         if [[ $want -gt 0 ]]; then
13881                 local count=$(echo $res | awk '{ print $2 }')
13882                 [[ $count -ne $want ]] &&
13883                         error "The $op counter on $facet is $count, not $want"
13884         fi
13885 }
13886
13887 test_133a() {
13888         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13889         remote_ost_nodsh && skip "remote OST with nodsh"
13890         remote_mds_nodsh && skip "remote MDS with nodsh"
13891         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13892                 skip_env "MDS doesn't support rename stats"
13893
13894         local testdir=$DIR/${tdir}/stats_testdir
13895
13896         mkdir -p $DIR/${tdir}
13897
13898         # clear stats.
13899         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13900         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13901
13902         # verify mdt stats first.
13903         mkdir ${testdir} || error "mkdir failed"
13904         check_stats $SINGLEMDS "mkdir" 1
13905         touch ${testdir}/${tfile} || error "touch failed"
13906         check_stats $SINGLEMDS "open" 1
13907         check_stats $SINGLEMDS "close" 1
13908         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
13909                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
13910                 check_stats $SINGLEMDS "mknod" 2
13911         }
13912         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
13913         check_stats $SINGLEMDS "unlink" 1
13914         rm -f ${testdir}/${tfile} || error "file remove failed"
13915         check_stats $SINGLEMDS "unlink" 2
13916
13917         # remove working dir and check mdt stats again.
13918         rmdir ${testdir} || error "rmdir failed"
13919         check_stats $SINGLEMDS "rmdir" 1
13920
13921         local testdir1=$DIR/${tdir}/stats_testdir1
13922         mkdir -p ${testdir}
13923         mkdir -p ${testdir1}
13924         touch ${testdir1}/test1
13925         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
13926         check_stats $SINGLEMDS "crossdir_rename" 1
13927
13928         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
13929         check_stats $SINGLEMDS "samedir_rename" 1
13930
13931         rm -rf $DIR/${tdir}
13932 }
13933 run_test 133a "Verifying MDT stats ========================================"
13934
13935 test_133b() {
13936         local res
13937
13938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13939         remote_ost_nodsh && skip "remote OST with nodsh"
13940         remote_mds_nodsh && skip "remote MDS with nodsh"
13941
13942         local testdir=$DIR/${tdir}/stats_testdir
13943
13944         mkdir -p ${testdir} || error "mkdir failed"
13945         touch ${testdir}/${tfile} || error "touch failed"
13946         cancel_lru_locks mdc
13947
13948         # clear stats.
13949         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13950         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13951
13952         # extra mdt stats verification.
13953         chmod 444 ${testdir}/${tfile} || error "chmod failed"
13954         check_stats $SINGLEMDS "setattr" 1
13955         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13956         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
13957         then            # LU-1740
13958                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
13959                 check_stats $SINGLEMDS "getattr" 1
13960         fi
13961         rm -rf $DIR/${tdir}
13962
13963         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
13964         # so the check below is not reliable
13965         [ $MDSCOUNT -eq 1 ] || return 0
13966
13967         # Sleep to avoid a cached response.
13968         #define OBD_STATFS_CACHE_SECONDS 1
13969         sleep 2
13970         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13971         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13972         $LFS df || error "lfs failed"
13973         check_stats $SINGLEMDS "statfs" 1
13974
13975         # check aggregated statfs (LU-10018)
13976         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
13977                 return 0
13978         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
13979                 return 0
13980         sleep 2
13981         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13982         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13983         df $DIR
13984         check_stats $SINGLEMDS "statfs" 1
13985
13986         # We want to check that the client didn't send OST_STATFS to
13987         # ost1 but the MDT also uses OST_STATFS for precreate. So some
13988         # extra care is needed here.
13989         if remote_mds; then
13990                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
13991                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
13992
13993                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
13994                 [ "$res" ] && error "OST got STATFS"
13995         fi
13996
13997         return 0
13998 }
13999 run_test 133b "Verifying extra MDT stats =================================="
14000
14001 test_133c() {
14002         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14003         remote_ost_nodsh && skip "remote OST with nodsh"
14004         remote_mds_nodsh && skip "remote MDS with nodsh"
14005
14006         local testdir=$DIR/$tdir/stats_testdir
14007
14008         test_mkdir -p $testdir
14009
14010         # verify obdfilter stats.
14011         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14012         sync
14013         cancel_lru_locks osc
14014         wait_delete_completed
14015
14016         # clear stats.
14017         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14018         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14019
14020         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14021                 error "dd failed"
14022         sync
14023         cancel_lru_locks osc
14024         check_stats ost1 "write" 1
14025
14026         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14027         check_stats ost1 "read" 1
14028
14029         > $testdir/$tfile || error "truncate failed"
14030         check_stats ost1 "punch" 1
14031
14032         rm -f $testdir/$tfile || error "file remove failed"
14033         wait_delete_completed
14034         check_stats ost1 "destroy" 1
14035
14036         rm -rf $DIR/$tdir
14037 }
14038 run_test 133c "Verifying OST stats ========================================"
14039
14040 order_2() {
14041         local value=$1
14042         local orig=$value
14043         local order=1
14044
14045         while [ $value -ge 2 ]; do
14046                 order=$((order*2))
14047                 value=$((value/2))
14048         done
14049
14050         if [ $orig -gt $order ]; then
14051                 order=$((order*2))
14052         fi
14053         echo $order
14054 }
14055
14056 size_in_KMGT() {
14057     local value=$1
14058     local size=('K' 'M' 'G' 'T');
14059     local i=0
14060     local size_string=$value
14061
14062     while [ $value -ge 1024 ]; do
14063         if [ $i -gt 3 ]; then
14064             #T is the biggest unit we get here, if that is bigger,
14065             #just return XXXT
14066             size_string=${value}T
14067             break
14068         fi
14069         value=$((value >> 10))
14070         if [ $value -lt 1024 ]; then
14071             size_string=${value}${size[$i]}
14072             break
14073         fi
14074         i=$((i + 1))
14075     done
14076
14077     echo $size_string
14078 }
14079
14080 get_rename_size() {
14081         local size=$1
14082         local context=${2:-.}
14083         local sample=$(do_facet $SINGLEMDS $LCTL \
14084                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14085                 grep -A1 $context |
14086                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14087         echo $sample
14088 }
14089
14090 test_133d() {
14091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14092         remote_ost_nodsh && skip "remote OST with nodsh"
14093         remote_mds_nodsh && skip "remote MDS with nodsh"
14094         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14095                 skip_env "MDS doesn't support rename stats"
14096
14097         local testdir1=$DIR/${tdir}/stats_testdir1
14098         local testdir2=$DIR/${tdir}/stats_testdir2
14099         mkdir -p $DIR/${tdir}
14100
14101         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14102
14103         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
14104         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
14105
14106         createmany -o $testdir1/test 512 || error "createmany failed"
14107
14108         # check samedir rename size
14109         mv ${testdir1}/test0 ${testdir1}/test_0
14110
14111         local testdir1_size=$(ls -l $DIR/${tdir} |
14112                 awk '/stats_testdir1/ {print $5}')
14113         local testdir2_size=$(ls -l $DIR/${tdir} |
14114                 awk '/stats_testdir2/ {print $5}')
14115
14116         testdir1_size=$(order_2 $testdir1_size)
14117         testdir2_size=$(order_2 $testdir2_size)
14118
14119         testdir1_size=$(size_in_KMGT $testdir1_size)
14120         testdir2_size=$(size_in_KMGT $testdir2_size)
14121
14122         echo "source rename dir size: ${testdir1_size}"
14123         echo "target rename dir size: ${testdir2_size}"
14124
14125         local cmd="do_facet $SINGLEMDS $LCTL "
14126         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14127
14128         eval $cmd || error "$cmd failed"
14129         local samedir=$($cmd | grep 'same_dir')
14130         local same_sample=$(get_rename_size $testdir1_size)
14131         [ -z "$samedir" ] && error "samedir_rename_size count error"
14132         [[ $same_sample -eq 1 ]] ||
14133                 error "samedir_rename_size error $same_sample"
14134         echo "Check same dir rename stats success"
14135
14136         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14137
14138         # check crossdir rename size
14139         mv ${testdir1}/test_0 ${testdir2}/test_0
14140
14141         testdir1_size=$(ls -l $DIR/${tdir} |
14142                 awk '/stats_testdir1/ {print $5}')
14143         testdir2_size=$(ls -l $DIR/${tdir} |
14144                 awk '/stats_testdir2/ {print $5}')
14145
14146         testdir1_size=$(order_2 $testdir1_size)
14147         testdir2_size=$(order_2 $testdir2_size)
14148
14149         testdir1_size=$(size_in_KMGT $testdir1_size)
14150         testdir2_size=$(size_in_KMGT $testdir2_size)
14151
14152         echo "source rename dir size: ${testdir1_size}"
14153         echo "target rename dir size: ${testdir2_size}"
14154
14155         eval $cmd || error "$cmd failed"
14156         local crossdir=$($cmd | grep 'crossdir')
14157         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14158         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14159         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14160         [[ $src_sample -eq 1 ]] ||
14161                 error "crossdir_rename_size error $src_sample"
14162         [[ $tgt_sample -eq 1 ]] ||
14163                 error "crossdir_rename_size error $tgt_sample"
14164         echo "Check cross dir rename stats success"
14165         rm -rf $DIR/${tdir}
14166 }
14167 run_test 133d "Verifying rename_stats ========================================"
14168
14169 test_133e() {
14170         remote_mds_nodsh && skip "remote MDS with nodsh"
14171         remote_ost_nodsh && skip "remote OST with nodsh"
14172         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14173
14174         local testdir=$DIR/${tdir}/stats_testdir
14175         local ctr f0 f1 bs=32768 count=42 sum
14176
14177         mkdir -p ${testdir} || error "mkdir failed"
14178
14179         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14180
14181         for ctr in {write,read}_bytes; do
14182                 sync
14183                 cancel_lru_locks osc
14184
14185                 do_facet ost1 $LCTL set_param -n \
14186                         "obdfilter.*.exports.clear=clear"
14187
14188                 if [ $ctr = write_bytes ]; then
14189                         f0=/dev/zero
14190                         f1=${testdir}/${tfile}
14191                 else
14192                         f0=${testdir}/${tfile}
14193                         f1=/dev/null
14194                 fi
14195
14196                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14197                         error "dd failed"
14198                 sync
14199                 cancel_lru_locks osc
14200
14201                 sum=$(do_facet ost1 $LCTL get_param \
14202                         "obdfilter.*.exports.*.stats" |
14203                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14204                                 $1 == ctr { sum += $7 }
14205                                 END { printf("%0.0f", sum) }')
14206
14207                 if ((sum != bs * count)); then
14208                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14209                 fi
14210         done
14211
14212         rm -rf $DIR/${tdir}
14213 }
14214 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14215
14216 test_133f() {
14217         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14218                 skip "too old lustre for get_param -R ($facet_ver)"
14219
14220         # verifying readability.
14221         $LCTL get_param -R '*' &> /dev/null
14222
14223         # Verifing writability with badarea_io.
14224         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14225         local skipped_params='force_lbug|changelog_mask|daemon_file'
14226         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14227                 egrep -v "$skipped_params" |
14228                 xargs -n 1 find $proc_dirs -name |
14229                 xargs -n 1 badarea_io ||
14230                 error "client badarea_io failed"
14231
14232         # remount the FS in case writes/reads /proc break the FS
14233         cleanup || error "failed to unmount"
14234         setup || error "failed to setup"
14235 }
14236 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14237
14238 test_133g() {
14239         remote_mds_nodsh && skip "remote MDS with nodsh"
14240         remote_ost_nodsh && skip "remote OST with nodsh"
14241
14242         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14243         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14244         local facet
14245         for facet in mds1 ost1; do
14246                 local facet_ver=$(lustre_version_code $facet)
14247                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14248                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14249                 else
14250                         log "$facet: too old lustre for get_param -R"
14251                 fi
14252                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14253                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14254                                 tr -d = | egrep -v $skipped_params |
14255                                 xargs -n 1 find $proc_dirs -name |
14256                                 xargs -n 1 badarea_io" ||
14257                                         error "$facet badarea_io failed"
14258                 else
14259                         skip_noexit "$facet: too old lustre for get_param -R"
14260                 fi
14261         done
14262
14263         # remount the FS in case writes/reads /proc break the FS
14264         cleanup || error "failed to unmount"
14265         setup || error "failed to setup"
14266 }
14267 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14268
14269 test_133h() {
14270         remote_mds_nodsh && skip "remote MDS with nodsh"
14271         remote_ost_nodsh && skip "remote OST with nodsh"
14272         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14273                 skip "Need MDS version at least 2.9.54"
14274
14275         local facet
14276         for facet in client mds1 ost1; do
14277                 # Get the list of files that are missing the terminating newline
14278                 local plist=$(do_facet $facet
14279                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14280                 local ent
14281                 for ent in $plist; do
14282                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14283                                 awk -v FS='\v' -v RS='\v\v' \
14284                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14285                                         print FILENAME}'" 2>/dev/null)
14286                         [ -z $missing ] || {
14287                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14288                                 error "file does not end with newline: $facet-$ent"
14289                         }
14290                 done
14291         done
14292 }
14293 run_test 133h "Proc files should end with newlines"
14294
14295 test_134a() {
14296         remote_mds_nodsh && skip "remote MDS with nodsh"
14297         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14298                 skip "Need MDS version at least 2.7.54"
14299
14300         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14301         cancel_lru_locks mdc
14302
14303         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14304         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14305         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14306
14307         local nr=1000
14308         createmany -o $DIR/$tdir/f $nr ||
14309                 error "failed to create $nr files in $DIR/$tdir"
14310         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14311
14312         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14313         do_facet mds1 $LCTL set_param fail_loc=0x327
14314         do_facet mds1 $LCTL set_param fail_val=500
14315         touch $DIR/$tdir/m
14316
14317         echo "sleep 10 seconds ..."
14318         sleep 10
14319         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14320
14321         do_facet mds1 $LCTL set_param fail_loc=0
14322         do_facet mds1 $LCTL set_param fail_val=0
14323         [ $lck_cnt -lt $unused ] ||
14324                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14325
14326         rm $DIR/$tdir/m
14327         unlinkmany $DIR/$tdir/f $nr
14328 }
14329 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14330
14331 test_134b() {
14332         remote_mds_nodsh && skip "remote MDS with nodsh"
14333         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14334                 skip "Need MDS version at least 2.7.54"
14335
14336         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14337         cancel_lru_locks mdc
14338
14339         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14340                         ldlm.lock_reclaim_threshold_mb)
14341         # disable reclaim temporarily
14342         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14343
14344         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14345         do_facet mds1 $LCTL set_param fail_loc=0x328
14346         do_facet mds1 $LCTL set_param fail_val=500
14347
14348         $LCTL set_param debug=+trace
14349
14350         local nr=600
14351         createmany -o $DIR/$tdir/f $nr &
14352         local create_pid=$!
14353
14354         echo "Sleep $TIMEOUT seconds ..."
14355         sleep $TIMEOUT
14356         if ! ps -p $create_pid  > /dev/null 2>&1; then
14357                 do_facet mds1 $LCTL set_param fail_loc=0
14358                 do_facet mds1 $LCTL set_param fail_val=0
14359                 do_facet mds1 $LCTL set_param \
14360                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14361                 error "createmany finished incorrectly!"
14362         fi
14363         do_facet mds1 $LCTL set_param fail_loc=0
14364         do_facet mds1 $LCTL set_param fail_val=0
14365         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14366         wait $create_pid || return 1
14367
14368         unlinkmany $DIR/$tdir/f $nr
14369 }
14370 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14371
14372 test_135() {
14373         remote_mds_nodsh && skip "remote MDS with nodsh"
14374         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14375                 skip "Need MDS version at least 2.13.50"
14376         local fname
14377
14378         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14379
14380 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14381         #set only one record at plain llog
14382         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14383
14384         #fill already existed plain llog each 64767
14385         #wrapping whole catalog
14386         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14387
14388         createmany -o $DIR/$tdir/$tfile_ 64700
14389         for (( i = 0; i < 64700; i = i + 2 ))
14390         do
14391                 rm $DIR/$tdir/$tfile_$i &
14392                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14393                 local pid=$!
14394                 wait $pid
14395         done
14396
14397         #waiting osp synchronization
14398         wait_delete_completed
14399 }
14400 run_test 135 "Race catalog processing"
14401
14402 test_136() {
14403         remote_mds_nodsh && skip "remote MDS with nodsh"
14404         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14405                 skip "Need MDS version at least 2.13.50"
14406         local fname
14407
14408         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14409         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14410         #set only one record at plain llog
14411 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14412         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14413
14414         #fill already existed 2 plain llogs each 64767
14415         #wrapping whole catalog
14416         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14417         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14418         wait_delete_completed
14419
14420         createmany -o $DIR/$tdir/$tfile_ 10
14421         sleep 25
14422
14423         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14424         for (( i = 0; i < 10; i = i + 3 ))
14425         do
14426                 rm $DIR/$tdir/$tfile_$i &
14427                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14428                 local pid=$!
14429                 wait $pid
14430                 sleep 7
14431                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14432         done
14433
14434         #waiting osp synchronization
14435         wait_delete_completed
14436 }
14437 run_test 136 "Race catalog processing 2"
14438
14439 test_140() { #bug-17379
14440         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14441
14442         test_mkdir $DIR/$tdir
14443         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14444         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14445
14446         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14447         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14448         local i=0
14449         while i=$((i + 1)); do
14450                 test_mkdir $i
14451                 cd $i || error "Changing to $i"
14452                 ln -s ../stat stat || error "Creating stat symlink"
14453                 # Read the symlink until ELOOP present,
14454                 # not LBUGing the system is considered success,
14455                 # we didn't overrun the stack.
14456                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14457                 if [ $ret -ne 0 ]; then
14458                         if [ $ret -eq 40 ]; then
14459                                 break  # -ELOOP
14460                         else
14461                                 error "Open stat symlink"
14462                                         return
14463                         fi
14464                 fi
14465         done
14466         i=$((i - 1))
14467         echo "The symlink depth = $i"
14468         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14469                 error "Invalid symlink depth"
14470
14471         # Test recursive symlink
14472         ln -s symlink_self symlink_self
14473         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14474         echo "open symlink_self returns $ret"
14475         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14476 }
14477 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14478
14479 test_150a() {
14480         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14481
14482         local TF="$TMP/$tfile"
14483
14484         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14485         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14486         cp $TF $DIR/$tfile
14487         cancel_lru_locks $OSC
14488         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14489         remount_client $MOUNT
14490         df -P $MOUNT
14491         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14492
14493         $TRUNCATE $TF 6000
14494         $TRUNCATE $DIR/$tfile 6000
14495         cancel_lru_locks $OSC
14496         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14497
14498         echo "12345" >>$TF
14499         echo "12345" >>$DIR/$tfile
14500         cancel_lru_locks $OSC
14501         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14502
14503         echo "12345" >>$TF
14504         echo "12345" >>$DIR/$tfile
14505         cancel_lru_locks $OSC
14506         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14507 }
14508 run_test 150a "truncate/append tests"
14509
14510 test_150b() {
14511         check_set_fallocate_or_skip
14512
14513         touch $DIR/$tfile
14514         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14515         check_fallocate $DIR/$tfile || error "fallocate failed"
14516 }
14517 run_test 150b "Verify fallocate (prealloc) functionality"
14518
14519 test_150bb() {
14520         check_set_fallocate_or_skip
14521
14522         touch $DIR/$tfile
14523         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14524         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14525         > $DIR/$tfile
14526         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14527         # precomputed md5sum for 20MB of zeroes
14528         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14529         local sum=($(md5sum $DIR/$tfile))
14530
14531         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14532
14533         check_set_fallocate 1
14534
14535         > $DIR/$tfile
14536         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14537         sum=($(md5sum $DIR/$tfile))
14538
14539         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14540 }
14541 run_test 150bb "Verify fallocate modes both zero space"
14542
14543 test_150c() {
14544         check_set_fallocate_or_skip
14545         local striping="-c2"
14546
14547         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14548         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14549         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14550         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14551         local want=$((OSTCOUNT * 1048576))
14552
14553         # Must allocate all requested space, not more than 5% extra
14554         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14555                 error "bytes $bytes is not $want"
14556
14557         rm -f $DIR/$tfile
14558
14559         echo "verify fallocate on PFL file"
14560
14561         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14562
14563         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14564                 error "Create $DIR/$tfile failed"
14565         fallocate -l $((1048576 * 512)) $DIR/$tfile ||
14566                         error "fallocate failed"
14567         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14568         want=$((512 * 1048576))
14569
14570         # Must allocate all requested space, not more than 5% extra
14571         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14572                 error "bytes $bytes is not $want"
14573 }
14574 run_test 150c "Verify fallocate Size and Blocks"
14575
14576 test_150d() {
14577         check_set_fallocate_or_skip
14578         local striping="-c2"
14579
14580         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14581
14582         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14583         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
14584                 error "setstripe failed"
14585         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14586         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14587         local want=$((OSTCOUNT * 1048576))
14588
14589         # Must allocate all requested space, not more than 5% extra
14590         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14591                 error "bytes $bytes is not $want"
14592 }
14593 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14594
14595 test_150e() {
14596         check_set_fallocate_or_skip
14597
14598         echo "df before:"
14599         $LFS df
14600         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14601         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14602                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14603
14604         # Find OST with Minimum Size
14605         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14606                        sort -un | head -1)
14607
14608         # Get 100MB per OST of the available space to reduce run time
14609         # else 60% of the available space if we are running SLOW tests
14610         if [ $SLOW == "no" ]; then
14611                 local space=$((1024 * 100 * OSTCOUNT))
14612         else
14613                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14614         fi
14615
14616         fallocate -l${space}k $DIR/$tfile ||
14617                 error "fallocate ${space}k $DIR/$tfile failed"
14618         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14619
14620         # get size immediately after fallocate. This should be correctly
14621         # updated
14622         local size=$(stat -c '%s' $DIR/$tfile)
14623         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14624
14625         # Sleep for a while for statfs to get updated. And not pull from cache.
14626         sleep 2
14627
14628         echo "df after fallocate:"
14629         $LFS df
14630
14631         (( size / 1024 == space )) || error "size $size != requested $space"
14632         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14633                 error "used $used < space $space"
14634
14635         rm $DIR/$tfile || error "rm failed"
14636         sync
14637         wait_delete_completed
14638
14639         echo "df after unlink:"
14640         $LFS df
14641 }
14642 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14643
14644 test_150f() {
14645         local size
14646         local blocks
14647         local want_size_before=20480 # in bytes
14648         local want_blocks_before=40 # 512 sized blocks
14649         local want_blocks_after=24  # 512 sized blocks
14650         local length=$(((want_blocks_before - want_blocks_after) * 512))
14651
14652         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14653                 skip "need at least 2.14.0 for fallocate punch"
14654
14655         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14656                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14657         fi
14658
14659         check_set_fallocate_or_skip
14660         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14661
14662         [[ "x$DOM" == "xyes" ]] &&
14663                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
14664
14665         echo "Verify fallocate punch: Range within the file range"
14666         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14667                 error "dd failed for bs 4096 and count 5"
14668
14669         # Call fallocate with punch range which is within the file range
14670         fallocate -p --offset 4096 -l $length $DIR/$tfile ||
14671                 error "fallocate failed: offset 4096 and length $length"
14672         # client must see changes immediately after fallocate
14673         size=$(stat -c '%s' $DIR/$tfile)
14674         blocks=$(stat -c '%b' $DIR/$tfile)
14675
14676         # Verify punch worked.
14677         (( blocks == want_blocks_after )) ||
14678                 error "punch failed: blocks $blocks != $want_blocks_after"
14679
14680         (( size == want_size_before )) ||
14681                 error "punch failed: size $size != $want_size_before"
14682
14683         # Verify there is hole in file
14684         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14685         # precomputed md5sum
14686         local expect="4a9a834a2db02452929c0a348273b4aa"
14687
14688         cksum=($(md5sum $DIR/$tfile))
14689         [[ "${cksum[0]}" == "$expect" ]] ||
14690                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14691
14692         # Start second sub-case for fallocate punch.
14693         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14694         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14695                 error "dd failed for bs 4096 and count 5"
14696
14697         # Punch range less than block size will have no change in block count
14698         want_blocks_after=40  # 512 sized blocks
14699
14700         # Punch overlaps two blocks and less than blocksize
14701         fallocate -p --offset 4000 -l 3000 $DIR/$tfile ||
14702                 error "fallocate failed: offset 4000 length 3000"
14703         size=$(stat -c '%s' $DIR/$tfile)
14704         blocks=$(stat -c '%b' $DIR/$tfile)
14705
14706         # Verify punch worked.
14707         (( blocks == want_blocks_after )) ||
14708                 error "punch failed: blocks $blocks != $want_blocks_after"
14709
14710         (( size == want_size_before )) ||
14711                 error "punch failed: size $size != $want_size_before"
14712
14713         # Verify if range is really zero'ed out. We expect Zeros.
14714         # precomputed md5sum
14715         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14716         cksum=($(md5sum $DIR/$tfile))
14717         [[ "${cksum[0]}" == "$expect" ]] ||
14718                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14719 }
14720 run_test 150f "Verify fallocate punch functionality"
14721
14722 test_150g() {
14723         local space
14724         local size
14725         local blocks
14726         local blocks_after
14727         local size_after
14728         local BS=4096 # Block size in bytes
14729
14730         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14731                 skip "need at least 2.14.0 for fallocate punch"
14732
14733         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14734                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14735         fi
14736
14737         check_set_fallocate_or_skip
14738         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14739
14740         if [[ "x$DOM" == "xyes" ]]; then
14741                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
14742                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
14743         else
14744                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14745                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14746         fi
14747
14748         # Get 100MB per OST of the available space to reduce run time
14749         # else 60% of the available space if we are running SLOW tests
14750         if [ $SLOW == "no" ]; then
14751                 space=$((1024 * 100 * OSTCOUNT))
14752         else
14753                 # Find OST with Minimum Size
14754                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14755                         sort -un | head -1)
14756                 echo "min size OST: $space"
14757                 space=$(((space * 60)/100 * OSTCOUNT))
14758         fi
14759         # space in 1k units, round to 4k blocks
14760         local blkcount=$((space * 1024 / $BS))
14761
14762         echo "Verify fallocate punch: Very large Range"
14763         fallocate -l${space}k $DIR/$tfile ||
14764                 error "fallocate ${space}k $DIR/$tfile failed"
14765         # write 1M at the end, start and in the middle
14766         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
14767                 error "dd failed: bs $BS count 256"
14768         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
14769                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
14770         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
14771                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
14772
14773         # Gather stats.
14774         size=$(stat -c '%s' $DIR/$tfile)
14775
14776         # gather punch length.
14777         local punch_size=$((size - (BS * 2)))
14778
14779         echo "punch_size = $punch_size"
14780         echo "size - punch_size: $((size - punch_size))"
14781         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
14782
14783         # Call fallocate to punch all except 2 blocks. We leave the
14784         # first and the last block
14785         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
14786         fallocate -p --offset $BS -l $punch_size $DIR/$tfile ||
14787                 error "fallocate failed: offset $BS length $punch_size"
14788
14789         size_after=$(stat -c '%s' $DIR/$tfile)
14790         blocks_after=$(stat -c '%b' $DIR/$tfile)
14791
14792         # Verify punch worked.
14793         # Size should be kept
14794         (( size == size_after )) ||
14795                 error "punch failed: size $size != $size_after"
14796
14797         # two 4k data blocks to remain plus possible 1 extra extent block
14798         (( blocks_after <= ((BS / 512) * 3) )) ||
14799                 error "too many blocks remains: $blocks_after"
14800
14801         # Verify that file has hole between the first and the last blocks
14802         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
14803         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
14804
14805         echo "Hole at [$hole_start, $hole_end)"
14806         (( hole_start == BS )) ||
14807                 error "no hole at offset $BS after punch"
14808
14809         (( hole_end == BS + punch_size )) ||
14810                 error "data at offset $hole_end < $((BS + punch_size))"
14811 }
14812 run_test 150g "Verify fallocate punch on large range"
14813
14814 #LU-2902 roc_hit was not able to read all values from lproc
14815 function roc_hit_init() {
14816         local list=$(comma_list $(osts_nodes))
14817         local dir=$DIR/$tdir-check
14818         local file=$dir/$tfile
14819         local BEFORE
14820         local AFTER
14821         local idx
14822
14823         test_mkdir $dir
14824         #use setstripe to do a write to every ost
14825         for i in $(seq 0 $((OSTCOUNT-1))); do
14826                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
14827                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
14828                 idx=$(printf %04x $i)
14829                 BEFORE=$(get_osd_param $list *OST*$idx stats |
14830                         awk '$1 == "cache_access" {sum += $7}
14831                                 END { printf("%0.0f", sum) }')
14832
14833                 cancel_lru_locks osc
14834                 cat $file >/dev/null
14835
14836                 AFTER=$(get_osd_param $list *OST*$idx stats |
14837                         awk '$1 == "cache_access" {sum += $7}
14838                                 END { printf("%0.0f", sum) }')
14839
14840                 echo BEFORE:$BEFORE AFTER:$AFTER
14841                 if ! let "AFTER - BEFORE == 4"; then
14842                         rm -rf $dir
14843                         error "roc_hit is not safe to use"
14844                 fi
14845                 rm $file
14846         done
14847
14848         rm -rf $dir
14849 }
14850
14851 function roc_hit() {
14852         local list=$(comma_list $(osts_nodes))
14853         echo $(get_osd_param $list '' stats |
14854                 awk '$1 == "cache_hit" {sum += $7}
14855                         END { printf("%0.0f", sum) }')
14856 }
14857
14858 function set_cache() {
14859         local on=1
14860
14861         if [ "$2" == "off" ]; then
14862                 on=0;
14863         fi
14864         local list=$(comma_list $(osts_nodes))
14865         set_osd_param $list '' $1_cache_enable $on
14866
14867         cancel_lru_locks osc
14868 }
14869
14870 test_151() {
14871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14872         remote_ost_nodsh && skip "remote OST with nodsh"
14873
14874         local CPAGES=3
14875         local list=$(comma_list $(osts_nodes))
14876
14877         # check whether obdfilter is cache capable at all
14878         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
14879                 skip "not cache-capable obdfilter"
14880         fi
14881
14882         # check cache is enabled on all obdfilters
14883         if get_osd_param $list '' read_cache_enable | grep 0; then
14884                 skip "oss cache is disabled"
14885         fi
14886
14887         set_osd_param $list '' writethrough_cache_enable 1
14888
14889         # check write cache is enabled on all obdfilters
14890         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
14891                 skip "oss write cache is NOT enabled"
14892         fi
14893
14894         roc_hit_init
14895
14896         #define OBD_FAIL_OBD_NO_LRU  0x609
14897         do_nodes $list $LCTL set_param fail_loc=0x609
14898
14899         # pages should be in the case right after write
14900         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
14901                 error "dd failed"
14902
14903         local BEFORE=$(roc_hit)
14904         cancel_lru_locks osc
14905         cat $DIR/$tfile >/dev/null
14906         local AFTER=$(roc_hit)
14907
14908         do_nodes $list $LCTL set_param fail_loc=0
14909
14910         if ! let "AFTER - BEFORE == CPAGES"; then
14911                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
14912         fi
14913
14914         cancel_lru_locks osc
14915         # invalidates OST cache
14916         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
14917         set_osd_param $list '' read_cache_enable 0
14918         cat $DIR/$tfile >/dev/null
14919
14920         # now data shouldn't be found in the cache
14921         BEFORE=$(roc_hit)
14922         cancel_lru_locks osc
14923         cat $DIR/$tfile >/dev/null
14924         AFTER=$(roc_hit)
14925         if let "AFTER - BEFORE != 0"; then
14926                 error "IN CACHE: before: $BEFORE, after: $AFTER"
14927         fi
14928
14929         set_osd_param $list '' read_cache_enable 1
14930         rm -f $DIR/$tfile
14931 }
14932 run_test 151 "test cache on oss and controls ==============================="
14933
14934 test_152() {
14935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14936
14937         local TF="$TMP/$tfile"
14938
14939         # simulate ENOMEM during write
14940 #define OBD_FAIL_OST_NOMEM      0x226
14941         lctl set_param fail_loc=0x80000226
14942         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14943         cp $TF $DIR/$tfile
14944         sync || error "sync failed"
14945         lctl set_param fail_loc=0
14946
14947         # discard client's cache
14948         cancel_lru_locks osc
14949
14950         # simulate ENOMEM during read
14951         lctl set_param fail_loc=0x80000226
14952         cmp $TF $DIR/$tfile || error "cmp failed"
14953         lctl set_param fail_loc=0
14954
14955         rm -f $TF
14956 }
14957 run_test 152 "test read/write with enomem ============================"
14958
14959 test_153() {
14960         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
14961 }
14962 run_test 153 "test if fdatasync does not crash ======================="
14963
14964 dot_lustre_fid_permission_check() {
14965         local fid=$1
14966         local ffid=$MOUNT/.lustre/fid/$fid
14967         local test_dir=$2
14968
14969         echo "stat fid $fid"
14970         stat $ffid > /dev/null || error "stat $ffid failed."
14971         echo "touch fid $fid"
14972         touch $ffid || error "touch $ffid failed."
14973         echo "write to fid $fid"
14974         cat /etc/hosts > $ffid || error "write $ffid failed."
14975         echo "read fid $fid"
14976         diff /etc/hosts $ffid || error "read $ffid failed."
14977         echo "append write to fid $fid"
14978         cat /etc/hosts >> $ffid || error "append write $ffid failed."
14979         echo "rename fid $fid"
14980         mv $ffid $test_dir/$tfile.1 &&
14981                 error "rename $ffid to $tfile.1 should fail."
14982         touch $test_dir/$tfile.1
14983         mv $test_dir/$tfile.1 $ffid &&
14984                 error "rename $tfile.1 to $ffid should fail."
14985         rm -f $test_dir/$tfile.1
14986         echo "truncate fid $fid"
14987         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
14988         echo "link fid $fid"
14989         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
14990         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
14991                 echo "setfacl fid $fid"
14992                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
14993                 echo "getfacl fid $fid"
14994                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
14995         fi
14996         echo "unlink fid $fid"
14997         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
14998         echo "mknod fid $fid"
14999         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15000
15001         fid=[0xf00000400:0x1:0x0]
15002         ffid=$MOUNT/.lustre/fid/$fid
15003
15004         echo "stat non-exist fid $fid"
15005         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15006         echo "write to non-exist fid $fid"
15007         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15008         echo "link new fid $fid"
15009         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15010
15011         mkdir -p $test_dir/$tdir
15012         touch $test_dir/$tdir/$tfile
15013         fid=$($LFS path2fid $test_dir/$tdir)
15014         rc=$?
15015         [ $rc -ne 0 ] &&
15016                 error "error: could not get fid for $test_dir/$dir/$tfile."
15017
15018         ffid=$MOUNT/.lustre/fid/$fid
15019
15020         echo "ls $fid"
15021         ls $ffid > /dev/null || error "ls $ffid failed."
15022         echo "touch $fid/$tfile.1"
15023         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15024
15025         echo "touch $MOUNT/.lustre/fid/$tfile"
15026         touch $MOUNT/.lustre/fid/$tfile && \
15027                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15028
15029         echo "setxattr to $MOUNT/.lustre/fid"
15030         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15031
15032         echo "listxattr for $MOUNT/.lustre/fid"
15033         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15034
15035         echo "delxattr from $MOUNT/.lustre/fid"
15036         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15037
15038         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15039         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15040                 error "touch invalid fid should fail."
15041
15042         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15043         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15044                 error "touch non-normal fid should fail."
15045
15046         echo "rename $tdir to $MOUNT/.lustre/fid"
15047         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15048                 error "rename to $MOUNT/.lustre/fid should fail."
15049
15050         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15051         then            # LU-3547
15052                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15053                 local new_obf_mode=777
15054
15055                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15056                 chmod $new_obf_mode $DIR/.lustre/fid ||
15057                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15058
15059                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15060                 [ $obf_mode -eq $new_obf_mode ] ||
15061                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15062
15063                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15064                 chmod $old_obf_mode $DIR/.lustre/fid ||
15065                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15066         fi
15067
15068         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15069         fid=$($LFS path2fid $test_dir/$tfile-2)
15070
15071         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15072         then # LU-5424
15073                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15074                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15075                         error "create lov data thru .lustre failed"
15076         fi
15077         echo "cp /etc/passwd $test_dir/$tfile-2"
15078         cp /etc/passwd $test_dir/$tfile-2 ||
15079                 error "copy to $test_dir/$tfile-2 failed."
15080         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15081         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15082                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15083
15084         rm -rf $test_dir/tfile.lnk
15085         rm -rf $test_dir/$tfile-2
15086 }
15087
15088 test_154A() {
15089         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15090                 skip "Need MDS version at least 2.4.1"
15091
15092         local tf=$DIR/$tfile
15093         touch $tf
15094
15095         local fid=$($LFS path2fid $tf)
15096         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15097
15098         # check that we get the same pathname back
15099         local rootpath
15100         local found
15101         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15102                 echo "$rootpath $fid"
15103                 found=$($LFS fid2path $rootpath "$fid")
15104                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15105                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15106         done
15107
15108         # check wrong root path format
15109         rootpath=$MOUNT"_wrong"
15110         found=$($LFS fid2path $rootpath "$fid")
15111         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15112 }
15113 run_test 154A "lfs path2fid and fid2path basic checks"
15114
15115 test_154B() {
15116         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15117                 skip "Need MDS version at least 2.4.1"
15118
15119         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15120         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15121         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15122         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15123
15124         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15125         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15126
15127         # check that we get the same pathname
15128         echo "PFID: $PFID, name: $name"
15129         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15130         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15131         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15132                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15133
15134         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15135 }
15136 run_test 154B "verify the ll_decode_linkea tool"
15137
15138 test_154a() {
15139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15140         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15141         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15142                 skip "Need MDS version at least 2.2.51"
15143         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15144
15145         cp /etc/hosts $DIR/$tfile
15146
15147         fid=$($LFS path2fid $DIR/$tfile)
15148         rc=$?
15149         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15150
15151         dot_lustre_fid_permission_check "$fid" $DIR ||
15152                 error "dot lustre permission check $fid failed"
15153
15154         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15155
15156         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15157
15158         touch $MOUNT/.lustre/file &&
15159                 error "creation is not allowed under .lustre"
15160
15161         mkdir $MOUNT/.lustre/dir &&
15162                 error "mkdir is not allowed under .lustre"
15163
15164         rm -rf $DIR/$tfile
15165 }
15166 run_test 154a "Open-by-FID"
15167
15168 test_154b() {
15169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15170         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15171         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15172         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15173                 skip "Need MDS version at least 2.2.51"
15174
15175         local remote_dir=$DIR/$tdir/remote_dir
15176         local MDTIDX=1
15177         local rc=0
15178
15179         mkdir -p $DIR/$tdir
15180         $LFS mkdir -i $MDTIDX $remote_dir ||
15181                 error "create remote directory failed"
15182
15183         cp /etc/hosts $remote_dir/$tfile
15184
15185         fid=$($LFS path2fid $remote_dir/$tfile)
15186         rc=$?
15187         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15188
15189         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15190                 error "dot lustre permission check $fid failed"
15191         rm -rf $DIR/$tdir
15192 }
15193 run_test 154b "Open-by-FID for remote directory"
15194
15195 test_154c() {
15196         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15197                 skip "Need MDS version at least 2.4.1"
15198
15199         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15200         local FID1=$($LFS path2fid $DIR/$tfile.1)
15201         local FID2=$($LFS path2fid $DIR/$tfile.2)
15202         local FID3=$($LFS path2fid $DIR/$tfile.3)
15203
15204         local N=1
15205         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15206                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15207                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15208                 local want=FID$N
15209                 [ "$FID" = "${!want}" ] ||
15210                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15211                 N=$((N + 1))
15212         done
15213
15214         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15215         do
15216                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15217                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15218                 N=$((N + 1))
15219         done
15220 }
15221 run_test 154c "lfs path2fid and fid2path multiple arguments"
15222
15223 test_154d() {
15224         remote_mds_nodsh && skip "remote MDS with nodsh"
15225         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15226                 skip "Need MDS version at least 2.5.53"
15227
15228         if remote_mds; then
15229                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15230         else
15231                 nid="0@lo"
15232         fi
15233         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15234         local fd
15235         local cmd
15236
15237         rm -f $DIR/$tfile
15238         touch $DIR/$tfile
15239
15240         local fid=$($LFS path2fid $DIR/$tfile)
15241         # Open the file
15242         fd=$(free_fd)
15243         cmd="exec $fd<$DIR/$tfile"
15244         eval $cmd
15245         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15246         echo "$fid_list" | grep "$fid"
15247         rc=$?
15248
15249         cmd="exec $fd>/dev/null"
15250         eval $cmd
15251         if [ $rc -ne 0 ]; then
15252                 error "FID $fid not found in open files list $fid_list"
15253         fi
15254 }
15255 run_test 154d "Verify open file fid"
15256
15257 test_154e()
15258 {
15259         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15260                 skip "Need MDS version at least 2.6.50"
15261
15262         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15263                 error ".lustre returned by readdir"
15264         fi
15265 }
15266 run_test 154e ".lustre is not returned by readdir"
15267
15268 test_154f() {
15269         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15270
15271         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15272         mkdir_on_mdt0 $DIR/$tdir
15273         # test dirs inherit from its stripe
15274         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15275         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15276         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15277         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15278         touch $DIR/f
15279
15280         # get fid of parents
15281         local FID0=$($LFS path2fid $DIR/$tdir)
15282         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15283         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15284         local FID3=$($LFS path2fid $DIR)
15285
15286         # check that path2fid --parents returns expected <parent_fid>/name
15287         # 1) test for a directory (single parent)
15288         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15289         [ "$parent" == "$FID0/foo1" ] ||
15290                 error "expected parent: $FID0/foo1, got: $parent"
15291
15292         # 2) test for a file with nlink > 1 (multiple parents)
15293         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15294         echo "$parent" | grep -F "$FID1/$tfile" ||
15295                 error "$FID1/$tfile not returned in parent list"
15296         echo "$parent" | grep -F "$FID2/link" ||
15297                 error "$FID2/link not returned in parent list"
15298
15299         # 3) get parent by fid
15300         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15301         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15302         echo "$parent" | grep -F "$FID1/$tfile" ||
15303                 error "$FID1/$tfile not returned in parent list (by fid)"
15304         echo "$parent" | grep -F "$FID2/link" ||
15305                 error "$FID2/link not returned in parent list (by fid)"
15306
15307         # 4) test for entry in root directory
15308         parent=$($LFS path2fid --parents $DIR/f)
15309         echo "$parent" | grep -F "$FID3/f" ||
15310                 error "$FID3/f not returned in parent list"
15311
15312         # 5) test it on root directory
15313         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15314                 error "$MOUNT should not have parents"
15315
15316         # enable xattr caching and check that linkea is correctly updated
15317         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15318         save_lustre_params client "llite.*.xattr_cache" > $save
15319         lctl set_param llite.*.xattr_cache 1
15320
15321         # 6.1) linkea update on rename
15322         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15323
15324         # get parents by fid
15325         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15326         # foo1 should no longer be returned in parent list
15327         echo "$parent" | grep -F "$FID1" &&
15328                 error "$FID1 should no longer be in parent list"
15329         # the new path should appear
15330         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15331                 error "$FID2/$tfile.moved is not in parent list"
15332
15333         # 6.2) linkea update on unlink
15334         rm -f $DIR/$tdir/foo2/link
15335         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15336         # foo2/link should no longer be returned in parent list
15337         echo "$parent" | grep -F "$FID2/link" &&
15338                 error "$FID2/link should no longer be in parent list"
15339         true
15340
15341         rm -f $DIR/f
15342         restore_lustre_params < $save
15343         rm -f $save
15344 }
15345 run_test 154f "get parent fids by reading link ea"
15346
15347 test_154g()
15348 {
15349         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15350         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15351            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15352                 skip "Need MDS version at least 2.6.92"
15353
15354         mkdir_on_mdt0 $DIR/$tdir
15355         llapi_fid_test -d $DIR/$tdir
15356 }
15357 run_test 154g "various llapi FID tests"
15358
15359 test_155_small_load() {
15360     local temp=$TMP/$tfile
15361     local file=$DIR/$tfile
15362
15363     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15364         error "dd of=$temp bs=6096 count=1 failed"
15365     cp $temp $file
15366     cancel_lru_locks $OSC
15367     cmp $temp $file || error "$temp $file differ"
15368
15369     $TRUNCATE $temp 6000
15370     $TRUNCATE $file 6000
15371     cmp $temp $file || error "$temp $file differ (truncate1)"
15372
15373     echo "12345" >>$temp
15374     echo "12345" >>$file
15375     cmp $temp $file || error "$temp $file differ (append1)"
15376
15377     echo "12345" >>$temp
15378     echo "12345" >>$file
15379     cmp $temp $file || error "$temp $file differ (append2)"
15380
15381     rm -f $temp $file
15382     true
15383 }
15384
15385 test_155_big_load() {
15386         remote_ost_nodsh && skip "remote OST with nodsh"
15387
15388         local temp=$TMP/$tfile
15389         local file=$DIR/$tfile
15390
15391         free_min_max
15392         local cache_size=$(do_facet ost$((MAXI+1)) \
15393                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15394         local large_file_size=$((cache_size * 2))
15395
15396         echo "OSS cache size: $cache_size KB"
15397         echo "Large file size: $large_file_size KB"
15398
15399         [ $MAXV -le $large_file_size ] &&
15400                 skip_env "max available OST size needs > $large_file_size KB"
15401
15402         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15403
15404         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15405                 error "dd of=$temp bs=$large_file_size count=1k failed"
15406         cp $temp $file
15407         ls -lh $temp $file
15408         cancel_lru_locks osc
15409         cmp $temp $file || error "$temp $file differ"
15410
15411         rm -f $temp $file
15412         true
15413 }
15414
15415 save_writethrough() {
15416         local facets=$(get_facets OST)
15417
15418         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15419 }
15420
15421 test_155a() {
15422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15423
15424         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15425
15426         save_writethrough $p
15427
15428         set_cache read on
15429         set_cache writethrough on
15430         test_155_small_load
15431         restore_lustre_params < $p
15432         rm -f $p
15433 }
15434 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15435
15436 test_155b() {
15437         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15438
15439         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15440
15441         save_writethrough $p
15442
15443         set_cache read on
15444         set_cache writethrough off
15445         test_155_small_load
15446         restore_lustre_params < $p
15447         rm -f $p
15448 }
15449 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15450
15451 test_155c() {
15452         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15453
15454         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15455
15456         save_writethrough $p
15457
15458         set_cache read off
15459         set_cache writethrough on
15460         test_155_small_load
15461         restore_lustre_params < $p
15462         rm -f $p
15463 }
15464 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15465
15466 test_155d() {
15467         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15468
15469         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15470
15471         save_writethrough $p
15472
15473         set_cache read off
15474         set_cache writethrough off
15475         test_155_small_load
15476         restore_lustre_params < $p
15477         rm -f $p
15478 }
15479 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15480
15481 test_155e() {
15482         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15483
15484         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15485
15486         save_writethrough $p
15487
15488         set_cache read on
15489         set_cache writethrough on
15490         test_155_big_load
15491         restore_lustre_params < $p
15492         rm -f $p
15493 }
15494 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15495
15496 test_155f() {
15497         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15498
15499         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15500
15501         save_writethrough $p
15502
15503         set_cache read on
15504         set_cache writethrough off
15505         test_155_big_load
15506         restore_lustre_params < $p
15507         rm -f $p
15508 }
15509 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15510
15511 test_155g() {
15512         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15513
15514         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15515
15516         save_writethrough $p
15517
15518         set_cache read off
15519         set_cache writethrough on
15520         test_155_big_load
15521         restore_lustre_params < $p
15522         rm -f $p
15523 }
15524 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15525
15526 test_155h() {
15527         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15528
15529         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15530
15531         save_writethrough $p
15532
15533         set_cache read off
15534         set_cache writethrough off
15535         test_155_big_load
15536         restore_lustre_params < $p
15537         rm -f $p
15538 }
15539 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15540
15541 test_156() {
15542         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15543         remote_ost_nodsh && skip "remote OST with nodsh"
15544         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15545                 skip "stats not implemented on old servers"
15546         [ "$ost1_FSTYPE" = "zfs" ] &&
15547                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15548
15549         local CPAGES=3
15550         local BEFORE
15551         local AFTER
15552         local file="$DIR/$tfile"
15553         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15554
15555         save_writethrough $p
15556         roc_hit_init
15557
15558         log "Turn on read and write cache"
15559         set_cache read on
15560         set_cache writethrough on
15561
15562         log "Write data and read it back."
15563         log "Read should be satisfied from the cache."
15564         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15565         BEFORE=$(roc_hit)
15566         cancel_lru_locks osc
15567         cat $file >/dev/null
15568         AFTER=$(roc_hit)
15569         if ! let "AFTER - BEFORE == CPAGES"; then
15570                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15571         else
15572                 log "cache hits: before: $BEFORE, after: $AFTER"
15573         fi
15574
15575         log "Read again; it should be satisfied from the cache."
15576         BEFORE=$AFTER
15577         cancel_lru_locks osc
15578         cat $file >/dev/null
15579         AFTER=$(roc_hit)
15580         if ! let "AFTER - BEFORE == CPAGES"; then
15581                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15582         else
15583                 log "cache hits:: before: $BEFORE, after: $AFTER"
15584         fi
15585
15586         log "Turn off the read cache and turn on the write cache"
15587         set_cache read off
15588         set_cache writethrough on
15589
15590         log "Read again; it should be satisfied from the cache."
15591         BEFORE=$(roc_hit)
15592         cancel_lru_locks osc
15593         cat $file >/dev/null
15594         AFTER=$(roc_hit)
15595         if ! let "AFTER - BEFORE == CPAGES"; then
15596                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15597         else
15598                 log "cache hits:: before: $BEFORE, after: $AFTER"
15599         fi
15600
15601         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15602                 # > 2.12.56 uses pagecache if cached
15603                 log "Read again; it should not be satisfied from the cache."
15604                 BEFORE=$AFTER
15605                 cancel_lru_locks osc
15606                 cat $file >/dev/null
15607                 AFTER=$(roc_hit)
15608                 if ! let "AFTER - BEFORE == 0"; then
15609                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15610                 else
15611                         log "cache hits:: before: $BEFORE, after: $AFTER"
15612                 fi
15613         fi
15614
15615         log "Write data and read it back."
15616         log "Read should be satisfied from the cache."
15617         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15618         BEFORE=$(roc_hit)
15619         cancel_lru_locks osc
15620         cat $file >/dev/null
15621         AFTER=$(roc_hit)
15622         if ! let "AFTER - BEFORE == CPAGES"; then
15623                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15624         else
15625                 log "cache hits:: before: $BEFORE, after: $AFTER"
15626         fi
15627
15628         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15629                 # > 2.12.56 uses pagecache if cached
15630                 log "Read again; it should not be satisfied from the cache."
15631                 BEFORE=$AFTER
15632                 cancel_lru_locks osc
15633                 cat $file >/dev/null
15634                 AFTER=$(roc_hit)
15635                 if ! let "AFTER - BEFORE == 0"; then
15636                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15637                 else
15638                         log "cache hits:: before: $BEFORE, after: $AFTER"
15639                 fi
15640         fi
15641
15642         log "Turn off read and write cache"
15643         set_cache read off
15644         set_cache writethrough off
15645
15646         log "Write data and read it back"
15647         log "It should not be satisfied from the cache."
15648         rm -f $file
15649         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15650         cancel_lru_locks osc
15651         BEFORE=$(roc_hit)
15652         cat $file >/dev/null
15653         AFTER=$(roc_hit)
15654         if ! let "AFTER - BEFORE == 0"; then
15655                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15656         else
15657                 log "cache hits:: before: $BEFORE, after: $AFTER"
15658         fi
15659
15660         log "Turn on the read cache and turn off the write cache"
15661         set_cache read on
15662         set_cache writethrough off
15663
15664         log "Write data and read it back"
15665         log "It should not be satisfied from the cache."
15666         rm -f $file
15667         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15668         BEFORE=$(roc_hit)
15669         cancel_lru_locks osc
15670         cat $file >/dev/null
15671         AFTER=$(roc_hit)
15672         if ! let "AFTER - BEFORE == 0"; then
15673                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15674         else
15675                 log "cache hits:: before: $BEFORE, after: $AFTER"
15676         fi
15677
15678         log "Read again; it should be satisfied from the cache."
15679         BEFORE=$(roc_hit)
15680         cancel_lru_locks osc
15681         cat $file >/dev/null
15682         AFTER=$(roc_hit)
15683         if ! let "AFTER - BEFORE == CPAGES"; then
15684                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15685         else
15686                 log "cache hits:: before: $BEFORE, after: $AFTER"
15687         fi
15688
15689         restore_lustre_params < $p
15690         rm -f $p $file
15691 }
15692 run_test 156 "Verification of tunables"
15693
15694 test_160a() {
15695         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15696         remote_mds_nodsh && skip "remote MDS with nodsh"
15697         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15698                 skip "Need MDS version at least 2.2.0"
15699
15700         changelog_register || error "changelog_register failed"
15701         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15702         changelog_users $SINGLEMDS | grep -q $cl_user ||
15703                 error "User $cl_user not found in changelog_users"
15704
15705         mkdir_on_mdt0 $DIR/$tdir
15706
15707         # change something
15708         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15709         changelog_clear 0 || error "changelog_clear failed"
15710         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15711         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15712         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15713         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15714         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15715         rm $DIR/$tdir/pics/desktop.jpg
15716
15717         echo "verifying changelog mask"
15718         changelog_chmask "-MKDIR"
15719         changelog_chmask "-CLOSE"
15720
15721         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15722         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15723
15724         changelog_chmask "+MKDIR"
15725         changelog_chmask "+CLOSE"
15726
15727         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15728         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15729
15730         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15731         CLOSES=$(changelog_dump | grep -c "CLOSE")
15732         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15733         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15734
15735         # verify contents
15736         echo "verifying target fid"
15737         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15738         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15739         [ "$fidc" == "$fidf" ] ||
15740                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15741         echo "verifying parent fid"
15742         # The FID returned from the Changelog may be the directory shard on
15743         # a different MDT, and not the FID returned by path2fid on the parent.
15744         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15745         # since this is what will matter when recreating this file in the tree.
15746         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15747         local pathp=$($LFS fid2path $MOUNT "$fidp")
15748         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15749                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15750
15751         echo "getting records for $cl_user"
15752         changelog_users $SINGLEMDS
15753         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
15754         local nclr=3
15755         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
15756                 error "changelog_clear failed"
15757         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
15758         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
15759         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
15760                 error "user index expect $user_rec1 + $nclr != $user_rec2"
15761
15762         local min0_rec=$(changelog_users $SINGLEMDS |
15763                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
15764         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
15765                           awk '{ print $1; exit; }')
15766
15767         changelog_dump | tail -n 5
15768         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
15769         [ $first_rec == $((min0_rec + 1)) ] ||
15770                 error "first index should be $min0_rec + 1 not $first_rec"
15771
15772         # LU-3446 changelog index reset on MDT restart
15773         local cur_rec1=$(changelog_users $SINGLEMDS |
15774                          awk '/^current.index:/ { print $NF }')
15775         changelog_clear 0 ||
15776                 error "clear all changelog records for $cl_user failed"
15777         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
15778         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
15779                 error "Fail to start $SINGLEMDS"
15780         local cur_rec2=$(changelog_users $SINGLEMDS |
15781                          awk '/^current.index:/ { print $NF }')
15782         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
15783         [ $cur_rec1 == $cur_rec2 ] ||
15784                 error "current index should be $cur_rec1 not $cur_rec2"
15785
15786         echo "verifying users from this test are deregistered"
15787         changelog_deregister || error "changelog_deregister failed"
15788         changelog_users $SINGLEMDS | grep -q $cl_user &&
15789                 error "User '$cl_user' still in changelog_users"
15790
15791         # lctl get_param -n mdd.*.changelog_users
15792         # current_index: 144
15793         # ID    index (idle seconds)
15794         # cl3   144   (2) mask=<list>
15795         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
15796                 # this is the normal case where all users were deregistered
15797                 # make sure no new records are added when no users are present
15798                 local last_rec1=$(changelog_users $SINGLEMDS |
15799                                   awk '/^current.index:/ { print $NF }')
15800                 touch $DIR/$tdir/chloe
15801                 local last_rec2=$(changelog_users $SINGLEMDS |
15802                                   awk '/^current.index:/ { print $NF }')
15803                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
15804                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
15805         else
15806                 # any changelog users must be leftovers from a previous test
15807                 changelog_users $SINGLEMDS
15808                 echo "other changelog users; can't verify off"
15809         fi
15810 }
15811 run_test 160a "changelog sanity"
15812
15813 test_160b() { # LU-3587
15814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15815         remote_mds_nodsh && skip "remote MDS with nodsh"
15816         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15817                 skip "Need MDS version at least 2.2.0"
15818
15819         changelog_register || error "changelog_register failed"
15820         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15821         changelog_users $SINGLEMDS | grep -q $cl_user ||
15822                 error "User '$cl_user' not found in changelog_users"
15823
15824         local longname1=$(str_repeat a 255)
15825         local longname2=$(str_repeat b 255)
15826
15827         cd $DIR
15828         echo "creating very long named file"
15829         touch $longname1 || error "create of '$longname1' failed"
15830         echo "renaming very long named file"
15831         mv $longname1 $longname2
15832
15833         changelog_dump | grep RENME | tail -n 5
15834         rm -f $longname2
15835 }
15836 run_test 160b "Verify that very long rename doesn't crash in changelog"
15837
15838 test_160c() {
15839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15840         remote_mds_nodsh && skip "remote MDS with nodsh"
15841
15842         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15843                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15844                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15845                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15846
15847         local rc=0
15848
15849         # Registration step
15850         changelog_register || error "changelog_register failed"
15851
15852         rm -rf $DIR/$tdir
15853         mkdir -p $DIR/$tdir
15854         $MCREATE $DIR/$tdir/foo_160c
15855         changelog_chmask "-TRUNC"
15856         $TRUNCATE $DIR/$tdir/foo_160c 200
15857         changelog_chmask "+TRUNC"
15858         $TRUNCATE $DIR/$tdir/foo_160c 199
15859         changelog_dump | tail -n 5
15860         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
15861         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
15862 }
15863 run_test 160c "verify that changelog log catch the truncate event"
15864
15865 test_160d() {
15866         remote_mds_nodsh && skip "remote MDS with nodsh"
15867         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15868         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15869         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
15870                 skip "Need MDS version at least 2.7.60"
15871
15872         # Registration step
15873         changelog_register || error "changelog_register failed"
15874
15875         mkdir -p $DIR/$tdir/migrate_dir
15876         changelog_clear 0 || error "changelog_clear failed"
15877
15878         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
15879         changelog_dump | tail -n 5
15880         local migrates=$(changelog_dump | grep -c "MIGRT")
15881         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
15882 }
15883 run_test 160d "verify that changelog log catch the migrate event"
15884
15885 test_160e() {
15886         remote_mds_nodsh && skip "remote MDS with nodsh"
15887
15888         # Create a user
15889         changelog_register || error "changelog_register failed"
15890
15891         local MDT0=$(facet_svc $SINGLEMDS)
15892         local rc
15893
15894         # No user (expect fail)
15895         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
15896         rc=$?
15897         if [ $rc -eq 0 ]; then
15898                 error "Should fail without user"
15899         elif [ $rc -ne 4 ]; then
15900                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
15901         fi
15902
15903         # Delete a future user (expect fail)
15904         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
15905         rc=$?
15906         if [ $rc -eq 0 ]; then
15907                 error "Deleted non-existant user cl77"
15908         elif [ $rc -ne 2 ]; then
15909                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
15910         fi
15911
15912         # Clear to a bad index (1 billion should be safe)
15913         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
15914         rc=$?
15915
15916         if [ $rc -eq 0 ]; then
15917                 error "Successfully cleared to invalid CL index"
15918         elif [ $rc -ne 22 ]; then
15919                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
15920         fi
15921 }
15922 run_test 160e "changelog negative testing (should return errors)"
15923
15924 test_160f() {
15925         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15926         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15927                 skip "Need MDS version at least 2.10.56"
15928
15929         local mdts=$(comma_list $(mdts_nodes))
15930
15931         # Create a user
15932         changelog_register || error "first changelog_register failed"
15933         changelog_register || error "second changelog_register failed"
15934         local cl_users
15935         declare -A cl_user1
15936         declare -A cl_user2
15937         local user_rec1
15938         local user_rec2
15939         local i
15940
15941         # generate some changelog records to accumulate on each MDT
15942         # use all_char because created files should be evenly distributed
15943         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15944                 error "test_mkdir $tdir failed"
15945         log "$(date +%s): creating first files"
15946         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15947                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
15948                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
15949         done
15950
15951         # check changelogs have been generated
15952         local start=$SECONDS
15953         local idle_time=$((MDSCOUNT * 5 + 5))
15954         local nbcl=$(changelog_dump | wc -l)
15955         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15956
15957         for param in "changelog_max_idle_time=$idle_time" \
15958                      "changelog_gc=1" \
15959                      "changelog_min_gc_interval=2" \
15960                      "changelog_min_free_cat_entries=3"; do
15961                 local MDT0=$(facet_svc $SINGLEMDS)
15962                 local var="${param%=*}"
15963                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15964
15965                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15966                 do_nodes $mdts $LCTL set_param mdd.*.$param
15967         done
15968
15969         # force cl_user2 to be idle (1st part), but also cancel the
15970         # cl_user1 records so that it is not evicted later in the test.
15971         local sleep1=$((idle_time / 2))
15972         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
15973         sleep $sleep1
15974
15975         # simulate changelog catalog almost full
15976         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15977         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15978
15979         for i in $(seq $MDSCOUNT); do
15980                 cl_users=(${CL_USERS[mds$i]})
15981                 cl_user1[mds$i]="${cl_users[0]}"
15982                 cl_user2[mds$i]="${cl_users[1]}"
15983
15984                 [ -n "${cl_user1[mds$i]}" ] ||
15985                         error "mds$i: no user registered"
15986                 [ -n "${cl_user2[mds$i]}" ] ||
15987                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15988
15989                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15990                 [ -n "$user_rec1" ] ||
15991                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15992                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15993                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15994                 [ -n "$user_rec2" ] ||
15995                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15996                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15997                      "$user_rec1 + 2 == $user_rec2"
15998                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15999                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16000                               "$user_rec1 + 2, but is $user_rec2"
16001                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16002                 [ -n "$user_rec2" ] ||
16003                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16004                 [ $user_rec1 == $user_rec2 ] ||
16005                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16006                               "$user_rec1, but is $user_rec2"
16007         done
16008
16009         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16010         local sleep2=$((idle_time - (SECONDS - start) + 1))
16011         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16012         sleep $sleep2
16013
16014         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16015         # cl_user1 should be OK because it recently processed records.
16016         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16017         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16018                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16019                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16020         done
16021
16022         # ensure gc thread is done
16023         for i in $(mdts_nodes); do
16024                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16025                         error "$i: GC-thread not done"
16026         done
16027
16028         local first_rec
16029         for (( i = 1; i <= MDSCOUNT; i++ )); do
16030                 # check cl_user1 still registered
16031                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16032                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16033                 # check cl_user2 unregistered
16034                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16035                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16036
16037                 # check changelogs are present and starting at $user_rec1 + 1
16038                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16039                 [ -n "$user_rec1" ] ||
16040                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16041                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16042                             awk '{ print $1; exit; }')
16043
16044                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16045                 [ $((user_rec1 + 1)) == $first_rec ] ||
16046                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16047         done
16048 }
16049 run_test 160f "changelog garbage collect (timestamped users)"
16050
16051 test_160g() {
16052         remote_mds_nodsh && skip "remote MDS with nodsh"
16053         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16054                 skip "Need MDS version at least 2.14.55"
16055
16056         local mdts=$(comma_list $(mdts_nodes))
16057
16058         # Create a user
16059         changelog_register || error "first changelog_register failed"
16060         changelog_register || error "second changelog_register failed"
16061         local cl_users
16062         declare -A cl_user1
16063         declare -A cl_user2
16064         local user_rec1
16065         local user_rec2
16066         local i
16067
16068         # generate some changelog records to accumulate on each MDT
16069         # use all_char because created files should be evenly distributed
16070         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16071                 error "test_mkdir $tdir failed"
16072         for ((i = 0; i < MDSCOUNT; i++)); do
16073                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16074                         error "create $DIR/$tdir/d$i.1 failed"
16075         done
16076
16077         # check changelogs have been generated
16078         local nbcl=$(changelog_dump | wc -l)
16079         (( $nbcl > 0 )) || error "no changelogs found"
16080
16081         # reduce the max_idle_indexes value to make sure we exceed it
16082         for param in "changelog_max_idle_indexes=2" \
16083                      "changelog_gc=1" \
16084                      "changelog_min_gc_interval=2"; do
16085                 local MDT0=$(facet_svc $SINGLEMDS)
16086                 local var="${param%=*}"
16087                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16088
16089                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16090                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16091                         error "unable to set mdd.*.$param"
16092         done
16093
16094         local start=$SECONDS
16095         for i in $(seq $MDSCOUNT); do
16096                 cl_users=(${CL_USERS[mds$i]})
16097                 cl_user1[mds$i]="${cl_users[0]}"
16098                 cl_user2[mds$i]="${cl_users[1]}"
16099
16100                 [ -n "${cl_user1[mds$i]}" ] ||
16101                         error "mds$i: user1 is not registered"
16102                 [ -n "${cl_user2[mds$i]}" ] ||
16103                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16104
16105                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16106                 [ -n "$user_rec1" ] ||
16107                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16108                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16109                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16110                 [ -n "$user_rec2" ] ||
16111                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16112                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16113                      "$user_rec1 + 2 == $user_rec2"
16114                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16115                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16116                               "expected $user_rec1 + 2, but is $user_rec2"
16117                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16118                 [ -n "$user_rec2" ] ||
16119                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16120                 [ $user_rec1 == $user_rec2 ] ||
16121                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16122                               "expected $user_rec1, but is $user_rec2"
16123         done
16124
16125         # ensure we are past the previous changelog_min_gc_interval set above
16126         local sleep2=$((start + 2 - SECONDS))
16127         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16128         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16129         # cl_user1 should be OK because it recently processed records.
16130         for ((i = 0; i < MDSCOUNT; i++)); do
16131                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16132                         error "create $DIR/$tdir/d$i.3 failed"
16133         done
16134
16135         # ensure gc thread is done
16136         for i in $(mdts_nodes); do
16137                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16138                         error "$i: GC-thread not done"
16139         done
16140
16141         local first_rec
16142         for (( i = 1; i <= MDSCOUNT; i++ )); do
16143                 # check cl_user1 still registered
16144                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16145                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16146                 # check cl_user2 unregistered
16147                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16148                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16149
16150                 # check changelogs are present and starting at $user_rec1 + 1
16151                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16152                 [ -n "$user_rec1" ] ||
16153                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16154                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16155                             awk '{ print $1; exit; }')
16156
16157                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16158                 [ $((user_rec1 + 1)) == $first_rec ] ||
16159                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16160         done
16161 }
16162 run_test 160g "changelog garbage collect on idle records"
16163
16164 test_160h() {
16165         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16166         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16167                 skip "Need MDS version at least 2.10.56"
16168
16169         local mdts=$(comma_list $(mdts_nodes))
16170
16171         # Create a user
16172         changelog_register || error "first changelog_register failed"
16173         changelog_register || error "second changelog_register failed"
16174         local cl_users
16175         declare -A cl_user1
16176         declare -A cl_user2
16177         local user_rec1
16178         local user_rec2
16179         local i
16180
16181         # generate some changelog records to accumulate on each MDT
16182         # use all_char because created files should be evenly distributed
16183         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16184                 error "test_mkdir $tdir failed"
16185         for ((i = 0; i < MDSCOUNT; i++)); do
16186                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16187                         error "create $DIR/$tdir/d$i.1 failed"
16188         done
16189
16190         # check changelogs have been generated
16191         local nbcl=$(changelog_dump | wc -l)
16192         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16193
16194         for param in "changelog_max_idle_time=10" \
16195                      "changelog_gc=1" \
16196                      "changelog_min_gc_interval=2"; do
16197                 local MDT0=$(facet_svc $SINGLEMDS)
16198                 local var="${param%=*}"
16199                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16200
16201                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16202                 do_nodes $mdts $LCTL set_param mdd.*.$param
16203         done
16204
16205         # force cl_user2 to be idle (1st part)
16206         sleep 9
16207
16208         for i in $(seq $MDSCOUNT); do
16209                 cl_users=(${CL_USERS[mds$i]})
16210                 cl_user1[mds$i]="${cl_users[0]}"
16211                 cl_user2[mds$i]="${cl_users[1]}"
16212
16213                 [ -n "${cl_user1[mds$i]}" ] ||
16214                         error "mds$i: no user registered"
16215                 [ -n "${cl_user2[mds$i]}" ] ||
16216                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16217
16218                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16219                 [ -n "$user_rec1" ] ||
16220                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16221                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16222                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16223                 [ -n "$user_rec2" ] ||
16224                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16225                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16226                      "$user_rec1 + 2 == $user_rec2"
16227                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16228                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16229                               "$user_rec1 + 2, but is $user_rec2"
16230                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16231                 [ -n "$user_rec2" ] ||
16232                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16233                 [ $user_rec1 == $user_rec2 ] ||
16234                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16235                               "$user_rec1, but is $user_rec2"
16236         done
16237
16238         # force cl_user2 to be idle (2nd part) and to reach
16239         # changelog_max_idle_time
16240         sleep 2
16241
16242         # force each GC-thread start and block then
16243         # one per MDT/MDD, set fail_val accordingly
16244         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16245         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16246
16247         # generate more changelogs to trigger fail_loc
16248         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16249                 error "create $DIR/$tdir/${tfile}bis failed"
16250
16251         # stop MDT to stop GC-thread, should be done in back-ground as it will
16252         # block waiting for the thread to be released and exit
16253         declare -A stop_pids
16254         for i in $(seq $MDSCOUNT); do
16255                 stop mds$i &
16256                 stop_pids[mds$i]=$!
16257         done
16258
16259         for i in $(mdts_nodes); do
16260                 local facet
16261                 local nb=0
16262                 local facets=$(facets_up_on_host $i)
16263
16264                 for facet in ${facets//,/ }; do
16265                         if [[ $facet == mds* ]]; then
16266                                 nb=$((nb + 1))
16267                         fi
16268                 done
16269                 # ensure each MDS's gc threads are still present and all in "R"
16270                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16271                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16272                         error "$i: expected $nb GC-thread"
16273                 wait_update $i \
16274                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16275                         "R" 20 ||
16276                         error "$i: GC-thread not found in R-state"
16277                 # check umounts of each MDT on MDS have reached kthread_stop()
16278                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16279                         error "$i: expected $nb umount"
16280                 wait_update $i \
16281                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16282                         error "$i: umount not found in D-state"
16283         done
16284
16285         # release all GC-threads
16286         do_nodes $mdts $LCTL set_param fail_loc=0
16287
16288         # wait for MDT stop to complete
16289         for i in $(seq $MDSCOUNT); do
16290                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16291         done
16292
16293         # XXX
16294         # may try to check if any orphan changelog records are present
16295         # via ldiskfs/zfs and llog_reader...
16296
16297         # re-start/mount MDTs
16298         for i in $(seq $MDSCOUNT); do
16299                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16300                         error "Fail to start mds$i"
16301         done
16302
16303         local first_rec
16304         for i in $(seq $MDSCOUNT); do
16305                 # check cl_user1 still registered
16306                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16307                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16308                 # check cl_user2 unregistered
16309                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16310                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16311
16312                 # check changelogs are present and starting at $user_rec1 + 1
16313                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16314                 [ -n "$user_rec1" ] ||
16315                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16316                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16317                             awk '{ print $1; exit; }')
16318
16319                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16320                 [ $((user_rec1 + 1)) == $first_rec ] ||
16321                         error "mds$i: first index should be $user_rec1 + 1, " \
16322                               "but is $first_rec"
16323         done
16324 }
16325 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16326               "during mount"
16327
16328 test_160i() {
16329
16330         local mdts=$(comma_list $(mdts_nodes))
16331
16332         changelog_register || error "first changelog_register failed"
16333
16334         # generate some changelog records to accumulate on each MDT
16335         # use all_char because created files should be evenly distributed
16336         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16337                 error "test_mkdir $tdir failed"
16338         for ((i = 0; i < MDSCOUNT; i++)); do
16339                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16340                         error "create $DIR/$tdir/d$i.1 failed"
16341         done
16342
16343         # check changelogs have been generated
16344         local nbcl=$(changelog_dump | wc -l)
16345         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16346
16347         # simulate race between register and unregister
16348         # XXX as fail_loc is set per-MDS, with DNE configs the race
16349         # simulation will only occur for one MDT per MDS and for the
16350         # others the normal race scenario will take place
16351         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16352         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16353         do_nodes $mdts $LCTL set_param fail_val=1
16354
16355         # unregister 1st user
16356         changelog_deregister &
16357         local pid1=$!
16358         # wait some time for deregister work to reach race rdv
16359         sleep 2
16360         # register 2nd user
16361         changelog_register || error "2nd user register failed"
16362
16363         wait $pid1 || error "1st user deregister failed"
16364
16365         local i
16366         local last_rec
16367         declare -A LAST_REC
16368         for i in $(seq $MDSCOUNT); do
16369                 if changelog_users mds$i | grep "^cl"; then
16370                         # make sure new records are added with one user present
16371                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16372                                           awk '/^current.index:/ { print $NF }')
16373                 else
16374                         error "mds$i has no user registered"
16375                 fi
16376         done
16377
16378         # generate more changelog records to accumulate on each MDT
16379         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16380                 error "create $DIR/$tdir/${tfile}bis failed"
16381
16382         for i in $(seq $MDSCOUNT); do
16383                 last_rec=$(changelog_users $SINGLEMDS |
16384                            awk '/^current.index:/ { print $NF }')
16385                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16386                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16387                         error "changelogs are off on mds$i"
16388         done
16389 }
16390 run_test 160i "changelog user register/unregister race"
16391
16392 test_160j() {
16393         remote_mds_nodsh && skip "remote MDS with nodsh"
16394         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16395                 skip "Need MDS version at least 2.12.56"
16396
16397         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16398         stack_trap "umount $MOUNT2" EXIT
16399
16400         changelog_register || error "first changelog_register failed"
16401         stack_trap "changelog_deregister" EXIT
16402
16403         # generate some changelog
16404         # use all_char because created files should be evenly distributed
16405         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16406                 error "mkdir $tdir failed"
16407         for ((i = 0; i < MDSCOUNT; i++)); do
16408                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16409                         error "create $DIR/$tdir/d$i.1 failed"
16410         done
16411
16412         # open the changelog device
16413         exec 3>/dev/changelog-$FSNAME-MDT0000
16414         stack_trap "exec 3>&-" EXIT
16415         exec 4</dev/changelog-$FSNAME-MDT0000
16416         stack_trap "exec 4<&-" EXIT
16417
16418         # umount the first lustre mount
16419         umount $MOUNT
16420         stack_trap "mount_client $MOUNT" EXIT
16421
16422         # read changelog, which may or may not fail, but should not crash
16423         cat <&4 >/dev/null
16424
16425         # clear changelog
16426         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16427         changelog_users $SINGLEMDS | grep -q $cl_user ||
16428                 error "User $cl_user not found in changelog_users"
16429
16430         printf 'clear:'$cl_user':0' >&3
16431 }
16432 run_test 160j "client can be umounted while its chanangelog is being used"
16433
16434 test_160k() {
16435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16436         remote_mds_nodsh && skip "remote MDS with nodsh"
16437
16438         mkdir -p $DIR/$tdir/1/1
16439
16440         changelog_register || error "changelog_register failed"
16441         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16442
16443         changelog_users $SINGLEMDS | grep -q $cl_user ||
16444                 error "User '$cl_user' not found in changelog_users"
16445 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16446         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16447         rmdir $DIR/$tdir/1/1 & sleep 1
16448         mkdir $DIR/$tdir/2
16449         touch $DIR/$tdir/2/2
16450         rm -rf $DIR/$tdir/2
16451
16452         wait
16453         sleep 4
16454
16455         changelog_dump | grep rmdir || error "rmdir not recorded"
16456 }
16457 run_test 160k "Verify that changelog records are not lost"
16458
16459 # Verifies that a file passed as a parameter has recently had an operation
16460 # performed on it that has generated an MTIME changelog which contains the
16461 # correct parent FID. As files might reside on a different MDT from the
16462 # parent directory in DNE configurations, the FIDs are translated to paths
16463 # before being compared, which should be identical
16464 compare_mtime_changelog() {
16465         local file="${1}"
16466         local mdtidx
16467         local mtime
16468         local cl_fid
16469         local pdir
16470         local dir
16471
16472         mdtidx=$($LFS getstripe --mdt-index $file)
16473         mdtidx=$(printf "%04x" $mdtidx)
16474
16475         # Obtain the parent FID from the MTIME changelog
16476         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16477         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16478
16479         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16480         [ -z "$cl_fid" ] && error "parent FID not present"
16481
16482         # Verify that the path for the parent FID is the same as the path for
16483         # the test directory
16484         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16485
16486         dir=$(dirname $1)
16487
16488         [[ "${pdir%/}" == "$dir" ]] ||
16489                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16490 }
16491
16492 test_160l() {
16493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16494
16495         remote_mds_nodsh && skip "remote MDS with nodsh"
16496         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16497                 skip "Need MDS version at least 2.13.55"
16498
16499         local cl_user
16500
16501         changelog_register || error "changelog_register failed"
16502         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16503
16504         changelog_users $SINGLEMDS | grep -q $cl_user ||
16505                 error "User '$cl_user' not found in changelog_users"
16506
16507         # Clear some types so that MTIME changelogs are generated
16508         changelog_chmask "-CREAT"
16509         changelog_chmask "-CLOSE"
16510
16511         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16512
16513         # Test CL_MTIME during setattr
16514         touch $DIR/$tdir/$tfile
16515         compare_mtime_changelog $DIR/$tdir/$tfile
16516
16517         # Test CL_MTIME during close
16518         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16519         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16520 }
16521 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16522
16523 test_160m() {
16524         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16525         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16526                 skip "Need MDS version at least 2.14.51"
16527         local cl_users
16528         local cl_user1
16529         local cl_user2
16530         local pid1
16531
16532         # Create a user
16533         changelog_register || error "first changelog_register failed"
16534         changelog_register || error "second changelog_register failed"
16535
16536         cl_users=(${CL_USERS[mds1]})
16537         cl_user1="${cl_users[0]}"
16538         cl_user2="${cl_users[1]}"
16539         # generate some changelog records to accumulate on MDT0
16540         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16541         createmany -m $DIR/$tdir/$tfile 50 ||
16542                 error "create $DIR/$tdir/$tfile failed"
16543         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16544         rm -f $DIR/$tdir
16545
16546         # check changelogs have been generated
16547         local nbcl=$(changelog_dump | wc -l)
16548         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16549
16550 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16551         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16552
16553         __changelog_clear mds1 $cl_user1 +10
16554         __changelog_clear mds1 $cl_user2 0 &
16555         pid1=$!
16556         sleep 2
16557         __changelog_clear mds1 $cl_user1 0 ||
16558                 error "fail to cancel record for $cl_user1"
16559         wait $pid1
16560         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16561 }
16562 run_test 160m "Changelog clear race"
16563
16564 test_160n() {
16565         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16566         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16567                 skip "Need MDS version at least 2.14.51"
16568         local cl_users
16569         local cl_user1
16570         local cl_user2
16571         local pid1
16572         local first_rec
16573         local last_rec=0
16574
16575         # Create a user
16576         changelog_register || error "first changelog_register failed"
16577
16578         cl_users=(${CL_USERS[mds1]})
16579         cl_user1="${cl_users[0]}"
16580
16581         # generate some changelog records to accumulate on MDT0
16582         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16583         first_rec=$(changelog_users $SINGLEMDS |
16584                         awk '/^current.index:/ { print $NF }')
16585         while (( last_rec < (( first_rec + 65000)) )); do
16586                 createmany -m $DIR/$tdir/$tfile 10000 ||
16587                         error "create $DIR/$tdir/$tfile failed"
16588
16589                 for i in $(seq 0 10000); do
16590                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16591                                 > /dev/null
16592                 done
16593
16594                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16595                         error "unlinkmany failed unlink"
16596                 last_rec=$(changelog_users $SINGLEMDS |
16597                         awk '/^current.index:/ { print $NF }')
16598                 echo last record $last_rec
16599                 (( last_rec == 0 )) && error "no changelog found"
16600         done
16601
16602 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16603         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16604
16605         __changelog_clear mds1 $cl_user1 0 &
16606         pid1=$!
16607         sleep 2
16608         __changelog_clear mds1 $cl_user1 0 ||
16609                 error "fail to cancel record for $cl_user1"
16610         wait $pid1
16611         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16612 }
16613 run_test 160n "Changelog destroy race"
16614
16615 test_160o() {
16616         local mdt="$(facet_svc $SINGLEMDS)"
16617
16618         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16619         remote_mds_nodsh && skip "remote MDS with nodsh"
16620         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
16621                 skip "Need MDS version at least 2.14.52"
16622
16623         changelog_register --user test_160o -m unlnk+close+open ||
16624                 error "changelog_register failed"
16625
16626         do_facet $SINGLEMDS $LCTL --device $mdt \
16627                                 changelog_register -u "Tt3_-#" &&
16628                 error "bad symbols in name should fail"
16629
16630         do_facet $SINGLEMDS $LCTL --device $mdt \
16631                                 changelog_register -u test_160o &&
16632                 error "the same name registration should fail"
16633
16634         do_facet $SINGLEMDS $LCTL --device $mdt \
16635                         changelog_register -u test_160toolongname &&
16636                 error "too long name registration should fail"
16637
16638         changelog_chmask "MARK+HSM"
16639         lctl get_param mdd.*.changelog*mask
16640         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16641         changelog_users $SINGLEMDS | grep -q $cl_user ||
16642                 error "User $cl_user not found in changelog_users"
16643         #verify username
16644         echo $cl_user | grep -q test_160o ||
16645                 error "User $cl_user has no specific name 'test160o'"
16646
16647         # change something
16648         changelog_clear 0 || error "changelog_clear failed"
16649         # generate some changelog records to accumulate on MDT0
16650         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16651         touch $DIR/$tdir/$tfile                 # open 1
16652
16653         OPENS=$(changelog_dump | grep -c "OPEN")
16654         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
16655
16656         # must be no MKDIR it wasn't set as user mask
16657         MKDIR=$(changelog_dump | grep -c "MKDIR")
16658         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
16659
16660         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
16661                                 mdd.$mdt.changelog_current_mask -n)
16662         # register maskless user
16663         changelog_register || error "changelog_register failed"
16664         # effective mask should be not changed because it is not minimal
16665         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16666                                 mdd.$mdt.changelog_current_mask -n)
16667         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
16668         # set server mask to minimal value
16669         changelog_chmask "MARK"
16670         # check effective mask again, should be treated as DEFMASK now
16671         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16672                                 mdd.$mdt.changelog_current_mask -n)
16673         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16674
16675         do_facet $SINGLEMDS $LCTL --device $mdt \
16676                                 changelog_deregister -u test_160o ||
16677                 error "cannot deregister by name"
16678 }
16679 run_test 160o "changelog user name and mask"
16680
16681 test_160p() {
16682         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16683         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16684                 skip "Need MDS version at least 2.14.51"
16685         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
16686         local cl_users
16687         local cl_user1
16688         local entry_count
16689
16690         # Create a user
16691         changelog_register || error "first changelog_register failed"
16692
16693         cl_users=(${CL_USERS[mds1]})
16694         cl_user1="${cl_users[0]}"
16695
16696         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16697         createmany -m $DIR/$tdir/$tfile 50 ||
16698                 error "create $DIR/$tdir/$tfile failed"
16699         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16700         rm -rf $DIR/$tdir
16701
16702         # check changelogs have been generated
16703         entry_count=$(changelog_dump | wc -l)
16704         ((entry_count != 0)) || error "no changelog entries found"
16705
16706         # remove changelog_users and check that orphan entries are removed
16707         stop mds1
16708         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $(mdsdevname 1)"
16709         start mds1 || error "cannot start mdt"
16710         entry_count=$(changelog_dump | wc -l)
16711         ((entry_count == 0)) ||
16712                 error "found $entry_count changelog entries, expected none"
16713 }
16714 run_test 160p "Changelog orphan cleanup with no users"
16715
16716 test_160q() {
16717         local mdt="$(facet_svc $SINGLEMDS)"
16718         local clu
16719
16720         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16721         remote_mds_nodsh && skip "remote MDS with nodsh"
16722         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
16723                 skip "Need MDS version at least 2.14.54"
16724
16725         # set server mask to minimal value like server init does
16726         changelog_chmask "MARK"
16727         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
16728                 error "changelog_register failed"
16729         # check effective mask again, should be treated as DEFMASK now
16730         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16731                                 mdd.$mdt.changelog_current_mask -n)
16732         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
16733                 error "changelog_deregister failed"
16734         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16735 }
16736 run_test 160q "changelog effective mask is DEFMASK if not set"
16737
16738 test_160s() {
16739         remote_mds_nodsh && skip "remote MDS with nodsh"
16740         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
16741                 skip "Need MDS version at least 2.14.55"
16742
16743         local mdts=$(comma_list $(mdts_nodes))
16744
16745         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
16746         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
16747                                        fail_val=$((24 * 3600 * 10))
16748
16749         # Create a user which is 10 days old
16750         changelog_register || error "first changelog_register failed"
16751         local cl_users
16752         declare -A cl_user1
16753         local i
16754
16755         # generate some changelog records to accumulate on each MDT
16756         # use all_char because created files should be evenly distributed
16757         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16758                 error "test_mkdir $tdir failed"
16759         for ((i = 0; i < MDSCOUNT; i++)); do
16760                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16761                         error "create $DIR/$tdir/d$i.1 failed"
16762         done
16763
16764         # check changelogs have been generated
16765         local nbcl=$(changelog_dump | wc -l)
16766         (( nbcl > 0 )) || error "no changelogs found"
16767
16768         # reduce the max_idle_indexes value to make sure we exceed it
16769         for param in "changelog_max_idle_indexes=2097446912" \
16770                      "changelog_max_idle_time=2592000" \
16771                      "changelog_gc=1" \
16772                      "changelog_min_gc_interval=2"; do
16773                 local MDT0=$(facet_svc $SINGLEMDS)
16774                 local var="${param%=*}"
16775                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16776
16777                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16778                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16779                         error "unable to set mdd.*.$param"
16780         done
16781
16782         local start=$SECONDS
16783         for i in $(seq $MDSCOUNT); do
16784                 cl_users=(${CL_USERS[mds$i]})
16785                 cl_user1[mds$i]="${cl_users[0]}"
16786
16787                 [[ -n "${cl_user1[mds$i]}" ]] ||
16788                         error "mds$i: no user registered"
16789         done
16790
16791         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
16792         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
16793
16794         # ensure we are past the previous changelog_min_gc_interval set above
16795         local sleep2=$((start + 2 - SECONDS))
16796         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16797
16798         # Generate one more changelog to trigger GC
16799         for ((i = 0; i < MDSCOUNT; i++)); do
16800                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
16801                         error "create $DIR/$tdir/d$i.3 failed"
16802         done
16803
16804         # ensure gc thread is done
16805         for node in $(mdts_nodes); do
16806                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
16807                         error "$node: GC-thread not done"
16808         done
16809
16810         do_nodes $mdts $LCTL set_param fail_loc=0
16811
16812         for (( i = 1; i <= MDSCOUNT; i++ )); do
16813                 # check cl_user1 is purged
16814                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
16815                         error "mds$i: User ${cl_user1[mds$i]} is registered"
16816         done
16817         return 0
16818 }
16819 run_test 160s "changelog garbage collect on idle records * time"
16820
16821 test_161a() {
16822         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16823
16824         test_mkdir -c1 $DIR/$tdir
16825         cp /etc/hosts $DIR/$tdir/$tfile
16826         test_mkdir -c1 $DIR/$tdir/foo1
16827         test_mkdir -c1 $DIR/$tdir/foo2
16828         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
16829         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
16830         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
16831         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
16832         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
16833         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16834                 $LFS fid2path $DIR $FID
16835                 error "bad link ea"
16836         fi
16837         # middle
16838         rm $DIR/$tdir/foo2/zachary
16839         # last
16840         rm $DIR/$tdir/foo2/thor
16841         # first
16842         rm $DIR/$tdir/$tfile
16843         # rename
16844         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
16845         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
16846                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
16847         rm $DIR/$tdir/foo2/maggie
16848
16849         # overflow the EA
16850         local longname=$tfile.avg_len_is_thirty_two_
16851         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
16852                 error_noexit 'failed to unlink many hardlinks'" EXIT
16853         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
16854                 error "failed to hardlink many files"
16855         links=$($LFS fid2path $DIR $FID | wc -l)
16856         echo -n "${links}/1000 links in link EA"
16857         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
16858 }
16859 run_test 161a "link ea sanity"
16860
16861 test_161b() {
16862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16863         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
16864
16865         local MDTIDX=1
16866         local remote_dir=$DIR/$tdir/remote_dir
16867
16868         mkdir -p $DIR/$tdir
16869         $LFS mkdir -i $MDTIDX $remote_dir ||
16870                 error "create remote directory failed"
16871
16872         cp /etc/hosts $remote_dir/$tfile
16873         mkdir -p $remote_dir/foo1
16874         mkdir -p $remote_dir/foo2
16875         ln $remote_dir/$tfile $remote_dir/foo1/sofia
16876         ln $remote_dir/$tfile $remote_dir/foo2/zachary
16877         ln $remote_dir/$tfile $remote_dir/foo1/luna
16878         ln $remote_dir/$tfile $remote_dir/foo2/thor
16879
16880         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
16881                      tr -d ']')
16882         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16883                 $LFS fid2path $DIR $FID
16884                 error "bad link ea"
16885         fi
16886         # middle
16887         rm $remote_dir/foo2/zachary
16888         # last
16889         rm $remote_dir/foo2/thor
16890         # first
16891         rm $remote_dir/$tfile
16892         # rename
16893         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
16894         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
16895         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
16896                 $LFS fid2path $DIR $FID
16897                 error "bad link rename"
16898         fi
16899         rm $remote_dir/foo2/maggie
16900
16901         # overflow the EA
16902         local longname=filename_avg_len_is_thirty_two_
16903         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
16904                 error "failed to hardlink many files"
16905         links=$($LFS fid2path $DIR $FID | wc -l)
16906         echo -n "${links}/1000 links in link EA"
16907         [[ ${links} -gt 60 ]] ||
16908                 error "expected at least 60 links in link EA"
16909         unlinkmany $remote_dir/foo2/$longname 1000 ||
16910         error "failed to unlink many hardlinks"
16911 }
16912 run_test 161b "link ea sanity under remote directory"
16913
16914 test_161c() {
16915         remote_mds_nodsh && skip "remote MDS with nodsh"
16916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16917         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
16918                 skip "Need MDS version at least 2.1.5"
16919
16920         # define CLF_RENAME_LAST 0x0001
16921         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
16922         changelog_register || error "changelog_register failed"
16923
16924         rm -rf $DIR/$tdir
16925         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
16926         touch $DIR/$tdir/foo_161c
16927         touch $DIR/$tdir/bar_161c
16928         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16929         changelog_dump | grep RENME | tail -n 5
16930         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16931         changelog_clear 0 || error "changelog_clear failed"
16932         if [ x$flags != "x0x1" ]; then
16933                 error "flag $flags is not 0x1"
16934         fi
16935
16936         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
16937         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
16938         touch $DIR/$tdir/foo_161c
16939         touch $DIR/$tdir/bar_161c
16940         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16941         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16942         changelog_dump | grep RENME | tail -n 5
16943         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16944         changelog_clear 0 || error "changelog_clear failed"
16945         if [ x$flags != "x0x0" ]; then
16946                 error "flag $flags is not 0x0"
16947         fi
16948         echo "rename overwrite a target having nlink > 1," \
16949                 "changelog record has flags of $flags"
16950
16951         # rename doesn't overwrite a target (changelog flag 0x0)
16952         touch $DIR/$tdir/foo_161c
16953         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
16954         changelog_dump | grep RENME | tail -n 5
16955         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
16956         changelog_clear 0 || error "changelog_clear failed"
16957         if [ x$flags != "x0x0" ]; then
16958                 error "flag $flags is not 0x0"
16959         fi
16960         echo "rename doesn't overwrite a target," \
16961                 "changelog record has flags of $flags"
16962
16963         # define CLF_UNLINK_LAST 0x0001
16964         # unlink a file having nlink = 1 (changelog flag 0x1)
16965         rm -f $DIR/$tdir/foo2_161c
16966         changelog_dump | grep UNLNK | tail -n 5
16967         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16968         changelog_clear 0 || error "changelog_clear failed"
16969         if [ x$flags != "x0x1" ]; then
16970                 error "flag $flags is not 0x1"
16971         fi
16972         echo "unlink a file having nlink = 1," \
16973                 "changelog record has flags of $flags"
16974
16975         # unlink a file having nlink > 1 (changelog flag 0x0)
16976         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16977         rm -f $DIR/$tdir/foobar_161c
16978         changelog_dump | grep UNLNK | tail -n 5
16979         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16980         changelog_clear 0 || error "changelog_clear failed"
16981         if [ x$flags != "x0x0" ]; then
16982                 error "flag $flags is not 0x0"
16983         fi
16984         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
16985 }
16986 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
16987
16988 test_161d() {
16989         remote_mds_nodsh && skip "remote MDS with nodsh"
16990         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
16991
16992         local pid
16993         local fid
16994
16995         changelog_register || error "changelog_register failed"
16996
16997         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
16998         # interfer with $MOUNT/.lustre/fid/ access
16999         mkdir $DIR/$tdir
17000         [[ $? -eq 0 ]] || error "mkdir failed"
17001
17002         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17003         $LCTL set_param fail_loc=0x8000140c
17004         # 5s pause
17005         $LCTL set_param fail_val=5
17006
17007         # create file
17008         echo foofoo > $DIR/$tdir/$tfile &
17009         pid=$!
17010
17011         # wait for create to be delayed
17012         sleep 2
17013
17014         ps -p $pid
17015         [[ $? -eq 0 ]] || error "create should be blocked"
17016
17017         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17018         stack_trap "rm -f $tempfile"
17019         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17020         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17021         # some delay may occur during ChangeLog publishing and file read just
17022         # above, that could allow file write to happen finally
17023         [[ -s $tempfile ]] && echo "file should be empty"
17024
17025         $LCTL set_param fail_loc=0
17026
17027         wait $pid
17028         [[ $? -eq 0 ]] || error "create failed"
17029 }
17030 run_test 161d "create with concurrent .lustre/fid access"
17031
17032 check_path() {
17033         local expected="$1"
17034         shift
17035         local fid="$2"
17036
17037         local path
17038         path=$($LFS fid2path "$@")
17039         local rc=$?
17040
17041         if [ $rc -ne 0 ]; then
17042                 error "path looked up of '$expected' failed: rc=$rc"
17043         elif [ "$path" != "$expected" ]; then
17044                 error "path looked up '$path' instead of '$expected'"
17045         else
17046                 echo "FID '$fid' resolves to path '$path' as expected"
17047         fi
17048 }
17049
17050 test_162a() { # was test_162
17051         test_mkdir -p -c1 $DIR/$tdir/d2
17052         touch $DIR/$tdir/d2/$tfile
17053         touch $DIR/$tdir/d2/x1
17054         touch $DIR/$tdir/d2/x2
17055         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17056         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17057         # regular file
17058         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17059         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17060
17061         # softlink
17062         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17063         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17064         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17065
17066         # softlink to wrong file
17067         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17068         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17069         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17070
17071         # hardlink
17072         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17073         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17074         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17075         # fid2path dir/fsname should both work
17076         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17077         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17078
17079         # hardlink count: check that there are 2 links
17080         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17081         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17082
17083         # hardlink indexing: remove the first link
17084         rm $DIR/$tdir/d2/p/q/r/hlink
17085         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17086 }
17087 run_test 162a "path lookup sanity"
17088
17089 test_162b() {
17090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17091         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17092
17093         mkdir $DIR/$tdir
17094         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17095                                 error "create striped dir failed"
17096
17097         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17098                                         tail -n 1 | awk '{print $2}')
17099         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17100
17101         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17102         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17103
17104         # regular file
17105         for ((i=0;i<5;i++)); do
17106                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17107                         error "get fid for f$i failed"
17108                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17109
17110                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17111                         error "get fid for d$i failed"
17112                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17113         done
17114
17115         return 0
17116 }
17117 run_test 162b "striped directory path lookup sanity"
17118
17119 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17120 test_162c() {
17121         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17122                 skip "Need MDS version at least 2.7.51"
17123
17124         local lpath=$tdir.local
17125         local rpath=$tdir.remote
17126
17127         test_mkdir $DIR/$lpath
17128         test_mkdir $DIR/$rpath
17129
17130         for ((i = 0; i <= 101; i++)); do
17131                 lpath="$lpath/$i"
17132                 mkdir $DIR/$lpath
17133                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17134                         error "get fid for local directory $DIR/$lpath failed"
17135                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17136
17137                 rpath="$rpath/$i"
17138                 test_mkdir $DIR/$rpath
17139                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17140                         error "get fid for remote directory $DIR/$rpath failed"
17141                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17142         done
17143
17144         return 0
17145 }
17146 run_test 162c "fid2path works with paths 100 or more directories deep"
17147
17148 oalr_event_count() {
17149         local event="${1}"
17150         local trace="${2}"
17151
17152         awk -v name="${FSNAME}-OST0000" \
17153             -v event="${event}" \
17154             '$1 == "TRACE" && $2 == event && $3 == name' \
17155             "${trace}" |
17156         wc -l
17157 }
17158
17159 oalr_expect_event_count() {
17160         local event="${1}"
17161         local trace="${2}"
17162         local expect="${3}"
17163         local count
17164
17165         count=$(oalr_event_count "${event}" "${trace}")
17166         if ((count == expect)); then
17167                 return 0
17168         fi
17169
17170         error_noexit "${event} event count was '${count}', expected ${expect}"
17171         cat "${trace}" >&2
17172         exit 1
17173 }
17174
17175 cleanup_165() {
17176         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
17177         stop ost1
17178         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
17179 }
17180
17181 setup_165() {
17182         sync # Flush previous IOs so we can count log entries.
17183         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
17184         stack_trap cleanup_165 EXIT
17185 }
17186
17187 test_165a() {
17188         local trace="/tmp/${tfile}.trace"
17189         local rc
17190         local count
17191
17192         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17193                 skip "OFD access log unsupported"
17194
17195         setup_165
17196         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17197         sleep 5
17198
17199         do_facet ost1 ofd_access_log_reader --list
17200         stop ost1
17201
17202         do_facet ost1 killall -TERM ofd_access_log_reader
17203         wait
17204         rc=$?
17205
17206         if ((rc != 0)); then
17207                 error "ofd_access_log_reader exited with rc = '${rc}'"
17208         fi
17209
17210         # Parse trace file for discovery events:
17211         oalr_expect_event_count alr_log_add "${trace}" 1
17212         oalr_expect_event_count alr_log_eof "${trace}" 1
17213         oalr_expect_event_count alr_log_free "${trace}" 1
17214 }
17215 run_test 165a "ofd access log discovery"
17216
17217 test_165b() {
17218         local trace="/tmp/${tfile}.trace"
17219         local file="${DIR}/${tfile}"
17220         local pfid1
17221         local pfid2
17222         local -a entry
17223         local rc
17224         local count
17225         local size
17226         local flags
17227
17228         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17229                 skip "OFD access log unsupported"
17230
17231         setup_165
17232         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17233         sleep 5
17234
17235         do_facet ost1 ofd_access_log_reader --list
17236
17237         lfs setstripe -c 1 -i 0 "${file}"
17238         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17239                 error "cannot create '${file}'"
17240
17241         sleep 5
17242         do_facet ost1 killall -TERM ofd_access_log_reader
17243         wait
17244         rc=$?
17245
17246         if ((rc != 0)); then
17247                 error "ofd_access_log_reader exited with rc = '${rc}'"
17248         fi
17249
17250         oalr_expect_event_count alr_log_entry "${trace}" 1
17251
17252         pfid1=$($LFS path2fid "${file}")
17253
17254         # 1     2             3   4    5     6   7    8    9     10
17255         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
17256         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17257
17258         echo "entry = '${entry[*]}'" >&2
17259
17260         pfid2=${entry[4]}
17261         if [[ "${pfid1}" != "${pfid2}" ]]; then
17262                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17263         fi
17264
17265         size=${entry[8]}
17266         if ((size != 1048576)); then
17267                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
17268         fi
17269
17270         flags=${entry[10]}
17271         if [[ "${flags}" != "w" ]]; then
17272                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
17273         fi
17274
17275         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17276         sleep 5
17277
17278         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17279                 error "cannot read '${file}'"
17280         sleep 5
17281
17282         do_facet ost1 killall -TERM ofd_access_log_reader
17283         wait
17284         rc=$?
17285
17286         if ((rc != 0)); then
17287                 error "ofd_access_log_reader exited with rc = '${rc}'"
17288         fi
17289
17290         oalr_expect_event_count alr_log_entry "${trace}" 1
17291
17292         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17293         echo "entry = '${entry[*]}'" >&2
17294
17295         pfid2=${entry[4]}
17296         if [[ "${pfid1}" != "${pfid2}" ]]; then
17297                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17298         fi
17299
17300         size=${entry[8]}
17301         if ((size != 524288)); then
17302                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17303         fi
17304
17305         flags=${entry[10]}
17306         if [[ "${flags}" != "r" ]]; then
17307                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17308         fi
17309 }
17310 run_test 165b "ofd access log entries are produced and consumed"
17311
17312 test_165c() {
17313         local trace="/tmp/${tfile}.trace"
17314         local file="${DIR}/${tdir}/${tfile}"
17315
17316         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17317                 skip "OFD access log unsupported"
17318
17319         test_mkdir "${DIR}/${tdir}"
17320
17321         setup_165
17322         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17323         sleep 5
17324
17325         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17326
17327         # 4096 / 64 = 64. Create twice as many entries.
17328         for ((i = 0; i < 128; i++)); do
17329                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17330                         error "cannot create file"
17331         done
17332
17333         sync
17334
17335         do_facet ost1 killall -TERM ofd_access_log_reader
17336         wait
17337         rc=$?
17338         if ((rc != 0)); then
17339                 error "ofd_access_log_reader exited with rc = '${rc}'"
17340         fi
17341
17342         unlinkmany  "${file}-%d" 128
17343 }
17344 run_test 165c "full ofd access logs do not block IOs"
17345
17346 oal_get_read_count() {
17347         local stats="$1"
17348
17349         # STATS lustre-OST0001 alr_read_count 1
17350
17351         do_facet ost1 cat "${stats}" |
17352         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17353              END { print count; }'
17354 }
17355
17356 oal_expect_read_count() {
17357         local stats="$1"
17358         local count
17359         local expect="$2"
17360
17361         # Ask ofd_access_log_reader to write stats.
17362         do_facet ost1 killall -USR1 ofd_access_log_reader
17363
17364         # Allow some time for things to happen.
17365         sleep 1
17366
17367         count=$(oal_get_read_count "${stats}")
17368         if ((count == expect)); then
17369                 return 0
17370         fi
17371
17372         error_noexit "bad read count, got ${count}, expected ${expect}"
17373         do_facet ost1 cat "${stats}" >&2
17374         exit 1
17375 }
17376
17377 test_165d() {
17378         local stats="/tmp/${tfile}.stats"
17379         local file="${DIR}/${tdir}/${tfile}"
17380         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
17381
17382         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17383                 skip "OFD access log unsupported"
17384
17385         test_mkdir "${DIR}/${tdir}"
17386
17387         setup_165
17388         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
17389         sleep 5
17390
17391         lfs setstripe -c 1 -i 0 "${file}"
17392
17393         do_facet ost1 lctl set_param "${param}=rw"
17394         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17395                 error "cannot create '${file}'"
17396         oal_expect_read_count "${stats}" 1
17397
17398         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17399                 error "cannot read '${file}'"
17400         oal_expect_read_count "${stats}" 2
17401
17402         do_facet ost1 lctl set_param "${param}=r"
17403         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17404                 error "cannot create '${file}'"
17405         oal_expect_read_count "${stats}" 2
17406
17407         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17408                 error "cannot read '${file}'"
17409         oal_expect_read_count "${stats}" 3
17410
17411         do_facet ost1 lctl set_param "${param}=w"
17412         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17413                 error "cannot create '${file}'"
17414         oal_expect_read_count "${stats}" 4
17415
17416         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17417                 error "cannot read '${file}'"
17418         oal_expect_read_count "${stats}" 4
17419
17420         do_facet ost1 lctl set_param "${param}=0"
17421         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17422                 error "cannot create '${file}'"
17423         oal_expect_read_count "${stats}" 4
17424
17425         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17426                 error "cannot read '${file}'"
17427         oal_expect_read_count "${stats}" 4
17428
17429         do_facet ost1 killall -TERM ofd_access_log_reader
17430         wait
17431         rc=$?
17432         if ((rc != 0)); then
17433                 error "ofd_access_log_reader exited with rc = '${rc}'"
17434         fi
17435 }
17436 run_test 165d "ofd_access_log mask works"
17437
17438 test_165e() {
17439         local stats="/tmp/${tfile}.stats"
17440         local file0="${DIR}/${tdir}-0/${tfile}"
17441         local file1="${DIR}/${tdir}-1/${tfile}"
17442
17443         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17444                 skip "OFD access log unsupported"
17445
17446         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
17447
17448         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
17449         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
17450
17451         lfs setstripe -c 1 -i 0 "${file0}"
17452         lfs setstripe -c 1 -i 0 "${file1}"
17453
17454         setup_165
17455         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
17456         sleep 5
17457
17458         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
17459                 error "cannot create '${file0}'"
17460         sync
17461         oal_expect_read_count "${stats}" 0
17462
17463         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
17464                 error "cannot create '${file1}'"
17465         sync
17466         oal_expect_read_count "${stats}" 1
17467
17468         do_facet ost1 killall -TERM ofd_access_log_reader
17469         wait
17470         rc=$?
17471         if ((rc != 0)); then
17472                 error "ofd_access_log_reader exited with rc = '${rc}'"
17473         fi
17474 }
17475 run_test 165e "ofd_access_log MDT index filter works"
17476
17477 test_165f() {
17478         local trace="/tmp/${tfile}.trace"
17479         local rc
17480         local count
17481
17482         setup_165
17483         do_facet ost1 timeout 60 ofd_access_log_reader \
17484                 --exit-on-close --debug=- --trace=- > "${trace}" &
17485         sleep 5
17486         stop ost1
17487
17488         wait
17489         rc=$?
17490
17491         if ((rc != 0)); then
17492                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
17493                 cat "${trace}"
17494                 exit 1
17495         fi
17496 }
17497 run_test 165f "ofd_access_log_reader --exit-on-close works"
17498
17499 test_169() {
17500         # do directio so as not to populate the page cache
17501         log "creating a 10 Mb file"
17502         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
17503                 error "multiop failed while creating a file"
17504         log "starting reads"
17505         dd if=$DIR/$tfile of=/dev/null bs=4096 &
17506         log "truncating the file"
17507         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
17508                 error "multiop failed while truncating the file"
17509         log "killing dd"
17510         kill %+ || true # reads might have finished
17511         echo "wait until dd is finished"
17512         wait
17513         log "removing the temporary file"
17514         rm -rf $DIR/$tfile || error "tmp file removal failed"
17515 }
17516 run_test 169 "parallel read and truncate should not deadlock"
17517
17518 test_170() {
17519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17520
17521         $LCTL clear     # bug 18514
17522         $LCTL debug_daemon start $TMP/${tfile}_log_good
17523         touch $DIR/$tfile
17524         $LCTL debug_daemon stop
17525         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
17526                 error "sed failed to read log_good"
17527
17528         $LCTL debug_daemon start $TMP/${tfile}_log_good
17529         rm -rf $DIR/$tfile
17530         $LCTL debug_daemon stop
17531
17532         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
17533                error "lctl df log_bad failed"
17534
17535         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17536         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17537
17538         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
17539         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
17540
17541         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
17542                 error "bad_line good_line1 good_line2 are empty"
17543
17544         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17545         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
17546         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17547
17548         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
17549         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17550         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17551
17552         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
17553                 error "bad_line_new good_line_new are empty"
17554
17555         local expected_good=$((good_line1 + good_line2*2))
17556
17557         rm -f $TMP/${tfile}*
17558         # LU-231, short malformed line may not be counted into bad lines
17559         if [ $bad_line -ne $bad_line_new ] &&
17560                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
17561                 error "expected $bad_line bad lines, but got $bad_line_new"
17562                 return 1
17563         fi
17564
17565         if [ $expected_good -ne $good_line_new ]; then
17566                 error "expected $expected_good good lines, but got $good_line_new"
17567                 return 2
17568         fi
17569         true
17570 }
17571 run_test 170 "test lctl df to handle corrupted log ====================="
17572
17573 test_171() { # bug20592
17574         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17575
17576         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
17577         $LCTL set_param fail_loc=0x50e
17578         $LCTL set_param fail_val=3000
17579         multiop_bg_pause $DIR/$tfile O_s || true
17580         local MULTIPID=$!
17581         kill -USR1 $MULTIPID
17582         # cause log dump
17583         sleep 3
17584         wait $MULTIPID
17585         if dmesg | grep "recursive fault"; then
17586                 error "caught a recursive fault"
17587         fi
17588         $LCTL set_param fail_loc=0
17589         true
17590 }
17591 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17592
17593 # it would be good to share it with obdfilter-survey/iokit-libecho code
17594 setup_obdecho_osc () {
17595         local rc=0
17596         local ost_nid=$1
17597         local obdfilter_name=$2
17598         echo "Creating new osc for $obdfilter_name on $ost_nid"
17599         # make sure we can find loopback nid
17600         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17601
17602         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17603                            ${obdfilter_name}_osc_UUID || rc=2; }
17604         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17605                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17606         return $rc
17607 }
17608
17609 cleanup_obdecho_osc () {
17610         local obdfilter_name=$1
17611         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17612         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17613         return 0
17614 }
17615
17616 obdecho_test() {
17617         local OBD=$1
17618         local node=$2
17619         local pages=${3:-64}
17620         local rc=0
17621         local id
17622
17623         local count=10
17624         local obd_size=$(get_obd_size $node $OBD)
17625         local page_size=$(get_page_size $node)
17626         if [[ -n "$obd_size" ]]; then
17627                 local new_count=$((obd_size / (pages * page_size / 1024)))
17628                 [[ $new_count -ge $count ]] || count=$new_count
17629         fi
17630
17631         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17632         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17633                            rc=2; }
17634         if [ $rc -eq 0 ]; then
17635             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17636             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17637         fi
17638         echo "New object id is $id"
17639         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17640                            rc=4; }
17641         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17642                            "test_brw $count w v $pages $id" || rc=4; }
17643         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17644                            rc=4; }
17645         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17646                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17647         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17648                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17649         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17650         return $rc
17651 }
17652
17653 test_180a() {
17654         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17655
17656         if ! [ -d /sys/fs/lustre/echo_client ] &&
17657            ! module_loaded obdecho; then
17658                 load_module obdecho/obdecho &&
17659                         stack_trap "rmmod obdecho" EXIT ||
17660                         error "unable to load obdecho on client"
17661         fi
17662
17663         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
17664         local host=$($LCTL get_param -n osc.$osc.import |
17665                      awk '/current_connection:/ { print $2 }' )
17666         local target=$($LCTL get_param -n osc.$osc.import |
17667                        awk '/target:/ { print $2 }' )
17668         target=${target%_UUID}
17669
17670         if [ -n "$target" ]; then
17671                 setup_obdecho_osc $host $target &&
17672                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
17673                         { error "obdecho setup failed with $?"; return; }
17674
17675                 obdecho_test ${target}_osc client ||
17676                         error "obdecho_test failed on ${target}_osc"
17677         else
17678                 $LCTL get_param osc.$osc.import
17679                 error "there is no osc.$osc.import target"
17680         fi
17681 }
17682 run_test 180a "test obdecho on osc"
17683
17684 test_180b() {
17685         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17686         remote_ost_nodsh && skip "remote OST with nodsh"
17687
17688         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17689                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17690                 error "failed to load module obdecho"
17691
17692         local target=$(do_facet ost1 $LCTL dl |
17693                        awk '/obdfilter/ { print $4; exit; }')
17694
17695         if [ -n "$target" ]; then
17696                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17697         else
17698                 do_facet ost1 $LCTL dl
17699                 error "there is no obdfilter target on ost1"
17700         fi
17701 }
17702 run_test 180b "test obdecho directly on obdfilter"
17703
17704 test_180c() { # LU-2598
17705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17706         remote_ost_nodsh && skip "remote OST with nodsh"
17707         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17708                 skip "Need MDS version at least 2.4.0"
17709
17710         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17711                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17712                 error "failed to load module obdecho"
17713
17714         local target=$(do_facet ost1 $LCTL dl |
17715                        awk '/obdfilter/ { print $4; exit; }')
17716
17717         if [ -n "$target" ]; then
17718                 local pages=16384 # 64MB bulk I/O RPC size
17719
17720                 obdecho_test "$target" ost1 "$pages" ||
17721                         error "obdecho_test with pages=$pages failed with $?"
17722         else
17723                 do_facet ost1 $LCTL dl
17724                 error "there is no obdfilter target on ost1"
17725         fi
17726 }
17727 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
17728
17729 test_181() { # bug 22177
17730         test_mkdir $DIR/$tdir
17731         # create enough files to index the directory
17732         createmany -o $DIR/$tdir/foobar 4000
17733         # print attributes for debug purpose
17734         lsattr -d .
17735         # open dir
17736         multiop_bg_pause $DIR/$tdir D_Sc || return 1
17737         MULTIPID=$!
17738         # remove the files & current working dir
17739         unlinkmany $DIR/$tdir/foobar 4000
17740         rmdir $DIR/$tdir
17741         kill -USR1 $MULTIPID
17742         wait $MULTIPID
17743         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
17744         return 0
17745 }
17746 run_test 181 "Test open-unlinked dir ========================"
17747
17748 test_182() {
17749         local fcount=1000
17750         local tcount=10
17751
17752         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17753
17754         $LCTL set_param mdc.*.rpc_stats=clear
17755
17756         for (( i = 0; i < $tcount; i++ )) ; do
17757                 mkdir $DIR/$tdir/$i
17758         done
17759
17760         for (( i = 0; i < $tcount; i++ )) ; do
17761                 createmany -o $DIR/$tdir/$i/f- $fcount &
17762         done
17763         wait
17764
17765         for (( i = 0; i < $tcount; i++ )) ; do
17766                 unlinkmany $DIR/$tdir/$i/f- $fcount &
17767         done
17768         wait
17769
17770         $LCTL get_param mdc.*.rpc_stats
17771
17772         rm -rf $DIR/$tdir
17773 }
17774 run_test 182 "Test parallel modify metadata operations ================"
17775
17776 test_183() { # LU-2275
17777         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17778         remote_mds_nodsh && skip "remote MDS with nodsh"
17779         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
17780                 skip "Need MDS version at least 2.3.56"
17781
17782         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17783         echo aaa > $DIR/$tdir/$tfile
17784
17785 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
17786         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
17787
17788         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
17789         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
17790
17791         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17792
17793         # Flush negative dentry cache
17794         touch $DIR/$tdir/$tfile
17795
17796         # We are not checking for any leaked references here, they'll
17797         # become evident next time we do cleanup with module unload.
17798         rm -rf $DIR/$tdir
17799 }
17800 run_test 183 "No crash or request leak in case of strange dispositions ========"
17801
17802 # test suite 184 is for LU-2016, LU-2017
17803 test_184a() {
17804         check_swap_layouts_support
17805
17806         dir0=$DIR/$tdir/$testnum
17807         test_mkdir -p -c1 $dir0
17808         ref1=/etc/passwd
17809         ref2=/etc/group
17810         file1=$dir0/f1
17811         file2=$dir0/f2
17812         $LFS setstripe -c1 $file1
17813         cp $ref1 $file1
17814         $LFS setstripe -c2 $file2
17815         cp $ref2 $file2
17816         gen1=$($LFS getstripe -g $file1)
17817         gen2=$($LFS getstripe -g $file2)
17818
17819         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
17820         gen=$($LFS getstripe -g $file1)
17821         [[ $gen1 != $gen ]] ||
17822                 "Layout generation on $file1 does not change"
17823         gen=$($LFS getstripe -g $file2)
17824         [[ $gen2 != $gen ]] ||
17825                 "Layout generation on $file2 does not change"
17826
17827         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
17828         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17829
17830         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
17831 }
17832 run_test 184a "Basic layout swap"
17833
17834 test_184b() {
17835         check_swap_layouts_support
17836
17837         dir0=$DIR/$tdir/$testnum
17838         mkdir -p $dir0 || error "creating dir $dir0"
17839         file1=$dir0/f1
17840         file2=$dir0/f2
17841         file3=$dir0/f3
17842         dir1=$dir0/d1
17843         dir2=$dir0/d2
17844         mkdir $dir1 $dir2
17845         $LFS setstripe -c1 $file1
17846         $LFS setstripe -c2 $file2
17847         $LFS setstripe -c1 $file3
17848         chown $RUNAS_ID $file3
17849         gen1=$($LFS getstripe -g $file1)
17850         gen2=$($LFS getstripe -g $file2)
17851
17852         $LFS swap_layouts $dir1 $dir2 &&
17853                 error "swap of directories layouts should fail"
17854         $LFS swap_layouts $dir1 $file1 &&
17855                 error "swap of directory and file layouts should fail"
17856         $RUNAS $LFS swap_layouts $file1 $file2 &&
17857                 error "swap of file we cannot write should fail"
17858         $LFS swap_layouts $file1 $file3 &&
17859                 error "swap of file with different owner should fail"
17860         /bin/true # to clear error code
17861 }
17862 run_test 184b "Forbidden layout swap (will generate errors)"
17863
17864 test_184c() {
17865         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
17866         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
17867         check_swap_layouts_support
17868         check_swap_layout_no_dom $DIR
17869
17870         local dir0=$DIR/$tdir/$testnum
17871         mkdir -p $dir0 || error "creating dir $dir0"
17872
17873         local ref1=$dir0/ref1
17874         local ref2=$dir0/ref2
17875         local file1=$dir0/file1
17876         local file2=$dir0/file2
17877         # create a file large enough for the concurrent test
17878         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
17879         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
17880         echo "ref file size: ref1($(stat -c %s $ref1))," \
17881              "ref2($(stat -c %s $ref2))"
17882
17883         cp $ref2 $file2
17884         dd if=$ref1 of=$file1 bs=16k &
17885         local DD_PID=$!
17886
17887         # Make sure dd starts to copy file, but wait at most 5 seconds
17888         local loops=0
17889         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
17890
17891         $LFS swap_layouts $file1 $file2
17892         local rc=$?
17893         wait $DD_PID
17894         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
17895         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
17896
17897         # how many bytes copied before swapping layout
17898         local copied=$(stat -c %s $file2)
17899         local remaining=$(stat -c %s $ref1)
17900         remaining=$((remaining - copied))
17901         echo "Copied $copied bytes before swapping layout..."
17902
17903         cmp -n $copied $file1 $ref2 | grep differ &&
17904                 error "Content mismatch [0, $copied) of ref2 and file1"
17905         cmp -n $copied $file2 $ref1 ||
17906                 error "Content mismatch [0, $copied) of ref1 and file2"
17907         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
17908                 error "Content mismatch [$copied, EOF) of ref1 and file1"
17909
17910         # clean up
17911         rm -f $ref1 $ref2 $file1 $file2
17912 }
17913 run_test 184c "Concurrent write and layout swap"
17914
17915 test_184d() {
17916         check_swap_layouts_support
17917         check_swap_layout_no_dom $DIR
17918         [ -z "$(which getfattr 2>/dev/null)" ] &&
17919                 skip_env "no getfattr command"
17920
17921         local file1=$DIR/$tdir/$tfile-1
17922         local file2=$DIR/$tdir/$tfile-2
17923         local file3=$DIR/$tdir/$tfile-3
17924         local lovea1
17925         local lovea2
17926
17927         mkdir -p $DIR/$tdir
17928         touch $file1 || error "create $file1 failed"
17929         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17930                 error "create $file2 failed"
17931         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17932                 error "create $file3 failed"
17933         lovea1=$(get_layout_param $file1)
17934
17935         $LFS swap_layouts $file2 $file3 ||
17936                 error "swap $file2 $file3 layouts failed"
17937         $LFS swap_layouts $file1 $file2 ||
17938                 error "swap $file1 $file2 layouts failed"
17939
17940         lovea2=$(get_layout_param $file2)
17941         echo "$lovea1"
17942         echo "$lovea2"
17943         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
17944
17945         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17946         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
17947 }
17948 run_test 184d "allow stripeless layouts swap"
17949
17950 test_184e() {
17951         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
17952                 skip "Need MDS version at least 2.6.94"
17953         check_swap_layouts_support
17954         check_swap_layout_no_dom $DIR
17955         [ -z "$(which getfattr 2>/dev/null)" ] &&
17956                 skip_env "no getfattr command"
17957
17958         local file1=$DIR/$tdir/$tfile-1
17959         local file2=$DIR/$tdir/$tfile-2
17960         local file3=$DIR/$tdir/$tfile-3
17961         local lovea
17962
17963         mkdir -p $DIR/$tdir
17964         touch $file1 || error "create $file1 failed"
17965         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17966                 error "create $file2 failed"
17967         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17968                 error "create $file3 failed"
17969
17970         $LFS swap_layouts $file1 $file2 ||
17971                 error "swap $file1 $file2 layouts failed"
17972
17973         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17974         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
17975
17976         echo 123 > $file1 || error "Should be able to write into $file1"
17977
17978         $LFS swap_layouts $file1 $file3 ||
17979                 error "swap $file1 $file3 layouts failed"
17980
17981         echo 123 > $file1 || error "Should be able to write into $file1"
17982
17983         rm -rf $file1 $file2 $file3
17984 }
17985 run_test 184e "Recreate layout after stripeless layout swaps"
17986
17987 test_184f() {
17988         # Create a file with name longer than sizeof(struct stat) ==
17989         # 144 to see if we can get chars from the file name to appear
17990         # in the returned striping. Note that 'f' == 0x66.
17991         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
17992
17993         mkdir -p $DIR/$tdir
17994         mcreate $DIR/$tdir/$file
17995         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
17996                 error "IOC_MDC_GETFILEINFO returned garbage striping"
17997         fi
17998 }
17999 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18000
18001 test_185() { # LU-2441
18002         # LU-3553 - no volatile file support in old servers
18003         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18004                 skip "Need MDS version at least 2.3.60"
18005
18006         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18007         touch $DIR/$tdir/spoo
18008         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18009         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18010                 error "cannot create/write a volatile file"
18011         [ "$FILESET" == "" ] &&
18012         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18013                 error "FID is still valid after close"
18014
18015         multiop_bg_pause $DIR/$tdir vVw4096_c
18016         local multi_pid=$!
18017
18018         local OLD_IFS=$IFS
18019         IFS=":"
18020         local fidv=($fid)
18021         IFS=$OLD_IFS
18022         # assume that the next FID for this client is sequential, since stdout
18023         # is unfortunately eaten by multiop_bg_pause
18024         local n=$((${fidv[1]} + 1))
18025         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18026         if [ "$FILESET" == "" ]; then
18027                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18028                         error "FID is missing before close"
18029         fi
18030         kill -USR1 $multi_pid
18031         # 1 second delay, so if mtime change we will see it
18032         sleep 1
18033         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18034         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18035 }
18036 run_test 185 "Volatile file support"
18037
18038 function create_check_volatile() {
18039         local idx=$1
18040         local tgt
18041
18042         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18043         local PID=$!
18044         sleep 1
18045         local FID=$(cat /tmp/${tfile}.fid)
18046         [ "$FID" == "" ] && error "can't get FID for volatile"
18047         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18048         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18049         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18050         kill -USR1 $PID
18051         wait
18052         sleep 1
18053         cancel_lru_locks mdc # flush opencache
18054         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18055         return 0
18056 }
18057
18058 test_185a(){
18059         # LU-12516 - volatile creation via .lustre
18060         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
18061                 skip "Need MDS version at least 2.3.55"
18062
18063         create_check_volatile 0
18064         [ $MDSCOUNT -lt 2 ] && return 0
18065
18066         # DNE case
18067         create_check_volatile 1
18068
18069         return 0
18070 }
18071 run_test 185a "Volatile file creation in .lustre/fid/"
18072
18073 test_187a() {
18074         remote_mds_nodsh && skip "remote MDS with nodsh"
18075         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18076                 skip "Need MDS version at least 2.3.0"
18077
18078         local dir0=$DIR/$tdir/$testnum
18079         mkdir -p $dir0 || error "creating dir $dir0"
18080
18081         local file=$dir0/file1
18082         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18083         local dv1=$($LFS data_version $file)
18084         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18085         local dv2=$($LFS data_version $file)
18086         [[ $dv1 != $dv2 ]] ||
18087                 error "data version did not change on write $dv1 == $dv2"
18088
18089         # clean up
18090         rm -f $file1
18091 }
18092 run_test 187a "Test data version change"
18093
18094 test_187b() {
18095         remote_mds_nodsh && skip "remote MDS with nodsh"
18096         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18097                 skip "Need MDS version at least 2.3.0"
18098
18099         local dir0=$DIR/$tdir/$testnum
18100         mkdir -p $dir0 || error "creating dir $dir0"
18101
18102         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
18103         [[ ${DV[0]} != ${DV[1]} ]] ||
18104                 error "data version did not change on write"\
18105                       " ${DV[0]} == ${DV[1]}"
18106
18107         # clean up
18108         rm -f $file1
18109 }
18110 run_test 187b "Test data version change on volatile file"
18111
18112 test_200() {
18113         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18114         remote_mgs_nodsh && skip "remote MGS with nodsh"
18115         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18116
18117         local POOL=${POOL:-cea1}
18118         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18119         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18120         # Pool OST targets
18121         local first_ost=0
18122         local last_ost=$(($OSTCOUNT - 1))
18123         local ost_step=2
18124         local ost_list=$(seq $first_ost $ost_step $last_ost)
18125         local ost_range="$first_ost $last_ost $ost_step"
18126         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18127         local file_dir=$POOL_ROOT/file_tst
18128         local subdir=$test_path/subdir
18129         local rc=0
18130
18131         while : ; do
18132                 # former test_200a test_200b
18133                 pool_add $POOL                          || { rc=$? ; break; }
18134                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
18135                 # former test_200c test_200d
18136                 mkdir -p $test_path
18137                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
18138                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
18139                 mkdir -p $subdir
18140                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
18141                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
18142                                                         || { rc=$? ; break; }
18143                 # former test_200e test_200f
18144                 local files=$((OSTCOUNT*3))
18145                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
18146                                                         || { rc=$? ; break; }
18147                 pool_create_files $POOL $file_dir $files "$ost_list" \
18148                                                         || { rc=$? ; break; }
18149                 # former test_200g test_200h
18150                 pool_lfs_df $POOL                       || { rc=$? ; break; }
18151                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
18152
18153                 # former test_201a test_201b test_201c
18154                 pool_remove_first_target $POOL          || { rc=$? ; break; }
18155
18156                 local f=$test_path/$tfile
18157                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
18158                 pool_remove $POOL $f                    || { rc=$? ; break; }
18159                 break
18160         done
18161
18162         destroy_test_pools
18163
18164         return $rc
18165 }
18166 run_test 200 "OST pools"
18167
18168 # usage: default_attr <count | size | offset>
18169 default_attr() {
18170         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
18171 }
18172
18173 # usage: check_default_stripe_attr
18174 check_default_stripe_attr() {
18175         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
18176         case $1 in
18177         --stripe-count|-c)
18178                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
18179         --stripe-size|-S)
18180                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
18181         --stripe-index|-i)
18182                 EXPECTED=-1;;
18183         *)
18184                 error "unknown getstripe attr '$1'"
18185         esac
18186
18187         [ $ACTUAL == $EXPECTED ] ||
18188                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
18189 }
18190
18191 test_204a() {
18192         test_mkdir $DIR/$tdir
18193         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
18194
18195         check_default_stripe_attr --stripe-count
18196         check_default_stripe_attr --stripe-size
18197         check_default_stripe_attr --stripe-index
18198 }
18199 run_test 204a "Print default stripe attributes"
18200
18201 test_204b() {
18202         test_mkdir $DIR/$tdir
18203         $LFS setstripe --stripe-count 1 $DIR/$tdir
18204
18205         check_default_stripe_attr --stripe-size
18206         check_default_stripe_attr --stripe-index
18207 }
18208 run_test 204b "Print default stripe size and offset"
18209
18210 test_204c() {
18211         test_mkdir $DIR/$tdir
18212         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18213
18214         check_default_stripe_attr --stripe-count
18215         check_default_stripe_attr --stripe-index
18216 }
18217 run_test 204c "Print default stripe count and offset"
18218
18219 test_204d() {
18220         test_mkdir $DIR/$tdir
18221         $LFS setstripe --stripe-index 0 $DIR/$tdir
18222
18223         check_default_stripe_attr --stripe-count
18224         check_default_stripe_attr --stripe-size
18225 }
18226 run_test 204d "Print default stripe count and size"
18227
18228 test_204e() {
18229         test_mkdir $DIR/$tdir
18230         $LFS setstripe -d $DIR/$tdir
18231
18232         check_default_stripe_attr --stripe-count --raw
18233         check_default_stripe_attr --stripe-size --raw
18234         check_default_stripe_attr --stripe-index --raw
18235 }
18236 run_test 204e "Print raw stripe attributes"
18237
18238 test_204f() {
18239         test_mkdir $DIR/$tdir
18240         $LFS setstripe --stripe-count 1 $DIR/$tdir
18241
18242         check_default_stripe_attr --stripe-size --raw
18243         check_default_stripe_attr --stripe-index --raw
18244 }
18245 run_test 204f "Print raw stripe size and offset"
18246
18247 test_204g() {
18248         test_mkdir $DIR/$tdir
18249         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18250
18251         check_default_stripe_attr --stripe-count --raw
18252         check_default_stripe_attr --stripe-index --raw
18253 }
18254 run_test 204g "Print raw stripe count and offset"
18255
18256 test_204h() {
18257         test_mkdir $DIR/$tdir
18258         $LFS setstripe --stripe-index 0 $DIR/$tdir
18259
18260         check_default_stripe_attr --stripe-count --raw
18261         check_default_stripe_attr --stripe-size --raw
18262 }
18263 run_test 204h "Print raw stripe count and size"
18264
18265 # Figure out which job scheduler is being used, if any,
18266 # or use a fake one
18267 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
18268         JOBENV=SLURM_JOB_ID
18269 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18270         JOBENV=LSB_JOBID
18271 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18272         JOBENV=PBS_JOBID
18273 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18274         JOBENV=LOADL_STEP_ID
18275 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18276         JOBENV=JOB_ID
18277 else
18278         $LCTL list_param jobid_name > /dev/null 2>&1
18279         if [ $? -eq 0 ]; then
18280                 JOBENV=nodelocal
18281         else
18282                 JOBENV=FAKE_JOBID
18283         fi
18284 fi
18285 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18286
18287 verify_jobstats() {
18288         local cmd=($1)
18289         shift
18290         local facets="$@"
18291
18292 # we don't really need to clear the stats for this test to work, since each
18293 # command has a unique jobid, but it makes debugging easier if needed.
18294 #       for facet in $facets; do
18295 #               local dev=$(convert_facet2label $facet)
18296 #               # clear old jobstats
18297 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18298 #       done
18299
18300         # use a new JobID for each test, or we might see an old one
18301         [ "$JOBENV" = "FAKE_JOBID" ] &&
18302                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
18303
18304         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
18305
18306         [ "$JOBENV" = "nodelocal" ] && {
18307                 FAKE_JOBID=id.$testnum.%e.$RANDOM
18308                 $LCTL set_param jobid_name=$FAKE_JOBID
18309                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
18310         }
18311
18312         log "Test: ${cmd[*]}"
18313         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
18314
18315         if [ $JOBENV = "FAKE_JOBID" ]; then
18316                 FAKE_JOBID=$JOBVAL ${cmd[*]}
18317         else
18318                 ${cmd[*]}
18319         fi
18320
18321         # all files are created on OST0000
18322         for facet in $facets; do
18323                 local stats="*.$(convert_facet2label $facet).job_stats"
18324
18325                 # strip out libtool wrappers for in-tree executables
18326                 if [ $(do_facet $facet lctl get_param $stats |
18327                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
18328                         do_facet $facet lctl get_param $stats
18329                         error "No jobstats for $JOBVAL found on $facet::$stats"
18330                 fi
18331         done
18332 }
18333
18334 jobstats_set() {
18335         local new_jobenv=$1
18336
18337         set_persistent_param_and_check client "jobid_var" \
18338                 "$FSNAME.sys.jobid_var" $new_jobenv
18339 }
18340
18341 test_205a() { # Job stats
18342         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18343         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
18344                 skip "Need MDS version with at least 2.7.1"
18345         remote_mgs_nodsh && skip "remote MGS with nodsh"
18346         remote_mds_nodsh && skip "remote MDS with nodsh"
18347         remote_ost_nodsh && skip "remote OST with nodsh"
18348         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
18349                 skip "Server doesn't support jobstats"
18350         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
18351
18352         local old_jobenv=$($LCTL get_param -n jobid_var)
18353         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
18354
18355         if [[ $PERM_CMD == *"set_param -P"* ]]; then
18356                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
18357         else
18358                 stack_trap "do_facet mgs $PERM_CMD \
18359                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
18360         fi
18361         changelog_register
18362
18363         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
18364                                 mdt.*.job_cleanup_interval | head -n 1)
18365         local new_interval=5
18366         do_facet $SINGLEMDS \
18367                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
18368         stack_trap "do_facet $SINGLEMDS \
18369                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
18370         local start=$SECONDS
18371
18372         local cmd
18373         # mkdir
18374         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
18375         verify_jobstats "$cmd" "$SINGLEMDS"
18376         # rmdir
18377         cmd="rmdir $DIR/$tdir"
18378         verify_jobstats "$cmd" "$SINGLEMDS"
18379         # mkdir on secondary MDT
18380         if [ $MDSCOUNT -gt 1 ]; then
18381                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
18382                 verify_jobstats "$cmd" "mds2"
18383         fi
18384         # mknod
18385         cmd="mknod $DIR/$tfile c 1 3"
18386         verify_jobstats "$cmd" "$SINGLEMDS"
18387         # unlink
18388         cmd="rm -f $DIR/$tfile"
18389         verify_jobstats "$cmd" "$SINGLEMDS"
18390         # create all files on OST0000 so verify_jobstats can find OST stats
18391         # open & close
18392         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
18393         verify_jobstats "$cmd" "$SINGLEMDS"
18394         # setattr
18395         cmd="touch $DIR/$tfile"
18396         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18397         # write
18398         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
18399         verify_jobstats "$cmd" "ost1"
18400         # read
18401         cancel_lru_locks osc
18402         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
18403         verify_jobstats "$cmd" "ost1"
18404         # truncate
18405         cmd="$TRUNCATE $DIR/$tfile 0"
18406         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18407         # rename
18408         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
18409         verify_jobstats "$cmd" "$SINGLEMDS"
18410         # jobstats expiry - sleep until old stats should be expired
18411         local left=$((new_interval + 5 - (SECONDS - start)))
18412         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
18413                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
18414                         "0" $left
18415         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
18416         verify_jobstats "$cmd" "$SINGLEMDS"
18417         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
18418             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
18419
18420         # Ensure that jobid are present in changelog (if supported by MDS)
18421         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
18422                 changelog_dump | tail -10
18423                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
18424                 [ $jobids -eq 9 ] ||
18425                         error "Wrong changelog jobid count $jobids != 9"
18426
18427                 # LU-5862
18428                 JOBENV="disable"
18429                 jobstats_set $JOBENV
18430                 touch $DIR/$tfile
18431                 changelog_dump | grep $tfile
18432                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
18433                 [ $jobids -eq 0 ] ||
18434                         error "Unexpected jobids when jobid_var=$JOBENV"
18435         fi
18436
18437         # test '%j' access to environment variable - if supported
18438         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
18439                 JOBENV="JOBCOMPLEX"
18440                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18441
18442                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18443         fi
18444
18445         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
18446                 JOBENV="JOBCOMPLEX"
18447                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
18448
18449                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18450         fi
18451
18452         # test '%j' access to per-session jobid - if supported
18453         if lctl list_param jobid_this_session > /dev/null 2>&1
18454         then
18455                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
18456                 lctl set_param jobid_this_session=$USER
18457
18458                 JOBENV="JOBCOMPLEX"
18459                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18460
18461                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18462         fi
18463 }
18464 run_test 205a "Verify job stats"
18465
18466 # LU-13117, LU-13597
18467 test_205b() {
18468         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
18469                 skip "Need MDS version at least 2.13.54.91"
18470
18471         job_stats="mdt.*.job_stats"
18472         $LCTL set_param $job_stats=clear
18473         # Setting jobid_var to USER might not be supported
18474         $LCTL set_param jobid_var=USER || true
18475         $LCTL set_param jobid_name="%e.%u"
18476         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
18477         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18478                 grep "job_id:.*foolish" &&
18479                         error "Unexpected jobid found"
18480         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18481                 grep "open:.*min.*max.*sum" ||
18482                         error "wrong job_stats format found"
18483 }
18484 run_test 205b "Verify job stats jobid and output format"
18485
18486 # LU-13733
18487 test_205c() {
18488         $LCTL set_param llite.*.stats=0
18489         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
18490         $LCTL get_param llite.*.stats
18491         $LCTL get_param llite.*.stats | grep \
18492                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
18493                         error "wrong client stats format found"
18494 }
18495 run_test 205c "Verify client stats format"
18496
18497 # LU-1480, LU-1773 and LU-1657
18498 test_206() {
18499         mkdir -p $DIR/$tdir
18500         $LFS setstripe -c -1 $DIR/$tdir
18501 #define OBD_FAIL_LOV_INIT 0x1403
18502         $LCTL set_param fail_loc=0xa0001403
18503         $LCTL set_param fail_val=1
18504         touch $DIR/$tdir/$tfile || true
18505 }
18506 run_test 206 "fail lov_init_raid0() doesn't lbug"
18507
18508 test_207a() {
18509         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18510         local fsz=`stat -c %s $DIR/$tfile`
18511         cancel_lru_locks mdc
18512
18513         # do not return layout in getattr intent
18514 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
18515         $LCTL set_param fail_loc=0x170
18516         local sz=`stat -c %s $DIR/$tfile`
18517
18518         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
18519
18520         rm -rf $DIR/$tfile
18521 }
18522 run_test 207a "can refresh layout at glimpse"
18523
18524 test_207b() {
18525         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18526         local cksum=`md5sum $DIR/$tfile`
18527         local fsz=`stat -c %s $DIR/$tfile`
18528         cancel_lru_locks mdc
18529         cancel_lru_locks osc
18530
18531         # do not return layout in getattr intent
18532 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
18533         $LCTL set_param fail_loc=0x171
18534
18535         # it will refresh layout after the file is opened but before read issues
18536         echo checksum is "$cksum"
18537         echo "$cksum" |md5sum -c --quiet || error "file differs"
18538
18539         rm -rf $DIR/$tfile
18540 }
18541 run_test 207b "can refresh layout at open"
18542
18543 test_208() {
18544         # FIXME: in this test suite, only RD lease is used. This is okay
18545         # for now as only exclusive open is supported. After generic lease
18546         # is done, this test suite should be revised. - Jinshan
18547
18548         remote_mds_nodsh && skip "remote MDS with nodsh"
18549         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
18550                 skip "Need MDS version at least 2.4.52"
18551
18552         echo "==== test 1: verify get lease work"
18553         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
18554
18555         echo "==== test 2: verify lease can be broken by upcoming open"
18556         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18557         local PID=$!
18558         sleep 1
18559
18560         $MULTIOP $DIR/$tfile oO_RDWR:c
18561         kill -USR1 $PID && wait $PID || error "break lease error"
18562
18563         echo "==== test 3: verify lease can't be granted if an open already exists"
18564         $MULTIOP $DIR/$tfile oO_RDWR:_c &
18565         local PID=$!
18566         sleep 1
18567
18568         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
18569         kill -USR1 $PID && wait $PID || error "open file error"
18570
18571         echo "==== test 4: lease can sustain over recovery"
18572         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
18573         PID=$!
18574         sleep 1
18575
18576         fail mds1
18577
18578         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
18579
18580         echo "==== test 5: lease broken can't be regained by replay"
18581         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18582         PID=$!
18583         sleep 1
18584
18585         # open file to break lease and then recovery
18586         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18587         fail mds1
18588
18589         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18590
18591         rm -f $DIR/$tfile
18592 }
18593 run_test 208 "Exclusive open"
18594
18595 test_209() {
18596         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18597                 skip_env "must have disp_stripe"
18598
18599         touch $DIR/$tfile
18600         sync; sleep 5; sync;
18601
18602         echo 3 > /proc/sys/vm/drop_caches
18603         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18604                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18605         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18606
18607         # open/close 500 times
18608         for i in $(seq 500); do
18609                 cat $DIR/$tfile
18610         done
18611
18612         echo 3 > /proc/sys/vm/drop_caches
18613         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18614                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18615         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18616
18617         echo "before: $req_before, after: $req_after"
18618         [ $((req_after - req_before)) -ge 300 ] &&
18619                 error "open/close requests are not freed"
18620         return 0
18621 }
18622 run_test 209 "read-only open/close requests should be freed promptly"
18623
18624 test_210() {
18625         local pid
18626
18627         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
18628         pid=$!
18629         sleep 1
18630
18631         $LFS getstripe $DIR/$tfile
18632         kill -USR1 $pid
18633         wait $pid || error "multiop failed"
18634
18635         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18636         pid=$!
18637         sleep 1
18638
18639         $LFS getstripe $DIR/$tfile
18640         kill -USR1 $pid
18641         wait $pid || error "multiop failed"
18642 }
18643 run_test 210 "lfs getstripe does not break leases"
18644
18645 test_212() {
18646         size=`date +%s`
18647         size=$((size % 8192 + 1))
18648         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
18649         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
18650         rm -f $DIR/f212 $DIR/f212.xyz
18651 }
18652 run_test 212 "Sendfile test ============================================"
18653
18654 test_213() {
18655         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
18656         cancel_lru_locks osc
18657         lctl set_param fail_loc=0x8000040f
18658         # generate a read lock
18659         cat $DIR/$tfile > /dev/null
18660         # write to the file, it will try to cancel the above read lock.
18661         cat /etc/hosts >> $DIR/$tfile
18662 }
18663 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
18664
18665 test_214() { # for bug 20133
18666         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
18667         for (( i=0; i < 340; i++ )) ; do
18668                 touch $DIR/$tdir/d214c/a$i
18669         done
18670
18671         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
18672         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
18673         ls $DIR/d214c || error "ls $DIR/d214c failed"
18674         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
18675         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
18676 }
18677 run_test 214 "hash-indexed directory test - bug 20133"
18678
18679 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
18680 create_lnet_proc_files() {
18681         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
18682 }
18683
18684 # counterpart of create_lnet_proc_files
18685 remove_lnet_proc_files() {
18686         rm -f $TMP/lnet_$1.sys
18687 }
18688
18689 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18690 # 3rd arg as regexp for body
18691 check_lnet_proc_stats() {
18692         local l=$(cat "$TMP/lnet_$1" |wc -l)
18693         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
18694
18695         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
18696 }
18697
18698 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18699 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
18700 # optional and can be regexp for 2nd line (lnet.routes case)
18701 check_lnet_proc_entry() {
18702         local blp=2          # blp stands for 'position of 1st line of body'
18703         [ -z "$5" ] || blp=3 # lnet.routes case
18704
18705         local l=$(cat "$TMP/lnet_$1" |wc -l)
18706         # subtracting one from $blp because the body can be empty
18707         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
18708
18709         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
18710                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
18711
18712         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
18713                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
18714
18715         # bail out if any unexpected line happened
18716         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
18717         [ "$?" != 0 ] || error "$2 misformatted"
18718 }
18719
18720 test_215() { # for bugs 18102, 21079, 21517
18721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18722
18723         local N='(0|[1-9][0-9]*)'       # non-negative numeric
18724         local P='[1-9][0-9]*'           # positive numeric
18725         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
18726         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
18727         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
18728         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
18729
18730         local L1 # regexp for 1st line
18731         local L2 # regexp for 2nd line (optional)
18732         local BR # regexp for the rest (body)
18733
18734         # lnet.stats should look as 11 space-separated non-negative numerics
18735         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
18736         create_lnet_proc_files "stats"
18737         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
18738         remove_lnet_proc_files "stats"
18739
18740         # lnet.routes should look like this:
18741         # Routing disabled/enabled
18742         # net hops priority state router
18743         # where net is a string like tcp0, hops > 0, priority >= 0,
18744         # state is up/down,
18745         # router is a string like 192.168.1.1@tcp2
18746         L1="^Routing (disabled|enabled)$"
18747         L2="^net +hops +priority +state +router$"
18748         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
18749         create_lnet_proc_files "routes"
18750         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
18751         remove_lnet_proc_files "routes"
18752
18753         # lnet.routers should look like this:
18754         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
18755         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
18756         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
18757         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
18758         L1="^ref +rtr_ref +alive +router$"
18759         BR="^$P +$P +(up|down) +$NID$"
18760         create_lnet_proc_files "routers"
18761         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
18762         remove_lnet_proc_files "routers"
18763
18764         # lnet.peers should look like this:
18765         # nid refs state last max rtr min tx min queue
18766         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
18767         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
18768         # numeric (0 or >0 or <0), queue >= 0.
18769         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
18770         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
18771         create_lnet_proc_files "peers"
18772         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
18773         remove_lnet_proc_files "peers"
18774
18775         # lnet.buffers  should look like this:
18776         # pages count credits min
18777         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
18778         L1="^pages +count +credits +min$"
18779         BR="^ +$N +$N +$I +$I$"
18780         create_lnet_proc_files "buffers"
18781         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
18782         remove_lnet_proc_files "buffers"
18783
18784         # lnet.nis should look like this:
18785         # nid status alive refs peer rtr max tx min
18786         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
18787         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
18788         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
18789         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
18790         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
18791         create_lnet_proc_files "nis"
18792         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
18793         remove_lnet_proc_files "nis"
18794
18795         # can we successfully write to lnet.stats?
18796         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
18797 }
18798 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
18799
18800 test_216() { # bug 20317
18801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18802         remote_ost_nodsh && skip "remote OST with nodsh"
18803
18804         local node
18805         local facets=$(get_facets OST)
18806         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18807
18808         save_lustre_params client "osc.*.contention_seconds" > $p
18809         save_lustre_params $facets \
18810                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
18811         save_lustre_params $facets \
18812                 "ldlm.namespaces.filter-*.contended_locks" >> $p
18813         save_lustre_params $facets \
18814                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
18815         clear_stats osc.*.osc_stats
18816
18817         # agressive lockless i/o settings
18818         do_nodes $(comma_list $(osts_nodes)) \
18819                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
18820                         ldlm.namespaces.filter-*.contended_locks=0 \
18821                         ldlm.namespaces.filter-*.contention_seconds=60"
18822         lctl set_param -n osc.*.contention_seconds=60
18823
18824         $DIRECTIO write $DIR/$tfile 0 10 4096
18825         $CHECKSTAT -s 40960 $DIR/$tfile
18826
18827         # disable lockless i/o
18828         do_nodes $(comma_list $(osts_nodes)) \
18829                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
18830                         ldlm.namespaces.filter-*.contended_locks=32 \
18831                         ldlm.namespaces.filter-*.contention_seconds=0"
18832         lctl set_param -n osc.*.contention_seconds=0
18833         clear_stats osc.*.osc_stats
18834
18835         dd if=/dev/zero of=$DIR/$tfile count=0
18836         $CHECKSTAT -s 0 $DIR/$tfile
18837
18838         restore_lustre_params <$p
18839         rm -f $p
18840         rm $DIR/$tfile
18841 }
18842 run_test 216 "check lockless direct write updates file size and kms correctly"
18843
18844 test_217() { # bug 22430
18845         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18846
18847         local node
18848         local nid
18849
18850         for node in $(nodes_list); do
18851                 nid=$(host_nids_address $node $NETTYPE)
18852                 if [[ $nid = *-* ]] ; then
18853                         echo "lctl ping $(h2nettype $nid)"
18854                         lctl ping $(h2nettype $nid)
18855                 else
18856                         echo "skipping $node (no hyphen detected)"
18857                 fi
18858         done
18859 }
18860 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
18861
18862 test_218() {
18863        # do directio so as not to populate the page cache
18864        log "creating a 10 Mb file"
18865        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
18866        log "starting reads"
18867        dd if=$DIR/$tfile of=/dev/null bs=4096 &
18868        log "truncating the file"
18869        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
18870        log "killing dd"
18871        kill %+ || true # reads might have finished
18872        echo "wait until dd is finished"
18873        wait
18874        log "removing the temporary file"
18875        rm -rf $DIR/$tfile || error "tmp file removal failed"
18876 }
18877 run_test 218 "parallel read and truncate should not deadlock"
18878
18879 test_219() {
18880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18881
18882         # write one partial page
18883         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
18884         # set no grant so vvp_io_commit_write will do sync write
18885         $LCTL set_param fail_loc=0x411
18886         # write a full page at the end of file
18887         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
18888
18889         $LCTL set_param fail_loc=0
18890         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
18891         $LCTL set_param fail_loc=0x411
18892         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
18893
18894         # LU-4201
18895         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
18896         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
18897 }
18898 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
18899
18900 test_220() { #LU-325
18901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18902         remote_ost_nodsh && skip "remote OST with nodsh"
18903         remote_mds_nodsh && skip "remote MDS with nodsh"
18904         remote_mgs_nodsh && skip "remote MGS with nodsh"
18905
18906         local OSTIDX=0
18907
18908         # create on MDT0000 so the last_id and next_id are correct
18909         mkdir_on_mdt0 $DIR/$tdir
18910         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
18911         OST=${OST%_UUID}
18912
18913         # on the mdt's osc
18914         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
18915         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
18916                         osp.$mdtosc_proc1.prealloc_last_id)
18917         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
18918                         osp.$mdtosc_proc1.prealloc_next_id)
18919
18920         $LFS df -i
18921
18922         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
18923         #define OBD_FAIL_OST_ENOINO              0x229
18924         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
18925         create_pool $FSNAME.$TESTNAME || return 1
18926         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
18927
18928         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
18929
18930         MDSOBJS=$((last_id - next_id))
18931         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
18932
18933         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
18934         echo "OST still has $count kbytes free"
18935
18936         echo "create $MDSOBJS files @next_id..."
18937         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
18938
18939         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18940                         osp.$mdtosc_proc1.prealloc_last_id)
18941         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18942                         osp.$mdtosc_proc1.prealloc_next_id)
18943
18944         echo "after creation, last_id=$last_id2, next_id=$next_id2"
18945         $LFS df -i
18946
18947         echo "cleanup..."
18948
18949         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
18950         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
18951
18952         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
18953                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
18954         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
18955                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
18956         echo "unlink $MDSOBJS files @$next_id..."
18957         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
18958 }
18959 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
18960
18961 test_221() {
18962         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18963
18964         dd if=`which date` of=$MOUNT/date oflag=sync
18965         chmod +x $MOUNT/date
18966
18967         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
18968         $LCTL set_param fail_loc=0x80001401
18969
18970         $MOUNT/date > /dev/null
18971         rm -f $MOUNT/date
18972 }
18973 run_test 221 "make sure fault and truncate race to not cause OOM"
18974
18975 test_222a () {
18976         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18977
18978         rm -rf $DIR/$tdir
18979         test_mkdir $DIR/$tdir
18980         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18981         createmany -o $DIR/$tdir/$tfile 10
18982         cancel_lru_locks mdc
18983         cancel_lru_locks osc
18984         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18985         $LCTL set_param fail_loc=0x31a
18986         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
18987         $LCTL set_param fail_loc=0
18988         rm -r $DIR/$tdir
18989 }
18990 run_test 222a "AGL for ls should not trigger CLIO lock failure"
18991
18992 test_222b () {
18993         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18994
18995         rm -rf $DIR/$tdir
18996         test_mkdir $DIR/$tdir
18997         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18998         createmany -o $DIR/$tdir/$tfile 10
18999         cancel_lru_locks mdc
19000         cancel_lru_locks osc
19001         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19002         $LCTL set_param fail_loc=0x31a
19003         rm -r $DIR/$tdir || error "AGL for rmdir failed"
19004         $LCTL set_param fail_loc=0
19005 }
19006 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
19007
19008 test_223 () {
19009         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19010
19011         rm -rf $DIR/$tdir
19012         test_mkdir $DIR/$tdir
19013         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19014         createmany -o $DIR/$tdir/$tfile 10
19015         cancel_lru_locks mdc
19016         cancel_lru_locks osc
19017         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
19018         $LCTL set_param fail_loc=0x31b
19019         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
19020         $LCTL set_param fail_loc=0
19021         rm -r $DIR/$tdir
19022 }
19023 run_test 223 "osc reenqueue if without AGL lock granted ======================="
19024
19025 test_224a() { # LU-1039, MRP-303
19026         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19027         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
19028         $LCTL set_param fail_loc=0x508
19029         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
19030         $LCTL set_param fail_loc=0
19031         df $DIR
19032 }
19033 run_test 224a "Don't panic on bulk IO failure"
19034
19035 test_224bd_sub() { # LU-1039, MRP-303
19036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19037         local timeout=$1
19038
19039         shift
19040         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
19041
19042         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19043
19044         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
19045         cancel_lru_locks osc
19046         set_checksums 0
19047         stack_trap "set_checksums $ORIG_CSUM" EXIT
19048         local at_max_saved=0
19049
19050         # adaptive timeouts may prevent seeing the issue
19051         if at_is_enabled; then
19052                 at_max_saved=$(at_max_get mds)
19053                 at_max_set 0 mds client
19054                 stack_trap "at_max_set $at_max_saved mds client" EXIT
19055         fi
19056
19057         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
19058         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
19059         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
19060
19061         do_facet ost1 $LCTL set_param fail_loc=0
19062         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
19063         df $DIR
19064 }
19065
19066 test_224b() {
19067         test_224bd_sub 3 error "dd failed"
19068 }
19069 run_test 224b "Don't panic on bulk IO failure"
19070
19071 test_224c() { # LU-6441
19072         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19073         remote_mds_nodsh && skip "remote MDS with nodsh"
19074
19075         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19076         save_writethrough $p
19077         set_cache writethrough on
19078
19079         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
19080         local at_max=$($LCTL get_param -n at_max)
19081         local timeout=$($LCTL get_param -n timeout)
19082         local test_at="at_max"
19083         local param_at="$FSNAME.sys.at_max"
19084         local test_timeout="timeout"
19085         local param_timeout="$FSNAME.sys.timeout"
19086
19087         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
19088
19089         set_persistent_param_and_check client "$test_at" "$param_at" 0
19090         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
19091
19092         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
19093         do_facet ost1 "$LCTL set_param fail_loc=0x520"
19094         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19095         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
19096         sync
19097         do_facet ost1 "$LCTL set_param fail_loc=0"
19098
19099         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
19100         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
19101                 $timeout
19102
19103         $LCTL set_param -n $pages_per_rpc
19104         restore_lustre_params < $p
19105         rm -f $p
19106 }
19107 run_test 224c "Don't hang if one of md lost during large bulk RPC"
19108
19109 test_224d() { # LU-11169
19110         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
19111 }
19112 run_test 224d "Don't corrupt data on bulk IO timeout"
19113
19114 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
19115 test_225a () {
19116         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19117         if [ -z ${MDSSURVEY} ]; then
19118                 skip_env "mds-survey not found"
19119         fi
19120         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19121                 skip "Need MDS version at least 2.2.51"
19122
19123         local mds=$(facet_host $SINGLEMDS)
19124         local target=$(do_nodes $mds 'lctl dl' |
19125                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19126
19127         local cmd1="file_count=1000 thrhi=4"
19128         local cmd2="dir_count=2 layer=mdd stripe_count=0"
19129         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19130         local cmd="$cmd1 $cmd2 $cmd3"
19131
19132         rm -f ${TMP}/mds_survey*
19133         echo + $cmd
19134         eval $cmd || error "mds-survey with zero-stripe failed"
19135         cat ${TMP}/mds_survey*
19136         rm -f ${TMP}/mds_survey*
19137 }
19138 run_test 225a "Metadata survey sanity with zero-stripe"
19139
19140 test_225b () {
19141         if [ -z ${MDSSURVEY} ]; then
19142                 skip_env "mds-survey not found"
19143         fi
19144         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19145                 skip "Need MDS version at least 2.2.51"
19146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19147         remote_mds_nodsh && skip "remote MDS with nodsh"
19148         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
19149                 skip_env "Need to mount OST to test"
19150         fi
19151
19152         local mds=$(facet_host $SINGLEMDS)
19153         local target=$(do_nodes $mds 'lctl dl' |
19154                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19155
19156         local cmd1="file_count=1000 thrhi=4"
19157         local cmd2="dir_count=2 layer=mdd stripe_count=1"
19158         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19159         local cmd="$cmd1 $cmd2 $cmd3"
19160
19161         rm -f ${TMP}/mds_survey*
19162         echo + $cmd
19163         eval $cmd || error "mds-survey with stripe_count failed"
19164         cat ${TMP}/mds_survey*
19165         rm -f ${TMP}/mds_survey*
19166 }
19167 run_test 225b "Metadata survey sanity with stripe_count = 1"
19168
19169 mcreate_path2fid () {
19170         local mode=$1
19171         local major=$2
19172         local minor=$3
19173         local name=$4
19174         local desc=$5
19175         local path=$DIR/$tdir/$name
19176         local fid
19177         local rc
19178         local fid_path
19179
19180         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
19181                 error "cannot create $desc"
19182
19183         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
19184         rc=$?
19185         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
19186
19187         fid_path=$($LFS fid2path $MOUNT $fid)
19188         rc=$?
19189         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
19190
19191         [ "$path" == "$fid_path" ] ||
19192                 error "fid2path returned $fid_path, expected $path"
19193
19194         echo "pass with $path and $fid"
19195 }
19196
19197 test_226a () {
19198         rm -rf $DIR/$tdir
19199         mkdir -p $DIR/$tdir
19200
19201         mcreate_path2fid 0010666 0 0 fifo "FIFO"
19202         mcreate_path2fid 0020666 1 3 null "character special file (null)"
19203         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
19204         mcreate_path2fid 0040666 0 0 dir "directory"
19205         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
19206         mcreate_path2fid 0100666 0 0 file "regular file"
19207         mcreate_path2fid 0120666 0 0 link "symbolic link"
19208         mcreate_path2fid 0140666 0 0 sock "socket"
19209 }
19210 run_test 226a "call path2fid and fid2path on files of all type"
19211
19212 test_226b () {
19213         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19214
19215         local MDTIDX=1
19216
19217         rm -rf $DIR/$tdir
19218         mkdir -p $DIR/$tdir
19219         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
19220                 error "create remote directory failed"
19221         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
19222         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
19223                                 "character special file (null)"
19224         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
19225                                 "character special file (no device)"
19226         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
19227         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
19228                                 "block special file (loop)"
19229         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
19230         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
19231         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
19232 }
19233 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
19234
19235 test_226c () {
19236         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19237         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
19238                 skip "Need MDS version at least 2.13.55"
19239
19240         local submnt=/mnt/submnt
19241         local srcfile=/etc/passwd
19242         local dstfile=$submnt/passwd
19243         local path
19244         local fid
19245
19246         rm -rf $DIR/$tdir
19247         rm -rf $submnt
19248         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
19249                 error "create remote directory failed"
19250         mkdir -p $submnt || error "create $submnt failed"
19251         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
19252                 error "mount $submnt failed"
19253         stack_trap "umount $submnt" EXIT
19254
19255         cp $srcfile $dstfile
19256         fid=$($LFS path2fid $dstfile)
19257         path=$($LFS fid2path $submnt "$fid")
19258         [ "$path" = "$dstfile" ] ||
19259                 error "fid2path $submnt $fid failed ($path != $dstfile)"
19260 }
19261 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
19262
19263 # LU-1299 Executing or running ldd on a truncated executable does not
19264 # cause an out-of-memory condition.
19265 test_227() {
19266         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19267         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
19268
19269         dd if=$(which date) of=$MOUNT/date bs=1k count=1
19270         chmod +x $MOUNT/date
19271
19272         $MOUNT/date > /dev/null
19273         ldd $MOUNT/date > /dev/null
19274         rm -f $MOUNT/date
19275 }
19276 run_test 227 "running truncated executable does not cause OOM"
19277
19278 # LU-1512 try to reuse idle OI blocks
19279 test_228a() {
19280         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19281         remote_mds_nodsh && skip "remote MDS with nodsh"
19282         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19283
19284         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19285         local myDIR=$DIR/$tdir
19286
19287         mkdir -p $myDIR
19288         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19289         $LCTL set_param fail_loc=0x80001002
19290         createmany -o $myDIR/t- 10000
19291         $LCTL set_param fail_loc=0
19292         # The guard is current the largest FID holder
19293         touch $myDIR/guard
19294         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19295                     tr -d '[')
19296         local IDX=$(($SEQ % 64))
19297
19298         do_facet $SINGLEMDS sync
19299         # Make sure journal flushed.
19300         sleep 6
19301         local blk1=$(do_facet $SINGLEMDS \
19302                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19303                      grep Blockcount | awk '{print $4}')
19304
19305         # Remove old files, some OI blocks will become idle.
19306         unlinkmany $myDIR/t- 10000
19307         # Create new files, idle OI blocks should be reused.
19308         createmany -o $myDIR/t- 2000
19309         do_facet $SINGLEMDS sync
19310         # Make sure journal flushed.
19311         sleep 6
19312         local blk2=$(do_facet $SINGLEMDS \
19313                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19314                      grep Blockcount | awk '{print $4}')
19315
19316         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19317 }
19318 run_test 228a "try to reuse idle OI blocks"
19319
19320 test_228b() {
19321         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19322         remote_mds_nodsh && skip "remote MDS with nodsh"
19323         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19324
19325         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19326         local myDIR=$DIR/$tdir
19327
19328         mkdir -p $myDIR
19329         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19330         $LCTL set_param fail_loc=0x80001002
19331         createmany -o $myDIR/t- 10000
19332         $LCTL set_param fail_loc=0
19333         # The guard is current the largest FID holder
19334         touch $myDIR/guard
19335         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19336                     tr -d '[')
19337         local IDX=$(($SEQ % 64))
19338
19339         do_facet $SINGLEMDS sync
19340         # Make sure journal flushed.
19341         sleep 6
19342         local blk1=$(do_facet $SINGLEMDS \
19343                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19344                      grep Blockcount | awk '{print $4}')
19345
19346         # Remove old files, some OI blocks will become idle.
19347         unlinkmany $myDIR/t- 10000
19348
19349         # stop the MDT
19350         stop $SINGLEMDS || error "Fail to stop MDT."
19351         # remount the MDT
19352         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
19353
19354         df $MOUNT || error "Fail to df."
19355         # Create new files, idle OI blocks should be reused.
19356         createmany -o $myDIR/t- 2000
19357         do_facet $SINGLEMDS sync
19358         # Make sure journal flushed.
19359         sleep 6
19360         local blk2=$(do_facet $SINGLEMDS \
19361                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19362                      grep Blockcount | awk '{print $4}')
19363
19364         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19365 }
19366 run_test 228b "idle OI blocks can be reused after MDT restart"
19367
19368 #LU-1881
19369 test_228c() {
19370         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19371         remote_mds_nodsh && skip "remote MDS with nodsh"
19372         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19373
19374         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19375         local myDIR=$DIR/$tdir
19376
19377         mkdir -p $myDIR
19378         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19379         $LCTL set_param fail_loc=0x80001002
19380         # 20000 files can guarantee there are index nodes in the OI file
19381         createmany -o $myDIR/t- 20000
19382         $LCTL set_param fail_loc=0
19383         # The guard is current the largest FID holder
19384         touch $myDIR/guard
19385         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19386                     tr -d '[')
19387         local IDX=$(($SEQ % 64))
19388
19389         do_facet $SINGLEMDS sync
19390         # Make sure journal flushed.
19391         sleep 6
19392         local blk1=$(do_facet $SINGLEMDS \
19393                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19394                      grep Blockcount | awk '{print $4}')
19395
19396         # Remove old files, some OI blocks will become idle.
19397         unlinkmany $myDIR/t- 20000
19398         rm -f $myDIR/guard
19399         # The OI file should become empty now
19400
19401         # Create new files, idle OI blocks should be reused.
19402         createmany -o $myDIR/t- 2000
19403         do_facet $SINGLEMDS sync
19404         # Make sure journal flushed.
19405         sleep 6
19406         local blk2=$(do_facet $SINGLEMDS \
19407                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19408                      grep Blockcount | awk '{print $4}')
19409
19410         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19411 }
19412 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
19413
19414 test_229() { # LU-2482, LU-3448
19415         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19416         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19417         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
19418                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
19419
19420         rm -f $DIR/$tfile
19421
19422         # Create a file with a released layout and stripe count 2.
19423         $MULTIOP $DIR/$tfile H2c ||
19424                 error "failed to create file with released layout"
19425
19426         $LFS getstripe -v $DIR/$tfile
19427
19428         local pattern=$($LFS getstripe -L $DIR/$tfile)
19429         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
19430
19431         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
19432                 error "getstripe"
19433         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
19434         stat $DIR/$tfile || error "failed to stat released file"
19435
19436         chown $RUNAS_ID $DIR/$tfile ||
19437                 error "chown $RUNAS_ID $DIR/$tfile failed"
19438
19439         chgrp $RUNAS_ID $DIR/$tfile ||
19440                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
19441
19442         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
19443         rm $DIR/$tfile || error "failed to remove released file"
19444 }
19445 run_test 229 "getstripe/stat/rm/attr changes work on released files"
19446
19447 test_230a() {
19448         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19449         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19450         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19451                 skip "Need MDS version at least 2.11.52"
19452
19453         local MDTIDX=1
19454
19455         test_mkdir $DIR/$tdir
19456         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
19457         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
19458         [ $mdt_idx -ne 0 ] &&
19459                 error "create local directory on wrong MDT $mdt_idx"
19460
19461         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
19462                         error "create remote directory failed"
19463         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
19464         [ $mdt_idx -ne $MDTIDX ] &&
19465                 error "create remote directory on wrong MDT $mdt_idx"
19466
19467         createmany -o $DIR/$tdir/test_230/t- 10 ||
19468                 error "create files on remote directory failed"
19469         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
19470         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
19471         rm -r $DIR/$tdir || error "unlink remote directory failed"
19472 }
19473 run_test 230a "Create remote directory and files under the remote directory"
19474
19475 test_230b() {
19476         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19477         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19478         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19479                 skip "Need MDS version at least 2.11.52"
19480
19481         local MDTIDX=1
19482         local mdt_index
19483         local i
19484         local file
19485         local pid
19486         local stripe_count
19487         local migrate_dir=$DIR/$tdir/migrate_dir
19488         local other_dir=$DIR/$tdir/other_dir
19489
19490         test_mkdir $DIR/$tdir
19491         test_mkdir -i0 -c1 $migrate_dir
19492         test_mkdir -i0 -c1 $other_dir
19493         for ((i=0; i<10; i++)); do
19494                 mkdir -p $migrate_dir/dir_${i}
19495                 createmany -o $migrate_dir/dir_${i}/f 10 ||
19496                         error "create files under remote dir failed $i"
19497         done
19498
19499         cp /etc/passwd $migrate_dir/$tfile
19500         cp /etc/passwd $other_dir/$tfile
19501         chattr +SAD $migrate_dir
19502         chattr +SAD $migrate_dir/$tfile
19503
19504         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19505         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19506         local old_dir_mode=$(stat -c%f $migrate_dir)
19507         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
19508
19509         mkdir -p $migrate_dir/dir_default_stripe2
19510         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
19511         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
19512
19513         mkdir -p $other_dir
19514         ln $migrate_dir/$tfile $other_dir/luna
19515         ln $migrate_dir/$tfile $migrate_dir/sofia
19516         ln $other_dir/$tfile $migrate_dir/david
19517         ln -s $migrate_dir/$tfile $other_dir/zachary
19518         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
19519         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
19520
19521         local len
19522         local lnktgt
19523
19524         # inline symlink
19525         for len in 58 59 60; do
19526                 lnktgt=$(str_repeat 'l' $len)
19527                 touch $migrate_dir/$lnktgt
19528                 ln -s $lnktgt $migrate_dir/${len}char_ln
19529         done
19530
19531         # PATH_MAX
19532         for len in 4094 4095; do
19533                 lnktgt=$(str_repeat 'l' $len)
19534                 ln -s $lnktgt $migrate_dir/${len}char_ln
19535         done
19536
19537         # NAME_MAX
19538         for len in 254 255; do
19539                 touch $migrate_dir/$(str_repeat 'l' $len)
19540         done
19541
19542         $LFS migrate -m $MDTIDX $migrate_dir ||
19543                 error "fails on migrating remote dir to MDT1"
19544
19545         echo "migratate to MDT1, then checking.."
19546         for ((i = 0; i < 10; i++)); do
19547                 for file in $(find $migrate_dir/dir_${i}); do
19548                         mdt_index=$($LFS getstripe -m $file)
19549                         # broken symlink getstripe will fail
19550                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19551                                 error "$file is not on MDT${MDTIDX}"
19552                 done
19553         done
19554
19555         # the multiple link file should still in MDT0
19556         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
19557         [ $mdt_index == 0 ] ||
19558                 error "$file is not on MDT${MDTIDX}"
19559
19560         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19561         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19562                 error " expect $old_dir_flag get $new_dir_flag"
19563
19564         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19565         [ "$old_file_flag" = "$new_file_flag" ] ||
19566                 error " expect $old_file_flag get $new_file_flag"
19567
19568         local new_dir_mode=$(stat -c%f $migrate_dir)
19569         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19570                 error "expect mode $old_dir_mode get $new_dir_mode"
19571
19572         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19573         [ "$old_file_mode" = "$new_file_mode" ] ||
19574                 error "expect mode $old_file_mode get $new_file_mode"
19575
19576         diff /etc/passwd $migrate_dir/$tfile ||
19577                 error "$tfile different after migration"
19578
19579         diff /etc/passwd $other_dir/luna ||
19580                 error "luna different after migration"
19581
19582         diff /etc/passwd $migrate_dir/sofia ||
19583                 error "sofia different after migration"
19584
19585         diff /etc/passwd $migrate_dir/david ||
19586                 error "david different after migration"
19587
19588         diff /etc/passwd $other_dir/zachary ||
19589                 error "zachary different after migration"
19590
19591         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19592                 error "${tfile}_ln different after migration"
19593
19594         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19595                 error "${tfile}_ln_other different after migration"
19596
19597         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
19598         [ $stripe_count = 2 ] ||
19599                 error "dir strpe_count $d != 2 after migration."
19600
19601         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
19602         [ $stripe_count = 2 ] ||
19603                 error "file strpe_count $d != 2 after migration."
19604
19605         #migrate back to MDT0
19606         MDTIDX=0
19607
19608         $LFS migrate -m $MDTIDX $migrate_dir ||
19609                 error "fails on migrating remote dir to MDT0"
19610
19611         echo "migrate back to MDT0, checking.."
19612         for file in $(find $migrate_dir); do
19613                 mdt_index=$($LFS getstripe -m $file)
19614                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19615                         error "$file is not on MDT${MDTIDX}"
19616         done
19617
19618         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19619         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19620                 error " expect $old_dir_flag get $new_dir_flag"
19621
19622         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19623         [ "$old_file_flag" = "$new_file_flag" ] ||
19624                 error " expect $old_file_flag get $new_file_flag"
19625
19626         local new_dir_mode=$(stat -c%f $migrate_dir)
19627         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19628                 error "expect mode $old_dir_mode get $new_dir_mode"
19629
19630         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19631         [ "$old_file_mode" = "$new_file_mode" ] ||
19632                 error "expect mode $old_file_mode get $new_file_mode"
19633
19634         diff /etc/passwd ${migrate_dir}/$tfile ||
19635                 error "$tfile different after migration"
19636
19637         diff /etc/passwd ${other_dir}/luna ||
19638                 error "luna different after migration"
19639
19640         diff /etc/passwd ${migrate_dir}/sofia ||
19641                 error "sofia different after migration"
19642
19643         diff /etc/passwd ${other_dir}/zachary ||
19644                 error "zachary different after migration"
19645
19646         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19647                 error "${tfile}_ln different after migration"
19648
19649         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19650                 error "${tfile}_ln_other different after migration"
19651
19652         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
19653         [ $stripe_count = 2 ] ||
19654                 error "dir strpe_count $d != 2 after migration."
19655
19656         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
19657         [ $stripe_count = 2 ] ||
19658                 error "file strpe_count $d != 2 after migration."
19659
19660         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19661 }
19662 run_test 230b "migrate directory"
19663
19664 test_230c() {
19665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19666         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19667         remote_mds_nodsh && skip "remote MDS with nodsh"
19668         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19669                 skip "Need MDS version at least 2.11.52"
19670
19671         local MDTIDX=1
19672         local total=3
19673         local mdt_index
19674         local file
19675         local migrate_dir=$DIR/$tdir/migrate_dir
19676
19677         #If migrating directory fails in the middle, all entries of
19678         #the directory is still accessiable.
19679         test_mkdir $DIR/$tdir
19680         test_mkdir -i0 -c1 $migrate_dir
19681         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
19682         stat $migrate_dir
19683         createmany -o $migrate_dir/f $total ||
19684                 error "create files under ${migrate_dir} failed"
19685
19686         # fail after migrating top dir, and this will fail only once, so the
19687         # first sub file migration will fail (currently f3), others succeed.
19688         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
19689         do_facet mds1 lctl set_param fail_loc=0x1801
19690         local t=$(ls $migrate_dir | wc -l)
19691         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
19692                 error "migrate should fail"
19693         local u=$(ls $migrate_dir | wc -l)
19694         [ "$u" == "$t" ] || error "$u != $t during migration"
19695
19696         # add new dir/file should succeed
19697         mkdir $migrate_dir/dir ||
19698                 error "mkdir failed under migrating directory"
19699         touch $migrate_dir/file ||
19700                 error "create file failed under migrating directory"
19701
19702         # add file with existing name should fail
19703         for file in $migrate_dir/f*; do
19704                 stat $file > /dev/null || error "stat $file failed"
19705                 $OPENFILE -f O_CREAT:O_EXCL $file &&
19706                         error "open(O_CREAT|O_EXCL) $file should fail"
19707                 $MULTIOP $file m && error "create $file should fail"
19708                 touch $DIR/$tdir/remote_dir/$tfile ||
19709                         error "touch $tfile failed"
19710                 ln $DIR/$tdir/remote_dir/$tfile $file &&
19711                         error "link $file should fail"
19712                 mdt_index=$($LFS getstripe -m $file)
19713                 if [ $mdt_index == 0 ]; then
19714                         # file failed to migrate is not allowed to rename to
19715                         mv $DIR/$tdir/remote_dir/$tfile $file &&
19716                                 error "rename to $file should fail"
19717                 else
19718                         mv $DIR/$tdir/remote_dir/$tfile $file ||
19719                                 error "rename to $file failed"
19720                 fi
19721                 echo hello >> $file || error "write $file failed"
19722         done
19723
19724         # resume migration with different options should fail
19725         $LFS migrate -m 0 $migrate_dir &&
19726                 error "migrate -m 0 $migrate_dir should fail"
19727
19728         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
19729                 error "migrate -c 2 $migrate_dir should fail"
19730
19731         # resume migration should succeed
19732         $LFS migrate -m $MDTIDX $migrate_dir ||
19733                 error "migrate $migrate_dir failed"
19734
19735         echo "Finish migration, then checking.."
19736         for file in $(find $migrate_dir); do
19737                 mdt_index=$($LFS getstripe -m $file)
19738                 [ $mdt_index == $MDTIDX ] ||
19739                         error "$file is not on MDT${MDTIDX}"
19740         done
19741
19742         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19743 }
19744 run_test 230c "check directory accessiblity if migration failed"
19745
19746 test_230d() {
19747         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19748         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19749         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19750                 skip "Need MDS version at least 2.11.52"
19751         # LU-11235
19752         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
19753
19754         local migrate_dir=$DIR/$tdir/migrate_dir
19755         local old_index
19756         local new_index
19757         local old_count
19758         local new_count
19759         local new_hash
19760         local mdt_index
19761         local i
19762         local j
19763
19764         old_index=$((RANDOM % MDSCOUNT))
19765         old_count=$((MDSCOUNT - old_index))
19766         new_index=$((RANDOM % MDSCOUNT))
19767         new_count=$((MDSCOUNT - new_index))
19768         new_hash=1 # for all_char
19769
19770         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
19771         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
19772
19773         test_mkdir $DIR/$tdir
19774         test_mkdir -i $old_index -c $old_count $migrate_dir
19775
19776         for ((i=0; i<100; i++)); do
19777                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
19778                 createmany -o $migrate_dir/dir_${i}/f 100 ||
19779                         error "create files under remote dir failed $i"
19780         done
19781
19782         echo -n "Migrate from MDT$old_index "
19783         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
19784         echo -n "to MDT$new_index"
19785         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
19786         echo
19787
19788         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
19789         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
19790                 error "migrate remote dir error"
19791
19792         echo "Finish migration, then checking.."
19793         for file in $(find $migrate_dir -maxdepth 1); do
19794                 mdt_index=$($LFS getstripe -m $file)
19795                 if [ $mdt_index -lt $new_index ] ||
19796                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
19797                         error "$file is on MDT$mdt_index"
19798                 fi
19799         done
19800
19801         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19802 }
19803 run_test 230d "check migrate big directory"
19804
19805 test_230e() {
19806         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19807         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19808         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19809                 skip "Need MDS version at least 2.11.52"
19810
19811         local i
19812         local j
19813         local a_fid
19814         local b_fid
19815
19816         mkdir_on_mdt0 $DIR/$tdir
19817         mkdir $DIR/$tdir/migrate_dir
19818         mkdir $DIR/$tdir/other_dir
19819         touch $DIR/$tdir/migrate_dir/a
19820         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
19821         ls $DIR/$tdir/other_dir
19822
19823         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19824                 error "migrate dir fails"
19825
19826         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19827         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19828
19829         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19830         [ $mdt_index == 0 ] || error "a is not on MDT0"
19831
19832         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
19833                 error "migrate dir fails"
19834
19835         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
19836         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
19837
19838         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19839         [ $mdt_index == 1 ] || error "a is not on MDT1"
19840
19841         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
19842         [ $mdt_index == 1 ] || error "b is not on MDT1"
19843
19844         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19845         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
19846
19847         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
19848
19849         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19850 }
19851 run_test 230e "migrate mulitple local link files"
19852
19853 test_230f() {
19854         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19855         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19856         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19857                 skip "Need MDS version at least 2.11.52"
19858
19859         local a_fid
19860         local ln_fid
19861
19862         mkdir -p $DIR/$tdir
19863         mkdir $DIR/$tdir/migrate_dir
19864         $LFS mkdir -i1 $DIR/$tdir/other_dir
19865         touch $DIR/$tdir/migrate_dir/a
19866         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
19867         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
19868         ls $DIR/$tdir/other_dir
19869
19870         # a should be migrated to MDT1, since no other links on MDT0
19871         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19872                 error "#1 migrate dir fails"
19873         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19874         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19875         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19876         [ $mdt_index == 1 ] || error "a is not on MDT1"
19877
19878         # a should stay on MDT1, because it is a mulitple link file
19879         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19880                 error "#2 migrate dir fails"
19881         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19882         [ $mdt_index == 1 ] || error "a is not on MDT1"
19883
19884         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19885                 error "#3 migrate dir fails"
19886
19887         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19888         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
19889         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
19890
19891         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
19892         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
19893
19894         # a should be migrated to MDT0, since no other links on MDT1
19895         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19896                 error "#4 migrate dir fails"
19897         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19898         [ $mdt_index == 0 ] || error "a is not on MDT0"
19899
19900         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19901 }
19902 run_test 230f "migrate mulitple remote link files"
19903
19904 test_230g() {
19905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19906         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19907         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19908                 skip "Need MDS version at least 2.11.52"
19909
19910         mkdir -p $DIR/$tdir/migrate_dir
19911
19912         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
19913                 error "migrating dir to non-exist MDT succeeds"
19914         true
19915 }
19916 run_test 230g "migrate dir to non-exist MDT"
19917
19918 test_230h() {
19919         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19920         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19921         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19922                 skip "Need MDS version at least 2.11.52"
19923
19924         local mdt_index
19925
19926         mkdir -p $DIR/$tdir/migrate_dir
19927
19928         $LFS migrate -m1 $DIR &&
19929                 error "migrating mountpoint1 should fail"
19930
19931         $LFS migrate -m1 $DIR/$tdir/.. &&
19932                 error "migrating mountpoint2 should fail"
19933
19934         # same as mv
19935         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
19936                 error "migrating $tdir/migrate_dir/.. should fail"
19937
19938         true
19939 }
19940 run_test 230h "migrate .. and root"
19941
19942 test_230i() {
19943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19944         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19945         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19946                 skip "Need MDS version at least 2.11.52"
19947
19948         mkdir -p $DIR/$tdir/migrate_dir
19949
19950         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
19951                 error "migration fails with a tailing slash"
19952
19953         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
19954                 error "migration fails with two tailing slashes"
19955 }
19956 run_test 230i "lfs migrate -m tolerates trailing slashes"
19957
19958 test_230j() {
19959         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19960         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19961                 skip "Need MDS version at least 2.11.52"
19962
19963         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19964         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
19965                 error "create $tfile failed"
19966         cat /etc/passwd > $DIR/$tdir/$tfile
19967
19968         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19969
19970         cmp /etc/passwd $DIR/$tdir/$tfile ||
19971                 error "DoM file mismatch after migration"
19972 }
19973 run_test 230j "DoM file data not changed after dir migration"
19974
19975 test_230k() {
19976         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
19977         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19978                 skip "Need MDS version at least 2.11.56"
19979
19980         local total=20
19981         local files_on_starting_mdt=0
19982
19983         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
19984         $LFS getdirstripe $DIR/$tdir
19985         for i in $(seq $total); do
19986                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
19987                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19988                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19989         done
19990
19991         echo "$files_on_starting_mdt files on MDT0"
19992
19993         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
19994         $LFS getdirstripe $DIR/$tdir
19995
19996         files_on_starting_mdt=0
19997         for i in $(seq $total); do
19998                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19999                         error "file $tfile.$i mismatch after migration"
20000                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
20001                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20002         done
20003
20004         echo "$files_on_starting_mdt files on MDT1 after migration"
20005         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
20006
20007         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
20008         $LFS getdirstripe $DIR/$tdir
20009
20010         files_on_starting_mdt=0
20011         for i in $(seq $total); do
20012                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20013                         error "file $tfile.$i mismatch after 2nd migration"
20014                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20015                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20016         done
20017
20018         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
20019         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
20020
20021         true
20022 }
20023 run_test 230k "file data not changed after dir migration"
20024
20025 test_230l() {
20026         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20027         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20028                 skip "Need MDS version at least 2.11.56"
20029
20030         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
20031         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
20032                 error "create files under remote dir failed $i"
20033         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20034 }
20035 run_test 230l "readdir between MDTs won't crash"
20036
20037 test_230m() {
20038         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20039         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20040                 skip "Need MDS version at least 2.11.56"
20041
20042         local MDTIDX=1
20043         local mig_dir=$DIR/$tdir/migrate_dir
20044         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
20045         local shortstr="b"
20046         local val
20047
20048         echo "Creating files and dirs with xattrs"
20049         test_mkdir $DIR/$tdir
20050         test_mkdir -i0 -c1 $mig_dir
20051         mkdir $mig_dir/dir
20052         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
20053                 error "cannot set xattr attr1 on dir"
20054         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
20055                 error "cannot set xattr attr2 on dir"
20056         touch $mig_dir/dir/f0
20057         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
20058                 error "cannot set xattr attr1 on file"
20059         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
20060                 error "cannot set xattr attr2 on file"
20061         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20062         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20063         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
20064         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20065         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
20066         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20067         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
20068         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20069         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
20070
20071         echo "Migrating to MDT1"
20072         $LFS migrate -m $MDTIDX $mig_dir ||
20073                 error "fails on migrating dir to MDT1"
20074
20075         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20076         echo "Checking xattrs"
20077         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20078         [ "$val" = $longstr ] ||
20079                 error "expecting xattr1 $longstr on dir, found $val"
20080         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20081         [ "$val" = $shortstr ] ||
20082                 error "expecting xattr2 $shortstr on dir, found $val"
20083         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20084         [ "$val" = $longstr ] ||
20085                 error "expecting xattr1 $longstr on file, found $val"
20086         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20087         [ "$val" = $shortstr ] ||
20088                 error "expecting xattr2 $shortstr on file, found $val"
20089 }
20090 run_test 230m "xattrs not changed after dir migration"
20091
20092 test_230n() {
20093         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20094         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20095                 skip "Need MDS version at least 2.13.53"
20096
20097         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
20098         cat /etc/hosts > $DIR/$tdir/$tfile
20099         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
20100         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
20101
20102         cmp /etc/hosts $DIR/$tdir/$tfile ||
20103                 error "File data mismatch after migration"
20104 }
20105 run_test 230n "Dir migration with mirrored file"
20106
20107 test_230o() {
20108         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
20109         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20110                 skip "Need MDS version at least 2.13.52"
20111
20112         local mdts=$(comma_list $(mdts_nodes))
20113         local timeout=100
20114         local restripe_status
20115         local delta
20116         local i
20117
20118         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20119
20120         # in case "crush" hash type is not set
20121         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20122
20123         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20124                            mdt.*MDT0000.enable_dir_restripe)
20125         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20126         stack_trap "do_nodes $mdts $LCTL set_param \
20127                     mdt.*.enable_dir_restripe=$restripe_status"
20128
20129         mkdir $DIR/$tdir
20130         createmany -m $DIR/$tdir/f 100 ||
20131                 error "create files under remote dir failed $i"
20132         createmany -d $DIR/$tdir/d 100 ||
20133                 error "create dirs under remote dir failed $i"
20134
20135         for i in $(seq 2 $MDSCOUNT); do
20136                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20137                 $LFS setdirstripe -c $i $DIR/$tdir ||
20138                         error "split -c $i $tdir failed"
20139                 wait_update $HOSTNAME \
20140                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
20141                         error "dir split not finished"
20142                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20143                         awk '/migrate/ {sum += $2} END { print sum }')
20144                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
20145                 # delta is around total_files/stripe_count
20146                 (( $delta < 200 / (i - 1) + 4 )) ||
20147                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
20148         done
20149 }
20150 run_test 230o "dir split"
20151
20152 test_230p() {
20153         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20154         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20155                 skip "Need MDS version at least 2.13.52"
20156
20157         local mdts=$(comma_list $(mdts_nodes))
20158         local timeout=100
20159         local restripe_status
20160         local delta
20161         local c
20162
20163         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20164
20165         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20166
20167         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20168                            mdt.*MDT0000.enable_dir_restripe)
20169         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20170         stack_trap "do_nodes $mdts $LCTL set_param \
20171                     mdt.*.enable_dir_restripe=$restripe_status"
20172
20173         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
20174         createmany -m $DIR/$tdir/f 100 ||
20175                 error "create files under remote dir failed"
20176         createmany -d $DIR/$tdir/d 100 ||
20177                 error "create dirs under remote dir failed"
20178
20179         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
20180                 local mdt_hash="crush"
20181
20182                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20183                 $LFS setdirstripe -c $c $DIR/$tdir ||
20184                         error "split -c $c $tdir failed"
20185                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
20186                         mdt_hash="$mdt_hash,fixed"
20187                 elif [ $c -eq 1 ]; then
20188                         mdt_hash="none"
20189                 fi
20190                 wait_update $HOSTNAME \
20191                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
20192                         error "dir merge not finished"
20193                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20194                         awk '/migrate/ {sum += $2} END { print sum }')
20195                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
20196                 # delta is around total_files/stripe_count
20197                 (( delta < 200 / c + 4 )) ||
20198                         error "$delta files migrated >= $((200 / c + 4))"
20199         done
20200 }
20201 run_test 230p "dir merge"
20202
20203 test_230q() {
20204         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
20205         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20206                 skip "Need MDS version at least 2.13.52"
20207
20208         local mdts=$(comma_list $(mdts_nodes))
20209         local saved_threshold=$(do_facet mds1 \
20210                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
20211         local saved_delta=$(do_facet mds1 \
20212                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
20213         local threshold=100
20214         local delta=2
20215         local total=0
20216         local stripe_count=0
20217         local stripe_index
20218         local nr_files
20219         local create
20220
20221         # test with fewer files on ZFS
20222         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
20223
20224         stack_trap "do_nodes $mdts $LCTL set_param \
20225                     mdt.*.dir_split_count=$saved_threshold"
20226         stack_trap "do_nodes $mdts $LCTL set_param \
20227                     mdt.*.dir_split_delta=$saved_delta"
20228         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
20229         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
20230         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
20231         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
20232         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
20233         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20234
20235         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20236         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20237
20238         create=$((threshold * 3 / 2))
20239         while [ $stripe_count -lt $MDSCOUNT ]; do
20240                 createmany -m $DIR/$tdir/f $total $create ||
20241                         error "create sub files failed"
20242                 stat $DIR/$tdir > /dev/null
20243                 total=$((total + create))
20244                 stripe_count=$((stripe_count + delta))
20245                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
20246
20247                 wait_update $HOSTNAME \
20248                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
20249                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
20250
20251                 wait_update $HOSTNAME \
20252                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
20253                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
20254
20255                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
20256                 echo "$nr_files/$total files on MDT$stripe_index after split"
20257                 # allow 10% margin of imbalance with crush hash
20258                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
20259                         error "$nr_files files on MDT$stripe_index after split"
20260
20261                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
20262                 [ $nr_files -eq $total ] ||
20263                         error "total sub files $nr_files != $total"
20264         done
20265
20266         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
20267
20268         echo "fixed layout directory won't auto split"
20269         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
20270         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
20271                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
20272         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
20273                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
20274 }
20275 run_test 230q "dir auto split"
20276
20277 test_230r() {
20278         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
20279         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20280         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
20281                 skip "Need MDS version at least 2.13.54"
20282
20283         # maximum amount of local locks:
20284         # parent striped dir - 2 locks
20285         # new stripe in parent to migrate to - 1 lock
20286         # source and target - 2 locks
20287         # Total 5 locks for regular file
20288         mkdir -p $DIR/$tdir
20289         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
20290         touch $DIR/$tdir/dir1/eee
20291
20292         # create 4 hardlink for 4 more locks
20293         # Total: 9 locks > RS_MAX_LOCKS (8)
20294         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
20295         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
20296         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
20297         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
20298         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
20299         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
20300         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
20301         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
20302
20303         cancel_lru_locks mdc
20304
20305         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
20306                 error "migrate dir fails"
20307
20308         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20309 }
20310 run_test 230r "migrate with too many local locks"
20311
20312 test_230s() {
20313         [ $MDS1_VERSION -ge $(version_code 2.13.57) ] ||
20314                 skip "Need MDS version at least 2.13.57"
20315
20316         local mdts=$(comma_list $(mdts_nodes))
20317         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
20318                                 mdt.*MDT0000.enable_dir_restripe)
20319
20320         stack_trap "do_nodes $mdts $LCTL set_param \
20321                     mdt.*.enable_dir_restripe=$restripe_status"
20322
20323         local st
20324         for st in 0 1; do
20325                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
20326                 test_mkdir $DIR/$tdir
20327                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
20328                         error "$LFS mkdir doesn't return -EEXIST if target exists"
20329                 rmdir $DIR/$tdir
20330         done
20331 }
20332 run_test 230s "lfs mkdir should return -EEXIST if target exists"
20333
20334 test_230t()
20335 {
20336         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20337         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
20338                 skip "Need MDS version at least 2.14.50"
20339
20340         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
20341         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
20342         $LFS project -p 1 -s $DIR/$tdir ||
20343                 error "set $tdir project id failed"
20344         $LFS project -p 2 -s $DIR/$tdir/subdir ||
20345                 error "set subdir project id failed"
20346         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
20347 }
20348 run_test 230t "migrate directory with project ID set"
20349
20350 test_230u()
20351 {
20352         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20353         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20354                 skip "Need MDS version at least 2.14.53"
20355
20356         local count
20357
20358         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20359         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20360         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
20361         for i in $(seq 0 $((MDSCOUNT - 1))); do
20362                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20363                 echo "$count dirs migrated to MDT$i"
20364         done
20365         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20366         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
20367 }
20368 run_test 230u "migrate directory by QOS"
20369
20370 test_230v()
20371 {
20372         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20373         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20374                 skip "Need MDS version at least 2.14.53"
20375
20376         local count
20377
20378         mkdir $DIR/$tdir || error "mkdir $tdir failed"
20379         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20380         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
20381         for i in $(seq 0 $((MDSCOUNT - 1))); do
20382                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20383                 echo "$count subdirs migrated to MDT$i"
20384                 (( i == 3 )) && (( count > 0 )) &&
20385                         error "subdir shouldn't be migrated to MDT3"
20386         done
20387         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20388         (( count == 3 )) || error "dirs migrated to $count MDTs"
20389 }
20390 run_test 230v "subdir migrated to the MDT where its parent is located"
20391
20392 test_231a()
20393 {
20394         # For simplicity this test assumes that max_pages_per_rpc
20395         # is the same across all OSCs
20396         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
20397         local bulk_size=$((max_pages * PAGE_SIZE))
20398         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
20399                                        head -n 1)
20400
20401         mkdir -p $DIR/$tdir
20402         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
20403                 error "failed to set stripe with -S ${brw_size}M option"
20404
20405         # clear the OSC stats
20406         $LCTL set_param osc.*.stats=0 &>/dev/null
20407         stop_writeback
20408
20409         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
20410         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
20411                 oflag=direct &>/dev/null || error "dd failed"
20412
20413         sync; sleep 1; sync # just to be safe
20414         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
20415         if [ x$nrpcs != "x1" ]; then
20416                 $LCTL get_param osc.*.stats
20417                 error "found $nrpcs ost_write RPCs, not 1 as expected"
20418         fi
20419
20420         start_writeback
20421         # Drop the OSC cache, otherwise we will read from it
20422         cancel_lru_locks osc
20423
20424         # clear the OSC stats
20425         $LCTL set_param osc.*.stats=0 &>/dev/null
20426
20427         # Client reads $bulk_size.
20428         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
20429                 iflag=direct &>/dev/null || error "dd failed"
20430
20431         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
20432         if [ x$nrpcs != "x1" ]; then
20433                 $LCTL get_param osc.*.stats
20434                 error "found $nrpcs ost_read RPCs, not 1 as expected"
20435         fi
20436 }
20437 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
20438
20439 test_231b() {
20440         mkdir -p $DIR/$tdir
20441         local i
20442         for i in {0..1023}; do
20443                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
20444                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
20445                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
20446         done
20447         sync
20448 }
20449 run_test 231b "must not assert on fully utilized OST request buffer"
20450
20451 test_232a() {
20452         mkdir -p $DIR/$tdir
20453         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20454
20455         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20456         do_facet ost1 $LCTL set_param fail_loc=0x31c
20457
20458         # ignore dd failure
20459         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
20460
20461         do_facet ost1 $LCTL set_param fail_loc=0
20462         umount_client $MOUNT || error "umount failed"
20463         mount_client $MOUNT || error "mount failed"
20464         stop ost1 || error "cannot stop ost1"
20465         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20466 }
20467 run_test 232a "failed lock should not block umount"
20468
20469 test_232b() {
20470         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
20471                 skip "Need MDS version at least 2.10.58"
20472
20473         mkdir -p $DIR/$tdir
20474         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20475         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
20476         sync
20477         cancel_lru_locks osc
20478
20479         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20480         do_facet ost1 $LCTL set_param fail_loc=0x31c
20481
20482         # ignore failure
20483         $LFS data_version $DIR/$tdir/$tfile || true
20484
20485         do_facet ost1 $LCTL set_param fail_loc=0
20486         umount_client $MOUNT || error "umount failed"
20487         mount_client $MOUNT || error "mount failed"
20488         stop ost1 || error "cannot stop ost1"
20489         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20490 }
20491 run_test 232b "failed data version lock should not block umount"
20492
20493 test_233a() {
20494         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
20495                 skip "Need MDS version at least 2.3.64"
20496         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20497
20498         local fid=$($LFS path2fid $MOUNT)
20499
20500         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20501                 error "cannot access $MOUNT using its FID '$fid'"
20502 }
20503 run_test 233a "checking that OBF of the FS root succeeds"
20504
20505 test_233b() {
20506         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
20507                 skip "Need MDS version at least 2.5.90"
20508         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20509
20510         local fid=$($LFS path2fid $MOUNT/.lustre)
20511
20512         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20513                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
20514
20515         fid=$($LFS path2fid $MOUNT/.lustre/fid)
20516         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20517                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
20518 }
20519 run_test 233b "checking that OBF of the FS .lustre succeeds"
20520
20521 test_234() {
20522         local p="$TMP/sanityN-$TESTNAME.parameters"
20523         save_lustre_params client "llite.*.xattr_cache" > $p
20524         lctl set_param llite.*.xattr_cache 1 ||
20525                 skip_env "xattr cache is not supported"
20526
20527         mkdir -p $DIR/$tdir || error "mkdir failed"
20528         touch $DIR/$tdir/$tfile || error "touch failed"
20529         # OBD_FAIL_LLITE_XATTR_ENOMEM
20530         $LCTL set_param fail_loc=0x1405
20531         getfattr -n user.attr $DIR/$tdir/$tfile &&
20532                 error "getfattr should have failed with ENOMEM"
20533         $LCTL set_param fail_loc=0x0
20534         rm -rf $DIR/$tdir
20535
20536         restore_lustre_params < $p
20537         rm -f $p
20538 }
20539 run_test 234 "xattr cache should not crash on ENOMEM"
20540
20541 test_235() {
20542         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
20543                 skip "Need MDS version at least 2.4.52"
20544
20545         flock_deadlock $DIR/$tfile
20546         local RC=$?
20547         case $RC in
20548                 0)
20549                 ;;
20550                 124) error "process hangs on a deadlock"
20551                 ;;
20552                 *) error "error executing flock_deadlock $DIR/$tfile"
20553                 ;;
20554         esac
20555 }
20556 run_test 235 "LU-1715: flock deadlock detection does not work properly"
20557
20558 #LU-2935
20559 test_236() {
20560         check_swap_layouts_support
20561
20562         local ref1=/etc/passwd
20563         local ref2=/etc/group
20564         local file1=$DIR/$tdir/f1
20565         local file2=$DIR/$tdir/f2
20566
20567         test_mkdir -c1 $DIR/$tdir
20568         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
20569         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
20570         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
20571         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
20572         local fd=$(free_fd)
20573         local cmd="exec $fd<>$file2"
20574         eval $cmd
20575         rm $file2
20576         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
20577                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
20578         cmd="exec $fd>&-"
20579         eval $cmd
20580         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20581
20582         #cleanup
20583         rm -rf $DIR/$tdir
20584 }
20585 run_test 236 "Layout swap on open unlinked file"
20586
20587 # LU-4659 linkea consistency
20588 test_238() {
20589         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
20590                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
20591                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
20592                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
20593
20594         touch $DIR/$tfile
20595         ln $DIR/$tfile $DIR/$tfile.lnk
20596         touch $DIR/$tfile.new
20597         mv $DIR/$tfile.new $DIR/$tfile
20598         local fid1=$($LFS path2fid $DIR/$tfile)
20599         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
20600         local path1=$($LFS fid2path $FSNAME "$fid1")
20601         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
20602         local path2=$($LFS fid2path $FSNAME "$fid2")
20603         [ $tfile.lnk == $path2 ] ||
20604                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
20605         rm -f $DIR/$tfile*
20606 }
20607 run_test 238 "Verify linkea consistency"
20608
20609 test_239A() { # was test_239
20610         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
20611                 skip "Need MDS version at least 2.5.60"
20612
20613         local list=$(comma_list $(mdts_nodes))
20614
20615         mkdir -p $DIR/$tdir
20616         createmany -o $DIR/$tdir/f- 5000
20617         unlinkmany $DIR/$tdir/f- 5000
20618         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
20619                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
20620         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
20621                         osp.*MDT*.sync_in_flight" | calc_sum)
20622         [ "$changes" -eq 0 ] || error "$changes not synced"
20623 }
20624 run_test 239A "osp_sync test"
20625
20626 test_239a() { #LU-5297
20627         remote_mds_nodsh && skip "remote MDS with nodsh"
20628
20629         touch $DIR/$tfile
20630         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
20631         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
20632         chgrp $RUNAS_GID $DIR/$tfile
20633         wait_delete_completed
20634 }
20635 run_test 239a "process invalid osp sync record correctly"
20636
20637 test_239b() { #LU-5297
20638         remote_mds_nodsh && skip "remote MDS with nodsh"
20639
20640         touch $DIR/$tfile1
20641         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
20642         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
20643         chgrp $RUNAS_GID $DIR/$tfile1
20644         wait_delete_completed
20645         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20646         touch $DIR/$tfile2
20647         chgrp $RUNAS_GID $DIR/$tfile2
20648         wait_delete_completed
20649 }
20650 run_test 239b "process osp sync record with ENOMEM error correctly"
20651
20652 test_240() {
20653         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20654         remote_mds_nodsh && skip "remote MDS with nodsh"
20655
20656         mkdir -p $DIR/$tdir
20657
20658         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
20659                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
20660         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
20661                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
20662
20663         umount_client $MOUNT || error "umount failed"
20664         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
20665         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
20666         mount_client $MOUNT || error "failed to mount client"
20667
20668         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
20669         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
20670 }
20671 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
20672
20673 test_241_bio() {
20674         local count=$1
20675         local bsize=$2
20676
20677         for LOOP in $(seq $count); do
20678                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
20679                 cancel_lru_locks $OSC || true
20680         done
20681 }
20682
20683 test_241_dio() {
20684         local count=$1
20685         local bsize=$2
20686
20687         for LOOP in $(seq $1); do
20688                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
20689                         2>/dev/null
20690         done
20691 }
20692
20693 test_241a() { # was test_241
20694         local bsize=$PAGE_SIZE
20695
20696         (( bsize < 40960 )) && bsize=40960
20697         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20698         ls -la $DIR/$tfile
20699         cancel_lru_locks $OSC
20700         test_241_bio 1000 $bsize &
20701         PID=$!
20702         test_241_dio 1000 $bsize
20703         wait $PID
20704 }
20705 run_test 241a "bio vs dio"
20706
20707 test_241b() {
20708         local bsize=$PAGE_SIZE
20709
20710         (( bsize < 40960 )) && bsize=40960
20711         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20712         ls -la $DIR/$tfile
20713         test_241_dio 1000 $bsize &
20714         PID=$!
20715         test_241_dio 1000 $bsize
20716         wait $PID
20717 }
20718 run_test 241b "dio vs dio"
20719
20720 test_242() {
20721         remote_mds_nodsh && skip "remote MDS with nodsh"
20722
20723         mkdir_on_mdt0 $DIR/$tdir
20724         touch $DIR/$tdir/$tfile
20725
20726         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
20727         do_facet mds1 lctl set_param fail_loc=0x105
20728         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
20729
20730         do_facet mds1 lctl set_param fail_loc=0
20731         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
20732 }
20733 run_test 242 "mdt_readpage failure should not cause directory unreadable"
20734
20735 test_243()
20736 {
20737         test_mkdir $DIR/$tdir
20738         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
20739 }
20740 run_test 243 "various group lock tests"
20741
20742 test_244a()
20743 {
20744         test_mkdir $DIR/$tdir
20745         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
20746         sendfile_grouplock $DIR/$tdir/$tfile || \
20747                 error "sendfile+grouplock failed"
20748         rm -rf $DIR/$tdir
20749 }
20750 run_test 244a "sendfile with group lock tests"
20751
20752 test_244b()
20753 {
20754         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20755
20756         local threads=50
20757         local size=$((1024*1024))
20758
20759         test_mkdir $DIR/$tdir
20760         for i in $(seq 1 $threads); do
20761                 local file=$DIR/$tdir/file_$((i / 10))
20762                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
20763                 local pids[$i]=$!
20764         done
20765         for i in $(seq 1 $threads); do
20766                 wait ${pids[$i]}
20767         done
20768 }
20769 run_test 244b "multi-threaded write with group lock"
20770
20771 test_245() {
20772         local flagname="multi_mod_rpcs"
20773         local connect_data_name="max_mod_rpcs"
20774         local out
20775
20776         # check if multiple modify RPCs flag is set
20777         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
20778                 grep "connect_flags:")
20779         echo "$out"
20780
20781         echo "$out" | grep -qw $flagname
20782         if [ $? -ne 0 ]; then
20783                 echo "connect flag $flagname is not set"
20784                 return
20785         fi
20786
20787         # check if multiple modify RPCs data is set
20788         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
20789         echo "$out"
20790
20791         echo "$out" | grep -qw $connect_data_name ||
20792                 error "import should have connect data $connect_data_name"
20793 }
20794 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
20795
20796 cleanup_247() {
20797         local submount=$1
20798
20799         trap 0
20800         umount_client $submount
20801         rmdir $submount
20802 }
20803
20804 test_247a() {
20805         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20806                 grep -q subtree ||
20807                 skip_env "Fileset feature is not supported"
20808
20809         local submount=${MOUNT}_$tdir
20810
20811         mkdir $MOUNT/$tdir
20812         mkdir -p $submount || error "mkdir $submount failed"
20813         FILESET="$FILESET/$tdir" mount_client $submount ||
20814                 error "mount $submount failed"
20815         trap "cleanup_247 $submount" EXIT
20816         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
20817         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
20818                 error "read $MOUNT/$tdir/$tfile failed"
20819         cleanup_247 $submount
20820 }
20821 run_test 247a "mount subdir as fileset"
20822
20823 test_247b() {
20824         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20825                 skip_env "Fileset feature is not supported"
20826
20827         local submount=${MOUNT}_$tdir
20828
20829         rm -rf $MOUNT/$tdir
20830         mkdir -p $submount || error "mkdir $submount failed"
20831         SKIP_FILESET=1
20832         FILESET="$FILESET/$tdir" mount_client $submount &&
20833                 error "mount $submount should fail"
20834         rmdir $submount
20835 }
20836 run_test 247b "mount subdir that dose not exist"
20837
20838 test_247c() {
20839         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20840                 skip_env "Fileset feature is not supported"
20841
20842         local submount=${MOUNT}_$tdir
20843
20844         mkdir -p $MOUNT/$tdir/dir1
20845         mkdir -p $submount || error "mkdir $submount failed"
20846         trap "cleanup_247 $submount" EXIT
20847         FILESET="$FILESET/$tdir" mount_client $submount ||
20848                 error "mount $submount failed"
20849         local fid=$($LFS path2fid $MOUNT/)
20850         $LFS fid2path $submount $fid && error "fid2path should fail"
20851         cleanup_247 $submount
20852 }
20853 run_test 247c "running fid2path outside subdirectory root"
20854
20855 test_247d() {
20856         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20857                 skip "Fileset feature is not supported"
20858
20859         local submount=${MOUNT}_$tdir
20860
20861         mkdir -p $MOUNT/$tdir/dir1
20862         mkdir -p $submount || error "mkdir $submount failed"
20863         FILESET="$FILESET/$tdir" mount_client $submount ||
20864                 error "mount $submount failed"
20865         trap "cleanup_247 $submount" EXIT
20866
20867         local td=$submount/dir1
20868         local fid=$($LFS path2fid $td)
20869         [ -z "$fid" ] && error "path2fid unable to get $td FID"
20870
20871         # check that we get the same pathname back
20872         local rootpath
20873         local found
20874         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
20875                 echo "$rootpath $fid"
20876                 found=$($LFS fid2path $rootpath "$fid")
20877                 [ -n "found" ] || error "fid2path should succeed"
20878                 [ "$found" == "$td" ] || error "fid2path $found != $td"
20879         done
20880         # check wrong root path format
20881         rootpath=$submount"_wrong"
20882         found=$($LFS fid2path $rootpath "$fid")
20883         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
20884
20885         cleanup_247 $submount
20886 }
20887 run_test 247d "running fid2path inside subdirectory root"
20888
20889 # LU-8037
20890 test_247e() {
20891         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20892                 grep -q subtree ||
20893                 skip "Fileset feature is not supported"
20894
20895         local submount=${MOUNT}_$tdir
20896
20897         mkdir $MOUNT/$tdir
20898         mkdir -p $submount || error "mkdir $submount failed"
20899         FILESET="$FILESET/.." mount_client $submount &&
20900                 error "mount $submount should fail"
20901         rmdir $submount
20902 }
20903 run_test 247e "mount .. as fileset"
20904
20905 test_247f() {
20906         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20907         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20908                 skip "Need at least version 2.13.52"
20909         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20910                 skip "Need at least version 2.14.50"
20911         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20912                 grep -q subtree ||
20913                 skip "Fileset feature is not supported"
20914
20915         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20916         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
20917                 error "mkdir remote failed"
20918         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
20919                 error "mkdir remote/subdir failed"
20920         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
20921                 error "mkdir striped failed"
20922         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
20923
20924         local submount=${MOUNT}_$tdir
20925
20926         mkdir -p $submount || error "mkdir $submount failed"
20927         stack_trap "rmdir $submount"
20928
20929         local dir
20930         local stat
20931         local fileset=$FILESET
20932         local mdts=$(comma_list $(mdts_nodes))
20933
20934         stat=$(do_facet mds1 $LCTL get_param -n \
20935                 mdt.*MDT0000.enable_remote_subdir_mount)
20936         stack_trap "do_nodes $mdts $LCTL set_param \
20937                 mdt.*.enable_remote_subdir_mount=$stat"
20938
20939         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
20940         stack_trap "umount_client $submount"
20941         FILESET="$fileset/$tdir/remote" mount_client $submount &&
20942                 error "mount remote dir $dir should fail"
20943
20944         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
20945                 $tdir/striped/. ; do
20946                 FILESET="$fileset/$dir" mount_client $submount ||
20947                         error "mount $dir failed"
20948                 umount_client $submount
20949         done
20950
20951         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
20952         FILESET="$fileset/$tdir/remote" mount_client $submount ||
20953                 error "mount $tdir/remote failed"
20954 }
20955 run_test 247f "mount striped or remote directory as fileset"
20956
20957 test_247g() {
20958         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
20959         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20960                 skip "Need at least version 2.14.50"
20961
20962         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
20963                 error "mkdir $tdir failed"
20964         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
20965
20966         local submount=${MOUNT}_$tdir
20967
20968         mkdir -p $submount || error "mkdir $submount failed"
20969         stack_trap "rmdir $submount"
20970
20971         FILESET="$fileset/$tdir" mount_client $submount ||
20972                 error "mount $dir failed"
20973         stack_trap "umount $submount"
20974
20975         local mdts=$(comma_list $(mdts_nodes))
20976
20977         local nrpcs
20978
20979         stat $submount > /dev/null
20980         cancel_lru_locks $MDC
20981         stat $submount > /dev/null
20982         stat $submount/$tfile > /dev/null
20983         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
20984         stat $submount/$tfile > /dev/null
20985         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
20986                 awk '/getattr/ {sum += $2} END {print sum}')
20987
20988         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
20989 }
20990 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
20991
20992 test_248a() {
20993         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
20994         [ -z "$fast_read_sav" ] && skip "no fast read support"
20995
20996         # create a large file for fast read verification
20997         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
20998
20999         # make sure the file is created correctly
21000         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
21001                 { rm -f $DIR/$tfile; skip "file creation error"; }
21002
21003         echo "Test 1: verify that fast read is 4 times faster on cache read"
21004
21005         # small read with fast read enabled
21006         $LCTL set_param -n llite.*.fast_read=1
21007         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21008                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21009                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21010         # small read with fast read disabled
21011         $LCTL set_param -n llite.*.fast_read=0
21012         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21013                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21014                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21015
21016         # verify that fast read is 4 times faster for cache read
21017         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
21018                 error_not_in_vm "fast read was not 4 times faster: " \
21019                            "$t_fast vs $t_slow"
21020
21021         echo "Test 2: verify the performance between big and small read"
21022         $LCTL set_param -n llite.*.fast_read=1
21023
21024         # 1k non-cache read
21025         cancel_lru_locks osc
21026         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21027                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21028                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21029
21030         # 1M non-cache read
21031         cancel_lru_locks osc
21032         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21033                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21034                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21035
21036         # verify that big IO is not 4 times faster than small IO
21037         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
21038                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
21039
21040         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
21041         rm -f $DIR/$tfile
21042 }
21043 run_test 248a "fast read verification"
21044
21045 test_248b() {
21046         # Default short_io_bytes=16384, try both smaller and larger sizes.
21047         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
21048         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
21049         echo "bs=53248 count=113 normal buffered write"
21050         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
21051                 error "dd of initial data file failed"
21052         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
21053
21054         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
21055         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
21056                 error "dd with sync normal writes failed"
21057         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
21058
21059         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
21060         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
21061                 error "dd with sync small writes failed"
21062         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
21063
21064         cancel_lru_locks osc
21065
21066         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
21067         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
21068         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
21069         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
21070                 iflag=direct || error "dd with O_DIRECT small read failed"
21071         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
21072         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
21073                 error "compare $TMP/$tfile.1 failed"
21074
21075         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
21076         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
21077
21078         # just to see what the maximum tunable value is, and test parsing
21079         echo "test invalid parameter 2MB"
21080         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
21081                 error "too-large short_io_bytes allowed"
21082         echo "test maximum parameter 512KB"
21083         # if we can set a larger short_io_bytes, run test regardless of version
21084         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
21085                 # older clients may not allow setting it this large, that's OK
21086                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
21087                         skip "Need at least client version 2.13.50"
21088                 error "medium short_io_bytes failed"
21089         fi
21090         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21091         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
21092
21093         echo "test large parameter 64KB"
21094         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
21095         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21096
21097         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
21098         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
21099                 error "dd with sync large writes failed"
21100         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
21101
21102         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
21103         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
21104         num=$((113 * 4096 / PAGE_SIZE))
21105         echo "bs=$size count=$num oflag=direct large write $tfile.3"
21106         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
21107                 error "dd with O_DIRECT large writes failed"
21108         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
21109                 error "compare $DIR/$tfile.3 failed"
21110
21111         cancel_lru_locks osc
21112
21113         echo "bs=$size count=$num iflag=direct large read $tfile.2"
21114         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
21115                 error "dd with O_DIRECT large read failed"
21116         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
21117                 error "compare $TMP/$tfile.2 failed"
21118
21119         echo "bs=$size count=$num iflag=direct large read $tfile.3"
21120         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
21121                 error "dd with O_DIRECT large read failed"
21122         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
21123                 error "compare $TMP/$tfile.3 failed"
21124 }
21125 run_test 248b "test short_io read and write for both small and large sizes"
21126
21127 test_249() { # LU-7890
21128         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
21129                 skip "Need at least version 2.8.54"
21130
21131         rm -f $DIR/$tfile
21132         $LFS setstripe -c 1 $DIR/$tfile
21133         # Offset 2T == 4k * 512M
21134         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
21135                 error "dd to 2T offset failed"
21136 }
21137 run_test 249 "Write above 2T file size"
21138
21139 test_250() {
21140         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
21141          && skip "no 16TB file size limit on ZFS"
21142
21143         $LFS setstripe -c 1 $DIR/$tfile
21144         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
21145         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
21146         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
21147         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
21148                 conv=notrunc,fsync && error "append succeeded"
21149         return 0
21150 }
21151 run_test 250 "Write above 16T limit"
21152
21153 test_251() {
21154         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
21155
21156         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
21157         #Skip once - writing the first stripe will succeed
21158         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21159         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
21160                 error "short write happened"
21161
21162         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21163         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
21164                 error "short read happened"
21165
21166         rm -f $DIR/$tfile
21167 }
21168 run_test 251 "Handling short read and write correctly"
21169
21170 test_252() {
21171         remote_mds_nodsh && skip "remote MDS with nodsh"
21172         remote_ost_nodsh && skip "remote OST with nodsh"
21173         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
21174                 skip_env "ldiskfs only test"
21175         fi
21176
21177         local tgt
21178         local dev
21179         local out
21180         local uuid
21181         local num
21182         local gen
21183
21184         # check lr_reader on OST0000
21185         tgt=ost1
21186         dev=$(facet_device $tgt)
21187         out=$(do_facet $tgt $LR_READER $dev)
21188         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21189         echo "$out"
21190         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
21191         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
21192                 error "Invalid uuid returned by $LR_READER on target $tgt"
21193         echo -e "uuid returned by $LR_READER is '$uuid'\n"
21194
21195         # check lr_reader -c on MDT0000
21196         tgt=mds1
21197         dev=$(facet_device $tgt)
21198         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
21199                 skip "$LR_READER does not support additional options"
21200         fi
21201         out=$(do_facet $tgt $LR_READER -c $dev)
21202         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21203         echo "$out"
21204         num=$(echo "$out" | grep -c "mdtlov")
21205         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
21206                 error "Invalid number of mdtlov clients returned by $LR_READER"
21207         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
21208
21209         # check lr_reader -cr on MDT0000
21210         out=$(do_facet $tgt $LR_READER -cr $dev)
21211         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21212         echo "$out"
21213         echo "$out" | grep -q "^reply_data:$" ||
21214                 error "$LR_READER should have returned 'reply_data' section"
21215         num=$(echo "$out" | grep -c "client_generation")
21216         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
21217 }
21218 run_test 252 "check lr_reader tool"
21219
21220 test_253() {
21221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21222         remote_mds_nodsh && skip "remote MDS with nodsh"
21223         remote_mgs_nodsh && skip "remote MGS with nodsh"
21224
21225         local ostidx=0
21226         local rc=0
21227         local ost_name=$(ostname_from_index $ostidx)
21228
21229         # on the mdt's osc
21230         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
21231         do_facet $SINGLEMDS $LCTL get_param -n \
21232                 osp.$mdtosc_proc1.reserved_mb_high ||
21233                 skip  "remote MDS does not support reserved_mb_high"
21234
21235         rm -rf $DIR/$tdir
21236         wait_mds_ost_sync
21237         wait_delete_completed
21238         mkdir $DIR/$tdir
21239
21240         pool_add $TESTNAME || error "Pool creation failed"
21241         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
21242
21243         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
21244                 error "Setstripe failed"
21245
21246         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
21247
21248         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
21249                     grep "watermarks")
21250         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
21251
21252         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21253                         osp.$mdtosc_proc1.prealloc_status)
21254         echo "prealloc_status $oa_status"
21255
21256         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
21257                 error "File creation should fail"
21258
21259         #object allocation was stopped, but we still able to append files
21260         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
21261                 oflag=append || error "Append failed"
21262
21263         rm -f $DIR/$tdir/$tfile.0
21264
21265         # For this test, we want to delete the files we created to go out of
21266         # space but leave the watermark, so we remain nearly out of space
21267         ost_watermarks_enospc_delete_files $tfile $ostidx
21268
21269         wait_delete_completed
21270
21271         sleep_maxage
21272
21273         for i in $(seq 10 12); do
21274                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
21275                         2>/dev/null || error "File creation failed after rm"
21276         done
21277
21278         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21279                         osp.$mdtosc_proc1.prealloc_status)
21280         echo "prealloc_status $oa_status"
21281
21282         if (( oa_status != 0 )); then
21283                 error "Object allocation still disable after rm"
21284         fi
21285 }
21286 run_test 253 "Check object allocation limit"
21287
21288 test_254() {
21289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21290         remote_mds_nodsh && skip "remote MDS with nodsh"
21291
21292         local mdt=$(facet_svc $SINGLEMDS)
21293
21294         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
21295                 skip "MDS does not support changelog_size"
21296
21297         local cl_user
21298
21299         changelog_register || error "changelog_register failed"
21300
21301         changelog_clear 0 || error "changelog_clear failed"
21302
21303         local size1=$(do_facet $SINGLEMDS \
21304                       $LCTL get_param -n mdd.$mdt.changelog_size)
21305         echo "Changelog size $size1"
21306
21307         rm -rf $DIR/$tdir
21308         $LFS mkdir -i 0 $DIR/$tdir
21309         # change something
21310         mkdir -p $DIR/$tdir/pics/2008/zachy
21311         touch $DIR/$tdir/pics/2008/zachy/timestamp
21312         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
21313         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
21314         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
21315         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
21316         rm $DIR/$tdir/pics/desktop.jpg
21317
21318         local size2=$(do_facet $SINGLEMDS \
21319                       $LCTL get_param -n mdd.$mdt.changelog_size)
21320         echo "Changelog size after work $size2"
21321
21322         (( $size2 > $size1 )) ||
21323                 error "new Changelog size=$size2 less than old size=$size1"
21324 }
21325 run_test 254 "Check changelog size"
21326
21327 ladvise_no_type()
21328 {
21329         local type=$1
21330         local file=$2
21331
21332         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
21333                 awk -F: '{print $2}' | grep $type > /dev/null
21334         if [ $? -ne 0 ]; then
21335                 return 0
21336         fi
21337         return 1
21338 }
21339
21340 ladvise_no_ioctl()
21341 {
21342         local file=$1
21343
21344         lfs ladvise -a willread $file > /dev/null 2>&1
21345         if [ $? -eq 0 ]; then
21346                 return 1
21347         fi
21348
21349         lfs ladvise -a willread $file 2>&1 |
21350                 grep "Inappropriate ioctl for device" > /dev/null
21351         if [ $? -eq 0 ]; then
21352                 return 0
21353         fi
21354         return 1
21355 }
21356
21357 percent() {
21358         bc <<<"scale=2; ($1 - $2) * 100 / $2"
21359 }
21360
21361 # run a random read IO workload
21362 # usage: random_read_iops <filename> <filesize> <iosize>
21363 random_read_iops() {
21364         local file=$1
21365         local fsize=$2
21366         local iosize=${3:-4096}
21367
21368         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
21369                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
21370 }
21371
21372 drop_file_oss_cache() {
21373         local file="$1"
21374         local nodes="$2"
21375
21376         $LFS ladvise -a dontneed $file 2>/dev/null ||
21377                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
21378 }
21379
21380 ladvise_willread_performance()
21381 {
21382         local repeat=10
21383         local average_origin=0
21384         local average_cache=0
21385         local average_ladvise=0
21386
21387         for ((i = 1; i <= $repeat; i++)); do
21388                 echo "Iter $i/$repeat: reading without willread hint"
21389                 cancel_lru_locks osc
21390                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21391                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
21392                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
21393                 average_origin=$(bc <<<"$average_origin + $speed_origin")
21394
21395                 cancel_lru_locks osc
21396                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
21397                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
21398                 average_cache=$(bc <<<"$average_cache + $speed_cache")
21399
21400                 cancel_lru_locks osc
21401                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21402                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
21403                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
21404                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
21405                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
21406         done
21407         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
21408         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
21409         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
21410
21411         speedup_cache=$(percent $average_cache $average_origin)
21412         speedup_ladvise=$(percent $average_ladvise $average_origin)
21413
21414         echo "Average uncached read: $average_origin"
21415         echo "Average speedup with OSS cached read: " \
21416                 "$average_cache = +$speedup_cache%"
21417         echo "Average speedup with ladvise willread: " \
21418                 "$average_ladvise = +$speedup_ladvise%"
21419
21420         local lowest_speedup=20
21421         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
21422                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
21423                         "got $average_cache%. Skipping ladvise willread check."
21424                 return 0
21425         fi
21426
21427         # the test won't work on ZFS until it supports 'ladvise dontneed', but
21428         # it is still good to run until then to exercise 'ladvise willread'
21429         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21430                 [ "$ost1_FSTYPE" = "zfs" ] &&
21431                 echo "osd-zfs does not support dontneed or drop_caches" &&
21432                 return 0
21433
21434         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
21435         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
21436                 error_not_in_vm "Speedup with willread is less than " \
21437                         "$lowest_speedup%, got $average_ladvise%"
21438 }
21439
21440 test_255a() {
21441         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21442                 skip "lustre < 2.8.54 does not support ladvise "
21443         remote_ost_nodsh && skip "remote OST with nodsh"
21444
21445         stack_trap "rm -f $DIR/$tfile"
21446         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
21447
21448         ladvise_no_type willread $DIR/$tfile &&
21449                 skip "willread ladvise is not supported"
21450
21451         ladvise_no_ioctl $DIR/$tfile &&
21452                 skip "ladvise ioctl is not supported"
21453
21454         local size_mb=100
21455         local size=$((size_mb * 1048576))
21456         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21457                 error "dd to $DIR/$tfile failed"
21458
21459         lfs ladvise -a willread $DIR/$tfile ||
21460                 error "Ladvise failed with no range argument"
21461
21462         lfs ladvise -a willread -s 0 $DIR/$tfile ||
21463                 error "Ladvise failed with no -l or -e argument"
21464
21465         lfs ladvise -a willread -e 1 $DIR/$tfile ||
21466                 error "Ladvise failed with only -e argument"
21467
21468         lfs ladvise -a willread -l 1 $DIR/$tfile ||
21469                 error "Ladvise failed with only -l argument"
21470
21471         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
21472                 error "End offset should not be smaller than start offset"
21473
21474         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
21475                 error "End offset should not be equal to start offset"
21476
21477         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
21478                 error "Ladvise failed with overflowing -s argument"
21479
21480         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
21481                 error "Ladvise failed with overflowing -e argument"
21482
21483         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
21484                 error "Ladvise failed with overflowing -l argument"
21485
21486         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
21487                 error "Ladvise succeeded with conflicting -l and -e arguments"
21488
21489         echo "Synchronous ladvise should wait"
21490         local delay=4
21491 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
21492         do_nodes $(comma_list $(osts_nodes)) \
21493                 $LCTL set_param fail_val=$delay fail_loc=0x237
21494
21495         local start_ts=$SECONDS
21496         lfs ladvise -a willread $DIR/$tfile ||
21497                 error "Ladvise failed with no range argument"
21498         local end_ts=$SECONDS
21499         local inteval_ts=$((end_ts - start_ts))
21500
21501         if [ $inteval_ts -lt $(($delay - 1)) ]; then
21502                 error "Synchronous advice didn't wait reply"
21503         fi
21504
21505         echo "Asynchronous ladvise shouldn't wait"
21506         local start_ts=$SECONDS
21507         lfs ladvise -a willread -b $DIR/$tfile ||
21508                 error "Ladvise failed with no range argument"
21509         local end_ts=$SECONDS
21510         local inteval_ts=$((end_ts - start_ts))
21511
21512         if [ $inteval_ts -gt $(($delay / 2)) ]; then
21513                 error "Asynchronous advice blocked"
21514         fi
21515
21516         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
21517         ladvise_willread_performance
21518 }
21519 run_test 255a "check 'lfs ladvise -a willread'"
21520
21521 facet_meminfo() {
21522         local facet=$1
21523         local info=$2
21524
21525         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
21526 }
21527
21528 test_255b() {
21529         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21530                 skip "lustre < 2.8.54 does not support ladvise "
21531         remote_ost_nodsh && skip "remote OST with nodsh"
21532
21533         stack_trap "rm -f $DIR/$tfile"
21534         lfs setstripe -c 1 -i 0 $DIR/$tfile
21535
21536         ladvise_no_type dontneed $DIR/$tfile &&
21537                 skip "dontneed ladvise is not supported"
21538
21539         ladvise_no_ioctl $DIR/$tfile &&
21540                 skip "ladvise ioctl is not supported"
21541
21542         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21543                 [ "$ost1_FSTYPE" = "zfs" ] &&
21544                 skip "zfs-osd does not support 'ladvise dontneed'"
21545
21546         local size_mb=100
21547         local size=$((size_mb * 1048576))
21548         # In order to prevent disturbance of other processes, only check 3/4
21549         # of the memory usage
21550         local kibibytes=$((size_mb * 1024 * 3 / 4))
21551
21552         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21553                 error "dd to $DIR/$tfile failed"
21554
21555         #force write to complete before dropping OST cache & checking memory
21556         sync
21557
21558         local total=$(facet_meminfo ost1 MemTotal)
21559         echo "Total memory: $total KiB"
21560
21561         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
21562         local before_read=$(facet_meminfo ost1 Cached)
21563         echo "Cache used before read: $before_read KiB"
21564
21565         lfs ladvise -a willread $DIR/$tfile ||
21566                 error "Ladvise willread failed"
21567         local after_read=$(facet_meminfo ost1 Cached)
21568         echo "Cache used after read: $after_read KiB"
21569
21570         lfs ladvise -a dontneed $DIR/$tfile ||
21571                 error "Ladvise dontneed again failed"
21572         local no_read=$(facet_meminfo ost1 Cached)
21573         echo "Cache used after dontneed ladvise: $no_read KiB"
21574
21575         if [ $total -lt $((before_read + kibibytes)) ]; then
21576                 echo "Memory is too small, abort checking"
21577                 return 0
21578         fi
21579
21580         if [ $((before_read + kibibytes)) -gt $after_read ]; then
21581                 error "Ladvise willread should use more memory" \
21582                         "than $kibibytes KiB"
21583         fi
21584
21585         if [ $((no_read + kibibytes)) -gt $after_read ]; then
21586                 error "Ladvise dontneed should release more memory" \
21587                         "than $kibibytes KiB"
21588         fi
21589 }
21590 run_test 255b "check 'lfs ladvise -a dontneed'"
21591
21592 test_255c() {
21593         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
21594                 skip "lustre < 2.10.50 does not support lockahead"
21595
21596         local ost1_imp=$(get_osc_import_name client ost1)
21597         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
21598                          cut -d'.' -f2)
21599         local count
21600         local new_count
21601         local difference
21602         local i
21603         local rc
21604
21605         test_mkdir -p $DIR/$tdir
21606         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21607
21608         #test 10 returns only success/failure
21609         i=10
21610         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21611         rc=$?
21612         if [ $rc -eq 255 ]; then
21613                 error "Ladvise test${i} failed, ${rc}"
21614         fi
21615
21616         #test 11 counts lock enqueue requests, all others count new locks
21617         i=11
21618         count=$(do_facet ost1 \
21619                 $LCTL get_param -n ost.OSS.ost.stats)
21620         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
21621
21622         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21623         rc=$?
21624         if [ $rc -eq 255 ]; then
21625                 error "Ladvise test${i} failed, ${rc}"
21626         fi
21627
21628         new_count=$(do_facet ost1 \
21629                 $LCTL get_param -n ost.OSS.ost.stats)
21630         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
21631                    awk '{ print $2 }')
21632
21633         difference="$((new_count - count))"
21634         if [ $difference -ne $rc ]; then
21635                 error "Ladvise test${i}, bad enqueue count, returned " \
21636                       "${rc}, actual ${difference}"
21637         fi
21638
21639         for i in $(seq 12 21); do
21640                 # If we do not do this, we run the risk of having too many
21641                 # locks and starting lock cancellation while we are checking
21642                 # lock counts.
21643                 cancel_lru_locks osc
21644
21645                 count=$($LCTL get_param -n \
21646                        ldlm.namespaces.$imp_name.lock_unused_count)
21647
21648                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
21649                 rc=$?
21650                 if [ $rc -eq 255 ]; then
21651                         error "Ladvise test ${i} failed, ${rc}"
21652                 fi
21653
21654                 new_count=$($LCTL get_param -n \
21655                        ldlm.namespaces.$imp_name.lock_unused_count)
21656                 difference="$((new_count - count))"
21657
21658                 # Test 15 output is divided by 100 to map down to valid return
21659                 if [ $i -eq 15 ]; then
21660                         rc="$((rc * 100))"
21661                 fi
21662
21663                 if [ $difference -ne $rc ]; then
21664                         error "Ladvise test ${i}, bad lock count, returned " \
21665                               "${rc}, actual ${difference}"
21666                 fi
21667         done
21668
21669         #test 22 returns only success/failure
21670         i=22
21671         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21672         rc=$?
21673         if [ $rc -eq 255 ]; then
21674                 error "Ladvise test${i} failed, ${rc}"
21675         fi
21676 }
21677 run_test 255c "suite of ladvise lockahead tests"
21678
21679 test_256() {
21680         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21681         remote_mds_nodsh && skip "remote MDS with nodsh"
21682         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21683         changelog_users $SINGLEMDS | grep "^cl" &&
21684                 skip "active changelog user"
21685
21686         local cl_user
21687         local cat_sl
21688         local mdt_dev
21689
21690         mdt_dev=$(mdsdevname 1)
21691         echo $mdt_dev
21692
21693         changelog_register || error "changelog_register failed"
21694
21695         rm -rf $DIR/$tdir
21696         mkdir_on_mdt0 $DIR/$tdir
21697
21698         changelog_clear 0 || error "changelog_clear failed"
21699
21700         # change something
21701         touch $DIR/$tdir/{1..10}
21702
21703         # stop the MDT
21704         stop $SINGLEMDS || error "Fail to stop MDT"
21705
21706         # remount the MDT
21707
21708         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
21709
21710         #after mount new plainllog is used
21711         touch $DIR/$tdir/{11..19}
21712         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
21713         stack_trap "rm -f $tmpfile"
21714         cat_sl=$(do_facet $SINGLEMDS "sync; \
21715                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21716                  llog_reader $tmpfile | grep -c type=1064553b")
21717         do_facet $SINGLEMDS llog_reader $tmpfile
21718
21719         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
21720
21721         changelog_clear 0 || error "changelog_clear failed"
21722
21723         cat_sl=$(do_facet $SINGLEMDS "sync; \
21724                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21725                  llog_reader $tmpfile | grep -c type=1064553b")
21726
21727         if (( cat_sl == 2 )); then
21728                 error "Empty plain llog was not deleted from changelog catalog"
21729         elif (( cat_sl != 1 )); then
21730                 error "Active plain llog shouldn't be deleted from catalog"
21731         fi
21732 }
21733 run_test 256 "Check llog delete for empty and not full state"
21734
21735 test_257() {
21736         remote_mds_nodsh && skip "remote MDS with nodsh"
21737         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
21738                 skip "Need MDS version at least 2.8.55"
21739
21740         test_mkdir $DIR/$tdir
21741
21742         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
21743                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
21744         stat $DIR/$tdir
21745
21746 #define OBD_FAIL_MDS_XATTR_REP                  0x161
21747         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21748         local facet=mds$((mdtidx + 1))
21749         set_nodes_failloc $(facet_active_host $facet) 0x80000161
21750         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
21751
21752         stop $facet || error "stop MDS failed"
21753         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
21754                 error "start MDS fail"
21755         wait_recovery_complete $facet
21756 }
21757 run_test 257 "xattr locks are not lost"
21758
21759 # Verify we take the i_mutex when security requires it
21760 test_258a() {
21761 #define OBD_FAIL_IMUTEX_SEC 0x141c
21762         $LCTL set_param fail_loc=0x141c
21763         touch $DIR/$tfile
21764         chmod u+s $DIR/$tfile
21765         chmod a+rwx $DIR/$tfile
21766         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21767         RC=$?
21768         if [ $RC -ne 0 ]; then
21769                 error "error, failed to take i_mutex, rc=$?"
21770         fi
21771         rm -f $DIR/$tfile
21772 }
21773 run_test 258a "verify i_mutex security behavior when suid attributes is set"
21774
21775 # Verify we do NOT take the i_mutex in the normal case
21776 test_258b() {
21777 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
21778         $LCTL set_param fail_loc=0x141d
21779         touch $DIR/$tfile
21780         chmod a+rwx $DIR
21781         chmod a+rw $DIR/$tfile
21782         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21783         RC=$?
21784         if [ $RC -ne 0 ]; then
21785                 error "error, took i_mutex unnecessarily, rc=$?"
21786         fi
21787         rm -f $DIR/$tfile
21788
21789 }
21790 run_test 258b "verify i_mutex security behavior"
21791
21792 test_259() {
21793         local file=$DIR/$tfile
21794         local before
21795         local after
21796
21797         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21798
21799         stack_trap "rm -f $file" EXIT
21800
21801         wait_delete_completed
21802         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21803         echo "before: $before"
21804
21805         $LFS setstripe -i 0 -c 1 $file
21806         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
21807         sync_all_data
21808         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21809         echo "after write: $after"
21810
21811 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
21812         do_facet ost1 $LCTL set_param fail_loc=0x2301
21813         $TRUNCATE $file 0
21814         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21815         echo "after truncate: $after"
21816
21817         stop ost1
21818         do_facet ost1 $LCTL set_param fail_loc=0
21819         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21820         sleep 2
21821         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21822         echo "after restart: $after"
21823         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
21824                 error "missing truncate?"
21825
21826         return 0
21827 }
21828 run_test 259 "crash at delayed truncate"
21829
21830 test_260() {
21831 #define OBD_FAIL_MDC_CLOSE               0x806
21832         $LCTL set_param fail_loc=0x80000806
21833         touch $DIR/$tfile
21834
21835 }
21836 run_test 260 "Check mdc_close fail"
21837
21838 ### Data-on-MDT sanity tests ###
21839 test_270a() {
21840         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21841                 skip "Need MDS version at least 2.10.55 for DoM"
21842
21843         # create DoM file
21844         local dom=$DIR/$tdir/dom_file
21845         local tmp=$DIR/$tdir/tmp_file
21846
21847         mkdir_on_mdt0 $DIR/$tdir
21848
21849         # basic checks for DoM component creation
21850         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
21851                 error "Can set MDT layout to non-first entry"
21852
21853         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
21854                 error "Can define multiple entries as MDT layout"
21855
21856         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
21857
21858         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
21859         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
21860         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
21861
21862         local mdtidx=$($LFS getstripe -m $dom)
21863         local mdtname=MDT$(printf %04x $mdtidx)
21864         local facet=mds$((mdtidx + 1))
21865         local space_check=1
21866
21867         # Skip free space checks with ZFS
21868         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
21869
21870         # write
21871         sync
21872         local size_tmp=$((65536 * 3))
21873         local mdtfree1=$(do_facet $facet \
21874                          lctl get_param -n osd*.*$mdtname.kbytesfree)
21875
21876         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21877         # check also direct IO along write
21878         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
21879         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21880         sync
21881         cmp $tmp $dom || error "file data is different"
21882         [ $(stat -c%s $dom) == $size_tmp ] ||
21883                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21884         if [ $space_check == 1 ]; then
21885                 local mdtfree2=$(do_facet $facet \
21886                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
21887
21888                 # increase in usage from by $size_tmp
21889                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21890                         error "MDT free space wrong after write: " \
21891                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21892         fi
21893
21894         # truncate
21895         local size_dom=10000
21896
21897         $TRUNCATE $dom $size_dom
21898         [ $(stat -c%s $dom) == $size_dom ] ||
21899                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
21900         if [ $space_check == 1 ]; then
21901                 mdtfree1=$(do_facet $facet \
21902                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21903                 # decrease in usage from $size_tmp to new $size_dom
21904                 [ $(($mdtfree1 - $mdtfree2)) -ge \
21905                   $(((size_tmp - size_dom) / 1024)) ] ||
21906                         error "MDT free space is wrong after truncate: " \
21907                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
21908         fi
21909
21910         # append
21911         cat $tmp >> $dom
21912         sync
21913         size_dom=$((size_dom + size_tmp))
21914         [ $(stat -c%s $dom) == $size_dom ] ||
21915                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
21916         if [ $space_check == 1 ]; then
21917                 mdtfree2=$(do_facet $facet \
21918                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21919                 # increase in usage by $size_tmp from previous
21920                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21921                         error "MDT free space is wrong after append: " \
21922                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21923         fi
21924
21925         # delete
21926         rm $dom
21927         if [ $space_check == 1 ]; then
21928                 mdtfree1=$(do_facet $facet \
21929                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21930                 # decrease in usage by $size_dom from previous
21931                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
21932                         error "MDT free space is wrong after removal: " \
21933                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
21934         fi
21935
21936         # combined striping
21937         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
21938                 error "Can't create DoM + OST striping"
21939
21940         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
21941         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21942         # check also direct IO along write
21943         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21944         sync
21945         cmp $tmp $dom || error "file data is different"
21946         [ $(stat -c%s $dom) == $size_tmp ] ||
21947                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21948         rm $dom $tmp
21949
21950         return 0
21951 }
21952 run_test 270a "DoM: basic functionality tests"
21953
21954 test_270b() {
21955         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21956                 skip "Need MDS version at least 2.10.55"
21957
21958         local dom=$DIR/$tdir/dom_file
21959         local max_size=1048576
21960
21961         mkdir -p $DIR/$tdir
21962         $LFS setstripe -E $max_size -L mdt $dom
21963
21964         # truncate over the limit
21965         $TRUNCATE $dom $(($max_size + 1)) &&
21966                 error "successful truncate over the maximum size"
21967         # write over the limit
21968         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
21969                 error "successful write over the maximum size"
21970         # append over the limit
21971         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
21972         echo "12345" >> $dom && error "successful append over the maximum size"
21973         rm $dom
21974
21975         return 0
21976 }
21977 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
21978
21979 test_270c() {
21980         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21981                 skip "Need MDS version at least 2.10.55"
21982
21983         mkdir -p $DIR/$tdir
21984         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21985
21986         # check files inherit DoM EA
21987         touch $DIR/$tdir/first
21988         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
21989                 error "bad pattern"
21990         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
21991                 error "bad stripe count"
21992         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
21993                 error "bad stripe size"
21994
21995         # check directory inherits DoM EA and uses it as default
21996         mkdir $DIR/$tdir/subdir
21997         touch $DIR/$tdir/subdir/second
21998         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
21999                 error "bad pattern in sub-directory"
22000         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
22001                 error "bad stripe count in sub-directory"
22002         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
22003                 error "bad stripe size in sub-directory"
22004         return 0
22005 }
22006 run_test 270c "DoM: DoM EA inheritance tests"
22007
22008 test_270d() {
22009         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22010                 skip "Need MDS version at least 2.10.55"
22011
22012         mkdir -p $DIR/$tdir
22013         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22014
22015         # inherit default DoM striping
22016         mkdir $DIR/$tdir/subdir
22017         touch $DIR/$tdir/subdir/f1
22018
22019         # change default directory striping
22020         $LFS setstripe -c 1 $DIR/$tdir/subdir
22021         touch $DIR/$tdir/subdir/f2
22022         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
22023                 error "wrong default striping in file 2"
22024         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
22025                 error "bad pattern in file 2"
22026         return 0
22027 }
22028 run_test 270d "DoM: change striping from DoM to RAID0"
22029
22030 test_270e() {
22031         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22032                 skip "Need MDS version at least 2.10.55"
22033
22034         mkdir -p $DIR/$tdir/dom
22035         mkdir -p $DIR/$tdir/norm
22036         DOMFILES=20
22037         NORMFILES=10
22038         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
22039         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
22040
22041         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
22042         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
22043
22044         # find DoM files by layout
22045         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
22046         [ $NUM -eq  $DOMFILES ] ||
22047                 error "lfs find -L: found $NUM, expected $DOMFILES"
22048         echo "Test 1: lfs find 20 DOM files by layout: OK"
22049
22050         # there should be 1 dir with default DOM striping
22051         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
22052         [ $NUM -eq  1 ] ||
22053                 error "lfs find -L: found $NUM, expected 1 dir"
22054         echo "Test 2: lfs find 1 DOM dir by layout: OK"
22055
22056         # find DoM files by stripe size
22057         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
22058         [ $NUM -eq  $DOMFILES ] ||
22059                 error "lfs find -S: found $NUM, expected $DOMFILES"
22060         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
22061
22062         # find files by stripe offset except DoM files
22063         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
22064         [ $NUM -eq  $NORMFILES ] ||
22065                 error "lfs find -i: found $NUM, expected $NORMFILES"
22066         echo "Test 5: lfs find no DOM files by stripe index: OK"
22067         return 0
22068 }
22069 run_test 270e "DoM: lfs find with DoM files test"
22070
22071 test_270f() {
22072         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22073                 skip "Need MDS version at least 2.10.55"
22074
22075         local mdtname=${FSNAME}-MDT0000-mdtlov
22076         local dom=$DIR/$tdir/dom_file
22077         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
22078                                                 lod.$mdtname.dom_stripesize)
22079         local dom_limit=131072
22080
22081         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
22082         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22083                                                 lod.$mdtname.dom_stripesize)
22084         [ ${dom_limit} -eq ${dom_current} ] ||
22085                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
22086
22087         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22088         $LFS setstripe -d $DIR/$tdir
22089         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
22090                 error "Can't set directory default striping"
22091
22092         # exceed maximum stripe size
22093         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22094                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
22095         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
22096                 error "Able to create DoM component size more than LOD limit"
22097
22098         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22099         dom_current=$(do_facet mds1 $LCTL get_param -n \
22100                                                 lod.$mdtname.dom_stripesize)
22101         [ 0 -eq ${dom_current} ] ||
22102                 error "Can't set zero DoM stripe limit"
22103         rm $dom
22104
22105         # attempt to create DoM file on server with disabled DoM should
22106         # remove DoM entry from layout and be succeed
22107         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
22108                 error "Can't create DoM file (DoM is disabled)"
22109         [ $($LFS getstripe -L $dom) == "mdt" ] &&
22110                 error "File has DoM component while DoM is disabled"
22111         rm $dom
22112
22113         # attempt to create DoM file with only DoM stripe should return error
22114         $LFS setstripe -E $dom_limit -L mdt $dom &&
22115                 error "Able to create DoM-only file while DoM is disabled"
22116
22117         # too low values to be aligned with smallest stripe size 64K
22118         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
22119         dom_current=$(do_facet mds1 $LCTL get_param -n \
22120                                                 lod.$mdtname.dom_stripesize)
22121         [ 30000 -eq ${dom_current} ] &&
22122                 error "Can set too small DoM stripe limit"
22123
22124         # 64K is a minimal stripe size in Lustre, expect limit of that size
22125         [ 65536 -eq ${dom_current} ] ||
22126                 error "Limit is not set to 64K but ${dom_current}"
22127
22128         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
22129         dom_current=$(do_facet mds1 $LCTL get_param -n \
22130                                                 lod.$mdtname.dom_stripesize)
22131         echo $dom_current
22132         [ 2147483648 -eq ${dom_current} ] &&
22133                 error "Can set too large DoM stripe limit"
22134
22135         do_facet mds1 $LCTL set_param -n \
22136                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
22137         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22138                 error "Can't create DoM component size after limit change"
22139         do_facet mds1 $LCTL set_param -n \
22140                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
22141         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
22142                 error "Can't create DoM file after limit decrease"
22143         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
22144                 error "Can create big DoM component after limit decrease"
22145         touch ${dom}_def ||
22146                 error "Can't create file with old default layout"
22147
22148         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
22149         return 0
22150 }
22151 run_test 270f "DoM: maximum DoM stripe size checks"
22152
22153 test_270g() {
22154         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22155                 skip "Need MDS version at least 2.13.52"
22156         local dom=$DIR/$tdir/$tfile
22157
22158         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22159         local lodname=${FSNAME}-MDT0000-mdtlov
22160
22161         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22162         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
22163         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
22164         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22165
22166         local dom_limit=1024
22167         local dom_threshold="50%"
22168
22169         $LFS setstripe -d $DIR/$tdir
22170         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
22171                 error "Can't set directory default striping"
22172
22173         do_facet mds1 $LCTL set_param -n \
22174                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
22175         # set 0 threshold and create DOM file to change tunable stripesize
22176         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
22177         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22178                 error "Failed to create $dom file"
22179         # now tunable dom_cur_stripesize should reach maximum
22180         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22181                                         lod.${lodname}.dom_stripesize_cur_kb)
22182         [[ $dom_current == $dom_limit ]] ||
22183                 error "Current DOM stripesize is not maximum"
22184         rm $dom
22185
22186         # set threshold for further tests
22187         do_facet mds1 $LCTL set_param -n \
22188                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
22189         echo "DOM threshold is $dom_threshold free space"
22190         local dom_def
22191         local dom_set
22192         # Spoof bfree to exceed threshold
22193         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
22194         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
22195         for spfree in 40 20 0 15 30 55; do
22196                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
22197                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22198                         error "Failed to create $dom file"
22199                 dom_def=$(do_facet mds1 $LCTL get_param -n \
22200                                         lod.${lodname}.dom_stripesize_cur_kb)
22201                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
22202                 [[ $dom_def != $dom_current ]] ||
22203                         error "Default stripe size was not changed"
22204                 if [[ $spfree > 0 ]] ; then
22205                         dom_set=$($LFS getstripe -S $dom)
22206                         [[ $dom_set == $((dom_def * 1024)) ]] ||
22207                                 error "DOM component size is still old"
22208                 else
22209                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22210                                 error "DoM component is set with no free space"
22211                 fi
22212                 rm $dom
22213                 dom_current=$dom_def
22214         done
22215 }
22216 run_test 270g "DoM: default DoM stripe size depends on free space"
22217
22218 test_270h() {
22219         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22220                 skip "Need MDS version at least 2.13.53"
22221
22222         local mdtname=${FSNAME}-MDT0000-mdtlov
22223         local dom=$DIR/$tdir/$tfile
22224         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22225
22226         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
22227         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22228
22229         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22230         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
22231                 error "can't create OST file"
22232         # mirrored file with DOM entry in the second mirror
22233         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
22234                 error "can't create mirror with DoM component"
22235
22236         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22237
22238         # DOM component in the middle and has other enries in the same mirror,
22239         # should succeed but lost DoM component
22240         $LFS setstripe --copy=${dom}_1 $dom ||
22241                 error "Can't create file from OST|DOM mirror layout"
22242         # check new file has no DoM layout after all
22243         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22244                 error "File has DoM component while DoM is disabled"
22245 }
22246 run_test 270h "DoM: DoM stripe removal when disabled on server"
22247
22248 test_270i() {
22249         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
22250                 skip "Need MDS version at least 2.14.54"
22251
22252         mkdir $DIR/$tdir
22253         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
22254                 error "setstripe should fail" || true
22255 }
22256 run_test 270i "DoM: setting invalid DoM striping should fail"
22257
22258 test_271a() {
22259         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22260                 skip "Need MDS version at least 2.10.55"
22261
22262         local dom=$DIR/$tdir/dom
22263
22264         mkdir -p $DIR/$tdir
22265
22266         $LFS setstripe -E 1024K -L mdt $dom
22267
22268         lctl set_param -n mdc.*.stats=clear
22269         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22270         cat $dom > /dev/null
22271         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
22272         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
22273         ls $dom
22274         rm -f $dom
22275 }
22276 run_test 271a "DoM: data is cached for read after write"
22277
22278 test_271b() {
22279         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22280                 skip "Need MDS version at least 2.10.55"
22281
22282         local dom=$DIR/$tdir/dom
22283
22284         mkdir -p $DIR/$tdir
22285
22286         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22287
22288         lctl set_param -n mdc.*.stats=clear
22289         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22290         cancel_lru_locks mdc
22291         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
22292         # second stat to check size is cached on client
22293         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
22294         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22295         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
22296         rm -f $dom
22297 }
22298 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
22299
22300 test_271ba() {
22301         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22302                 skip "Need MDS version at least 2.10.55"
22303
22304         local dom=$DIR/$tdir/dom
22305
22306         mkdir -p $DIR/$tdir
22307
22308         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22309
22310         lctl set_param -n mdc.*.stats=clear
22311         lctl set_param -n osc.*.stats=clear
22312         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
22313         cancel_lru_locks mdc
22314         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22315         # second stat to check size is cached on client
22316         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22317         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22318         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
22319         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
22320         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
22321         rm -f $dom
22322 }
22323 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
22324
22325
22326 get_mdc_stats() {
22327         local mdtidx=$1
22328         local param=$2
22329         local mdt=MDT$(printf %04x $mdtidx)
22330
22331         if [ -z $param ]; then
22332                 lctl get_param -n mdc.*$mdt*.stats
22333         else
22334                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
22335         fi
22336 }
22337
22338 test_271c() {
22339         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22340                 skip "Need MDS version at least 2.10.55"
22341
22342         local dom=$DIR/$tdir/dom
22343
22344         mkdir -p $DIR/$tdir
22345
22346         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22347
22348         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22349         local facet=mds$((mdtidx + 1))
22350
22351         cancel_lru_locks mdc
22352         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
22353         createmany -o $dom 1000
22354         lctl set_param -n mdc.*.stats=clear
22355         smalliomany -w $dom 1000 200
22356         get_mdc_stats $mdtidx
22357         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22358         # Each file has 1 open, 1 IO enqueues, total 2000
22359         # but now we have also +1 getxattr for security.capability, total 3000
22360         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
22361         unlinkmany $dom 1000
22362
22363         cancel_lru_locks mdc
22364         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
22365         createmany -o $dom 1000
22366         lctl set_param -n mdc.*.stats=clear
22367         smalliomany -w $dom 1000 200
22368         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22369         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
22370         # for OPEN and IO lock.
22371         [ $((enq - enq_2)) -ge 1000 ] ||
22372                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
22373         unlinkmany $dom 1000
22374         return 0
22375 }
22376 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
22377
22378 cleanup_271def_tests() {
22379         trap 0
22380         rm -f $1
22381 }
22382
22383 test_271d() {
22384         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22385                 skip "Need MDS version at least 2.10.57"
22386
22387         local dom=$DIR/$tdir/dom
22388         local tmp=$TMP/$tfile
22389         trap "cleanup_271def_tests $tmp" EXIT
22390
22391         mkdir -p $DIR/$tdir
22392
22393         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22394
22395         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22396
22397         cancel_lru_locks mdc
22398         dd if=/dev/urandom of=$tmp bs=1000 count=1
22399         dd if=$tmp of=$dom bs=1000 count=1
22400         cancel_lru_locks mdc
22401
22402         cat /etc/hosts >> $tmp
22403         lctl set_param -n mdc.*.stats=clear
22404
22405         # append data to the same file it should update local page
22406         echo "Append to the same page"
22407         cat /etc/hosts >> $dom
22408         local num=$(get_mdc_stats $mdtidx ost_read)
22409         local ra=$(get_mdc_stats $mdtidx req_active)
22410         local rw=$(get_mdc_stats $mdtidx req_waittime)
22411
22412         [ -z $num ] || error "$num READ RPC occured"
22413         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22414         echo "... DONE"
22415
22416         # compare content
22417         cmp $tmp $dom || error "file miscompare"
22418
22419         cancel_lru_locks mdc
22420         lctl set_param -n mdc.*.stats=clear
22421
22422         echo "Open and read file"
22423         cat $dom > /dev/null
22424         local num=$(get_mdc_stats $mdtidx ost_read)
22425         local ra=$(get_mdc_stats $mdtidx req_active)
22426         local rw=$(get_mdc_stats $mdtidx req_waittime)
22427
22428         [ -z $num ] || error "$num READ RPC occured"
22429         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22430         echo "... DONE"
22431
22432         # compare content
22433         cmp $tmp $dom || error "file miscompare"
22434
22435         return 0
22436 }
22437 run_test 271d "DoM: read on open (1K file in reply buffer)"
22438
22439 test_271f() {
22440         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22441                 skip "Need MDS version at least 2.10.57"
22442
22443         local dom=$DIR/$tdir/dom
22444         local tmp=$TMP/$tfile
22445         trap "cleanup_271def_tests $tmp" EXIT
22446
22447         mkdir -p $DIR/$tdir
22448
22449         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22450
22451         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22452
22453         cancel_lru_locks mdc
22454         dd if=/dev/urandom of=$tmp bs=265000 count=1
22455         dd if=$tmp of=$dom bs=265000 count=1
22456         cancel_lru_locks mdc
22457         cat /etc/hosts >> $tmp
22458         lctl set_param -n mdc.*.stats=clear
22459
22460         echo "Append to the same page"
22461         cat /etc/hosts >> $dom
22462         local num=$(get_mdc_stats $mdtidx ost_read)
22463         local ra=$(get_mdc_stats $mdtidx req_active)
22464         local rw=$(get_mdc_stats $mdtidx req_waittime)
22465
22466         [ -z $num ] || error "$num READ RPC occured"
22467         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22468         echo "... DONE"
22469
22470         # compare content
22471         cmp $tmp $dom || error "file miscompare"
22472
22473         cancel_lru_locks mdc
22474         lctl set_param -n mdc.*.stats=clear
22475
22476         echo "Open and read file"
22477         cat $dom > /dev/null
22478         local num=$(get_mdc_stats $mdtidx ost_read)
22479         local ra=$(get_mdc_stats $mdtidx req_active)
22480         local rw=$(get_mdc_stats $mdtidx req_waittime)
22481
22482         [ -z $num ] && num=0
22483         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
22484         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22485         echo "... DONE"
22486
22487         # compare content
22488         cmp $tmp $dom || error "file miscompare"
22489
22490         return 0
22491 }
22492 run_test 271f "DoM: read on open (200K file and read tail)"
22493
22494 test_271g() {
22495         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
22496                 skip "Skipping due to old client or server version"
22497
22498         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
22499         # to get layout
22500         $CHECKSTAT -t file $DIR1/$tfile
22501
22502         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
22503         MULTIOP_PID=$!
22504         sleep 1
22505         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
22506         $LCTL set_param fail_loc=0x80000314
22507         rm $DIR1/$tfile || error "Unlink fails"
22508         RC=$?
22509         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
22510         [ $RC -eq 0 ] || error "Failed write to stale object"
22511 }
22512 run_test 271g "Discard DoM data vs client flush race"
22513
22514 test_272a() {
22515         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22516                 skip "Need MDS version at least 2.11.50"
22517
22518         local dom=$DIR/$tdir/dom
22519         mkdir -p $DIR/$tdir
22520
22521         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
22522         dd if=/dev/urandom of=$dom bs=512K count=1 ||
22523                 error "failed to write data into $dom"
22524         local old_md5=$(md5sum $dom)
22525
22526         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
22527                 error "failed to migrate to the same DoM component"
22528
22529         local new_md5=$(md5sum $dom)
22530
22531         [ "$old_md5" == "$new_md5" ] ||
22532                 error "md5sum differ: $old_md5, $new_md5"
22533
22534         [ $($LFS getstripe -c $dom) -eq 2 ] ||
22535                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
22536 }
22537 run_test 272a "DoM migration: new layout with the same DOM component"
22538
22539 test_272b() {
22540         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22541                 skip "Need MDS version at least 2.11.50"
22542
22543         local dom=$DIR/$tdir/dom
22544         mkdir -p $DIR/$tdir
22545         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22546
22547         local mdtidx=$($LFS getstripe -m $dom)
22548         local mdtname=MDT$(printf %04x $mdtidx)
22549         local facet=mds$((mdtidx + 1))
22550
22551         local mdtfree1=$(do_facet $facet \
22552                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22553         dd if=/dev/urandom of=$dom bs=2M count=1 ||
22554                 error "failed to write data into $dom"
22555         local old_md5=$(md5sum $dom)
22556         cancel_lru_locks mdc
22557         local mdtfree1=$(do_facet $facet \
22558                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22559
22560         $LFS migrate -c2 $dom ||
22561                 error "failed to migrate to the new composite layout"
22562         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22563                 error "MDT stripe was not removed"
22564
22565         cancel_lru_locks mdc
22566         local new_md5=$(md5sum $dom)
22567         [ "$old_md5" == "$new_md5" ] ||
22568                 error "$old_md5 != $new_md5"
22569
22570         # Skip free space checks with ZFS
22571         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22572                 local mdtfree2=$(do_facet $facet \
22573                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22574                 [ $mdtfree2 -gt $mdtfree1 ] ||
22575                         error "MDT space is not freed after migration"
22576         fi
22577         return 0
22578 }
22579 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
22580
22581 test_272c() {
22582         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22583                 skip "Need MDS version at least 2.11.50"
22584
22585         local dom=$DIR/$tdir/$tfile
22586         mkdir -p $DIR/$tdir
22587         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22588
22589         local mdtidx=$($LFS getstripe -m $dom)
22590         local mdtname=MDT$(printf %04x $mdtidx)
22591         local facet=mds$((mdtidx + 1))
22592
22593         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22594                 error "failed to write data into $dom"
22595         local old_md5=$(md5sum $dom)
22596         cancel_lru_locks mdc
22597         local mdtfree1=$(do_facet $facet \
22598                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22599
22600         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
22601                 error "failed to migrate to the new composite layout"
22602         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
22603                 error "MDT stripe was not removed"
22604
22605         cancel_lru_locks mdc
22606         local new_md5=$(md5sum $dom)
22607         [ "$old_md5" == "$new_md5" ] ||
22608                 error "$old_md5 != $new_md5"
22609
22610         # Skip free space checks with ZFS
22611         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22612                 local mdtfree2=$(do_facet $facet \
22613                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22614                 [ $mdtfree2 -gt $mdtfree1 ] ||
22615                         error "MDS space is not freed after migration"
22616         fi
22617         return 0
22618 }
22619 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
22620
22621 test_272d() {
22622         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22623                 skip "Need MDS version at least 2.12.55"
22624
22625         local dom=$DIR/$tdir/$tfile
22626         mkdir -p $DIR/$tdir
22627         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22628
22629         local mdtidx=$($LFS getstripe -m $dom)
22630         local mdtname=MDT$(printf %04x $mdtidx)
22631         local facet=mds$((mdtidx + 1))
22632
22633         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22634                 error "failed to write data into $dom"
22635         local old_md5=$(md5sum $dom)
22636         cancel_lru_locks mdc
22637         local mdtfree1=$(do_facet $facet \
22638                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22639
22640         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
22641                 error "failed mirroring to the new composite layout"
22642         $LFS mirror resync $dom ||
22643                 error "failed mirror resync"
22644         $LFS mirror split --mirror-id 1 -d $dom ||
22645                 error "failed mirror split"
22646
22647         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22648                 error "MDT stripe was not removed"
22649
22650         cancel_lru_locks mdc
22651         local new_md5=$(md5sum $dom)
22652         [ "$old_md5" == "$new_md5" ] ||
22653                 error "$old_md5 != $new_md5"
22654
22655         # Skip free space checks with ZFS
22656         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22657                 local mdtfree2=$(do_facet $facet \
22658                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22659                 [ $mdtfree2 -gt $mdtfree1 ] ||
22660                         error "MDS space is not freed after DOM mirror deletion"
22661         fi
22662         return 0
22663 }
22664 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
22665
22666 test_272e() {
22667         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22668                 skip "Need MDS version at least 2.12.55"
22669
22670         local dom=$DIR/$tdir/$tfile
22671         mkdir -p $DIR/$tdir
22672         $LFS setstripe -c 2 $dom
22673
22674         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
22675                 error "failed to write data into $dom"
22676         local old_md5=$(md5sum $dom)
22677         cancel_lru_locks mdc
22678
22679         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
22680                 error "failed mirroring to the DOM layout"
22681         $LFS mirror resync $dom ||
22682                 error "failed mirror resync"
22683         $LFS mirror split --mirror-id 1 -d $dom ||
22684                 error "failed mirror split"
22685
22686         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22687                 error "MDT stripe was not removed"
22688
22689         cancel_lru_locks mdc
22690         local new_md5=$(md5sum $dom)
22691         [ "$old_md5" == "$new_md5" ] ||
22692                 error "$old_md5 != $new_md5"
22693
22694         return 0
22695 }
22696 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
22697
22698 test_272f() {
22699         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22700                 skip "Need MDS version at least 2.12.55"
22701
22702         local dom=$DIR/$tdir/$tfile
22703         mkdir -p $DIR/$tdir
22704         $LFS setstripe -c 2 $dom
22705
22706         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
22707                 error "failed to write data into $dom"
22708         local old_md5=$(md5sum $dom)
22709         cancel_lru_locks mdc
22710
22711         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
22712                 error "failed migrating to the DOM file"
22713
22714         cancel_lru_locks mdc
22715         local new_md5=$(md5sum $dom)
22716         [ "$old_md5" != "$new_md5" ] &&
22717                 error "$old_md5 != $new_md5"
22718
22719         return 0
22720 }
22721 run_test 272f "DoM migration: OST-striped file to DOM file"
22722
22723 test_273a() {
22724         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22725                 skip "Need MDS version at least 2.11.50"
22726
22727         # Layout swap cannot be done if either file has DOM component,
22728         # this will never be supported, migration should be used instead
22729
22730         local dom=$DIR/$tdir/$tfile
22731         mkdir -p $DIR/$tdir
22732
22733         $LFS setstripe -c2 ${dom}_plain
22734         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
22735         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
22736                 error "can swap layout with DoM component"
22737         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
22738                 error "can swap layout with DoM component"
22739
22740         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
22741         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
22742                 error "can swap layout with DoM component"
22743         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
22744                 error "can swap layout with DoM component"
22745         return 0
22746 }
22747 run_test 273a "DoM: layout swapping should fail with DOM"
22748
22749 test_273b() {
22750         mkdir -p $DIR/$tdir
22751         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
22752
22753 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
22754         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
22755
22756         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
22757 }
22758 run_test 273b "DoM: race writeback and object destroy"
22759
22760 test_275() {
22761         remote_ost_nodsh && skip "remote OST with nodsh"
22762         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
22763                 skip "Need OST version >= 2.10.57"
22764
22765         local file=$DIR/$tfile
22766         local oss
22767
22768         oss=$(comma_list $(osts_nodes))
22769
22770         dd if=/dev/urandom of=$file bs=1M count=2 ||
22771                 error "failed to create a file"
22772         cancel_lru_locks osc
22773
22774         #lock 1
22775         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22776                 error "failed to read a file"
22777
22778 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
22779         $LCTL set_param fail_loc=0x8000031f
22780
22781         cancel_lru_locks osc &
22782         sleep 1
22783
22784 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
22785         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
22786         #IO takes another lock, but matches the PENDING one
22787         #and places it to the IO RPC
22788         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22789                 error "failed to read a file with PENDING lock"
22790 }
22791 run_test 275 "Read on a canceled duplicate lock"
22792
22793 test_276() {
22794         remote_ost_nodsh && skip "remote OST with nodsh"
22795         local pid
22796
22797         do_facet ost1 "(while true; do \
22798                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
22799                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
22800         pid=$!
22801
22802         for LOOP in $(seq 20); do
22803                 stop ost1
22804                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
22805         done
22806         kill -9 $pid
22807         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
22808                 rm $TMP/sanity_276_pid"
22809 }
22810 run_test 276 "Race between mount and obd_statfs"
22811
22812 test_277() {
22813         $LCTL set_param ldlm.namespaces.*.lru_size=0
22814         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22815         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22816                         grep ^used_mb | awk '{print $2}')
22817         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
22818         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
22819                 oflag=direct conv=notrunc
22820         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22821                         grep ^used_mb | awk '{print $2}')
22822         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
22823 }
22824 run_test 277 "Direct IO shall drop page cache"
22825
22826 test_278() {
22827         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22828         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22829         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
22830                 skip "needs the same host for mdt1 mdt2" && return
22831
22832         local pid1
22833         local pid2
22834
22835 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
22836         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
22837         stop mds2 &
22838         pid2=$!
22839
22840         stop mds1
22841
22842         echo "Starting MDTs"
22843         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
22844         wait $pid2
22845 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
22846 #will return NULL
22847         do_facet mds2 $LCTL set_param fail_loc=0
22848
22849         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
22850         wait_recovery_complete mds2
22851 }
22852 run_test 278 "Race starting MDS between MDTs stop/start"
22853
22854 test_280() {
22855         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
22856                 skip "Need MGS version at least 2.13.52"
22857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22858         combined_mgs_mds || skip "needs combined MGS/MDT"
22859
22860         umount_client $MOUNT
22861 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
22862         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
22863
22864         mount_client $MOUNT &
22865         sleep 1
22866         stop mgs || error "stop mgs failed"
22867         #for a race mgs would crash
22868         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
22869         # make sure we unmount client before remounting
22870         wait
22871         umount_client $MOUNT
22872         mount_client $MOUNT || error "mount client failed"
22873 }
22874 run_test 280 "Race between MGS umount and client llog processing"
22875
22876 cleanup_test_300() {
22877         trap 0
22878         umask $SAVE_UMASK
22879 }
22880 test_striped_dir() {
22881         local mdt_index=$1
22882         local stripe_count
22883         local stripe_index
22884
22885         mkdir -p $DIR/$tdir
22886
22887         SAVE_UMASK=$(umask)
22888         trap cleanup_test_300 RETURN EXIT
22889
22890         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
22891                                                 $DIR/$tdir/striped_dir ||
22892                 error "set striped dir error"
22893
22894         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
22895         [ "$mode" = "755" ] || error "expect 755 got $mode"
22896
22897         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
22898                 error "getdirstripe failed"
22899         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
22900         if [ "$stripe_count" != "2" ]; then
22901                 error "1:stripe_count is $stripe_count, expect 2"
22902         fi
22903         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
22904         if [ "$stripe_count" != "2" ]; then
22905                 error "2:stripe_count is $stripe_count, expect 2"
22906         fi
22907
22908         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
22909         if [ "$stripe_index" != "$mdt_index" ]; then
22910                 error "stripe_index is $stripe_index, expect $mdt_index"
22911         fi
22912
22913         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22914                 error "nlink error after create striped dir"
22915
22916         mkdir $DIR/$tdir/striped_dir/a
22917         mkdir $DIR/$tdir/striped_dir/b
22918
22919         stat $DIR/$tdir/striped_dir/a ||
22920                 error "create dir under striped dir failed"
22921         stat $DIR/$tdir/striped_dir/b ||
22922                 error "create dir under striped dir failed"
22923
22924         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
22925                 error "nlink error after mkdir"
22926
22927         rmdir $DIR/$tdir/striped_dir/a
22928         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
22929                 error "nlink error after rmdir"
22930
22931         rmdir $DIR/$tdir/striped_dir/b
22932         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22933                 error "nlink error after rmdir"
22934
22935         chattr +i $DIR/$tdir/striped_dir
22936         createmany -o $DIR/$tdir/striped_dir/f 10 &&
22937                 error "immutable flags not working under striped dir!"
22938         chattr -i $DIR/$tdir/striped_dir
22939
22940         rmdir $DIR/$tdir/striped_dir ||
22941                 error "rmdir striped dir error"
22942
22943         cleanup_test_300
22944
22945         true
22946 }
22947
22948 test_300a() {
22949         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22950                 skip "skipped for lustre < 2.7.0"
22951         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22952         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22953
22954         test_striped_dir 0 || error "failed on striped dir on MDT0"
22955         test_striped_dir 1 || error "failed on striped dir on MDT0"
22956 }
22957 run_test 300a "basic striped dir sanity test"
22958
22959 test_300b() {
22960         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22961                 skip "skipped for lustre < 2.7.0"
22962         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22963         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22964
22965         local i
22966         local mtime1
22967         local mtime2
22968         local mtime3
22969
22970         test_mkdir $DIR/$tdir || error "mkdir fail"
22971         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22972                 error "set striped dir error"
22973         for i in {0..9}; do
22974                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
22975                 sleep 1
22976                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
22977                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
22978                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
22979                 sleep 1
22980                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
22981                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
22982                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
22983         done
22984         true
22985 }
22986 run_test 300b "check ctime/mtime for striped dir"
22987
22988 test_300c() {
22989         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22990                 skip "skipped for lustre < 2.7.0"
22991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22992         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22993
22994         local file_count
22995
22996         mkdir_on_mdt0 $DIR/$tdir
22997         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
22998                 error "set striped dir error"
22999
23000         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
23001                 error "chown striped dir failed"
23002
23003         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
23004                 error "create 5k files failed"
23005
23006         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
23007
23008         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
23009
23010         rm -rf $DIR/$tdir
23011 }
23012 run_test 300c "chown && check ls under striped directory"
23013
23014 test_300d() {
23015         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23016                 skip "skipped for lustre < 2.7.0"
23017         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23018         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23019
23020         local stripe_count
23021         local file
23022
23023         mkdir -p $DIR/$tdir
23024         $LFS setstripe -c 2 $DIR/$tdir
23025
23026         #local striped directory
23027         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23028                 error "set striped dir error"
23029         #look at the directories for debug purposes
23030         ls -l $DIR/$tdir
23031         $LFS getdirstripe $DIR/$tdir
23032         ls -l $DIR/$tdir/striped_dir
23033         $LFS getdirstripe $DIR/$tdir/striped_dir
23034         createmany -o $DIR/$tdir/striped_dir/f 10 ||
23035                 error "create 10 files failed"
23036
23037         #remote striped directory
23038         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
23039                 error "set striped dir error"
23040         #look at the directories for debug purposes
23041         ls -l $DIR/$tdir
23042         $LFS getdirstripe $DIR/$tdir
23043         ls -l $DIR/$tdir/remote_striped_dir
23044         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
23045         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
23046                 error "create 10 files failed"
23047
23048         for file in $(find $DIR/$tdir); do
23049                 stripe_count=$($LFS getstripe -c $file)
23050                 [ $stripe_count -eq 2 ] ||
23051                         error "wrong stripe $stripe_count for $file"
23052         done
23053
23054         rm -rf $DIR/$tdir
23055 }
23056 run_test 300d "check default stripe under striped directory"
23057
23058 test_300e() {
23059         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23060                 skip "Need MDS version at least 2.7.55"
23061         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23062         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23063
23064         local stripe_count
23065         local file
23066
23067         mkdir -p $DIR/$tdir
23068
23069         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23070                 error "set striped dir error"
23071
23072         touch $DIR/$tdir/striped_dir/a
23073         touch $DIR/$tdir/striped_dir/b
23074         touch $DIR/$tdir/striped_dir/c
23075
23076         mkdir $DIR/$tdir/striped_dir/dir_a
23077         mkdir $DIR/$tdir/striped_dir/dir_b
23078         mkdir $DIR/$tdir/striped_dir/dir_c
23079
23080         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
23081                 error "set striped adir under striped dir error"
23082
23083         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
23084                 error "set striped bdir under striped dir error"
23085
23086         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
23087                 error "set striped cdir under striped dir error"
23088
23089         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
23090                 error "rename dir under striped dir fails"
23091
23092         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
23093                 error "rename dir under different stripes fails"
23094
23095         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
23096                 error "rename file under striped dir should succeed"
23097
23098         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
23099                 error "rename dir under striped dir should succeed"
23100
23101         rm -rf $DIR/$tdir
23102 }
23103 run_test 300e "check rename under striped directory"
23104
23105 test_300f() {
23106         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23107         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23108         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23109                 skip "Need MDS version at least 2.7.55"
23110
23111         local stripe_count
23112         local file
23113
23114         rm -rf $DIR/$tdir
23115         mkdir -p $DIR/$tdir
23116
23117         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23118                 error "set striped dir error"
23119
23120         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
23121                 error "set striped dir error"
23122
23123         touch $DIR/$tdir/striped_dir/a
23124         mkdir $DIR/$tdir/striped_dir/dir_a
23125         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
23126                 error "create striped dir under striped dir fails"
23127
23128         touch $DIR/$tdir/striped_dir1/b
23129         mkdir $DIR/$tdir/striped_dir1/dir_b
23130         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
23131                 error "create striped dir under striped dir fails"
23132
23133         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
23134                 error "rename dir under different striped dir should fail"
23135
23136         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
23137                 error "rename striped dir under diff striped dir should fail"
23138
23139         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
23140                 error "rename file under diff striped dirs fails"
23141
23142         rm -rf $DIR/$tdir
23143 }
23144 run_test 300f "check rename cross striped directory"
23145
23146 test_300_check_default_striped_dir()
23147 {
23148         local dirname=$1
23149         local default_count=$2
23150         local default_index=$3
23151         local stripe_count
23152         local stripe_index
23153         local dir_stripe_index
23154         local dir
23155
23156         echo "checking $dirname $default_count $default_index"
23157         $LFS setdirstripe -D -c $default_count -i $default_index \
23158                                 -H all_char $DIR/$tdir/$dirname ||
23159                 error "set default stripe on striped dir error"
23160         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
23161         [ $stripe_count -eq $default_count ] ||
23162                 error "expect $default_count get $stripe_count for $dirname"
23163
23164         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
23165         [ $stripe_index -eq $default_index ] ||
23166                 error "expect $default_index get $stripe_index for $dirname"
23167
23168         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
23169                                                 error "create dirs failed"
23170
23171         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
23172         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
23173         for dir in $(find $DIR/$tdir/$dirname/*); do
23174                 stripe_count=$($LFS getdirstripe -c $dir)
23175                 (( $stripe_count == $default_count )) ||
23176                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
23177                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
23178                 error "stripe count $default_count != $stripe_count for $dir"
23179
23180                 stripe_index=$($LFS getdirstripe -i $dir)
23181                 [ $default_index -eq -1 ] ||
23182                         [ $stripe_index -eq $default_index ] ||
23183                         error "$stripe_index != $default_index for $dir"
23184
23185                 #check default stripe
23186                 stripe_count=$($LFS getdirstripe -D -c $dir)
23187                 [ $stripe_count -eq $default_count ] ||
23188                 error "default count $default_count != $stripe_count for $dir"
23189
23190                 stripe_index=$($LFS getdirstripe -D -i $dir)
23191                 [ $stripe_index -eq $default_index ] ||
23192                 error "default index $default_index != $stripe_index for $dir"
23193         done
23194         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
23195 }
23196
23197 test_300g() {
23198         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23199         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23200                 skip "Need MDS version at least 2.7.55"
23201
23202         local dir
23203         local stripe_count
23204         local stripe_index
23205
23206         mkdir_on_mdt0 $DIR/$tdir
23207         mkdir $DIR/$tdir/normal_dir
23208
23209         #Checking when client cache stripe index
23210         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23211         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
23212                 error "create striped_dir failed"
23213
23214         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
23215                 error "create dir0 fails"
23216         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
23217         [ $stripe_index -eq 0 ] ||
23218                 error "dir0 expect index 0 got $stripe_index"
23219
23220         mkdir $DIR/$tdir/striped_dir/dir1 ||
23221                 error "create dir1 fails"
23222         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
23223         [ $stripe_index -eq 1 ] ||
23224                 error "dir1 expect index 1 got $stripe_index"
23225
23226         #check default stripe count/stripe index
23227         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
23228         test_300_check_default_striped_dir normal_dir 1 0
23229         test_300_check_default_striped_dir normal_dir -1 1
23230         test_300_check_default_striped_dir normal_dir 2 -1
23231
23232         #delete default stripe information
23233         echo "delete default stripeEA"
23234         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
23235                 error "set default stripe on striped dir error"
23236
23237         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
23238         for dir in $(find $DIR/$tdir/normal_dir/*); do
23239                 stripe_count=$($LFS getdirstripe -c $dir)
23240                 [ $stripe_count -eq 0 ] ||
23241                         error "expect 1 get $stripe_count for $dir"
23242         done
23243 }
23244 run_test 300g "check default striped directory for normal directory"
23245
23246 test_300h() {
23247         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23248         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23249                 skip "Need MDS version at least 2.7.55"
23250
23251         local dir
23252         local stripe_count
23253
23254         mkdir $DIR/$tdir
23255         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23256                 error "set striped dir error"
23257
23258         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
23259         test_300_check_default_striped_dir striped_dir 1 0
23260         test_300_check_default_striped_dir striped_dir -1 1
23261         test_300_check_default_striped_dir striped_dir 2 -1
23262
23263         #delete default stripe information
23264         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
23265                 error "set default stripe on striped dir error"
23266
23267         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
23268         for dir in $(find $DIR/$tdir/striped_dir/*); do
23269                 stripe_count=$($LFS getdirstripe -c $dir)
23270                 [ $stripe_count -eq 0 ] ||
23271                         error "expect 1 get $stripe_count for $dir"
23272         done
23273 }
23274 run_test 300h "check default striped directory for striped directory"
23275
23276 test_300i() {
23277         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23278         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23279         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23280                 skip "Need MDS version at least 2.7.55"
23281
23282         local stripe_count
23283         local file
23284
23285         mkdir $DIR/$tdir
23286
23287         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23288                 error "set striped dir error"
23289
23290         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23291                 error "create files under striped dir failed"
23292
23293         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
23294                 error "set striped hashdir error"
23295
23296         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
23297                 error "create dir0 under hash dir failed"
23298         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
23299                 error "create dir1 under hash dir failed"
23300         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
23301                 error "create dir2 under hash dir failed"
23302
23303         # unfortunately, we need to umount to clear dir layout cache for now
23304         # once we fully implement dir layout, we can drop this
23305         umount_client $MOUNT || error "umount failed"
23306         mount_client $MOUNT || error "mount failed"
23307
23308         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
23309         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
23310         [ $dircnt -eq 2 ] || error "lfs find striped dir got:$dircnt,except:1"
23311
23312         #set the stripe to be unknown hash type
23313         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
23314         $LCTL set_param fail_loc=0x1901
23315         for ((i = 0; i < 10; i++)); do
23316                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
23317                         error "stat f-$i failed"
23318                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
23319         done
23320
23321         touch $DIR/$tdir/striped_dir/f0 &&
23322                 error "create under striped dir with unknown hash should fail"
23323
23324         $LCTL set_param fail_loc=0
23325
23326         umount_client $MOUNT || error "umount failed"
23327         mount_client $MOUNT || error "mount failed"
23328
23329         return 0
23330 }
23331 run_test 300i "client handle unknown hash type striped directory"
23332
23333 test_300j() {
23334         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23335         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23336         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23337                 skip "Need MDS version at least 2.7.55"
23338
23339         local stripe_count
23340         local file
23341
23342         mkdir $DIR/$tdir
23343
23344         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
23345         $LCTL set_param fail_loc=0x1702
23346         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23347                 error "set striped dir error"
23348
23349         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23350                 error "create files under striped dir failed"
23351
23352         $LCTL set_param fail_loc=0
23353
23354         rm -rf $DIR/$tdir || error "unlink striped dir fails"
23355
23356         return 0
23357 }
23358 run_test 300j "test large update record"
23359
23360 test_300k() {
23361         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23362         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23363         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23364                 skip "Need MDS version at least 2.7.55"
23365
23366         # this test needs a huge transaction
23367         local kb
23368         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23369              osd*.$FSNAME-MDT0000.kbytestotal")
23370         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
23371
23372         local stripe_count
23373         local file
23374
23375         mkdir $DIR/$tdir
23376
23377         #define OBD_FAIL_LARGE_STRIPE   0x1703
23378         $LCTL set_param fail_loc=0x1703
23379         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
23380                 error "set striped dir error"
23381         $LCTL set_param fail_loc=0
23382
23383         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23384                 error "getstripeddir fails"
23385         rm -rf $DIR/$tdir/striped_dir ||
23386                 error "unlink striped dir fails"
23387
23388         return 0
23389 }
23390 run_test 300k "test large striped directory"
23391
23392 test_300l() {
23393         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23394         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23395         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23396                 skip "Need MDS version at least 2.7.55"
23397
23398         local stripe_index
23399
23400         test_mkdir -p $DIR/$tdir/striped_dir
23401         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
23402                         error "chown $RUNAS_ID failed"
23403         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
23404                 error "set default striped dir failed"
23405
23406         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
23407         $LCTL set_param fail_loc=0x80000158
23408         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
23409
23410         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
23411         [ $stripe_index -eq 1 ] ||
23412                 error "expect 1 get $stripe_index for $dir"
23413 }
23414 run_test 300l "non-root user to create dir under striped dir with stale layout"
23415
23416 test_300m() {
23417         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23418         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
23419         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23420                 skip "Need MDS version at least 2.7.55"
23421
23422         mkdir -p $DIR/$tdir/striped_dir
23423         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
23424                 error "set default stripes dir error"
23425
23426         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
23427
23428         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
23429         [ $stripe_count -eq 0 ] ||
23430                         error "expect 0 get $stripe_count for a"
23431
23432         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
23433                 error "set default stripes dir error"
23434
23435         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
23436
23437         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
23438         [ $stripe_count -eq 0 ] ||
23439                         error "expect 0 get $stripe_count for b"
23440
23441         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
23442                 error "set default stripes dir error"
23443
23444         mkdir $DIR/$tdir/striped_dir/c &&
23445                 error "default stripe_index is invalid, mkdir c should fails"
23446
23447         rm -rf $DIR/$tdir || error "rmdir fails"
23448 }
23449 run_test 300m "setstriped directory on single MDT FS"
23450
23451 cleanup_300n() {
23452         local list=$(comma_list $(mdts_nodes))
23453
23454         trap 0
23455         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23456 }
23457
23458 test_300n() {
23459         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23460         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23461         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23462                 skip "Need MDS version at least 2.7.55"
23463         remote_mds_nodsh && skip "remote MDS with nodsh"
23464
23465         local stripe_index
23466         local list=$(comma_list $(mdts_nodes))
23467
23468         trap cleanup_300n RETURN EXIT
23469         mkdir -p $DIR/$tdir
23470         chmod 777 $DIR/$tdir
23471         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
23472                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23473                 error "create striped dir succeeds with gid=0"
23474
23475         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23476         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
23477                 error "create striped dir fails with gid=-1"
23478
23479         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23480         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
23481                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23482                 error "set default striped dir succeeds with gid=0"
23483
23484
23485         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23486         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
23487                 error "set default striped dir fails with gid=-1"
23488
23489
23490         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23491         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
23492                                         error "create test_dir fails"
23493         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
23494                                         error "create test_dir1 fails"
23495         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
23496                                         error "create test_dir2 fails"
23497         cleanup_300n
23498 }
23499 run_test 300n "non-root user to create dir under striped dir with default EA"
23500
23501 test_300o() {
23502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23503         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23504         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23505                 skip "Need MDS version at least 2.7.55"
23506
23507         local numfree1
23508         local numfree2
23509
23510         mkdir -p $DIR/$tdir
23511
23512         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
23513         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
23514         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
23515                 skip "not enough free inodes $numfree1 $numfree2"
23516         fi
23517
23518         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
23519         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
23520         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
23521                 skip "not enough free space $numfree1 $numfree2"
23522         fi
23523
23524         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
23525                 error "setdirstripe fails"
23526
23527         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
23528                 error "create dirs fails"
23529
23530         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
23531         ls $DIR/$tdir/striped_dir > /dev/null ||
23532                 error "ls striped dir fails"
23533         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
23534                 error "unlink big striped dir fails"
23535 }
23536 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
23537
23538 test_300p() {
23539         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23540         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23541         remote_mds_nodsh && skip "remote MDS with nodsh"
23542
23543         mkdir_on_mdt0 $DIR/$tdir
23544
23545         #define OBD_FAIL_OUT_ENOSPC     0x1704
23546         do_facet mds2 lctl set_param fail_loc=0x80001704
23547         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
23548                  && error "create striped directory should fail"
23549
23550         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
23551
23552         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
23553         true
23554 }
23555 run_test 300p "create striped directory without space"
23556
23557 test_300q() {
23558         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23559         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23560
23561         local fd=$(free_fd)
23562         local cmd="exec $fd<$tdir"
23563         cd $DIR
23564         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
23565         eval $cmd
23566         cmd="exec $fd<&-"
23567         trap "eval $cmd" EXIT
23568         cd $tdir || error "cd $tdir fails"
23569         rmdir  ../$tdir || error "rmdir $tdir fails"
23570         mkdir local_dir && error "create dir succeeds"
23571         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
23572         eval $cmd
23573         return 0
23574 }
23575 run_test 300q "create remote directory under orphan directory"
23576
23577 test_300r() {
23578         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23579                 skip "Need MDS version at least 2.7.55" && return
23580         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23581
23582         mkdir $DIR/$tdir
23583
23584         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
23585                 error "set striped dir error"
23586
23587         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23588                 error "getstripeddir fails"
23589
23590         local stripe_count
23591         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
23592                       awk '/lmv_stripe_count:/ { print $2 }')
23593
23594         [ $MDSCOUNT -ne $stripe_count ] &&
23595                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
23596
23597         rm -rf $DIR/$tdir/striped_dir ||
23598                 error "unlink striped dir fails"
23599 }
23600 run_test 300r "test -1 striped directory"
23601
23602 test_300s_helper() {
23603         local count=$1
23604
23605         local stripe_dir=$DIR/$tdir/striped_dir.$count
23606
23607         $LFS mkdir -c $count $stripe_dir ||
23608                 error "lfs mkdir -c error"
23609
23610         $LFS getdirstripe $stripe_dir ||
23611                 error "lfs getdirstripe fails"
23612
23613         local stripe_count
23614         stripe_count=$($LFS getdirstripe $stripe_dir |
23615                       awk '/lmv_stripe_count:/ { print $2 }')
23616
23617         [ $count -ne $stripe_count ] &&
23618                 error_noexit "bad stripe count $stripe_count expected $count"
23619
23620         local dupe_stripes
23621         dupe_stripes=$($LFS getdirstripe $stripe_dir |
23622                 awk '/0x/ {count[$1] += 1}; END {
23623                         for (idx in count) {
23624                                 if (count[idx]>1) {
23625                                         print "index " idx " count " count[idx]
23626                                 }
23627                         }
23628                 }')
23629
23630         if [[ -n "$dupe_stripes" ]] ; then
23631                 lfs getdirstripe $stripe_dir
23632                 error_noexit "Dupe MDT above: $dupe_stripes "
23633         fi
23634
23635         rm -rf $stripe_dir ||
23636                 error_noexit "unlink $stripe_dir fails"
23637 }
23638
23639 test_300s() {
23640         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23641                 skip "Need MDS version at least 2.7.55" && return
23642         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23643
23644         mkdir $DIR/$tdir
23645         for count in $(seq 2 $MDSCOUNT); do
23646                 test_300s_helper $count
23647         done
23648 }
23649 run_test 300s "test lfs mkdir -c without -i"
23650
23651
23652 prepare_remote_file() {
23653         mkdir $DIR/$tdir/src_dir ||
23654                 error "create remote source failed"
23655
23656         cp /etc/hosts $DIR/$tdir/src_dir/a ||
23657                  error "cp to remote source failed"
23658         touch $DIR/$tdir/src_dir/a
23659
23660         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
23661                 error "create remote target dir failed"
23662
23663         touch $DIR/$tdir/tgt_dir/b
23664
23665         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
23666                 error "rename dir cross MDT failed!"
23667
23668         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
23669                 error "src_child still exists after rename"
23670
23671         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
23672                 error "missing file(a) after rename"
23673
23674         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
23675                 error "diff after rename"
23676 }
23677
23678 test_310a() {
23679         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23680         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23681
23682         local remote_file=$DIR/$tdir/tgt_dir/b
23683
23684         mkdir -p $DIR/$tdir
23685
23686         prepare_remote_file || error "prepare remote file failed"
23687
23688         #open-unlink file
23689         $OPENUNLINK $remote_file $remote_file ||
23690                 error "openunlink $remote_file failed"
23691         $CHECKSTAT -a $remote_file || error "$remote_file exists"
23692 }
23693 run_test 310a "open unlink remote file"
23694
23695 test_310b() {
23696         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23697         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23698
23699         local remote_file=$DIR/$tdir/tgt_dir/b
23700
23701         mkdir -p $DIR/$tdir
23702
23703         prepare_remote_file || error "prepare remote file failed"
23704
23705         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23706         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
23707         $CHECKSTAT -t file $remote_file || error "check file failed"
23708 }
23709 run_test 310b "unlink remote file with multiple links while open"
23710
23711 test_310c() {
23712         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23713         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
23714
23715         local remote_file=$DIR/$tdir/tgt_dir/b
23716
23717         mkdir -p $DIR/$tdir
23718
23719         prepare_remote_file || error "prepare remote file failed"
23720
23721         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23722         multiop_bg_pause $remote_file O_uc ||
23723                         error "mulitop failed for remote file"
23724         MULTIPID=$!
23725         $MULTIOP $DIR/$tfile Ouc
23726         kill -USR1 $MULTIPID
23727         wait $MULTIPID
23728 }
23729 run_test 310c "open-unlink remote file with multiple links"
23730
23731 #LU-4825
23732 test_311() {
23733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23734         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23735         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
23736                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
23737         remote_mds_nodsh && skip "remote MDS with nodsh"
23738
23739         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23740         local mdts=$(comma_list $(mdts_nodes))
23741
23742         mkdir -p $DIR/$tdir
23743         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23744         createmany -o $DIR/$tdir/$tfile. 1000
23745
23746         # statfs data is not real time, let's just calculate it
23747         old_iused=$((old_iused + 1000))
23748
23749         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23750                         osp.*OST0000*MDT0000.create_count")
23751         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23752                                 osp.*OST0000*MDT0000.max_create_count")
23753         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
23754
23755         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
23756         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
23757         [ $index -ne 0 ] || error "$tfile stripe index is 0"
23758
23759         unlinkmany $DIR/$tdir/$tfile. 1000
23760
23761         do_nodes $mdts "$LCTL set_param -n \
23762                         osp.*OST0000*.max_create_count=$max_count"
23763         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
23764                 do_nodes $mdts "$LCTL set_param -n \
23765                                 osp.*OST0000*.create_count=$count"
23766         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
23767                         grep "=0" && error "create_count is zero"
23768
23769         local new_iused
23770         for i in $(seq 120); do
23771                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23772                 # system may be too busy to destroy all objs in time, use
23773                 # a somewhat small value to not fail autotest
23774                 [ $((old_iused - new_iused)) -gt 400 ] && break
23775                 sleep 1
23776         done
23777
23778         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
23779         [ $((old_iused - new_iused)) -gt 400 ] ||
23780                 error "objs not destroyed after unlink"
23781 }
23782 run_test 311 "disable OSP precreate, and unlink should destroy objs"
23783
23784 zfs_oid_to_objid()
23785 {
23786         local ost=$1
23787         local objid=$2
23788
23789         local vdevdir=$(dirname $(facet_vdevice $ost))
23790         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
23791         local zfs_zapid=$(do_facet $ost $cmd |
23792                           grep -w "/O/0/d$((objid%32))" -C 5 |
23793                           awk '/Object/{getline; print $1}')
23794         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
23795                           awk "/$objid = /"'{printf $3}')
23796
23797         echo $zfs_objid
23798 }
23799
23800 zfs_object_blksz() {
23801         local ost=$1
23802         local objid=$2
23803
23804         local vdevdir=$(dirname $(facet_vdevice $ost))
23805         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
23806         local blksz=$(do_facet $ost $cmd $objid |
23807                       awk '/dblk/{getline; printf $4}')
23808
23809         case "${blksz: -1}" in
23810                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
23811                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
23812                 *) ;;
23813         esac
23814
23815         echo $blksz
23816 }
23817
23818 test_312() { # LU-4856
23819         remote_ost_nodsh && skip "remote OST with nodsh"
23820         [ "$ost1_FSTYPE" = "zfs" ] ||
23821                 skip_env "the test only applies to zfs"
23822
23823         local max_blksz=$(do_facet ost1 \
23824                           $ZFS get -p recordsize $(facet_device ost1) |
23825                           awk '!/VALUE/{print $3}')
23826
23827         # to make life a little bit easier
23828         $LFS mkdir -c 1 -i 0 $DIR/$tdir
23829         $LFS setstripe -c 1 -i 0 $DIR/$tdir
23830
23831         local tf=$DIR/$tdir/$tfile
23832         touch $tf
23833         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23834
23835         # Get ZFS object id
23836         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23837         # block size change by sequential overwrite
23838         local bs
23839
23840         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
23841                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
23842
23843                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
23844                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
23845         done
23846         rm -f $tf
23847
23848         # block size change by sequential append write
23849         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
23850         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23851         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23852         local count
23853
23854         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
23855                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
23856                         oflag=sync conv=notrunc
23857
23858                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
23859                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
23860                         error "blksz error, actual $blksz, " \
23861                                 "expected: 2 * $count * $PAGE_SIZE"
23862         done
23863         rm -f $tf
23864
23865         # random write
23866         touch $tf
23867         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23868         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23869
23870         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
23871         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23872         [ $blksz -eq $PAGE_SIZE ] ||
23873                 error "blksz error: $blksz, expected: $PAGE_SIZE"
23874
23875         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
23876         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23877         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
23878
23879         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
23880         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23881         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
23882 }
23883 run_test 312 "make sure ZFS adjusts its block size by write pattern"
23884
23885 test_313() {
23886         remote_ost_nodsh && skip "remote OST with nodsh"
23887
23888         local file=$DIR/$tfile
23889
23890         rm -f $file
23891         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
23892
23893         # define OBD_FAIL_TGT_RCVD_EIO           0x720
23894         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23895         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
23896                 error "write should failed"
23897         do_facet ost1 "$LCTL set_param fail_loc=0"
23898         rm -f $file
23899 }
23900 run_test 313 "io should fail after last_rcvd update fail"
23901
23902 test_314() {
23903         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23904
23905         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
23906         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23907         rm -f $DIR/$tfile
23908         wait_delete_completed
23909         do_facet ost1 "$LCTL set_param fail_loc=0"
23910 }
23911 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
23912
23913 test_315() { # LU-618
23914         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
23915
23916         local file=$DIR/$tfile
23917         rm -f $file
23918
23919         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
23920                 error "multiop file write failed"
23921         $MULTIOP $file oO_RDONLY:r4063232_c &
23922         PID=$!
23923
23924         sleep 2
23925
23926         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
23927         kill -USR1 $PID
23928
23929         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
23930         rm -f $file
23931 }
23932 run_test 315 "read should be accounted"
23933
23934 test_316() {
23935         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23936         large_xattr_enabled || skip_env "ea_inode feature disabled"
23937
23938         rm -rf $DIR/$tdir/d
23939         mkdir -p $DIR/$tdir/d
23940         chown nobody $DIR/$tdir/d
23941         touch $DIR/$tdir/d/file
23942
23943         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
23944 }
23945 run_test 316 "lfs mv"
23946
23947 test_317() {
23948         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
23949                 skip "Need MDS version at least 2.11.53"
23950         if [ "$ost1_FSTYPE" == "zfs" ]; then
23951                 skip "LU-10370: no implementation for ZFS"
23952         fi
23953
23954         local trunc_sz
23955         local grant_blk_size
23956
23957         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
23958                         awk '/grant_block_size:/ { print $2; exit; }')
23959         #
23960         # Create File of size 5M. Truncate it to below size's and verify
23961         # blocks count.
23962         #
23963         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
23964                 error "Create file $DIR/$tfile failed"
23965         stack_trap "rm -f $DIR/$tfile" EXIT
23966
23967         for trunc_sz in 2097152 4097 4000 509 0; do
23968                 $TRUNCATE $DIR/$tfile $trunc_sz ||
23969                         error "truncate $tfile to $trunc_sz failed"
23970                 local sz=$(stat --format=%s $DIR/$tfile)
23971                 local blk=$(stat --format=%b $DIR/$tfile)
23972                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
23973                                      grant_blk_size) * 8))
23974
23975                 if [[ $blk -ne $trunc_blk ]]; then
23976                         $(which stat) $DIR/$tfile
23977                         error "Expected Block $trunc_blk got $blk for $tfile"
23978                 fi
23979
23980                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23981                         error "Expected Size $trunc_sz got $sz for $tfile"
23982         done
23983
23984         #
23985         # sparse file test
23986         # Create file with a hole and write actual 65536 bytes which aligned
23987         # with 4K and 64K PAGE_SIZE. Block count must be 128.
23988         #
23989         local bs=65536
23990         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
23991                 error "Create file : $DIR/$tfile"
23992
23993         #
23994         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
23995         # blocks. The block count must drop to 8.
23996         #
23997         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - \
23998                 ((bs - grant_blk_size) + 1)))
23999         $TRUNCATE $DIR/$tfile $trunc_sz ||
24000                 error "truncate $tfile to $trunc_sz failed"
24001
24002         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
24003         sz=$(stat --format=%s $DIR/$tfile)
24004         blk=$(stat --format=%b $DIR/$tfile)
24005
24006         if [[ $blk -ne $trunc_bsz ]]; then
24007                 $(which stat) $DIR/$tfile
24008                 error "Expected Block $trunc_bsz got $blk for $tfile"
24009         fi
24010
24011         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24012                 error "Expected Size $trunc_sz got $sz for $tfile"
24013 }
24014 run_test 317 "Verify blocks get correctly update after truncate"
24015
24016 test_318() {
24017         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
24018         local old_max_active=$($LCTL get_param -n \
24019                             ${llite_name}.max_read_ahead_async_active \
24020                             2>/dev/null)
24021
24022         $LCTL set_param llite.*.max_read_ahead_async_active=256
24023         local max_active=$($LCTL get_param -n \
24024                            ${llite_name}.max_read_ahead_async_active \
24025                            2>/dev/null)
24026         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
24027
24028         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
24029                 error "set max_read_ahead_async_active should succeed"
24030
24031         $LCTL set_param llite.*.max_read_ahead_async_active=512
24032         max_active=$($LCTL get_param -n \
24033                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
24034         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
24035
24036         # restore @max_active
24037         [ $old_max_active -ne 0 ] && $LCTL set_param \
24038                 llite.*.max_read_ahead_async_active=$old_max_active
24039
24040         local old_threshold=$($LCTL get_param -n \
24041                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24042         local max_per_file_mb=$($LCTL get_param -n \
24043                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
24044
24045         local invalid=$(($max_per_file_mb + 1))
24046         $LCTL set_param \
24047                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
24048                         && error "set $invalid should fail"
24049
24050         local valid=$(($invalid - 1))
24051         $LCTL set_param \
24052                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
24053                         error "set $valid should succeed"
24054         local threshold=$($LCTL get_param -n \
24055                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24056         [ $threshold -eq $valid ] || error \
24057                 "expect threshold $valid got $threshold"
24058         $LCTL set_param \
24059                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
24060 }
24061 run_test 318 "Verify async readahead tunables"
24062
24063 test_319() {
24064         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
24065
24066         local before=$(date +%s)
24067         local evict
24068         local mdir=$DIR/$tdir
24069         local file=$mdir/xxx
24070
24071         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
24072         touch $file
24073
24074 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
24075         $LCTL set_param fail_val=5 fail_loc=0x8000032c
24076         $LFS mv -m1 $file &
24077
24078         sleep 1
24079         dd if=$file of=/dev/null
24080         wait
24081         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
24082           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
24083
24084         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
24085 }
24086 run_test 319 "lost lease lock on migrate error"
24087
24088 test_398a() { # LU-4198
24089         local ost1_imp=$(get_osc_import_name client ost1)
24090         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24091                          cut -d'.' -f2)
24092
24093         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24094         $LCTL set_param ldlm.namespaces.*.lru_size=clear
24095
24096         # request a new lock on client
24097         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24098
24099         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24100         local lock_count=$($LCTL get_param -n \
24101                            ldlm.namespaces.$imp_name.lru_size)
24102         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
24103
24104         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24105
24106         # no lock cached, should use lockless IO and not enqueue new lock
24107         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24108         lock_count=$($LCTL get_param -n \
24109                      ldlm.namespaces.$imp_name.lru_size)
24110         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
24111 }
24112 run_test 398a "direct IO should cancel lock otherwise lockless"
24113
24114 test_398b() { # LU-4198
24115         which fio || skip_env "no fio installed"
24116         $LFS setstripe -c -1 $DIR/$tfile
24117
24118         local size=12
24119         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
24120
24121         local njobs=4
24122         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
24123         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24124                 --numjobs=$njobs --fallocate=none \
24125                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24126                 --filename=$DIR/$tfile &
24127         bg_pid=$!
24128
24129         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
24130         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
24131                 --numjobs=$njobs --fallocate=none \
24132                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24133                 --filename=$DIR/$tfile || true
24134         wait $bg_pid
24135
24136         rm -f $DIR/$tfile
24137 }
24138 run_test 398b "DIO and buffer IO race"
24139
24140 test_398c() { # LU-4198
24141         local ost1_imp=$(get_osc_import_name client ost1)
24142         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24143                          cut -d'.' -f2)
24144
24145         which fio || skip_env "no fio installed"
24146
24147         saved_debug=$($LCTL get_param -n debug)
24148         $LCTL set_param debug=0
24149
24150         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
24151         ((size /= 1024)) # by megabytes
24152         ((size /= 2)) # write half of the OST at most
24153         [ $size -gt 40 ] && size=40 #reduce test time anyway
24154
24155         $LFS setstripe -c 1 $DIR/$tfile
24156
24157         # it seems like ldiskfs reserves more space than necessary if the
24158         # writing blocks are not mapped, so it extends the file firstly
24159         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
24160         cancel_lru_locks osc
24161
24162         # clear and verify rpc_stats later
24163         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
24164
24165         local njobs=4
24166         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
24167         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
24168                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24169                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24170                 --filename=$DIR/$tfile
24171         [ $? -eq 0 ] || error "fio write error"
24172
24173         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
24174                 error "Locks were requested while doing AIO"
24175
24176         # get the percentage of 1-page I/O
24177         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
24178                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
24179                 awk '{print $7}')
24180         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
24181
24182         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
24183         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24184                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24185                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24186                 --filename=$DIR/$tfile
24187         [ $? -eq 0 ] || error "fio mixed read write error"
24188
24189         echo "AIO with large block size ${size}M"
24190         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
24191                 --numjobs=1 --fallocate=none --ioengine=libaio \
24192                 --iodepth=16 --allow_file_create=0 --size=${size}M \
24193                 --filename=$DIR/$tfile
24194         [ $? -eq 0 ] || error "fio large block size failed"
24195
24196         rm -f $DIR/$tfile
24197         $LCTL set_param debug="$saved_debug"
24198 }
24199 run_test 398c "run fio to test AIO"
24200
24201 test_398d() { #  LU-13846
24202         which aiocp || skip_env "no aiocp installed"
24203         local aio_file=$DIR/$tfile.aio
24204
24205         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24206
24207         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
24208         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
24209         stack_trap "rm -f $DIR/$tfile $aio_file"
24210
24211         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
24212
24213         # make sure we don't crash and fail properly
24214         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24215                 error "aio not aligned with PAGE SIZE should fail"
24216
24217         rm -f $DIR/$tfile $aio_file
24218 }
24219 run_test 398d "run aiocp to verify block size > stripe size"
24220
24221 test_398e() {
24222         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
24223         touch $DIR/$tfile.new
24224         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
24225 }
24226 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
24227
24228 test_398f() { #  LU-14687
24229         which aiocp || skip_env "no aiocp installed"
24230         local aio_file=$DIR/$tfile.aio
24231
24232         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24233
24234         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
24235         stack_trap "rm -f $DIR/$tfile $aio_file"
24236
24237         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24238         $LCTL set_param fail_loc=0x1418
24239         # make sure we don't crash and fail properly
24240         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24241                 error "aio with page allocation failure succeeded"
24242         $LCTL set_param fail_loc=0
24243         diff $DIR/$tfile $aio_file
24244         [[ $? != 0 ]] || error "no diff after failed aiocp"
24245 }
24246 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
24247
24248 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
24249 # stripe and i/o size must be > stripe size
24250 # Old style synchronous DIO waits after submitting each chunk, resulting in a
24251 # single RPC in flight.  This test shows async DIO submission is working by
24252 # showing multiple RPCs in flight.
24253 test_398g() { #  LU-13798
24254         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24255
24256         # We need to do some i/o first to acquire enough grant to put our RPCs
24257         # in flight; otherwise a new connection may not have enough grant
24258         # available
24259         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24260                 error "parallel dio failed"
24261         stack_trap "rm -f $DIR/$tfile"
24262
24263         # Reduce RPC size to 1M to avoid combination in to larger RPCs
24264         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24265         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24266         stack_trap "$LCTL set_param -n $pages_per_rpc"
24267
24268         # Recreate file so it's empty
24269         rm -f $DIR/$tfile
24270         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24271         #Pause rpc completion to guarantee we see multiple rpcs in flight
24272         #define OBD_FAIL_OST_BRW_PAUSE_BULK
24273         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
24274         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24275
24276         # Clear rpc stats
24277         $LCTL set_param osc.*.rpc_stats=c
24278
24279         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24280                 error "parallel dio failed"
24281         stack_trap "rm -f $DIR/$tfile"
24282
24283         $LCTL get_param osc.*-OST0000-*.rpc_stats
24284         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24285                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24286                 grep "8:" | awk '{print $8}')
24287         # We look at the "8 rpcs in flight" field, and verify A) it is present
24288         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
24289         # as expected for an 8M DIO to a file with 1M stripes.
24290         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
24291
24292         # Verify turning off parallel dio works as expected
24293         # Clear rpc stats
24294         $LCTL set_param osc.*.rpc_stats=c
24295         $LCTL set_param llite.*.parallel_dio=0
24296         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
24297
24298         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24299                 error "dio with parallel dio disabled failed"
24300
24301         # Ideally, we would see only one RPC in flight here, but there is an
24302         # unavoidable race between i/o completion and RPC in flight counting,
24303         # so while only 1 i/o is in flight at a time, the RPC in flight counter
24304         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
24305         # So instead we just verify it's always < 8.
24306         $LCTL get_param osc.*-OST0000-*.rpc_stats
24307         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24308                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24309                 grep '^$' -B1 | grep . | awk '{print $1}')
24310         [ $ret != "8:" ] ||
24311                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
24312 }
24313 run_test 398g "verify parallel dio async RPC submission"
24314
24315 test_398h() { #  LU-13798
24316         local dio_file=$DIR/$tfile.dio
24317
24318         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24319
24320         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24321         stack_trap "rm -f $DIR/$tfile $dio_file"
24322
24323         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
24324                 error "parallel dio failed"
24325         diff $DIR/$tfile $dio_file
24326         [[ $? == 0 ]] || error "file diff after aiocp"
24327 }
24328 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
24329
24330 test_398i() { #  LU-13798
24331         local dio_file=$DIR/$tfile.dio
24332
24333         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24334
24335         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24336         stack_trap "rm -f $DIR/$tfile $dio_file"
24337
24338         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24339         $LCTL set_param fail_loc=0x1418
24340         # make sure we don't crash and fail properly
24341         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
24342                 error "parallel dio page allocation failure succeeded"
24343         diff $DIR/$tfile $dio_file
24344         [[ $? != 0 ]] || error "no diff after failed aiocp"
24345 }
24346 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
24347
24348 test_398j() { #  LU-13798
24349         # Stripe size > RPC size but less than i/o size tests split across
24350         # stripes and RPCs for individual i/o op
24351         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
24352
24353         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
24354         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24355         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24356         stack_trap "$LCTL set_param -n $pages_per_rpc"
24357
24358         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24359                 error "parallel dio write failed"
24360         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
24361
24362         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
24363                 error "parallel dio read failed"
24364         diff $DIR/$tfile $DIR/$tfile.2
24365         [[ $? == 0 ]] || error "file diff after parallel dio read"
24366 }
24367 run_test 398j "test parallel dio where stripe size > rpc_size"
24368
24369 test_398k() { #  LU-13798
24370         wait_delete_completed
24371         wait_mds_ost_sync
24372
24373         # 4 stripe file; we will cause out of space on OST0
24374         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24375
24376         # Fill OST0 (if it's not too large)
24377         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24378                    head -n1)
24379         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24380                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24381         fi
24382         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24383         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24384                 error "dd should fill OST0"
24385         stack_trap "rm -f $DIR/$tfile.1"
24386
24387         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24388         err=$?
24389
24390         ls -la $DIR/$tfile
24391         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
24392                 error "file is not 0 bytes in size"
24393
24394         # dd above should not succeed, but don't error until here so we can
24395         # get debug info above
24396         [[ $err != 0 ]] ||
24397                 error "parallel dio write with enospc succeeded"
24398         stack_trap "rm -f $DIR/$tfile"
24399 }
24400 run_test 398k "test enospc on first stripe"
24401
24402 test_398l() { #  LU-13798
24403         wait_delete_completed
24404         wait_mds_ost_sync
24405
24406         # 4 stripe file; we will cause out of space on OST0
24407         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
24408         # happens on the second i/o chunk we issue
24409         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
24410
24411         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
24412         stack_trap "rm -f $DIR/$tfile"
24413
24414         # Fill OST0 (if it's not too large)
24415         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24416                    head -n1)
24417         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24418                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24419         fi
24420         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24421         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24422                 error "dd should fill OST0"
24423         stack_trap "rm -f $DIR/$tfile.1"
24424
24425         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
24426         err=$?
24427         stack_trap "rm -f $DIR/$tfile.2"
24428
24429         # Check that short write completed as expected
24430         ls -la $DIR/$tfile.2
24431         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
24432                 error "file is not 1M in size"
24433
24434         # dd above should not succeed, but don't error until here so we can
24435         # get debug info above
24436         [[ $err != 0 ]] ||
24437                 error "parallel dio write with enospc succeeded"
24438
24439         # Truncate source file to same length as output file and diff them
24440         $TRUNCATE $DIR/$tfile 1048576
24441         diff $DIR/$tfile $DIR/$tfile.2
24442         [[ $? == 0 ]] || error "data incorrect after short write"
24443 }
24444 run_test 398l "test enospc on intermediate stripe/RPC"
24445
24446 test_398m() { #  LU-13798
24447         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24448
24449         # Set up failure on OST0, the first stripe:
24450         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
24451         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
24452         # So this fail_val specifies OST0
24453         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
24454         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24455
24456         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24457                 error "parallel dio write with failure on first stripe succeeded"
24458         stack_trap "rm -f $DIR/$tfile"
24459         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24460
24461         # Place data in file for read
24462         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24463                 error "parallel dio write failed"
24464
24465         # Fail read on OST0, first stripe
24466         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24467         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
24468         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24469                 error "parallel dio read with error on first stripe succeeded"
24470         rm -f $DIR/$tfile.2
24471         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24472
24473         # Switch to testing on OST1, second stripe
24474         # Clear file contents, maintain striping
24475         echo > $DIR/$tfile
24476         # Set up failure on OST1, second stripe:
24477         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
24478         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24479
24480         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24481                 error "parallel dio write with failure on first stripe succeeded"
24482         stack_trap "rm -f $DIR/$tfile"
24483         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24484
24485         # Place data in file for read
24486         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24487                 error "parallel dio write failed"
24488
24489         # Fail read on OST1, second stripe
24490         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24491         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
24492         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24493                 error "parallel dio read with error on first stripe succeeded"
24494         rm -f $DIR/$tfile.2
24495         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
24496 }
24497 run_test 398m "test RPC failures with parallel dio"
24498
24499 # Parallel submission of DIO should not cause problems for append, but it's
24500 # important to verify.
24501 test_398n() { #  LU-13798
24502         $LFS setstripe -C 2 -S 1M $DIR/$tfile
24503
24504         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
24505                 error "dd to create source file failed"
24506         stack_trap "rm -f $DIR/$tfile"
24507
24508         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
24509                 error "parallel dio write with failure on second stripe succeeded"
24510         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
24511         diff $DIR/$tfile $DIR/$tfile.1
24512         [[ $? == 0 ]] || error "data incorrect after append"
24513
24514 }
24515 run_test 398n "test append with parallel DIO"
24516
24517 test_fake_rw() {
24518         local read_write=$1
24519         if [ "$read_write" = "write" ]; then
24520                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
24521         elif [ "$read_write" = "read" ]; then
24522                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
24523         else
24524                 error "argument error"
24525         fi
24526
24527         # turn off debug for performance testing
24528         local saved_debug=$($LCTL get_param -n debug)
24529         $LCTL set_param debug=0
24530
24531         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24532
24533         # get ost1 size - $FSNAME-OST0000
24534         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
24535         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
24536         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
24537
24538         if [ "$read_write" = "read" ]; then
24539                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
24540         fi
24541
24542         local start_time=$(date +%s.%N)
24543         $dd_cmd bs=1M count=$blocks oflag=sync ||
24544                 error "real dd $read_write error"
24545         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
24546
24547         if [ "$read_write" = "write" ]; then
24548                 rm -f $DIR/$tfile
24549         fi
24550
24551         # define OBD_FAIL_OST_FAKE_RW           0x238
24552         do_facet ost1 $LCTL set_param fail_loc=0x238
24553
24554         local start_time=$(date +%s.%N)
24555         $dd_cmd bs=1M count=$blocks oflag=sync ||
24556                 error "fake dd $read_write error"
24557         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
24558
24559         if [ "$read_write" = "write" ]; then
24560                 # verify file size
24561                 cancel_lru_locks osc
24562                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
24563                         error "$tfile size not $blocks MB"
24564         fi
24565         do_facet ost1 $LCTL set_param fail_loc=0
24566
24567         echo "fake $read_write $duration_fake vs. normal $read_write" \
24568                 "$duration in seconds"
24569         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
24570                 error_not_in_vm "fake write is slower"
24571
24572         $LCTL set_param -n debug="$saved_debug"
24573         rm -f $DIR/$tfile
24574 }
24575 test_399a() { # LU-7655 for OST fake write
24576         remote_ost_nodsh && skip "remote OST with nodsh"
24577
24578         test_fake_rw write
24579 }
24580 run_test 399a "fake write should not be slower than normal write"
24581
24582 test_399b() { # LU-8726 for OST fake read
24583         remote_ost_nodsh && skip "remote OST with nodsh"
24584         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
24585                 skip_env "ldiskfs only test"
24586         fi
24587
24588         test_fake_rw read
24589 }
24590 run_test 399b "fake read should not be slower than normal read"
24591
24592 test_400a() { # LU-1606, was conf-sanity test_74
24593         if ! which $CC > /dev/null 2>&1; then
24594                 skip_env "$CC is not installed"
24595         fi
24596
24597         local extra_flags=''
24598         local out=$TMP/$tfile
24599         local prefix=/usr/include/lustre
24600         local prog
24601
24602         # Oleg removes c files in his test rig so test if any c files exist
24603         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
24604                 skip_env "Needed c test files are missing"
24605
24606         if ! [[ -d $prefix ]]; then
24607                 # Assume we're running in tree and fixup the include path.
24608                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
24609                 extra_flags+=" -L$LUSTRE/utils/.lib"
24610         fi
24611
24612         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
24613                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
24614                         error "client api broken"
24615         done
24616         rm -f $out
24617 }
24618 run_test 400a "Lustre client api program can compile and link"
24619
24620 test_400b() { # LU-1606, LU-5011
24621         local header
24622         local out=$TMP/$tfile
24623         local prefix=/usr/include/linux/lustre
24624
24625         # We use a hard coded prefix so that this test will not fail
24626         # when run in tree. There are headers in lustre/include/lustre/
24627         # that are not packaged (like lustre_idl.h) and have more
24628         # complicated include dependencies (like config.h and lnet/types.h).
24629         # Since this test about correct packaging we just skip them when
24630         # they don't exist (see below) rather than try to fixup cppflags.
24631
24632         if ! which $CC > /dev/null 2>&1; then
24633                 skip_env "$CC is not installed"
24634         fi
24635
24636         for header in $prefix/*.h; do
24637                 if ! [[ -f "$header" ]]; then
24638                         continue
24639                 fi
24640
24641                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
24642                         continue # lustre_ioctl.h is internal header
24643                 fi
24644
24645                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
24646                         error "cannot compile '$header'"
24647         done
24648         rm -f $out
24649 }
24650 run_test 400b "packaged headers can be compiled"
24651
24652 test_401a() { #LU-7437
24653         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
24654         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
24655
24656         #count the number of parameters by "list_param -R"
24657         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
24658         #count the number of parameters by listing proc files
24659         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
24660         echo "proc_dirs='$proc_dirs'"
24661         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
24662         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
24663                       sort -u | wc -l)
24664
24665         [ $params -eq $procs ] ||
24666                 error "found $params parameters vs. $procs proc files"
24667
24668         # test the list_param -D option only returns directories
24669         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
24670         #count the number of parameters by listing proc directories
24671         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
24672                 sort -u | wc -l)
24673
24674         [ $params -eq $procs ] ||
24675                 error "found $params parameters vs. $procs proc files"
24676 }
24677 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
24678
24679 test_401b() {
24680         # jobid_var may not allow arbitrary values, so use jobid_name
24681         # if available
24682         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24683                 local testname=jobid_name tmp='testing%p'
24684         else
24685                 local testname=jobid_var tmp=testing
24686         fi
24687
24688         local save=$($LCTL get_param -n $testname)
24689
24690         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
24691                 error "no error returned when setting bad parameters"
24692
24693         local jobid_new=$($LCTL get_param -n foe $testname baz)
24694         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
24695
24696         $LCTL set_param -n fog=bam $testname=$save bat=fog
24697         local jobid_old=$($LCTL get_param -n foe $testname bag)
24698         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
24699 }
24700 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
24701
24702 test_401c() {
24703         # jobid_var may not allow arbitrary values, so use jobid_name
24704         # if available
24705         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24706                 local testname=jobid_name
24707         else
24708                 local testname=jobid_var
24709         fi
24710
24711         local jobid_var_old=$($LCTL get_param -n $testname)
24712         local jobid_var_new
24713
24714         $LCTL set_param $testname= &&
24715                 error "no error returned for 'set_param a='"
24716
24717         jobid_var_new=$($LCTL get_param -n $testname)
24718         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24719                 error "$testname was changed by setting without value"
24720
24721         $LCTL set_param $testname &&
24722                 error "no error returned for 'set_param a'"
24723
24724         jobid_var_new=$($LCTL get_param -n $testname)
24725         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24726                 error "$testname was changed by setting without value"
24727 }
24728 run_test 401c "Verify 'lctl set_param' without value fails in either format."
24729
24730 test_401d() {
24731         # jobid_var may not allow arbitrary values, so use jobid_name
24732         # if available
24733         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24734                 local testname=jobid_name new_value='foo=bar%p'
24735         else
24736                 local testname=jobid_var new_valuie=foo=bar
24737         fi
24738
24739         local jobid_var_old=$($LCTL get_param -n $testname)
24740         local jobid_var_new
24741
24742         $LCTL set_param $testname=$new_value ||
24743                 error "'set_param a=b' did not accept a value containing '='"
24744
24745         jobid_var_new=$($LCTL get_param -n $testname)
24746         [[ "$jobid_var_new" == "$new_value" ]] ||
24747                 error "'set_param a=b' failed on a value containing '='"
24748
24749         # Reset the $testname to test the other format
24750         $LCTL set_param $testname=$jobid_var_old
24751         jobid_var_new=$($LCTL get_param -n $testname)
24752         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24753                 error "failed to reset $testname"
24754
24755         $LCTL set_param $testname $new_value ||
24756                 error "'set_param a b' did not accept a value containing '='"
24757
24758         jobid_var_new=$($LCTL get_param -n $testname)
24759         [[ "$jobid_var_new" == "$new_value" ]] ||
24760                 error "'set_param a b' failed on a value containing '='"
24761
24762         $LCTL set_param $testname $jobid_var_old
24763         jobid_var_new=$($LCTL get_param -n $testname)
24764         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24765                 error "failed to reset $testname"
24766 }
24767 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
24768
24769 test_401e() { # LU-14779
24770         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
24771                 error "lctl list_param MGC* failed"
24772         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
24773         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
24774                 error "lctl get_param lru_size failed"
24775 }
24776 run_test 401e "verify 'lctl get_param' works with NID in parameter"
24777
24778 test_402() {
24779         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
24780         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
24781                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
24782         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
24783                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
24784                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
24785         remote_mds_nodsh && skip "remote MDS with nodsh"
24786
24787         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
24788 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
24789         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
24790         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
24791                 echo "Touch failed - OK"
24792 }
24793 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
24794
24795 test_403() {
24796         local file1=$DIR/$tfile.1
24797         local file2=$DIR/$tfile.2
24798         local tfile=$TMP/$tfile
24799
24800         rm -f $file1 $file2 $tfile
24801
24802         touch $file1
24803         ln $file1 $file2
24804
24805         # 30 sec OBD_TIMEOUT in ll_getattr()
24806         # right before populating st_nlink
24807         $LCTL set_param fail_loc=0x80001409
24808         stat -c %h $file1 > $tfile &
24809
24810         # create an alias, drop all locks and reclaim the dentry
24811         < $file2
24812         cancel_lru_locks mdc
24813         cancel_lru_locks osc
24814         sysctl -w vm.drop_caches=2
24815
24816         wait
24817
24818         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
24819
24820         rm -f $tfile $file1 $file2
24821 }
24822 run_test 403 "i_nlink should not drop to zero due to aliasing"
24823
24824 test_404() { # LU-6601
24825         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
24826                 skip "Need server version newer than 2.8.52"
24827         remote_mds_nodsh && skip "remote MDS with nodsh"
24828
24829         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
24830                 awk '/osp .*-osc-MDT/ { print $4}')
24831
24832         local osp
24833         for osp in $mosps; do
24834                 echo "Deactivate: " $osp
24835                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
24836                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
24837                         awk -vp=$osp '$4 == p { print $2 }')
24838                 [ $stat = IN ] || {
24839                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
24840                         error "deactivate error"
24841                 }
24842                 echo "Activate: " $osp
24843                 do_facet $SINGLEMDS $LCTL --device %$osp activate
24844                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
24845                         awk -vp=$osp '$4 == p { print $2 }')
24846                 [ $stat = UP ] || {
24847                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
24848                         error "activate error"
24849                 }
24850         done
24851 }
24852 run_test 404 "validate manual {de}activated works properly for OSPs"
24853
24854 test_405() {
24855         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
24856         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
24857                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
24858                         skip "Layout swap lock is not supported"
24859
24860         check_swap_layouts_support
24861         check_swap_layout_no_dom $DIR
24862
24863         test_mkdir $DIR/$tdir
24864         swap_lock_test -d $DIR/$tdir ||
24865                 error "One layout swap locked test failed"
24866 }
24867 run_test 405 "Various layout swap lock tests"
24868
24869 test_406() {
24870         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24871         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
24872         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
24873         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24874         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
24875                 skip "Need MDS version at least 2.8.50"
24876
24877         local def_stripe_size=$($LFS getstripe -S $MOUNT)
24878         local test_pool=$TESTNAME
24879
24880         pool_add $test_pool || error "pool_add failed"
24881         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
24882                 error "pool_add_targets failed"
24883
24884         save_layout_restore_at_exit $MOUNT
24885
24886         # parent set default stripe count only, child will stripe from both
24887         # parent and fs default
24888         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
24889                 error "setstripe $MOUNT failed"
24890         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
24891         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
24892         for i in $(seq 10); do
24893                 local f=$DIR/$tdir/$tfile.$i
24894                 touch $f || error "touch failed"
24895                 local count=$($LFS getstripe -c $f)
24896                 [ $count -eq $OSTCOUNT ] ||
24897                         error "$f stripe count $count != $OSTCOUNT"
24898                 local offset=$($LFS getstripe -i $f)
24899                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
24900                 local size=$($LFS getstripe -S $f)
24901                 [ $size -eq $((def_stripe_size * 2)) ] ||
24902                         error "$f stripe size $size != $((def_stripe_size * 2))"
24903                 local pool=$($LFS getstripe -p $f)
24904                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
24905         done
24906
24907         # change fs default striping, delete parent default striping, now child
24908         # will stripe from new fs default striping only
24909         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
24910                 error "change $MOUNT default stripe failed"
24911         $LFS setstripe -c 0 $DIR/$tdir ||
24912                 error "delete $tdir default stripe failed"
24913         for i in $(seq 11 20); do
24914                 local f=$DIR/$tdir/$tfile.$i
24915                 touch $f || error "touch $f failed"
24916                 local count=$($LFS getstripe -c $f)
24917                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
24918                 local offset=$($LFS getstripe -i $f)
24919                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
24920                 local size=$($LFS getstripe -S $f)
24921                 [ $size -eq $def_stripe_size ] ||
24922                         error "$f stripe size $size != $def_stripe_size"
24923                 local pool=$($LFS getstripe -p $f)
24924                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
24925         done
24926
24927         unlinkmany $DIR/$tdir/$tfile. 1 20
24928
24929         local f=$DIR/$tdir/$tfile
24930         pool_remove_all_targets $test_pool $f
24931         pool_remove $test_pool $f
24932 }
24933 run_test 406 "DNE support fs default striping"
24934
24935 test_407() {
24936         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24937         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
24938                 skip "Need MDS version at least 2.8.55"
24939         remote_mds_nodsh && skip "remote MDS with nodsh"
24940
24941         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
24942                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
24943         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
24944                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
24945         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
24946
24947         #define OBD_FAIL_DT_TXN_STOP    0x2019
24948         for idx in $(seq $MDSCOUNT); do
24949                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
24950         done
24951         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
24952         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
24953                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
24954         true
24955 }
24956 run_test 407 "transaction fail should cause operation fail"
24957
24958 test_408() {
24959         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
24960
24961         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
24962         lctl set_param fail_loc=0x8000040a
24963         # let ll_prepare_partial_page() fail
24964         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
24965
24966         rm -f $DIR/$tfile
24967
24968         # create at least 100 unused inodes so that
24969         # shrink_icache_memory(0) should not return 0
24970         touch $DIR/$tfile-{0..100}
24971         rm -f $DIR/$tfile-{0..100}
24972         sync
24973
24974         echo 2 > /proc/sys/vm/drop_caches
24975 }
24976 run_test 408 "drop_caches should not hang due to page leaks"
24977
24978 test_409()
24979 {
24980         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24981
24982         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
24983         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
24984         touch $DIR/$tdir/guard || error "(2) Fail to create"
24985
24986         local PREFIX=$(str_repeat 'A' 128)
24987         echo "Create 1K hard links start at $(date)"
24988         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
24989                 error "(3) Fail to hard link"
24990
24991         echo "Links count should be right although linkEA overflow"
24992         stat $DIR/$tdir/guard || error "(4) Fail to stat"
24993         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
24994         [ $linkcount -eq 1001 ] ||
24995                 error "(5) Unexpected hard links count: $linkcount"
24996
24997         echo "List all links start at $(date)"
24998         ls -l $DIR/$tdir/foo > /dev/null ||
24999                 error "(6) Fail to list $DIR/$tdir/foo"
25000
25001         echo "Unlink hard links start at $(date)"
25002         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25003                 error "(7) Fail to unlink"
25004         echo "Unlink hard links finished at $(date)"
25005 }
25006 run_test 409 "Large amount of cross-MDTs hard links on the same file"
25007
25008 test_410()
25009 {
25010         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
25011                 skip "Need client version at least 2.9.59"
25012         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
25013                 skip "Need MODULES build"
25014
25015         # Create a file, and stat it from the kernel
25016         local testfile=$DIR/$tfile
25017         touch $testfile
25018
25019         local run_id=$RANDOM
25020         local my_ino=$(stat --format "%i" $testfile)
25021
25022         # Try to insert the module. This will always fail as the
25023         # module is designed to not be inserted.
25024         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
25025             &> /dev/null
25026
25027         # Anything but success is a test failure
25028         dmesg | grep -q \
25029             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
25030             error "no inode match"
25031 }
25032 run_test 410 "Test inode number returned from kernel thread"
25033
25034 cleanup_test411_cgroup() {
25035         trap 0
25036         rmdir "$1"
25037 }
25038
25039 test_411() {
25040         local cg_basedir=/sys/fs/cgroup/memory
25041         # LU-9966
25042         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
25043                 skip "no setup for cgroup"
25044
25045         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
25046                 error "test file creation failed"
25047         cancel_lru_locks osc
25048
25049         # Create a very small memory cgroup to force a slab allocation error
25050         local cgdir=$cg_basedir/osc_slab_alloc
25051         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
25052         trap "cleanup_test411_cgroup $cgdir" EXIT
25053         echo 2M > $cgdir/memory.kmem.limit_in_bytes
25054         echo 1M > $cgdir/memory.limit_in_bytes
25055
25056         # Should not LBUG, just be killed by oom-killer
25057         # dd will return 0 even allocation failure in some environment.
25058         # So don't check return value
25059         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
25060         cleanup_test411_cgroup $cgdir
25061
25062         return 0
25063 }
25064 run_test 411 "Slab allocation error with cgroup does not LBUG"
25065
25066 test_412() {
25067         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25068         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
25069                 skip "Need server version at least 2.10.55"
25070         fi
25071
25072         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
25073                 error "mkdir failed"
25074         $LFS getdirstripe $DIR/$tdir
25075         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
25076         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
25077                 error "expect $((MDSCOUT - 1)) get $stripe_index"
25078         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
25079         [ $stripe_count -eq 2 ] ||
25080                 error "expect 2 get $stripe_count"
25081 }
25082 run_test 412 "mkdir on specific MDTs"
25083
25084 generate_uneven_mdts() {
25085         local threshold=$1
25086         local lmv_qos_maxage
25087         local lod_qos_maxage
25088         local ffree
25089         local bavail
25090         local max
25091         local min
25092         local max_index
25093         local min_index
25094         local tmp
25095         local i
25096
25097         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25098         $LCTL set_param lmv.*.qos_maxage=1
25099         stack_trap "$LCTL set_param \
25100                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
25101         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25102                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25103         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25104                 lod.*.mdt_qos_maxage=1
25105         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25106                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
25107
25108         echo
25109         echo "Check for uneven MDTs: "
25110
25111         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25112         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25113         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25114
25115         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25116         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25117         max_index=0
25118         min_index=0
25119         for ((i = 1; i < ${#ffree[@]}; i++)); do
25120                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25121                 if [ $tmp -gt $max ]; then
25122                         max=$tmp
25123                         max_index=$i
25124                 fi
25125                 if [ $tmp -lt $min ]; then
25126                         min=$tmp
25127                         min_index=$i
25128                 fi
25129         done
25130
25131         (( ${ffree[min_index]} > 0 )) ||
25132                 skip "no free files in MDT$min_index"
25133         (( ${ffree[min_index]} < 10000000 )) ||
25134                 skip "too many free files in MDT$min_index"
25135
25136         # Check if we need to generate uneven MDTs
25137         local diff=$(((max - min) * 100 / min))
25138         local testdir=$DIR/$tdir-fillmdt
25139         local start
25140
25141         mkdir -p $testdir
25142
25143         i=0
25144         while (( diff < threshold )); do
25145                 # generate uneven MDTs, create till $threshold% diff
25146                 echo -n "weight diff=$diff% must be > $threshold% ..."
25147                 echo "Fill MDT$min_index with 1000 files: loop $i"
25148                 testdir=$DIR/$tdir-fillmdt/$i
25149                 [ -d $testdir ] || $LFS mkdir -i $min_index $testdir ||
25150                         error "mkdir $testdir failed"
25151                 $LFS setstripe -E 1M -L mdt $testdir ||
25152                         error "setstripe $testdir failed"
25153                 start=$SECONDS
25154                 for F in f.{0..999}; do
25155                         dd if=/dev/zero of=$testdir/$F bs=64K count=1 > \
25156                                 /dev/null 2>&1 || error "dd $F failed"
25157                 done
25158
25159                 # wait for QOS to update
25160                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
25161
25162                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
25163                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
25164                 max=$(((${ffree[max_index]} >> 8) * \
25165                         (${bavail[max_index]} * bsize >> 16)))
25166                 min=$(((${ffree[min_index]} >> 8) * \
25167                         (${bavail[min_index]} * bsize >> 16)))
25168                 diff=$(((max - min) * 100 / min))
25169                 i=$((i + 1))
25170         done
25171
25172         echo "MDT filesfree available: ${ffree[@]}"
25173         echo "MDT blocks available: ${bavail[@]}"
25174         echo "weight diff=$diff%"
25175 }
25176
25177 test_qos_mkdir() {
25178         local mkdir_cmd=$1
25179         local stripe_count=$2
25180         local mdts=$(comma_list $(mdts_nodes))
25181
25182         local testdir
25183         local lmv_qos_prio_free
25184         local lmv_qos_threshold_rr
25185         local lmv_qos_maxage
25186         local lod_qos_prio_free
25187         local lod_qos_threshold_rr
25188         local lod_qos_maxage
25189         local count
25190         local i
25191
25192         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
25193         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
25194         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25195                 head -n1)
25196         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
25197         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25198         stack_trap "$LCTL set_param \
25199                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
25200         stack_trap "$LCTL set_param \
25201                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
25202         stack_trap "$LCTL set_param \
25203                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
25204
25205         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
25206                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
25207         lod_qos_prio_free=${lod_qos_prio_free%%%}
25208         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
25209                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
25210         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
25211         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25212                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25213         stack_trap "do_nodes $mdts $LCTL set_param \
25214                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
25215         stack_trap "do_nodes $mdts $LCTL set_param \
25216                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
25217         stack_trap "do_nodes $mdts $LCTL set_param \
25218                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
25219
25220         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25221         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
25222
25223         testdir=$DIR/$tdir-s$stripe_count/rr
25224
25225         local stripe_index=$($LFS getstripe -m $testdir)
25226         local test_mkdir_rr=true
25227
25228         getfattr -d -m dmv -e hex $testdir | grep dmv
25229         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
25230                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
25231                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
25232                         test_mkdir_rr=false
25233         fi
25234
25235         echo
25236         $test_mkdir_rr &&
25237                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
25238                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
25239
25240         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
25241         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
25242                 eval $mkdir_cmd $testdir/subdir$i ||
25243                         error "$mkdir_cmd subdir$i failed"
25244         done
25245
25246         for (( i = 0; i < $MDSCOUNT; i++ )); do
25247                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25248                 echo "$count directories created on MDT$i"
25249                 if $test_mkdir_rr; then
25250                         (( $count == 100 )) ||
25251                                 error "subdirs are not evenly distributed"
25252                 elif (( $i == $stripe_index )); then
25253                         (( $count == 100 * MDSCOUNT )) ||
25254                                 error "$count subdirs created on MDT$i"
25255                 else
25256                         (( $count == 0 )) ||
25257                                 error "$count subdirs created on MDT$i"
25258                 fi
25259
25260                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
25261                         count=$($LFS getdirstripe $testdir/* |
25262                                 grep -c -P "^\s+$i\t")
25263                         echo "$count stripes created on MDT$i"
25264                         # deviation should < 5% of average
25265                         (( $count >= 95 * stripe_count &&
25266                            $count <= 105 * stripe_count)) ||
25267                                 error "stripes are not evenly distributed"
25268                 fi
25269         done
25270
25271         echo
25272         echo "Check for uneven MDTs: "
25273
25274         local ffree
25275         local bavail
25276         local max
25277         local min
25278         local max_index
25279         local min_index
25280         local tmp
25281
25282         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25283         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25284         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25285
25286         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25287         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25288         max_index=0
25289         min_index=0
25290         for ((i = 1; i < ${#ffree[@]}; i++)); do
25291                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25292                 if [ $tmp -gt $max ]; then
25293                         max=$tmp
25294                         max_index=$i
25295                 fi
25296                 if [ $tmp -lt $min ]; then
25297                         min=$tmp
25298                         min_index=$i
25299                 fi
25300         done
25301
25302         (( ${ffree[min_index]} > 0 )) ||
25303                 skip "no free files in MDT$min_index"
25304         (( ${ffree[min_index]} < 10000000 )) ||
25305                 skip "too many free files in MDT$min_index"
25306
25307         echo "MDT filesfree available: ${ffree[@]}"
25308         echo "MDT blocks available: ${bavail[@]}"
25309         echo "weight diff=$(((max - min) * 100 / min))%"
25310         echo
25311         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
25312
25313         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
25314         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
25315         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
25316         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
25317         # decrease statfs age, so that it can be updated in time
25318         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
25319         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
25320
25321         sleep 1
25322
25323         testdir=$DIR/$tdir-s$stripe_count/qos
25324         local num=200
25325
25326         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
25327         for (( i = 0; i < num * MDSCOUNT; i++ )); do
25328                 eval $mkdir_cmd $testdir/subdir$i ||
25329                         error "$mkdir_cmd subdir$i failed"
25330         done
25331
25332         max=0
25333         for (( i = 0; i < $MDSCOUNT; i++ )); do
25334                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25335                 (( count > max )) && max=$count
25336                 echo "$count directories created on MDT$i"
25337         done
25338
25339         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
25340
25341         # D-value should > 10% of averge
25342         (( max - min > num / 10 )) ||
25343                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
25344
25345         # ditto for stripes
25346         if (( stripe_count > 1 )); then
25347                 max=0
25348                 for (( i = 0; i < $MDSCOUNT; i++ )); do
25349                         count=$($LFS getdirstripe $testdir/* |
25350                                 grep -c -P "^\s+$i\t")
25351                         (( count > max )) && max=$count
25352                         echo "$count stripes created on MDT$i"
25353                 done
25354
25355                 min=$($LFS getdirstripe $testdir/* |
25356                         grep -c -P "^\s+$min_index\t")
25357                 (( max - min > num * stripe_count / 10 )) ||
25358                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
25359         fi
25360 }
25361
25362 most_full_mdt() {
25363         local ffree
25364         local bavail
25365         local bsize
25366         local min
25367         local min_index
25368         local tmp
25369
25370         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25371         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25372         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25373
25374         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25375         min_index=0
25376         for ((i = 1; i < ${#ffree[@]}; i++)); do
25377                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25378                 (( tmp < min )) && min=$tmp && min_index=$i
25379         done
25380
25381         echo -n $min_index
25382 }
25383
25384 test_413a() {
25385         [ $MDSCOUNT -lt 2 ] &&
25386                 skip "We need at least 2 MDTs for this test"
25387
25388         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25389                 skip "Need server version at least 2.12.52"
25390
25391         local stripe_count
25392
25393         generate_uneven_mdts 100
25394         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25395                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
25396                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
25397                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
25398                         error "mkdir failed"
25399                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
25400         done
25401 }
25402 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
25403
25404 test_413b() {
25405         [ $MDSCOUNT -lt 2 ] &&
25406                 skip "We need at least 2 MDTs for this test"
25407
25408         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25409                 skip "Need server version at least 2.12.52"
25410
25411         local testdir
25412         local stripe_count
25413
25414         generate_uneven_mdts 100
25415         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25416                 testdir=$DIR/$tdir-s$stripe_count
25417                 mkdir $testdir || error "mkdir $testdir failed"
25418                 mkdir $testdir/rr || error "mkdir rr failed"
25419                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
25420                         error "mkdir qos failed"
25421                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
25422                         $testdir/rr || error "setdirstripe rr failed"
25423                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
25424                         error "setdirstripe failed"
25425                 test_qos_mkdir "mkdir" $stripe_count
25426         done
25427 }
25428 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
25429
25430 test_413c() {
25431         (( $MDSCOUNT >= 2 )) ||
25432                 skip "We need at least 2 MDTs for this test"
25433
25434         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
25435                 skip "Need server version at least 2.14.51"
25436
25437         local testdir
25438         local inherit
25439         local inherit_rr
25440
25441         testdir=$DIR/${tdir}-s1
25442         mkdir $testdir || error "mkdir $testdir failed"
25443         mkdir $testdir/rr || error "mkdir rr failed"
25444         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
25445         # default max_inherit is -1, default max_inherit_rr is 0
25446         $LFS setdirstripe -D -c 1 $testdir/rr ||
25447                 error "setdirstripe rr failed"
25448         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
25449                 error "setdirstripe qos failed"
25450         test_qos_mkdir "mkdir" 1
25451
25452         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
25453         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
25454         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
25455         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
25456         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
25457
25458         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
25459         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
25460         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
25461         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
25462         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
25463         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
25464         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
25465                 error "level2 shouldn't have default LMV" || true
25466 }
25467 run_test 413c "mkdir with default LMV max inherit rr"
25468
25469 test_413d() {
25470         (( MDSCOUNT >= 2 )) ||
25471                 skip "We need at least 2 MDTs for this test"
25472
25473         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
25474                 skip "Need server version at least 2.14.51"
25475
25476         local lmv_qos_threshold_rr
25477
25478         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25479                 head -n1)
25480         stack_trap "$LCTL set_param \
25481                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
25482
25483         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25484         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25485         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
25486                 error "$tdir shouldn't have default LMV"
25487         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
25488                 error "mkdir sub failed"
25489
25490         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
25491
25492         (( count == 100 )) || error "$count subdirs on MDT0"
25493 }
25494 run_test 413d "inherit ROOT default LMV"
25495
25496 test_413z() {
25497         local pids=""
25498         local subdir
25499         local pid
25500
25501         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
25502                 unlinkmany $subdir/f. 1000 &
25503                 pids="$pids $!"
25504         done
25505
25506         for pid in $pids; do
25507                 wait $pid
25508         done
25509 }
25510 run_test 413z "413 test cleanup"
25511
25512 test_414() {
25513 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
25514         $LCTL set_param fail_loc=0x80000521
25515         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
25516         rm -f $DIR/$tfile
25517 }
25518 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
25519
25520 test_415() {
25521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25522         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25523                 skip "Need server version at least 2.11.52"
25524
25525         # LU-11102
25526         local total
25527         local setattr_pid
25528         local start_time
25529         local end_time
25530         local duration
25531
25532         total=500
25533         # this test may be slow on ZFS
25534         [ "$mds1_FSTYPE" == "zfs" ] && total=100
25535
25536         # though this test is designed for striped directory, let's test normal
25537         # directory too since lock is always saved as CoS lock.
25538         test_mkdir $DIR/$tdir || error "mkdir $tdir"
25539         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
25540
25541         (
25542                 while true; do
25543                         touch $DIR/$tdir
25544                 done
25545         ) &
25546         setattr_pid=$!
25547
25548         start_time=$(date +%s)
25549         for i in $(seq $total); do
25550                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
25551                         > /dev/null
25552         done
25553         end_time=$(date +%s)
25554         duration=$((end_time - start_time))
25555
25556         kill -9 $setattr_pid
25557
25558         echo "rename $total files took $duration sec"
25559         [ $duration -lt 100 ] || error "rename took $duration sec"
25560 }
25561 run_test 415 "lock revoke is not missing"
25562
25563 test_416() {
25564         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
25565                 skip "Need server version at least 2.11.55"
25566
25567         # define OBD_FAIL_OSD_TXN_START    0x19a
25568         do_facet mds1 lctl set_param fail_loc=0x19a
25569
25570         lfs mkdir -c $MDSCOUNT $DIR/$tdir
25571
25572         true
25573 }
25574 run_test 416 "transaction start failure won't cause system hung"
25575
25576 cleanup_417() {
25577         trap 0
25578         do_nodes $(comma_list $(mdts_nodes)) \
25579                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
25580         do_nodes $(comma_list $(mdts_nodes)) \
25581                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
25582         do_nodes $(comma_list $(mdts_nodes)) \
25583                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
25584 }
25585
25586 test_417() {
25587         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25588         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
25589                 skip "Need MDS version at least 2.11.56"
25590
25591         trap cleanup_417 RETURN EXIT
25592
25593         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
25594         do_nodes $(comma_list $(mdts_nodes)) \
25595                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
25596         $LFS migrate -m 0 $DIR/$tdir.1 &&
25597                 error "migrate dir $tdir.1 should fail"
25598
25599         do_nodes $(comma_list $(mdts_nodes)) \
25600                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
25601         $LFS mkdir -i 1 $DIR/$tdir.2 &&
25602                 error "create remote dir $tdir.2 should fail"
25603
25604         do_nodes $(comma_list $(mdts_nodes)) \
25605                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
25606         $LFS mkdir -c 2 $DIR/$tdir.3 &&
25607                 error "create striped dir $tdir.3 should fail"
25608         true
25609 }
25610 run_test 417 "disable remote dir, striped dir and dir migration"
25611
25612 # Checks that the outputs of df [-i] and lfs df [-i] match
25613 #
25614 # usage: check_lfs_df <blocks | inodes> <mountpoint>
25615 check_lfs_df() {
25616         local dir=$2
25617         local inodes
25618         local df_out
25619         local lfs_df_out
25620         local count
25621         local passed=false
25622
25623         # blocks or inodes
25624         [ "$1" == "blocks" ] && inodes= || inodes="-i"
25625
25626         for count in {1..100}; do
25627                 do_nodes "$CLIENTS" \
25628                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
25629                 sync; sleep 0.2
25630
25631                 # read the lines of interest
25632                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
25633                         error "df $inodes $dir | tail -n +2 failed"
25634                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
25635                         error "lfs df $inodes $dir | grep summary: failed"
25636
25637                 # skip first substrings of each output as they are different
25638                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
25639                 # compare the two outputs
25640                 passed=true
25641                 #  skip "available" on MDT until LU-13997 is fixed.
25642                 #for i in {1..5}; do
25643                 for i in 1 2 4 5; do
25644                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
25645                 done
25646                 $passed && break
25647         done
25648
25649         if ! $passed; then
25650                 df -P $inodes $dir
25651                 echo
25652                 lfs df $inodes $dir
25653                 error "df and lfs df $1 output mismatch: "      \
25654                       "df ${inodes}: ${df_out[*]}, "            \
25655                       "lfs df ${inodes}: ${lfs_df_out[*]}"
25656         fi
25657 }
25658
25659 test_418() {
25660         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25661
25662         local dir=$DIR/$tdir
25663         local numfiles=$((RANDOM % 4096 + 2))
25664         local numblocks=$((RANDOM % 256 + 1))
25665
25666         wait_delete_completed
25667         test_mkdir $dir
25668
25669         # check block output
25670         check_lfs_df blocks $dir
25671         # check inode output
25672         check_lfs_df inodes $dir
25673
25674         # create a single file and retest
25675         echo "Creating a single file and testing"
25676         createmany -o $dir/$tfile- 1 &>/dev/null ||
25677                 error "creating 1 file in $dir failed"
25678         check_lfs_df blocks $dir
25679         check_lfs_df inodes $dir
25680
25681         # create a random number of files
25682         echo "Creating $((numfiles - 1)) files and testing"
25683         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
25684                 error "creating $((numfiles - 1)) files in $dir failed"
25685
25686         # write a random number of blocks to the first test file
25687         echo "Writing $numblocks 4K blocks and testing"
25688         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
25689                 count=$numblocks &>/dev/null ||
25690                 error "dd to $dir/${tfile}-0 failed"
25691
25692         # retest
25693         check_lfs_df blocks $dir
25694         check_lfs_df inodes $dir
25695
25696         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
25697                 error "unlinking $numfiles files in $dir failed"
25698 }
25699 run_test 418 "df and lfs df outputs match"
25700
25701 test_419()
25702 {
25703         local dir=$DIR/$tdir
25704
25705         mkdir -p $dir
25706         touch $dir/file
25707
25708         cancel_lru_locks mdc
25709
25710         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
25711         $LCTL set_param fail_loc=0x1410
25712         cat $dir/file
25713         $LCTL set_param fail_loc=0
25714         rm -rf $dir
25715 }
25716 run_test 419 "Verify open file by name doesn't crash kernel"
25717
25718 test_420()
25719 {
25720         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
25721                 skip "Need MDS version at least 2.12.53"
25722
25723         local SAVE_UMASK=$(umask)
25724         local dir=$DIR/$tdir
25725         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
25726
25727         mkdir -p $dir
25728         umask 0000
25729         mkdir -m03777 $dir/testdir
25730         ls -dn $dir/testdir
25731         # Need to remove trailing '.' when SELinux is enabled
25732         local dirperms=$(ls -dn $dir/testdir |
25733                          awk '{ sub(/\.$/, "", $1); print $1}')
25734         [ $dirperms == "drwxrwsrwt" ] ||
25735                 error "incorrect perms on $dir/testdir"
25736
25737         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
25738                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
25739         ls -n $dir/testdir/testfile
25740         local fileperms=$(ls -n $dir/testdir/testfile |
25741                           awk '{ sub(/\.$/, "", $1); print $1}')
25742         [ $fileperms == "-rwxr-xr-x" ] ||
25743                 error "incorrect perms on $dir/testdir/testfile"
25744
25745         umask $SAVE_UMASK
25746 }
25747 run_test 420 "clear SGID bit on non-directories for non-members"
25748
25749 test_421a() {
25750         local cnt
25751         local fid1
25752         local fid2
25753
25754         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25755                 skip "Need MDS version at least 2.12.54"
25756
25757         test_mkdir $DIR/$tdir
25758         createmany -o $DIR/$tdir/f 3
25759         cnt=$(ls -1 $DIR/$tdir | wc -l)
25760         [ $cnt != 3 ] && error "unexpected #files: $cnt"
25761
25762         fid1=$(lfs path2fid $DIR/$tdir/f1)
25763         fid2=$(lfs path2fid $DIR/$tdir/f2)
25764         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
25765
25766         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
25767         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
25768
25769         cnt=$(ls -1 $DIR/$tdir | wc -l)
25770         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
25771
25772         rm -f $DIR/$tdir/f3 || error "can't remove f3"
25773         createmany -o $DIR/$tdir/f 3
25774         cnt=$(ls -1 $DIR/$tdir | wc -l)
25775         [ $cnt != 3 ] && error "unexpected #files: $cnt"
25776
25777         fid1=$(lfs path2fid $DIR/$tdir/f1)
25778         fid2=$(lfs path2fid $DIR/$tdir/f2)
25779         echo "remove using fsname $FSNAME"
25780         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
25781
25782         cnt=$(ls -1 $DIR/$tdir | wc -l)
25783         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
25784 }
25785 run_test 421a "simple rm by fid"
25786
25787 test_421b() {
25788         local cnt
25789         local FID1
25790         local FID2
25791
25792         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25793                 skip "Need MDS version at least 2.12.54"
25794
25795         test_mkdir $DIR/$tdir
25796         createmany -o $DIR/$tdir/f 3
25797         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
25798         MULTIPID=$!
25799
25800         FID1=$(lfs path2fid $DIR/$tdir/f1)
25801         FID2=$(lfs path2fid $DIR/$tdir/f2)
25802         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
25803
25804         kill -USR1 $MULTIPID
25805         wait
25806
25807         cnt=$(ls $DIR/$tdir | wc -l)
25808         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
25809 }
25810 run_test 421b "rm by fid on open file"
25811
25812 test_421c() {
25813         local cnt
25814         local FIDS
25815
25816         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25817                 skip "Need MDS version at least 2.12.54"
25818
25819         test_mkdir $DIR/$tdir
25820         createmany -o $DIR/$tdir/f 3
25821         touch $DIR/$tdir/$tfile
25822         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
25823         cnt=$(ls -1 $DIR/$tdir | wc -l)
25824         [ $cnt != 184 ] && error "unexpected #files: $cnt"
25825
25826         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
25827         $LFS rmfid $DIR $FID1 || error "rmfid failed"
25828
25829         cnt=$(ls $DIR/$tdir | wc -l)
25830         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
25831 }
25832 run_test 421c "rm by fid against hardlinked files"
25833
25834 test_421d() {
25835         local cnt
25836         local FIDS
25837
25838         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25839                 skip "Need MDS version at least 2.12.54"
25840
25841         test_mkdir $DIR/$tdir
25842         createmany -o $DIR/$tdir/f 4097
25843         cnt=$(ls -1 $DIR/$tdir | wc -l)
25844         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
25845
25846         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
25847         $LFS rmfid $DIR $FIDS || error "rmfid failed"
25848
25849         cnt=$(ls $DIR/$tdir | wc -l)
25850         rm -rf $DIR/$tdir
25851         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25852 }
25853 run_test 421d "rmfid en masse"
25854
25855 test_421e() {
25856         local cnt
25857         local FID
25858
25859         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25860         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25861                 skip "Need MDS version at least 2.12.54"
25862
25863         mkdir -p $DIR/$tdir
25864         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25865         createmany -o $DIR/$tdir/striped_dir/f 512
25866         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25867         [ $cnt != 512 ] && error "unexpected #files: $cnt"
25868
25869         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
25870                 sed "s/[/][^:]*://g")
25871         $LFS rmfid $DIR $FIDS || error "rmfid failed"
25872
25873         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
25874         rm -rf $DIR/$tdir
25875         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25876 }
25877 run_test 421e "rmfid in DNE"
25878
25879 test_421f() {
25880         local cnt
25881         local FID
25882
25883         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25884                 skip "Need MDS version at least 2.12.54"
25885
25886         test_mkdir $DIR/$tdir
25887         touch $DIR/$tdir/f
25888         cnt=$(ls -1 $DIR/$tdir | wc -l)
25889         [ $cnt != 1 ] && error "unexpected #files: $cnt"
25890
25891         FID=$(lfs path2fid $DIR/$tdir/f)
25892         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
25893         # rmfid should fail
25894         cnt=$(ls -1 $DIR/$tdir | wc -l)
25895         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
25896
25897         chmod a+rw $DIR/$tdir
25898         ls -la $DIR/$tdir
25899         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
25900         # rmfid should fail
25901         cnt=$(ls -1 $DIR/$tdir | wc -l)
25902         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
25903
25904         rm -f $DIR/$tdir/f
25905         $RUNAS touch $DIR/$tdir/f
25906         FID=$(lfs path2fid $DIR/$tdir/f)
25907         echo "rmfid as root"
25908         $LFS rmfid $DIR $FID || error "rmfid as root failed"
25909         cnt=$(ls -1 $DIR/$tdir | wc -l)
25910         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
25911
25912         rm -f $DIR/$tdir/f
25913         $RUNAS touch $DIR/$tdir/f
25914         cnt=$(ls -1 $DIR/$tdir | wc -l)
25915         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
25916         FID=$(lfs path2fid $DIR/$tdir/f)
25917         # rmfid w/o user_fid2path mount option should fail
25918         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
25919         cnt=$(ls -1 $DIR/$tdir | wc -l)
25920         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
25921
25922         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
25923         stack_trap "rmdir $tmpdir"
25924         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
25925                 error "failed to mount client'"
25926         stack_trap "umount_client $tmpdir"
25927
25928         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
25929         # rmfid should succeed
25930         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
25931         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
25932
25933         # rmfid shouldn't allow to remove files due to dir's permission
25934         chmod a+rwx $tmpdir/$tdir
25935         touch $tmpdir/$tdir/f
25936         ls -la $tmpdir/$tdir
25937         FID=$(lfs path2fid $tmpdir/$tdir/f)
25938         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
25939         return 0
25940 }
25941 run_test 421f "rmfid checks permissions"
25942
25943 test_421g() {
25944         local cnt
25945         local FIDS
25946
25947         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25948         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25949                 skip "Need MDS version at least 2.12.54"
25950
25951         mkdir -p $DIR/$tdir
25952         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25953         createmany -o $DIR/$tdir/striped_dir/f 512
25954         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25955         [ $cnt != 512 ] && error "unexpected #files: $cnt"
25956
25957         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
25958                 sed "s/[/][^:]*://g")
25959
25960         rm -f $DIR/$tdir/striped_dir/f1*
25961         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25962         removed=$((512 - cnt))
25963
25964         # few files have been just removed, so we expect
25965         # rmfid to fail on their fids
25966         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
25967         [ $removed != $errors ] && error "$errors != $removed"
25968
25969         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
25970         rm -rf $DIR/$tdir
25971         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25972 }
25973 run_test 421g "rmfid to return errors properly"
25974
25975 test_422() {
25976         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
25977         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
25978         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
25979         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
25980         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
25981
25982         local amc=$(at_max_get client)
25983         local amo=$(at_max_get mds1)
25984         local timeout=`lctl get_param -n timeout`
25985
25986         at_max_set 0 client
25987         at_max_set 0 mds1
25988
25989 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
25990         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
25991                         fail_val=$(((2*timeout + 10)*1000))
25992         touch $DIR/$tdir/d3/file &
25993         sleep 2
25994 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
25995         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
25996                         fail_val=$((2*timeout + 5))
25997         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
25998         local pid=$!
25999         sleep 1
26000         kill -9 $pid
26001         sleep $((2 * timeout))
26002         echo kill $pid
26003         kill -9 $pid
26004         lctl mark touch
26005         touch $DIR/$tdir/d2/file3
26006         touch $DIR/$tdir/d2/file4
26007         touch $DIR/$tdir/d2/file5
26008
26009         wait
26010         at_max_set $amc client
26011         at_max_set $amo mds1
26012
26013         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
26014         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
26015                 error "Watchdog is always throttled"
26016 }
26017 run_test 422 "kill a process with RPC in progress"
26018
26019 stat_test() {
26020     df -h $MOUNT &
26021     df -h $MOUNT &
26022     df -h $MOUNT &
26023     df -h $MOUNT &
26024     df -h $MOUNT &
26025     df -h $MOUNT &
26026 }
26027
26028 test_423() {
26029     local _stats
26030     # ensure statfs cache is expired
26031     sleep 2;
26032
26033     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
26034     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
26035
26036     return 0
26037 }
26038 run_test 423 "statfs should return a right data"
26039
26040 test_424() {
26041 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
26042         $LCTL set_param fail_loc=0x80000522
26043         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26044         rm -f $DIR/$tfile
26045 }
26046 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
26047
26048 test_425() {
26049         test_mkdir -c -1 $DIR/$tdir
26050         $LFS setstripe -c -1 $DIR/$tdir
26051
26052         lru_resize_disable "" 100
26053         stack_trap "lru_resize_enable" EXIT
26054
26055         sleep 5
26056
26057         for i in $(seq $((MDSCOUNT * 125))); do
26058                 local t=$DIR/$tdir/$tfile_$i
26059
26060                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
26061                         error_noexit "Create file $t"
26062         done
26063         stack_trap "rm -rf $DIR/$tdir" EXIT
26064
26065         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
26066                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
26067                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
26068
26069                 [ $lock_count -le $lru_size ] ||
26070                         error "osc lock count $lock_count > lru size $lru_size"
26071         done
26072
26073         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
26074                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
26075                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
26076
26077                 [ $lock_count -le $lru_size ] ||
26078                         error "mdc lock count $lock_count > lru size $lru_size"
26079         done
26080 }
26081 run_test 425 "lock count should not exceed lru size"
26082
26083 test_426() {
26084         splice-test -r $DIR/$tfile
26085         splice-test -rd $DIR/$tfile
26086         splice-test $DIR/$tfile
26087         splice-test -d $DIR/$tfile
26088 }
26089 run_test 426 "splice test on Lustre"
26090
26091 test_427() {
26092         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
26093         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
26094                 skip "Need MDS version at least 2.12.4"
26095         local log
26096
26097         mkdir $DIR/$tdir
26098         mkdir $DIR/$tdir/1
26099         mkdir $DIR/$tdir/2
26100         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
26101         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
26102
26103         $LFS getdirstripe $DIR/$tdir/1/dir
26104
26105         #first setfattr for creating updatelog
26106         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
26107
26108 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
26109         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
26110         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
26111         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
26112
26113         sleep 2
26114         fail mds2
26115         wait_recovery_complete mds2 $((2*TIMEOUT))
26116
26117         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
26118         echo $log | grep "get update log failed" &&
26119                 error "update log corruption is detected" || true
26120 }
26121 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
26122
26123 test_428() {
26124         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26125         local cache_limit=$CACHE_MAX
26126
26127         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
26128         $LCTL set_param -n llite.*.max_cached_mb=64
26129
26130         mkdir $DIR/$tdir
26131         $LFS setstripe -c 1 $DIR/$tdir
26132         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
26133         stack_trap "rm -f $DIR/$tdir/$tfile.*"
26134         #test write
26135         for f in $(seq 4); do
26136                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
26137         done
26138         wait
26139
26140         cancel_lru_locks osc
26141         # Test read
26142         for f in $(seq 4); do
26143                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
26144         done
26145         wait
26146 }
26147 run_test 428 "large block size IO should not hang"
26148
26149 test_429() { # LU-7915 / LU-10948
26150         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
26151         local testfile=$DIR/$tfile
26152         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
26153         local new_flag=1
26154         local first_rpc
26155         local second_rpc
26156         local third_rpc
26157
26158         $LCTL get_param $ll_opencache_threshold_count ||
26159                 skip "client does not have opencache parameter"
26160
26161         set_opencache $new_flag
26162         stack_trap "restore_opencache"
26163         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
26164                 error "enable opencache failed"
26165         touch $testfile
26166         # drop MDC DLM locks
26167         cancel_lru_locks mdc
26168         # clear MDC RPC stats counters
26169         $LCTL set_param $mdc_rpcstats=clear
26170
26171         # According to the current implementation, we need to run 3 times
26172         # open & close file to verify if opencache is enabled correctly.
26173         # 1st, RPCs are sent for lookup/open and open handle is released on
26174         #      close finally.
26175         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
26176         #      so open handle won't be released thereafter.
26177         # 3rd, No RPC is sent out.
26178         $MULTIOP $testfile oc || error "multiop failed"
26179         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26180         echo "1st: $first_rpc RPCs in flight"
26181
26182         $MULTIOP $testfile oc || error "multiop failed"
26183         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26184         echo "2nd: $second_rpc RPCs in flight"
26185
26186         $MULTIOP $testfile oc || error "multiop failed"
26187         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26188         echo "3rd: $third_rpc RPCs in flight"
26189
26190         #verify no MDC RPC is sent
26191         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
26192 }
26193 run_test 429 "verify if opencache flag on client side does work"
26194
26195 lseek_test_430() {
26196         local offset
26197         local file=$1
26198
26199         # data at [200K, 400K)
26200         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
26201                 error "256K->512K dd fails"
26202         # data at [2M, 3M)
26203         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
26204                 error "2M->3M dd fails"
26205         # data at [4M, 5M)
26206         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
26207                 error "4M->5M dd fails"
26208         echo "Data at 256K...512K, 2M...3M and 4M...5M"
26209         # start at first component hole #1
26210         printf "Seeking hole from 1000 ... "
26211         offset=$(lseek_test -l 1000 $file)
26212         echo $offset
26213         [[ $offset == 1000 ]] || error "offset $offset != 1000"
26214         printf "Seeking data from 1000 ... "
26215         offset=$(lseek_test -d 1000 $file)
26216         echo $offset
26217         [[ $offset == 262144 ]] || error "offset $offset != 262144"
26218
26219         # start at first component data block
26220         printf "Seeking hole from 300000 ... "
26221         offset=$(lseek_test -l 300000 $file)
26222         echo $offset
26223         [[ $offset == 524288 ]] || error "offset $offset != 524288"
26224         printf "Seeking data from 300000 ... "
26225         offset=$(lseek_test -d 300000 $file)
26226         echo $offset
26227         [[ $offset == 300000 ]] || error "offset $offset != 300000"
26228
26229         # start at the first component but beyond end of object size
26230         printf "Seeking hole from 1000000 ... "
26231         offset=$(lseek_test -l 1000000 $file)
26232         echo $offset
26233         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26234         printf "Seeking data from 1000000 ... "
26235         offset=$(lseek_test -d 1000000 $file)
26236         echo $offset
26237         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26238
26239         # start at second component stripe 2 (empty file)
26240         printf "Seeking hole from 1500000 ... "
26241         offset=$(lseek_test -l 1500000 $file)
26242         echo $offset
26243         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
26244         printf "Seeking data from 1500000 ... "
26245         offset=$(lseek_test -d 1500000 $file)
26246         echo $offset
26247         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26248
26249         # start at second component stripe 1 (all data)
26250         printf "Seeking hole from 3000000 ... "
26251         offset=$(lseek_test -l 3000000 $file)
26252         echo $offset
26253         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
26254         printf "Seeking data from 3000000 ... "
26255         offset=$(lseek_test -d 3000000 $file)
26256         echo $offset
26257         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
26258
26259         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
26260                 error "2nd dd fails"
26261         echo "Add data block at 640K...1280K"
26262
26263         # start at before new data block, in hole
26264         printf "Seeking hole from 600000 ... "
26265         offset=$(lseek_test -l 600000 $file)
26266         echo $offset
26267         [[ $offset == 600000 ]] || error "offset $offset != 600000"
26268         printf "Seeking data from 600000 ... "
26269         offset=$(lseek_test -d 600000 $file)
26270         echo $offset
26271         [[ $offset == 655360 ]] || error "offset $offset != 655360"
26272
26273         # start at the first component new data block
26274         printf "Seeking hole from 1000000 ... "
26275         offset=$(lseek_test -l 1000000 $file)
26276         echo $offset
26277         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26278         printf "Seeking data from 1000000 ... "
26279         offset=$(lseek_test -d 1000000 $file)
26280         echo $offset
26281         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26282
26283         # start at second component stripe 2, new data
26284         printf "Seeking hole from 1200000 ... "
26285         offset=$(lseek_test -l 1200000 $file)
26286         echo $offset
26287         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26288         printf "Seeking data from 1200000 ... "
26289         offset=$(lseek_test -d 1200000 $file)
26290         echo $offset
26291         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
26292
26293         # start beyond file end
26294         printf "Using offset > filesize ... "
26295         lseek_test -l 4000000 $file && error "lseek should fail"
26296         printf "Using offset > filesize ... "
26297         lseek_test -d 4000000 $file && error "lseek should fail"
26298
26299         printf "Done\n\n"
26300 }
26301
26302 test_430a() {
26303         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
26304                 skip "MDT does not support SEEK_HOLE"
26305
26306         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26307                 skip "OST does not support SEEK_HOLE"
26308
26309         local file=$DIR/$tdir/$tfile
26310
26311         mkdir -p $DIR/$tdir
26312
26313         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
26314         # OST stripe #1 will have continuous data at [1M, 3M)
26315         # OST stripe #2 is empty
26316         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
26317         lseek_test_430 $file
26318         rm $file
26319         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
26320         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
26321         lseek_test_430 $file
26322         rm $file
26323         $LFS setstripe -c2 -S 512K $file
26324         echo "Two stripes, stripe size 512K"
26325         lseek_test_430 $file
26326         rm $file
26327         # FLR with stale mirror
26328         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
26329                        -N -c2 -S 1M $file
26330         echo "Mirrored file:"
26331         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
26332         echo "Plain 2 stripes 1M"
26333         lseek_test_430 $file
26334         rm $file
26335 }
26336 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
26337
26338 test_430b() {
26339         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26340                 skip "OST does not support SEEK_HOLE"
26341
26342         local offset
26343         local file=$DIR/$tdir/$tfile
26344
26345         mkdir -p $DIR/$tdir
26346         # Empty layout lseek should fail
26347         $MCREATE $file
26348         # seek from 0
26349         printf "Seeking hole from 0 ... "
26350         lseek_test -l 0 $file && error "lseek should fail"
26351         printf "Seeking data from 0 ... "
26352         lseek_test -d 0 $file && error "lseek should fail"
26353         rm $file
26354
26355         # 1M-hole file
26356         $LFS setstripe -E 1M -c2 -E eof $file
26357         $TRUNCATE $file 1048576
26358         printf "Seeking hole from 1000000 ... "
26359         offset=$(lseek_test -l 1000000 $file)
26360         echo $offset
26361         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26362         printf "Seeking data from 1000000 ... "
26363         lseek_test -d 1000000 $file && error "lseek should fail"
26364         rm $file
26365
26366         # full component followed by non-inited one
26367         $LFS setstripe -E 1M -c2 -E eof $file
26368         dd if=/dev/urandom of=$file bs=1M count=1
26369         printf "Seeking hole from 1000000 ... "
26370         offset=$(lseek_test -l 1000000 $file)
26371         echo $offset
26372         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26373         printf "Seeking hole from 1048576 ... "
26374         lseek_test -l 1048576 $file && error "lseek should fail"
26375         # init second component and truncate back
26376         echo "123" >> $file
26377         $TRUNCATE $file 1048576
26378         printf "Seeking hole from 1000000 ... "
26379         offset=$(lseek_test -l 1000000 $file)
26380         echo $offset
26381         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26382         printf "Seeking hole from 1048576 ... "
26383         lseek_test -l 1048576 $file && error "lseek should fail"
26384         # boundary checks for big values
26385         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
26386         offset=$(lseek_test -d 0 $file.10g)
26387         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
26388         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
26389         offset=$(lseek_test -d 0 $file.100g)
26390         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
26391         return 0
26392 }
26393 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
26394
26395 test_430c() {
26396         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26397                 skip "OST does not support SEEK_HOLE"
26398
26399         local file=$DIR/$tdir/$tfile
26400         local start
26401
26402         mkdir -p $DIR/$tdir
26403         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
26404
26405         # cp version 8.33+ prefers lseek over fiemap
26406         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
26407                 start=$SECONDS
26408                 time cp $file /dev/null
26409                 (( SECONDS - start < 5 )) ||
26410                         error "cp: too long runtime $((SECONDS - start))"
26411
26412         fi
26413         # tar version 1.29+ supports SEEK_HOLE/DATA
26414         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
26415                 start=$SECONDS
26416                 time tar cS $file - | cat > /dev/null
26417                 (( SECONDS - start < 5 )) ||
26418                         error "tar: too long runtime $((SECONDS - start))"
26419         fi
26420 }
26421 run_test 430c "lseek: external tools check"
26422
26423 test_431() { # LU-14187
26424         local file=$DIR/$tdir/$tfile
26425
26426         mkdir -p $DIR/$tdir
26427         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
26428         dd if=/dev/urandom of=$file bs=4k count=1
26429         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
26430         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
26431         #define OBD_FAIL_OST_RESTART_IO 0x251
26432         do_facet ost1 "$LCTL set_param fail_loc=0x251"
26433         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
26434         cp $file $file.0
26435         cancel_lru_locks
26436         sync_all_data
26437         echo 3 > /proc/sys/vm/drop_caches
26438         diff  $file $file.0 || error "data diff"
26439 }
26440 run_test 431 "Restart transaction for IO"
26441
26442 cleanup_test_432() {
26443         do_facet mgs $LCTL nodemap_activate 0
26444         wait_nm_sync active
26445 }
26446
26447 test_432() {
26448         local tmpdir=$TMP/dir432
26449
26450         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
26451                 skip "Need MDS version at least 2.14.52"
26452
26453         stack_trap cleanup_test_432 EXIT
26454         mkdir $DIR/$tdir
26455         mkdir $tmpdir
26456
26457         do_facet mgs $LCTL nodemap_activate 1
26458         wait_nm_sync active
26459         do_facet mgs $LCTL nodemap_modify --name default \
26460                 --property admin --value 1
26461         do_facet mgs $LCTL nodemap_modify --name default \
26462                 --property trusted --value 1
26463         cancel_lru_locks mdc
26464         wait_nm_sync default admin_nodemap
26465         wait_nm_sync default trusted_nodemap
26466
26467         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
26468                grep -ci "Operation not permitted") -ne 0 ]; then
26469                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
26470         fi
26471 }
26472 run_test 432 "mv dir from outside Lustre"
26473
26474 prep_801() {
26475         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
26476         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
26477                 skip "Need server version at least 2.9.55"
26478
26479         start_full_debug_logging
26480 }
26481
26482 post_801() {
26483         stop_full_debug_logging
26484 }
26485
26486 barrier_stat() {
26487         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26488                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26489                            awk '/The barrier for/ { print $7 }')
26490                 echo $st
26491         else
26492                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
26493                 echo \'$st\'
26494         fi
26495 }
26496
26497 barrier_expired() {
26498         local expired
26499
26500         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26501                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26502                           awk '/will be expired/ { print $7 }')
26503         else
26504                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
26505         fi
26506
26507         echo $expired
26508 }
26509
26510 test_801a() {
26511         prep_801
26512
26513         echo "Start barrier_freeze at: $(date)"
26514         #define OBD_FAIL_BARRIER_DELAY          0x2202
26515         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26516         # Do not reduce barrier time - See LU-11873
26517         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
26518
26519         sleep 2
26520         local b_status=$(barrier_stat)
26521         echo "Got barrier status at: $(date)"
26522         [ "$b_status" = "'freezing_p1'" ] ||
26523                 error "(1) unexpected barrier status $b_status"
26524
26525         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26526         wait
26527         b_status=$(barrier_stat)
26528         [ "$b_status" = "'frozen'" ] ||
26529                 error "(2) unexpected barrier status $b_status"
26530
26531         local expired=$(barrier_expired)
26532         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
26533         sleep $((expired + 3))
26534
26535         b_status=$(barrier_stat)
26536         [ "$b_status" = "'expired'" ] ||
26537                 error "(3) unexpected barrier status $b_status"
26538
26539         # Do not reduce barrier time - See LU-11873
26540         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
26541                 error "(4) fail to freeze barrier"
26542
26543         b_status=$(barrier_stat)
26544         [ "$b_status" = "'frozen'" ] ||
26545                 error "(5) unexpected barrier status $b_status"
26546
26547         echo "Start barrier_thaw at: $(date)"
26548         #define OBD_FAIL_BARRIER_DELAY          0x2202
26549         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26550         do_facet mgs $LCTL barrier_thaw $FSNAME &
26551
26552         sleep 2
26553         b_status=$(barrier_stat)
26554         echo "Got barrier status at: $(date)"
26555         [ "$b_status" = "'thawing'" ] ||
26556                 error "(6) unexpected barrier status $b_status"
26557
26558         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26559         wait
26560         b_status=$(barrier_stat)
26561         [ "$b_status" = "'thawed'" ] ||
26562                 error "(7) unexpected barrier status $b_status"
26563
26564         #define OBD_FAIL_BARRIER_FAILURE        0x2203
26565         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
26566         do_facet mgs $LCTL barrier_freeze $FSNAME
26567
26568         b_status=$(barrier_stat)
26569         [ "$b_status" = "'failed'" ] ||
26570                 error "(8) unexpected barrier status $b_status"
26571
26572         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
26573         do_facet mgs $LCTL barrier_thaw $FSNAME
26574
26575         post_801
26576 }
26577 run_test 801a "write barrier user interfaces and stat machine"
26578
26579 test_801b() {
26580         prep_801
26581
26582         mkdir $DIR/$tdir || error "(1) fail to mkdir"
26583         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
26584         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
26585         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
26586         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
26587
26588         cancel_lru_locks mdc
26589
26590         # 180 seconds should be long enough
26591         do_facet mgs $LCTL barrier_freeze $FSNAME 180
26592
26593         local b_status=$(barrier_stat)
26594         [ "$b_status" = "'frozen'" ] ||
26595                 error "(6) unexpected barrier status $b_status"
26596
26597         mkdir $DIR/$tdir/d0/d10 &
26598         mkdir_pid=$!
26599
26600         touch $DIR/$tdir/d1/f13 &
26601         touch_pid=$!
26602
26603         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
26604         ln_pid=$!
26605
26606         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
26607         mv_pid=$!
26608
26609         rm -f $DIR/$tdir/d4/f12 &
26610         rm_pid=$!
26611
26612         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
26613
26614         # To guarantee taht the 'stat' is not blocked
26615         b_status=$(barrier_stat)
26616         [ "$b_status" = "'frozen'" ] ||
26617                 error "(8) unexpected barrier status $b_status"
26618
26619         # let above commands to run at background
26620         sleep 5
26621
26622         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
26623         ps -p $touch_pid || error "(10) touch should be blocked"
26624         ps -p $ln_pid || error "(11) link should be blocked"
26625         ps -p $mv_pid || error "(12) rename should be blocked"
26626         ps -p $rm_pid || error "(13) unlink should be blocked"
26627
26628         b_status=$(barrier_stat)
26629         [ "$b_status" = "'frozen'" ] ||
26630                 error "(14) unexpected barrier status $b_status"
26631
26632         do_facet mgs $LCTL barrier_thaw $FSNAME
26633         b_status=$(barrier_stat)
26634         [ "$b_status" = "'thawed'" ] ||
26635                 error "(15) unexpected barrier status $b_status"
26636
26637         wait $mkdir_pid || error "(16) mkdir should succeed"
26638         wait $touch_pid || error "(17) touch should succeed"
26639         wait $ln_pid || error "(18) link should succeed"
26640         wait $mv_pid || error "(19) rename should succeed"
26641         wait $rm_pid || error "(20) unlink should succeed"
26642
26643         post_801
26644 }
26645 run_test 801b "modification will be blocked by write barrier"
26646
26647 test_801c() {
26648         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26649
26650         prep_801
26651
26652         stop mds2 || error "(1) Fail to stop mds2"
26653
26654         do_facet mgs $LCTL barrier_freeze $FSNAME 30
26655
26656         local b_status=$(barrier_stat)
26657         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
26658                 do_facet mgs $LCTL barrier_thaw $FSNAME
26659                 error "(2) unexpected barrier status $b_status"
26660         }
26661
26662         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26663                 error "(3) Fail to rescan barrier bitmap"
26664
26665         # Do not reduce barrier time - See LU-11873
26666         do_facet mgs $LCTL barrier_freeze $FSNAME 20
26667
26668         b_status=$(barrier_stat)
26669         [ "$b_status" = "'frozen'" ] ||
26670                 error "(4) unexpected barrier status $b_status"
26671
26672         do_facet mgs $LCTL barrier_thaw $FSNAME
26673         b_status=$(barrier_stat)
26674         [ "$b_status" = "'thawed'" ] ||
26675                 error "(5) unexpected barrier status $b_status"
26676
26677         local devname=$(mdsdevname 2)
26678
26679         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
26680
26681         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26682                 error "(7) Fail to rescan barrier bitmap"
26683
26684         post_801
26685 }
26686 run_test 801c "rescan barrier bitmap"
26687
26688 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
26689 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
26690 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
26691 saved_MOUNT_OPTS=$MOUNT_OPTS
26692
26693 cleanup_802a() {
26694         trap 0
26695
26696         stopall
26697         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
26698         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
26699         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
26700         MOUNT_OPTS=$saved_MOUNT_OPTS
26701         setupall
26702 }
26703
26704 test_802a() {
26705         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
26706         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
26707         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
26708                 skip "Need server version at least 2.9.55"
26709
26710         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
26711
26712         mkdir $DIR/$tdir || error "(1) fail to mkdir"
26713
26714         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
26715                 error "(2) Fail to copy"
26716
26717         trap cleanup_802a EXIT
26718
26719         # sync by force before remount as readonly
26720         sync; sync_all_data; sleep 3; sync_all_data
26721
26722         stopall
26723
26724         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
26725         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
26726         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
26727
26728         echo "Mount the server as read only"
26729         setupall server_only || error "(3) Fail to start servers"
26730
26731         echo "Mount client without ro should fail"
26732         mount_client $MOUNT &&
26733                 error "(4) Mount client without 'ro' should fail"
26734
26735         echo "Mount client with ro should succeed"
26736         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
26737         mount_client $MOUNT ||
26738                 error "(5) Mount client with 'ro' should succeed"
26739
26740         echo "Modify should be refused"
26741         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
26742
26743         echo "Read should be allowed"
26744         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
26745                 error "(7) Read should succeed under ro mode"
26746
26747         cleanup_802a
26748 }
26749 run_test 802a "simulate readonly device"
26750
26751 test_802b() {
26752         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26753         remote_mds_nodsh && skip "remote MDS with nodsh"
26754
26755         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
26756                 skip "readonly option not available"
26757
26758         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
26759
26760         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
26761                 error "(2) Fail to copy"
26762
26763         # write back all cached data before setting MDT to readonly
26764         cancel_lru_locks
26765         sync_all_data
26766
26767         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
26768         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
26769
26770         echo "Modify should be refused"
26771         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
26772
26773         echo "Read should be allowed"
26774         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
26775                 error "(7) Read should succeed under ro mode"
26776
26777         # disable readonly
26778         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
26779 }
26780 run_test 802b "be able to set MDTs to readonly"
26781
26782 test_803a() {
26783         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26784         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
26785                 skip "MDS needs to be newer than 2.10.54"
26786
26787         mkdir_on_mdt0 $DIR/$tdir
26788         # Create some objects on all MDTs to trigger related logs objects
26789         for idx in $(seq $MDSCOUNT); do
26790                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
26791                         $DIR/$tdir/dir${idx} ||
26792                         error "Fail to create $DIR/$tdir/dir${idx}"
26793         done
26794
26795         sync; sleep 3
26796         wait_delete_completed # ensure old test cleanups are finished
26797         echo "before create:"
26798         $LFS df -i $MOUNT
26799         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26800
26801         for i in {1..10}; do
26802                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
26803                         error "Fail to create $DIR/$tdir/foo$i"
26804         done
26805
26806         sync; sleep 3
26807         echo "after create:"
26808         $LFS df -i $MOUNT
26809         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26810
26811         # allow for an llog to be cleaned up during the test
26812         [ $after_used -ge $((before_used + 10 - 1)) ] ||
26813                 error "before ($before_used) + 10 > after ($after_used)"
26814
26815         for i in {1..10}; do
26816                 rm -rf $DIR/$tdir/foo$i ||
26817                         error "Fail to remove $DIR/$tdir/foo$i"
26818         done
26819
26820         sleep 3 # avoid MDT return cached statfs
26821         wait_delete_completed
26822         echo "after unlink:"
26823         $LFS df -i $MOUNT
26824         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26825
26826         # allow for an llog to be created during the test
26827         [ $after_used -le $((before_used + 1)) ] ||
26828                 error "after ($after_used) > before ($before_used) + 1"
26829 }
26830 run_test 803a "verify agent object for remote object"
26831
26832 test_803b() {
26833         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26834         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
26835                 skip "MDS needs to be newer than 2.13.56"
26836         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26837
26838         for i in $(seq 0 $((MDSCOUNT - 1))); do
26839                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
26840         done
26841
26842         local before=0
26843         local after=0
26844
26845         local tmp
26846
26847         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
26848         for i in $(seq 0 $((MDSCOUNT - 1))); do
26849                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
26850                         awk '/getattr/ { print $2 }')
26851                 before=$((before + tmp))
26852         done
26853         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
26854         for i in $(seq 0 $((MDSCOUNT - 1))); do
26855                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
26856                         awk '/getattr/ { print $2 }')
26857                 after=$((after + tmp))
26858         done
26859
26860         [ $before -eq $after ] || error "getattr count $before != $after"
26861 }
26862 run_test 803b "remote object can getattr from cache"
26863
26864 test_804() {
26865         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26866         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
26867                 skip "MDS needs to be newer than 2.10.54"
26868         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
26869
26870         mkdir -p $DIR/$tdir
26871         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
26872                 error "Fail to create $DIR/$tdir/dir0"
26873
26874         local fid=$($LFS path2fid $DIR/$tdir/dir0)
26875         local dev=$(mdsdevname 2)
26876
26877         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26878                 grep ${fid} || error "NOT found agent entry for dir0"
26879
26880         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
26881                 error "Fail to create $DIR/$tdir/dir1"
26882
26883         touch $DIR/$tdir/dir1/foo0 ||
26884                 error "Fail to create $DIR/$tdir/dir1/foo0"
26885         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
26886         local rc=0
26887
26888         for idx in $(seq $MDSCOUNT); do
26889                 dev=$(mdsdevname $idx)
26890                 do_facet mds${idx} \
26891                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26892                         grep ${fid} && rc=$idx
26893         done
26894
26895         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
26896                 error "Fail to rename foo0 to foo1"
26897         if [ $rc -eq 0 ]; then
26898                 for idx in $(seq $MDSCOUNT); do
26899                         dev=$(mdsdevname $idx)
26900                         do_facet mds${idx} \
26901                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26902                         grep ${fid} && rc=$idx
26903                 done
26904         fi
26905
26906         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
26907                 error "Fail to rename foo1 to foo2"
26908         if [ $rc -eq 0 ]; then
26909                 for idx in $(seq $MDSCOUNT); do
26910                         dev=$(mdsdevname $idx)
26911                         do_facet mds${idx} \
26912                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26913                         grep ${fid} && rc=$idx
26914                 done
26915         fi
26916
26917         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
26918
26919         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
26920                 error "Fail to link to $DIR/$tdir/dir1/foo2"
26921         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
26922                 error "Fail to rename foo2 to foo0"
26923         unlink $DIR/$tdir/dir1/foo0 ||
26924                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
26925         rm -rf $DIR/$tdir/dir0 ||
26926                 error "Fail to rm $DIR/$tdir/dir0"
26927
26928         for idx in $(seq $MDSCOUNT); do
26929                 dev=$(mdsdevname $idx)
26930                 rc=0
26931
26932                 stop mds${idx}
26933                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
26934                         rc=$?
26935                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
26936                         error "mount mds$idx failed"
26937                 df $MOUNT > /dev/null 2>&1
26938
26939                 # e2fsck should not return error
26940                 [ $rc -eq 0 ] ||
26941                         error "e2fsck detected error on MDT${idx}: rc=$rc"
26942         done
26943 }
26944 run_test 804 "verify agent entry for remote entry"
26945
26946 cleanup_805() {
26947         do_facet $SINGLEMDS zfs set quota=$old $fsset
26948         unlinkmany $DIR/$tdir/f- 1000000
26949         trap 0
26950 }
26951
26952 test_805() {
26953         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
26954         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
26955         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
26956                 skip "netfree not implemented before 0.7"
26957         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
26958                 skip "Need MDS version at least 2.10.57"
26959
26960         local fsset
26961         local freekb
26962         local usedkb
26963         local old
26964         local quota
26965         local pref="osd-zfs.$FSNAME-MDT0000."
26966
26967         # limit available space on MDS dataset to meet nospace issue
26968         # quickly. then ZFS 0.7.2 can use reserved space if asked
26969         # properly (using netfree flag in osd_declare_destroy()
26970         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
26971         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
26972                 gawk '{print $3}')
26973         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
26974         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
26975         let "usedkb=usedkb-freekb"
26976         let "freekb=freekb/2"
26977         if let "freekb > 5000"; then
26978                 let "freekb=5000"
26979         fi
26980         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
26981         trap cleanup_805 EXIT
26982         mkdir_on_mdt0 $DIR/$tdir
26983         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
26984                 error "Can't set PFL layout"
26985         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
26986         rm -rf $DIR/$tdir || error "not able to remove"
26987         do_facet $SINGLEMDS zfs set quota=$old $fsset
26988         trap 0
26989 }
26990 run_test 805 "ZFS can remove from full fs"
26991
26992 # Size-on-MDS test
26993 check_lsom_data()
26994 {
26995         local file=$1
26996         local expect=$(stat -c %s $file)
26997
26998         check_lsom_size $1 $expect
26999
27000         local blocks=$($LFS getsom -b $file)
27001         expect=$(stat -c %b $file)
27002         [[ $blocks == $expect ]] ||
27003                 error "$file expected blocks: $expect, got: $blocks"
27004 }
27005
27006 check_lsom_size()
27007 {
27008         local size
27009         local expect=$2
27010
27011         cancel_lru_locks mdc
27012
27013         size=$($LFS getsom -s $1)
27014         [[ $size == $expect ]] ||
27015                 error "$file expected size: $expect, got: $size"
27016 }
27017
27018 test_806() {
27019         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27020                 skip "Need MDS version at least 2.11.52"
27021
27022         local bs=1048576
27023
27024         touch $DIR/$tfile || error "touch $tfile failed"
27025
27026         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27027         save_lustre_params client "llite.*.xattr_cache" > $save
27028         lctl set_param llite.*.xattr_cache=0
27029         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27030
27031         # single-threaded write
27032         echo "Test SOM for single-threaded write"
27033         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
27034                 error "write $tfile failed"
27035         check_lsom_size $DIR/$tfile $bs
27036
27037         local num=32
27038         local size=$(($num * $bs))
27039         local offset=0
27040         local i
27041
27042         echo "Test SOM for single client multi-threaded($num) write"
27043         $TRUNCATE $DIR/$tfile 0
27044         for ((i = 0; i < $num; i++)); do
27045                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27046                 local pids[$i]=$!
27047                 offset=$((offset + $bs))
27048         done
27049         for (( i=0; i < $num; i++ )); do
27050                 wait ${pids[$i]}
27051         done
27052         check_lsom_size $DIR/$tfile $size
27053
27054         $TRUNCATE $DIR/$tfile 0
27055         for ((i = 0; i < $num; i++)); do
27056                 offset=$((offset - $bs))
27057                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27058                 local pids[$i]=$!
27059         done
27060         for (( i=0; i < $num; i++ )); do
27061                 wait ${pids[$i]}
27062         done
27063         check_lsom_size $DIR/$tfile $size
27064
27065         # multi-client writes
27066         num=$(get_node_count ${CLIENTS//,/ })
27067         size=$(($num * $bs))
27068         offset=0
27069         i=0
27070
27071         echo "Test SOM for multi-client ($num) writes"
27072         $TRUNCATE $DIR/$tfile 0
27073         for client in ${CLIENTS//,/ }; do
27074                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27075                 local pids[$i]=$!
27076                 i=$((i + 1))
27077                 offset=$((offset + $bs))
27078         done
27079         for (( i=0; i < $num; i++ )); do
27080                 wait ${pids[$i]}
27081         done
27082         check_lsom_size $DIR/$tfile $offset
27083
27084         i=0
27085         $TRUNCATE $DIR/$tfile 0
27086         for client in ${CLIENTS//,/ }; do
27087                 offset=$((offset - $bs))
27088                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27089                 local pids[$i]=$!
27090                 i=$((i + 1))
27091         done
27092         for (( i=0; i < $num; i++ )); do
27093                 wait ${pids[$i]}
27094         done
27095         check_lsom_size $DIR/$tfile $size
27096
27097         # verify truncate
27098         echo "Test SOM for truncate"
27099         $TRUNCATE $DIR/$tfile 1048576
27100         check_lsom_size $DIR/$tfile 1048576
27101         $TRUNCATE $DIR/$tfile 1234
27102         check_lsom_size $DIR/$tfile 1234
27103
27104         # verify SOM blocks count
27105         echo "Verify SOM block count"
27106         $TRUNCATE $DIR/$tfile 0
27107         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
27108                 error "failed to write file $tfile"
27109         check_lsom_data $DIR/$tfile
27110 }
27111 run_test 806 "Verify Lazy Size on MDS"
27112
27113 test_807() {
27114         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27115         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27116                 skip "Need MDS version at least 2.11.52"
27117
27118         # Registration step
27119         changelog_register || error "changelog_register failed"
27120         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
27121         changelog_users $SINGLEMDS | grep -q $cl_user ||
27122                 error "User $cl_user not found in changelog_users"
27123
27124         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27125         save_lustre_params client "llite.*.xattr_cache" > $save
27126         lctl set_param llite.*.xattr_cache=0
27127         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27128
27129         rm -rf $DIR/$tdir || error "rm $tdir failed"
27130         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27131         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
27132         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
27133         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
27134                 error "truncate $tdir/trunc failed"
27135
27136         local bs=1048576
27137         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
27138                 error "write $tfile failed"
27139
27140         # multi-client wirtes
27141         local num=$(get_node_count ${CLIENTS//,/ })
27142         local offset=0
27143         local i=0
27144
27145         echo "Test SOM for multi-client ($num) writes"
27146         touch $DIR/$tfile || error "touch $tfile failed"
27147         $TRUNCATE $DIR/$tfile 0
27148         for client in ${CLIENTS//,/ }; do
27149                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27150                 local pids[$i]=$!
27151                 i=$((i + 1))
27152                 offset=$((offset + $bs))
27153         done
27154         for (( i=0; i < $num; i++ )); do
27155                 wait ${pids[$i]}
27156         done
27157
27158         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
27159         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
27160         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
27161         check_lsom_data $DIR/$tdir/trunc
27162         check_lsom_data $DIR/$tdir/single_dd
27163         check_lsom_data $DIR/$tfile
27164
27165         rm -rf $DIR/$tdir
27166         # Deregistration step
27167         changelog_deregister || error "changelog_deregister failed"
27168 }
27169 run_test 807 "verify LSOM syncing tool"
27170
27171 check_som_nologged()
27172 {
27173         local lines=$($LFS changelog $FSNAME-MDT0000 |
27174                 grep 'x=trusted.som' | wc -l)
27175         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
27176 }
27177
27178 test_808() {
27179         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27180                 skip "Need MDS version at least 2.11.55"
27181
27182         # Registration step
27183         changelog_register || error "changelog_register failed"
27184
27185         touch $DIR/$tfile || error "touch $tfile failed"
27186         check_som_nologged
27187
27188         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
27189                 error "write $tfile failed"
27190         check_som_nologged
27191
27192         $TRUNCATE $DIR/$tfile 1234
27193         check_som_nologged
27194
27195         $TRUNCATE $DIR/$tfile 1048576
27196         check_som_nologged
27197
27198         # Deregistration step
27199         changelog_deregister || error "changelog_deregister failed"
27200 }
27201 run_test 808 "Check trusted.som xattr not logged in Changelogs"
27202
27203 check_som_nodata()
27204 {
27205         $LFS getsom $1
27206         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
27207 }
27208
27209 test_809() {
27210         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
27211                 skip "Need MDS version at least 2.11.56"
27212
27213         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
27214                 error "failed to create DoM-only file $DIR/$tfile"
27215         touch $DIR/$tfile || error "touch $tfile failed"
27216         check_som_nodata $DIR/$tfile
27217
27218         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
27219                 error "write $tfile failed"
27220         check_som_nodata $DIR/$tfile
27221
27222         $TRUNCATE $DIR/$tfile 1234
27223         check_som_nodata $DIR/$tfile
27224
27225         $TRUNCATE $DIR/$tfile 4097
27226         check_som_nodata $DIR/$file
27227 }
27228 run_test 809 "Verify no SOM xattr store for DoM-only files"
27229
27230 test_810() {
27231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27232         $GSS && skip_env "could not run with gss"
27233         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
27234                 skip "OST < 2.12.58 doesn't align checksum"
27235
27236         set_checksums 1
27237         stack_trap "set_checksums $ORIG_CSUM" EXIT
27238         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
27239
27240         local csum
27241         local before
27242         local after
27243         for csum in $CKSUM_TYPES; do
27244                 #define OBD_FAIL_OSC_NO_GRANT   0x411
27245                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
27246                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
27247                         eval set -- $i
27248                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
27249                         before=$(md5sum $DIR/$tfile)
27250                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
27251                         after=$(md5sum $DIR/$tfile)
27252                         [ "$before" == "$after" ] ||
27253                                 error "$csum: $before != $after bs=$1 seek=$2"
27254                 done
27255         done
27256 }
27257 run_test 810 "partial page writes on ZFS (LU-11663)"
27258
27259 test_812a() {
27260         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27261                 skip "OST < 2.12.51 doesn't support this fail_loc"
27262
27263         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27264         # ensure ost1 is connected
27265         stat $DIR/$tfile >/dev/null || error "can't stat"
27266         wait_osc_import_state client ost1 FULL
27267         # no locks, no reqs to let the connection idle
27268         cancel_lru_locks osc
27269
27270         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27271 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27272         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27273         wait_osc_import_state client ost1 CONNECTING
27274         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27275
27276         stat $DIR/$tfile >/dev/null || error "can't stat file"
27277 }
27278 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
27279
27280 test_812b() { # LU-12378
27281         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27282                 skip "OST < 2.12.51 doesn't support this fail_loc"
27283
27284         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
27285         # ensure ost1 is connected
27286         stat $DIR/$tfile >/dev/null || error "can't stat"
27287         wait_osc_import_state client ost1 FULL
27288         # no locks, no reqs to let the connection idle
27289         cancel_lru_locks osc
27290
27291         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27292 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27293         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27294         wait_osc_import_state client ost1 CONNECTING
27295         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27296
27297         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
27298         wait_osc_import_state client ost1 IDLE
27299 }
27300 run_test 812b "do not drop no resend request for idle connect"
27301
27302 test_812c() {
27303         local old
27304
27305         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
27306
27307         $LFS setstripe -c 1 -o 0 $DIR/$tfile
27308         $LFS getstripe $DIR/$tfile
27309         $LCTL set_param osc.*.idle_timeout=10
27310         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
27311         # ensure ost1 is connected
27312         stat $DIR/$tfile >/dev/null || error "can't stat"
27313         wait_osc_import_state client ost1 FULL
27314         # no locks, no reqs to let the connection idle
27315         cancel_lru_locks osc
27316
27317 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
27318         $LCTL set_param fail_loc=0x80000533
27319         sleep 15
27320         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
27321 }
27322 run_test 812c "idle import vs lock enqueue race"
27323
27324 test_813() {
27325         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
27326         [ -z "$file_heat_sav" ] && skip "no file heat support"
27327
27328         local readsample
27329         local writesample
27330         local readbyte
27331         local writebyte
27332         local readsample1
27333         local writesample1
27334         local readbyte1
27335         local writebyte1
27336
27337         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
27338         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
27339
27340         $LCTL set_param -n llite.*.file_heat=1
27341         echo "Turn on file heat"
27342         echo "Period second: $period_second, Decay percentage: $decay_pct"
27343
27344         echo "QQQQ" > $DIR/$tfile
27345         echo "QQQQ" > $DIR/$tfile
27346         echo "QQQQ" > $DIR/$tfile
27347         cat $DIR/$tfile > /dev/null
27348         cat $DIR/$tfile > /dev/null
27349         cat $DIR/$tfile > /dev/null
27350         cat $DIR/$tfile > /dev/null
27351
27352         local out=$($LFS heat_get $DIR/$tfile)
27353
27354         $LFS heat_get $DIR/$tfile
27355         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27356         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27357         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27358         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27359
27360         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
27361         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
27362         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
27363         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
27364
27365         sleep $((period_second + 3))
27366         echo "Sleep $((period_second + 3)) seconds..."
27367         # The recursion formula to calculate the heat of the file f is as
27368         # follow:
27369         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
27370         # Where Hi is the heat value in the period between time points i*I and
27371         # (i+1)*I; Ci is the access count in the period; the symbol P refers
27372         # to the weight of Ci.
27373         out=$($LFS heat_get $DIR/$tfile)
27374         $LFS heat_get $DIR/$tfile
27375         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27376         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27377         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27378         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27379
27380         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
27381                 error "read sample ($readsample) is wrong"
27382         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
27383                 error "write sample ($writesample) is wrong"
27384         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
27385                 error "read bytes ($readbyte) is wrong"
27386         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
27387                 error "write bytes ($writebyte) is wrong"
27388
27389         echo "QQQQ" > $DIR/$tfile
27390         echo "QQQQ" > $DIR/$tfile
27391         echo "QQQQ" > $DIR/$tfile
27392         cat $DIR/$tfile > /dev/null
27393         cat $DIR/$tfile > /dev/null
27394         cat $DIR/$tfile > /dev/null
27395         cat $DIR/$tfile > /dev/null
27396
27397         sleep $((period_second + 3))
27398         echo "Sleep $((period_second + 3)) seconds..."
27399
27400         out=$($LFS heat_get $DIR/$tfile)
27401         $LFS heat_get $DIR/$tfile
27402         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27403         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27404         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27405         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27406
27407         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
27408                 4 * $decay_pct) / 100") -eq 1 ] ||
27409                 error "read sample ($readsample1) is wrong"
27410         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
27411                 3 * $decay_pct) / 100") -eq 1 ] ||
27412                 error "write sample ($writesample1) is wrong"
27413         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
27414                 20 * $decay_pct) / 100") -eq 1 ] ||
27415                 error "read bytes ($readbyte1) is wrong"
27416         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
27417                 15 * $decay_pct) / 100") -eq 1 ] ||
27418                 error "write bytes ($writebyte1) is wrong"
27419
27420         echo "Turn off file heat for the file $DIR/$tfile"
27421         $LFS heat_set -o $DIR/$tfile
27422
27423         echo "QQQQ" > $DIR/$tfile
27424         echo "QQQQ" > $DIR/$tfile
27425         echo "QQQQ" > $DIR/$tfile
27426         cat $DIR/$tfile > /dev/null
27427         cat $DIR/$tfile > /dev/null
27428         cat $DIR/$tfile > /dev/null
27429         cat $DIR/$tfile > /dev/null
27430
27431         out=$($LFS heat_get $DIR/$tfile)
27432         $LFS heat_get $DIR/$tfile
27433         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27434         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27435         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27436         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27437
27438         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27439         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27440         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27441         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27442
27443         echo "Trun on file heat for the file $DIR/$tfile"
27444         $LFS heat_set -O $DIR/$tfile
27445
27446         echo "QQQQ" > $DIR/$tfile
27447         echo "QQQQ" > $DIR/$tfile
27448         echo "QQQQ" > $DIR/$tfile
27449         cat $DIR/$tfile > /dev/null
27450         cat $DIR/$tfile > /dev/null
27451         cat $DIR/$tfile > /dev/null
27452         cat $DIR/$tfile > /dev/null
27453
27454         out=$($LFS heat_get $DIR/$tfile)
27455         $LFS heat_get $DIR/$tfile
27456         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27457         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27458         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27459         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27460
27461         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
27462         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
27463         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
27464         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
27465
27466         $LFS heat_set -c $DIR/$tfile
27467         $LCTL set_param -n llite.*.file_heat=0
27468         echo "Turn off file heat support for the Lustre filesystem"
27469
27470         echo "QQQQ" > $DIR/$tfile
27471         echo "QQQQ" > $DIR/$tfile
27472         echo "QQQQ" > $DIR/$tfile
27473         cat $DIR/$tfile > /dev/null
27474         cat $DIR/$tfile > /dev/null
27475         cat $DIR/$tfile > /dev/null
27476         cat $DIR/$tfile > /dev/null
27477
27478         out=$($LFS heat_get $DIR/$tfile)
27479         $LFS heat_get $DIR/$tfile
27480         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27481         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27482         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27483         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27484
27485         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27486         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27487         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27488         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27489
27490         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
27491         rm -f $DIR/$tfile
27492 }
27493 run_test 813 "File heat verfication"
27494
27495 test_814()
27496 {
27497         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
27498         echo -n y >> $DIR/$tfile
27499         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
27500         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
27501 }
27502 run_test 814 "sparse cp works as expected (LU-12361)"
27503
27504 test_815()
27505 {
27506         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
27507         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
27508 }
27509 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
27510
27511 test_816() {
27512         local ost1_imp=$(get_osc_import_name client ost1)
27513         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27514                          cut -d'.' -f2)
27515
27516         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27517         # ensure ost1 is connected
27518
27519         stat $DIR/$tfile >/dev/null || error "can't stat"
27520         wait_osc_import_state client ost1 FULL
27521         # no locks, no reqs to let the connection idle
27522         cancel_lru_locks osc
27523         lru_resize_disable osc
27524         local before
27525         local now
27526         before=$($LCTL get_param -n \
27527                  ldlm.namespaces.$imp_name.lru_size)
27528
27529         wait_osc_import_state client ost1 IDLE
27530         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
27531         now=$($LCTL get_param -n \
27532               ldlm.namespaces.$imp_name.lru_size)
27533         [ $before == $now ] || error "lru_size changed $before != $now"
27534 }
27535 run_test 816 "do not reset lru_resize on idle reconnect"
27536
27537 cleanup_817() {
27538         umount $tmpdir
27539         exportfs -u localhost:$DIR/nfsexp
27540         rm -rf $DIR/nfsexp
27541 }
27542
27543 test_817() {
27544         systemctl restart nfs-server.service || skip "failed to restart nfsd"
27545
27546         mkdir -p $DIR/nfsexp
27547         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
27548                 error "failed to export nfs"
27549
27550         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
27551         stack_trap cleanup_817 EXIT
27552
27553         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
27554                 error "failed to mount nfs to $tmpdir"
27555
27556         cp /bin/true $tmpdir
27557         $DIR/nfsexp/true || error "failed to execute 'true' command"
27558 }
27559 run_test 817 "nfsd won't cache write lock for exec file"
27560
27561 test_818() {
27562         mkdir $DIR/$tdir
27563         $LFS setstripe -c1 -i0 $DIR/$tfile
27564         $LFS setstripe -c1 -i1 $DIR/$tfile
27565         stop $SINGLEMDS
27566         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
27567         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
27568         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
27569                 error "start $SINGLEMDS failed"
27570         rm -rf $DIR/$tdir
27571 }
27572 run_test 818 "unlink with failed llog"
27573
27574 test_819a() {
27575         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27576         cancel_lru_locks osc
27577         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27578         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27579         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
27580         rm -f $TDIR/$tfile
27581 }
27582 run_test 819a "too big niobuf in read"
27583
27584 test_819b() {
27585         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27586         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27587         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27588         cancel_lru_locks osc
27589         sleep 1
27590         rm -f $TDIR/$tfile
27591 }
27592 run_test 819b "too big niobuf in write"
27593
27594
27595 function test_820_start_ost() {
27596         sleep 5
27597
27598         for num in $(seq $OSTCOUNT); do
27599                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
27600         done
27601 }
27602
27603 test_820() {
27604         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27605
27606         mkdir $DIR/$tdir
27607         umount_client $MOUNT || error "umount failed"
27608         for num in $(seq $OSTCOUNT); do
27609                 stop ost$num
27610         done
27611
27612         # mount client with no active OSTs
27613         # so that the client can't initialize max LOV EA size
27614         # from OSC notifications
27615         mount_client $MOUNT || error "mount failed"
27616         # delay OST starting to keep this 0 max EA size for a while
27617         test_820_start_ost &
27618
27619         # create a directory on MDS2
27620         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
27621                 error "Failed to create directory"
27622         # open intent should update default EA size
27623         # see mdc_update_max_ea_from_body()
27624         # notice this is the very first RPC to MDS2
27625         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
27626         ret=$?
27627         echo $out
27628         # With SSK, this situation can lead to -EPERM being returned.
27629         # In that case, simply retry.
27630         if [ $ret -ne 0 ] && $SHARED_KEY; then
27631                 if echo "$out" | grep -q "not permitted"; then
27632                         cp /etc/services $DIR/$tdir/mds2
27633                         ret=$?
27634                 fi
27635         fi
27636         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
27637 }
27638 run_test 820 "update max EA from open intent"
27639
27640 test_822() {
27641         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27642
27643         save_lustre_params mds1 \
27644                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
27645         do_facet $SINGLEMDS "$LCTL set_param -n \
27646                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
27647         do_facet $SINGLEMDS "$LCTL set_param -n \
27648                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
27649
27650         # wait for statfs update to clear OS_STATFS_NOPRECREATE
27651         local maxage=$(do_facet mds1 $LCTL get_param -n \
27652                        osp.$FSNAME-OST0000*MDT0000.maxage)
27653         sleep $((maxage + 1))
27654
27655         #define OBD_FAIL_NET_ERROR_RPC          0x532
27656         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
27657
27658         stack_trap "restore_lustre_params < $p; rm $p"
27659
27660         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
27661                       osp.$FSNAME-OST0000*MDT0000.create_count")
27662         for i in $(seq 1 $count); do
27663                 touch $DIR/$tfile.${i} || error "touch failed"
27664         done
27665 }
27666 run_test 822 "test precreate failure"
27667
27668 test_823() {
27669         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27670         local OST_MAX_PRECREATE=20000
27671
27672         save_lustre_params mds1 \
27673                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
27674         do_facet $SINGLEMDS "$LCTL set_param -n \
27675                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
27676         do_facet $SINGLEMDS "$LCTL set_param -n \
27677                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
27678
27679         stack_trap "restore_lustre_params < $p; rm $p"
27680
27681         do_facet $SINGLEMDS "$LCTL set_param -n \
27682                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
27683
27684         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27685                       osp.$FSNAME-OST0000*MDT0000.create_count")
27686         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27687                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
27688         local expect_count=$(((($max/2)/256) * 256))
27689
27690         log "setting create_count to 100200:"
27691         log " -result- count: $count with max: $max, expecting: $expect_count"
27692
27693         [[ $count -eq expect_count ]] ||
27694                 error "Create count not set to max precreate."
27695 }
27696 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
27697
27698 test_831() {
27699         local sync_changes=$(do_facet $SINGLEMDS \
27700                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
27701
27702         [ "$sync_changes" -gt 100 ] &&
27703                 skip "Sync changes $sync_changes > 100 already"
27704
27705         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27706
27707         $LFS mkdir -i 0 $DIR/$tdir
27708         $LFS setstripe -c 1 -i 0 $DIR/$tdir
27709
27710         save_lustre_params mds1 \
27711                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
27712         save_lustre_params mds1 \
27713                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
27714
27715         do_facet mds1 "$LCTL set_param -n \
27716                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
27717                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
27718         stack_trap "restore_lustre_params < $p" EXIT
27719
27720         createmany -o $DIR/$tdir/f- 1000
27721         unlinkmany $DIR/$tdir/f- 1000 &
27722         local UNLINK_PID=$!
27723
27724         while sleep 1; do
27725                 sync_changes=$(do_facet mds1 \
27726                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
27727                 # the check in the code is racy, fail the test
27728                 # if the value above the limit by 10.
27729                 [ $sync_changes -gt 110 ] && {
27730                         kill -2 $UNLINK_PID
27731                         wait
27732                         error "osp changes throttling failed, $sync_changes>110"
27733                 }
27734                 kill -0 $UNLINK_PID 2> /dev/null || break
27735         done
27736         wait
27737 }
27738 run_test 831 "throttling unlink/setattr queuing on OSP"
27739
27740 #
27741 # tests that do cleanup/setup should be run at the end
27742 #
27743
27744 test_900() {
27745         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27746         local ls
27747
27748         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
27749         $LCTL set_param fail_loc=0x903
27750
27751         cancel_lru_locks MGC
27752
27753         FAIL_ON_ERROR=true cleanup
27754         FAIL_ON_ERROR=true setup
27755 }
27756 run_test 900 "umount should not race with any mgc requeue thread"
27757
27758 # LUS-6253/LU-11185
27759 test_901() {
27760         local oldc
27761         local newc
27762         local olds
27763         local news
27764         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27765
27766         # some get_param have a bug to handle dot in param name
27767         cancel_lru_locks MGC
27768         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
27769         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
27770         umount_client $MOUNT || error "umount failed"
27771         mount_client $MOUNT || error "mount failed"
27772         cancel_lru_locks MGC
27773         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
27774         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
27775
27776         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
27777         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
27778
27779         return 0
27780 }
27781 run_test 901 "don't leak a mgc lock on client umount"
27782
27783 # LU-13377
27784 test_902() {
27785         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
27786                 skip "client does not have LU-13377 fix"
27787         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
27788         $LCTL set_param fail_loc=0x1415
27789         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27790         cancel_lru_locks osc
27791         rm -f $DIR/$tfile
27792 }
27793 run_test 902 "test short write doesn't hang lustre"
27794
27795 # LU-14711
27796 test_903() {
27797         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
27798         echo "blah" > $DIR/${tfile}-2
27799         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
27800         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
27801         $LCTL set_param fail_loc=0x417 fail_val=20
27802
27803         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
27804         sleep 1 # To start the destroy
27805         wait_destroy_complete 150 || error "Destroy taking too long"
27806         cat $DIR/$tfile > /dev/null || error "Evicted"
27807 }
27808 run_test 903 "Test long page discard does not cause evictions"
27809
27810 complete $SECONDS
27811 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
27812 check_and_cleanup_lustre
27813 if [ "$I_MOUNTED" != "yes" ]; then
27814         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
27815 fi
27816 exit_status