Whamcloud - gitweb
LU-17081 build: compatibility for 6.5 kernels
[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 SOCKETSERVER=${SOCKETSERVER:-socketserver}
23 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
24 MEMHOG=${MEMHOG:-memhog}
25 DIRECTIO=${DIRECTIO:-directio}
26 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
27 DEF_STRIPE_COUNT=-1
28 CHECK_GRANT=${CHECK_GRANT:-"yes"}
29 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
30
31 TRACE=${TRACE:-""}
32 LUSTRE=${LUSTRE:-$(dirname $0)/..}
33 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
34 . $LUSTRE/tests/test-framework.sh
35 init_test_env "$@"
36
37 init_logging
38
39 ALWAYS_EXCEPT="$SANITY_EXCEPT "
40 always_except LU-9693  42a 42c
41 always_except LU-6493  42b
42 always_except LU-16515 118c 118d
43 always_except LU-8411  407
44
45 if $SHARED_KEY; then
46         always_except LU-14181 64e 64f
47         always_except LU-17127 39o
48 fi
49
50 # skip the grant tests for ARM until they are fixed
51 if [[ $(uname -m) = aarch64 ]]; then
52         always_except LU-11671 45
53 fi
54
55 # skip nfs tests on kernels >= 4.12.0 until they are fixed
56 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
57         always_except LU-12661 817
58 fi
59 # skip cgroup tests on RHEL8.1 kernels until they are fixed
60 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
61       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
62         always_except LU-13063 411a
63 fi
64
65 # skip cgroup tests for kernels < v4.18.0
66 if (( $LINUX_VERSION_CODE < $(version_code 4.18.0) )); then
67         always_except LU-13063 411b
68 fi
69
70 #                                  5              12     8   12  15   (min)"
71 [[ "$SLOW" = "no" ]] && EXCEPT_SLOW="27m 60i 64b 68 71 135 136 230d 300o"
72
73 if [[ "$mds1_FSTYPE" == "zfs" ]]; then
74         #                                               13    (min)"
75         [[ "$SLOW" == "no" ]] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
76 fi
77
78 if [[ "$ost1_FSTYPE" = "zfs" ]]; then
79         always_except LU-1941 130b 130c 130d 130e 130f 130g
80         always_except LU-9054 312
81 fi
82
83 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
84
85 # Get the SLES distro version
86 #
87 # Returns a version string that should only be used in comparing
88 # strings returned by version_code()
89 sles_version_code()
90 {
91         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
92
93         # All SuSE Linux versions have one decimal. version_code expects two
94         local sles_version=$version.0
95         version_code $sles_version
96 }
97
98 # Check if we are running on Ubuntu or SLES so we can make decisions on
99 # what tests to run
100 if [ -r /etc/SuSE-release ] || [ -r /etc/SUSE-brand ]; then
101         sles_version=$(sles_version_code)
102         (( $sles_version >= $(version_code 11.4.0) )) ||
103                 always_except LU-4341 170
104
105         (( $sles_version >= $(version_code 12.0.0) )) ||
106                 always_except LU-3703 234
107 elif [ -r /etc/redhat-release ]; then
108         rhel_version=$(cat /etc/redhat-release |
109                 sed -e 's/^[^0-9.]*//g' | sed -e 's/[ ].*//')
110         if (( $(version_code $rhel_version) >= $(version_code 9.3.0) )); then
111                 # disable test_906 temporarily until rhel9.3 solves the
112                 # failure on fio io_uring I/O engine.
113                 always_except LU-17289 906
114         fi
115 elif [ -r /etc/os-release ]; then
116         if grep -qi ubuntu /etc/os-release; then
117                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
118                                                 -e 's/^VERSION=//p' \
119                                                 /etc/os-release |
120                                                 awk '{ print $1 }'))
121
122                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
123                         always_except LU-10366 410
124                 fi
125         fi
126 fi
127
128 build_test_filter
129 FAIL_ON_ERROR=false
130
131 cleanup() {
132         echo -n "cln.."
133         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
134         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
135 }
136 setup() {
137         echo -n "mnt.."
138         load_modules
139         setupall || exit 10
140         echo "done"
141 }
142
143 check_swap_layouts_support()
144 {
145         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
146                 skip "Does not support layout lock."
147 }
148
149 check_swap_layout_no_dom()
150 {
151         local FOLDER=$1
152         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
153         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
154 }
155
156 check_and_setup_lustre
157 DIR=${DIR:-$MOUNT}
158 assert_DIR
159
160 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
161
162 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
163 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
164 rm -rf $DIR/[Rdfs][0-9]*
165
166 # $RUNAS_ID may get set incorrectly somewhere else
167 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
168         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
169
170 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
171
172 if [ "${ONLY}" = "MOUNT" ] ; then
173         echo "Lustre is up, please go on"
174         exit
175 fi
176
177 echo "preparing for tests involving mounts"
178 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
179 touch $EXT2_DEV
180 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
181 echo # add a newline after mke2fs.
182
183 umask 077
184
185 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
186
187 # ensure all internal functions know we want full debug
188 export PTLDEBUG=all
189 lctl set_param debug=$PTLDEBUG 2> /dev/null || true
190
191 test_0a() {
192         touch $DIR/$tfile
193         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
194         rm $DIR/$tfile
195         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
196 }
197 run_test 0a "touch; rm ====================="
198
199 test_0b() {
200         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
201         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
202 }
203 run_test 0b "chmod 0755 $DIR ============================="
204
205 test_0c() {
206         $LCTL get_param mdc.*.import | grep "state: FULL" ||
207                 error "import not FULL"
208         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
209                 error "bad target"
210 }
211 run_test 0c "check import proc"
212
213 test_0d() { # LU-3397
214         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
215                 skip "proc exports not supported before 2.10.57"
216
217         local mgs_exp="mgs.MGS.exports"
218         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
219         local exp_client_nid
220         local exp_client_version
221         local exp_val
222         local imp_val
223         local temp_imp=$DIR/$tfile.import
224         local temp_exp=$DIR/$tfile.export
225
226         # save mgc import file to $temp_imp
227         $LCTL get_param mgc.*.import | tee $temp_imp
228         # Check if client uuid is found in MGS export
229         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
230                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
231                         $client_uuid ] &&
232                         break;
233         done
234         # save mgs export file to $temp_exp
235         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
236
237         # Compare the value of field "connect_flags"
238         imp_val=$(grep "connect_flags" $temp_imp)
239         exp_val=$(grep "connect_flags" $temp_exp)
240         [ "$exp_val" == "$imp_val" ] ||
241                 error "export flags '$exp_val' != import flags '$imp_val'"
242
243         # Compare client versions.  Only compare top-3 fields for compatibility
244         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
245         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
246         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
247         [ "$exp_val" == "$imp_val" ] ||
248                 error "exp version '$exp_client_version'($exp_val) != " \
249                         "'$(lustre_build_version client)'($imp_val)"
250 }
251 run_test 0d "check export proc ============================="
252
253 test_0e() { # LU-13417
254         (( $MDSCOUNT > 1 )) ||
255                 skip "We need at least 2 MDTs for this test"
256
257         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
258                 skip "Need server version at least 2.14.51"
259
260         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
261         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
262
263         [ $default_lmv_count -eq 1 ] ||
264                 error "$MOUNT default stripe count $default_lmv_count"
265
266         [ $default_lmv_index -eq -1 ] ||
267                 error "$MOUNT default stripe index $default_lmv_index"
268
269         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
270         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
271
272         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
273         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
274
275         [ $mdt_index1 -eq $mdt_index2 ] &&
276                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
277
278         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
279 }
280 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
281
282 test_0f() { # LU-17471
283         (( $MDS1_VERSION < $(version_code 2.17.53) )) ||
284                 skip "MDS >= 2.17.53 removes /proc/.../brw_stats symlink"
285         (( $MDS1_VERSION < $(version_code 2.14.55-100-g8a84c7f9c7) ||
286            $MDS1_VERSION > $(version_code 2.15.60-25) )) ||
287                 skip "MDS was missing /proc/.../brw_stats value"
288
289         local path="lustre/osd-$FSTYPE/$FSNAME-MDT0000/brw_stats"
290         local out_proc=$(do_facet mds1 grep snapshot_time /proc/fs/$path)
291
292         [[ -n "$out_proc" ]] || error "brw_stats /proc/fs/$path not found"
293 }
294 run_test 0f "Symlink to /sys/kernel/debug/*/*/brw_stats should work properly"
295
296 test_1() {
297         test_mkdir $DIR/$tdir
298         test_mkdir $DIR/$tdir/d2
299         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
300         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
301         rmdir $DIR/$tdir/d2
302         rmdir $DIR/$tdir
303         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
304 }
305 run_test 1 "mkdir; remkdir; rmdir"
306
307 test_2() {
308         test_mkdir $DIR/$tdir
309         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
310         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
311         rm -r $DIR/$tdir
312         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
313 }
314 run_test 2 "mkdir; touch; rmdir; check file"
315
316 test_3() {
317         test_mkdir $DIR/$tdir
318         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
319         touch $DIR/$tdir/$tfile
320         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
321         rm -r $DIR/$tdir
322         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
323 }
324 run_test 3 "mkdir; touch; rmdir; check dir"
325
326 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
327 test_4() {
328         test_mkdir -i 1 $DIR/$tdir
329
330         touch $DIR/$tdir/$tfile ||
331                 error "Create file under remote directory failed"
332
333         rmdir $DIR/$tdir &&
334                 error "Expect error removing in-use dir $DIR/$tdir"
335
336         test -d $DIR/$tdir || error "Remote directory disappeared"
337
338         rm -rf $DIR/$tdir || error "remove remote dir error"
339 }
340 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
341
342 test_5() {
343         test_mkdir $DIR/$tdir
344         test_mkdir $DIR/$tdir/d2
345         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
346         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
347         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
348 }
349 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
350
351 test_6a() {
352         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
353         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
354         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
355                 error "$tfile does not have perm 0666 or UID $UID"
356         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
357         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
358                 error "$tfile should be 0666 and owned by UID $UID"
359 }
360 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
361
362 test_6c() {
363         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
364
365         touch $DIR/$tfile
366         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
367         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
368                 error "$tfile should be owned by UID $RUNAS_ID"
369         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
370         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
371                 error "$tfile should be owned by UID $RUNAS_ID"
372 }
373 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
374
375 test_6e() {
376         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
377
378         touch $DIR/$tfile
379         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
380         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
381                 error "$tfile should be owned by GID $UID"
382         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
383         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
384                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
385 }
386 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
387
388 test_6g() {
389         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
390
391         test_mkdir $DIR/$tdir
392         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
393         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
394         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
395         test_mkdir $DIR/$tdir/d/subdir
396         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
397                 error "$tdir/d/subdir should be GID $RUNAS_GID"
398         if [[ $MDSCOUNT -gt 1 ]]; then
399                 # check remote dir sgid inherite
400                 $LFS mkdir -i 0 $DIR/$tdir.local ||
401                         error "mkdir $tdir.local failed"
402                 chmod g+s $DIR/$tdir.local ||
403                         error "chmod $tdir.local failed"
404                 chgrp $RUNAS_GID $DIR/$tdir.local ||
405                         error "chgrp $tdir.local failed"
406                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
407                         error "mkdir $tdir.remote failed"
408                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
409                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
410                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
411                         error "$tdir.remote should be mode 02755"
412         fi
413 }
414 run_test 6g "verify new dir in sgid dir inherits group"
415
416 test_6h() { # bug 7331
417         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
418
419         touch $DIR/$tfile || error "touch failed"
420         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
421         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
422                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
423         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
424                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
425 }
426 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
427
428 test_7a() {
429         test_mkdir $DIR/$tdir
430         $MCREATE $DIR/$tdir/$tfile
431         chmod 0666 $DIR/$tdir/$tfile
432         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
433                 error "$tdir/$tfile should be mode 0666"
434 }
435 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
436
437 test_7b() {
438         if [ ! -d $DIR/$tdir ]; then
439                 test_mkdir $DIR/$tdir
440         fi
441         $MCREATE $DIR/$tdir/$tfile
442         echo -n foo > $DIR/$tdir/$tfile
443         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
444         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
445 }
446 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
447
448 test_8() {
449         test_mkdir $DIR/$tdir
450         touch $DIR/$tdir/$tfile
451         chmod 0666 $DIR/$tdir/$tfile
452         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
453                 error "$tfile mode not 0666"
454 }
455 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
456
457 test_9() {
458         test_mkdir $DIR/$tdir
459         test_mkdir $DIR/$tdir/d2
460         test_mkdir $DIR/$tdir/d2/d3
461         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
462 }
463 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
464
465 test_10() {
466         test_mkdir $DIR/$tdir
467         test_mkdir $DIR/$tdir/d2
468         touch $DIR/$tdir/d2/$tfile
469         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
470                 error "$tdir/d2/$tfile not a file"
471 }
472 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
473
474 test_11() {
475         test_mkdir $DIR/$tdir
476         test_mkdir $DIR/$tdir/d2
477         chmod 0666 $DIR/$tdir/d2
478         chmod 0705 $DIR/$tdir/d2
479         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
480                 error "$tdir/d2 mode not 0705"
481 }
482 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
483
484 test_12() {
485         test_mkdir $DIR/$tdir
486         touch $DIR/$tdir/$tfile
487         chmod 0666 $DIR/$tdir/$tfile
488         chmod 0654 $DIR/$tdir/$tfile
489         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
490                 error "$tdir/d2 mode not 0654"
491 }
492 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
493
494 test_13() {
495         test_mkdir $DIR/$tdir
496         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
497         >  $DIR/$tdir/$tfile
498         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
499                 error "$tdir/$tfile size not 0 after truncate"
500 }
501 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
502
503 test_14() {
504         test_mkdir $DIR/$tdir
505         touch $DIR/$tdir/$tfile
506         rm $DIR/$tdir/$tfile
507         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
508 }
509 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
510
511 test_15() {
512         test_mkdir $DIR/$tdir
513         touch $DIR/$tdir/$tfile
514         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
515         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
516                 error "$tdir/${tfile_2} not a file after rename"
517         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
518 }
519 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
520
521 test_16() {
522         test_mkdir $DIR/$tdir
523         touch $DIR/$tdir/$tfile
524         rm -rf $DIR/$tdir/$tfile
525         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
526 }
527 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
528
529 test_17a() {
530         test_mkdir $DIR/$tdir
531         touch $DIR/$tdir/$tfile
532         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
533         ls -l $DIR/$tdir
534         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
535                 error "$tdir/l-exist not a symlink"
536         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
537                 error "$tdir/l-exist not referencing a file"
538         rm -f $DIR/$tdir/l-exist
539         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
540 }
541 run_test 17a "symlinks: create, remove (real)"
542
543 test_17b() {
544         test_mkdir $DIR/$tdir
545         ln -s no-such-file $DIR/$tdir/l-dangle
546         ls -l $DIR/$tdir
547         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
548                 error "$tdir/l-dangle not referencing no-such-file"
549         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
550                 error "$tdir/l-dangle not referencing non-existent file"
551         rm -f $DIR/$tdir/l-dangle
552         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
553 }
554 run_test 17b "symlinks: create, remove (dangling)"
555
556 test_17c() { # bug 3440 - don't save failed open RPC for replay
557         test_mkdir $DIR/$tdir
558         ln -s foo $DIR/$tdir/$tfile
559         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
560 }
561 run_test 17c "symlinks: open dangling (should return error)"
562
563 test_17d() {
564         test_mkdir $DIR/$tdir
565         ln -s foo $DIR/$tdir/$tfile
566         touch $DIR/$tdir/$tfile || error "creating to new symlink"
567 }
568 run_test 17d "symlinks: create dangling"
569
570 test_17e() {
571         test_mkdir $DIR/$tdir
572         local foo=$DIR/$tdir/$tfile
573         ln -s $foo $foo || error "create symlink failed"
574         ls -l $foo || error "ls -l failed"
575         ls $foo && error "ls not failed" || true
576 }
577 run_test 17e "symlinks: create recursive symlink (should return error)"
578
579 test_17f() {
580         test_mkdir $DIR/$tdir
581         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
582         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
583         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
584         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
585         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
586         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
587         ls -l  $DIR/$tdir
588 }
589 run_test 17f "symlinks: long and very long symlink name"
590
591 # str_repeat(S, N) generate a string that is string S repeated N times
592 str_repeat() {
593         local s=$1
594         local n=$2
595         local ret=''
596         while [ $((n -= 1)) -ge 0 ]; do
597                 ret=$ret$s
598         done
599         echo $ret
600 }
601
602 # Long symlinks and LU-2241
603 test_17g() {
604         test_mkdir $DIR/$tdir
605         local TESTS="59 60 61 4094 4095"
606
607         # Fix for inode size boundary in 2.1.4
608         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
609                 TESTS="4094 4095"
610
611         # Patch not applied to 2.2 or 2.3 branches
612         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
613         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
614                 TESTS="4094 4095"
615
616         for i in $TESTS; do
617                 local SYMNAME=$(str_repeat 'x' $i)
618                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
619                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
620         done
621 }
622 run_test 17g "symlinks: really long symlink name and inode boundaries"
623
624 test_17h() { #bug 17378
625         [ $PARALLEL == "yes" ] && skip "skip parallel run"
626         remote_mds_nodsh && skip "remote MDS with nodsh"
627
628         local mdt_idx
629
630         test_mkdir $DIR/$tdir
631         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
632         $LFS setstripe -c -1 $DIR/$tdir
633         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
634         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
635         touch $DIR/$tdir/$tfile || true
636 }
637 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
638
639 test_17i() { #bug 20018
640         [ $PARALLEL == "yes" ] && skip "skip parallel run"
641         remote_mds_nodsh && skip "remote MDS with nodsh"
642
643         local foo=$DIR/$tdir/$tfile
644         local mdt_idx
645
646         test_mkdir -c1 $DIR/$tdir
647         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
648         ln -s $foo $foo || error "create symlink failed"
649 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
650         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
651         ls -l $foo && error "error not detected"
652         return 0
653 }
654 run_test 17i "don't panic on short symlink (should return error)"
655
656 test_17k() { #bug 22301
657         [ $PARALLEL == "yes" ] && skip "skip parallel run"
658         [[ -z "$(which rsync 2>/dev/null)" ]] &&
659                 skip "no rsync command"
660         rsync --help | grep -q xattr ||
661                 skip_env "$(rsync --version | head -n1) does not support xattrs"
662         test_mkdir $DIR/$tdir
663         test_mkdir $DIR/$tdir.new
664         touch $DIR/$tdir/$tfile
665         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
666         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
667                 error "rsync failed with xattrs enabled"
668 }
669 run_test 17k "symlinks: rsync with xattrs enabled"
670
671 test_17l() { # LU-279
672         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
673                 skip "no getfattr command"
674
675         test_mkdir $DIR/$tdir
676         touch $DIR/$tdir/$tfile
677         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
678         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
679                 # -h to not follow symlinks. -m '' to list all the xattrs.
680                 # grep to remove first line: '# file: $path'.
681                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
682                 do
683                         lgetxattr_size_check $path $xattr ||
684                                 error "lgetxattr_size_check $path $xattr failed"
685                 done
686         done
687 }
688 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
689
690 # LU-1540
691 test_17m() {
692         [ $PARALLEL == "yes" ] && skip "skip parallel run"
693         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
694         remote_mds_nodsh && skip "remote MDS with nodsh"
695         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
696         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
697                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
698
699         local short_sym="0123456789"
700         local wdir=$DIR/$tdir
701         local i
702
703         test_mkdir $wdir
704         long_sym=$short_sym
705         # create a long symlink file
706         for ((i = 0; i < 4; ++i)); do
707                 long_sym=${long_sym}${long_sym}
708         done
709
710         echo "create 512 short and long symlink files under $wdir"
711         for ((i = 0; i < 256; ++i)); do
712                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
713                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
714         done
715
716         echo "erase them"
717         rm -f $wdir/*
718         sync
719         wait_delete_completed
720
721         echo "recreate the 512 symlink files with a shorter string"
722         for ((i = 0; i < 512; ++i)); do
723                 # rewrite the symlink file with a shorter string
724                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
725                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
726         done
727
728         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
729
730         echo "stop and checking mds${mds_index}:"
731         # e2fsck should not return error
732         stop mds${mds_index}
733         local devname=$(mdsdevname $mds_index)
734         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
735         rc=$?
736
737         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
738                 error "start mds${mds_index} failed"
739         df $MOUNT > /dev/null 2>&1
740         [ $rc -eq 0 ] ||
741                 error "e2fsck detected error for short/long symlink: rc=$rc"
742         rm -f $wdir/*
743 }
744 run_test 17m "run e2fsck against MDT which contains short/long symlink"
745
746 check_fs_consistency_17n() {
747         local mdt_index
748         local rc=0
749
750         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
751         # so it only check MDT1/MDT2 instead of all of MDTs.
752         for mdt_index in 1 2; do
753                 # e2fsck should not return error
754                 stop mds${mdt_index}
755                 local devname=$(mdsdevname $mdt_index)
756                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
757                         rc=$((rc + $?))
758
759                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
760                         error "mount mds$mdt_index failed"
761                 df $MOUNT > /dev/null 2>&1
762         done
763         return $rc
764 }
765
766 test_17n() {
767         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
768         [ $PARALLEL == "yes" ] && skip "skip parallel run"
769         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
770         remote_mds_nodsh && skip "remote MDS with nodsh"
771         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
772         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
773                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
774
775         local i
776
777         test_mkdir $DIR/$tdir
778         for ((i=0; i<10; i++)); do
779                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
780                         error "create remote dir error $i"
781                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
782                         error "create files under remote dir failed $i"
783         done
784
785         check_fs_consistency_17n ||
786                 error "e2fsck report error after create files under remote dir"
787
788         for ((i = 0; i < 10; i++)); do
789                 rm -rf $DIR/$tdir/remote_dir_${i} ||
790                         error "destroy remote dir error $i"
791         done
792
793         check_fs_consistency_17n ||
794                 error "e2fsck report error after unlink files under remote dir"
795
796         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
797                 skip "lustre < 2.4.50 does not support migrate mv"
798
799         for ((i = 0; i < 10; i++)); do
800                 mkdir -p $DIR/$tdir/remote_dir_${i}
801                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
802                         error "create files under remote dir failed $i"
803                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
804                         error "migrate remote dir error $i"
805         done
806         check_fs_consistency_17n || error "e2fsck report error after migration"
807
808         for ((i = 0; i < 10; i++)); do
809                 rm -rf $DIR/$tdir/remote_dir_${i} ||
810                         error "destroy remote dir error $i"
811         done
812
813         check_fs_consistency_17n || error "e2fsck report error after unlink"
814 }
815 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
816
817 test_17o() {
818         remote_mds_nodsh && skip "remote MDS with nodsh"
819         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
820                 skip "Need MDS version at least 2.3.64"
821
822         local wdir=$DIR/${tdir}o
823         local mdt_index
824         local rc=0
825
826         test_mkdir $wdir
827         touch $wdir/$tfile
828         mdt_index=$($LFS getstripe -m $wdir/$tfile)
829         mdt_index=$((mdt_index + 1))
830
831         cancel_lru_locks mdc
832         #fail mds will wait the failover finish then set
833         #following fail_loc to avoid interfer the recovery process.
834         fail mds${mdt_index}
835
836         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
837         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
838         ls -l $wdir/$tfile && rc=1
839         do_facet mds${mdt_index} lctl set_param fail_loc=0
840         [[ $rc -eq 0 ]] || error "stat file should fail"
841 }
842 run_test 17o "stat file with incompat LMA feature"
843
844 test_18() {
845         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
846         ls $DIR || error "Failed to ls $DIR: $?"
847 }
848 run_test 18 "touch .../f ; ls ... =============================="
849
850 test_19a() {
851         touch $DIR/$tfile
852         ls -l $DIR
853         rm $DIR/$tfile
854         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
855 }
856 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
857
858 test_19b() {
859         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
860 }
861 run_test 19b "ls -l .../f19 (should return error) =============="
862
863 test_19c() {
864         [ $RUNAS_ID -eq $UID ] &&
865                 skip_env "RUNAS_ID = UID = $UID -- skipping"
866
867         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
868 }
869 run_test 19c "$RUNAS touch .../f19 (should return error) =="
870
871 test_19d() {
872         cat $DIR/f19 && error || true
873 }
874 run_test 19d "cat .../f19 (should return error) =============="
875
876 test_20() {
877         touch $DIR/$tfile
878         rm $DIR/$tfile
879         touch $DIR/$tfile
880         rm $DIR/$tfile
881         touch $DIR/$tfile
882         rm $DIR/$tfile
883         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
884 }
885 run_test 20 "touch .../f ; ls -l ..."
886
887 test_21() {
888         test_mkdir $DIR/$tdir
889         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
890         ln -s dangle $DIR/$tdir/link
891         echo foo >> $DIR/$tdir/link
892         cat $DIR/$tdir/dangle
893         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
894         $CHECKSTAT -f -t file $DIR/$tdir/link ||
895                 error "$tdir/link not linked to a file"
896 }
897 run_test 21 "write to dangling link"
898
899 test_22() {
900         local wdir=$DIR/$tdir
901         test_mkdir $wdir
902         chown $RUNAS_ID:$RUNAS_GID $wdir
903         (cd $wdir || error "cd $wdir failed";
904                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
905                 $RUNAS tar xf -)
906         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
907         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
908         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
909                 error "checkstat -u failed"
910 }
911 run_test 22 "unpack tar archive as non-root user"
912
913 # was test_23
914 test_23a() {
915         test_mkdir $DIR/$tdir
916         local file=$DIR/$tdir/$tfile
917
918         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
919         openfile -f O_CREAT:O_EXCL $file &&
920                 error "$file recreate succeeded" || true
921 }
922 run_test 23a "O_CREAT|O_EXCL in subdir"
923
924 test_23b() { # bug 18988
925         test_mkdir $DIR/$tdir
926         local file=$DIR/$tdir/$tfile
927
928         rm -f $file
929         echo foo > $file || error "write filed"
930         echo bar >> $file || error "append filed"
931         $CHECKSTAT -s 8 $file || error "wrong size"
932         rm $file
933 }
934 run_test 23b "O_APPEND check"
935
936 # LU-9409, size with O_APPEND and tiny writes
937 test_23c() {
938         local file=$DIR/$tfile
939
940         # single dd
941         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
942         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
943         rm -f $file
944
945         # racing tiny writes
946         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
947         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
948         wait
949         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
950         rm -f $file
951
952         #racing tiny & normal writes
953         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
954         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
955         wait
956         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
957         rm -f $file
958
959         #racing tiny & normal writes 2, ugly numbers
960         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
961         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
962         wait
963         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
964         rm -f $file
965 }
966 run_test 23c "O_APPEND size checks for tiny writes"
967
968 # LU-11069 file offset is correct after appending writes
969 test_23d() {
970         local file=$DIR/$tfile
971         local offset
972
973         echo CentaurHauls > $file
974         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
975         if ((offset != 26)); then
976                 error "wrong offset, expected 26, got '$offset'"
977         fi
978 }
979 run_test 23d "file offset is correct after appending writes"
980
981 # rename sanity
982 test_24a() {
983         echo '-- same directory rename'
984         test_mkdir $DIR/$tdir
985         touch $DIR/$tdir/$tfile.1
986         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
987         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
988 }
989 run_test 24a "rename file to non-existent target"
990
991 test_24b() {
992         test_mkdir $DIR/$tdir
993         touch $DIR/$tdir/$tfile.{1,2}
994         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
995         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
996         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
997 }
998 run_test 24b "rename file to existing target"
999
1000 test_24c() {
1001         test_mkdir $DIR/$tdir
1002         test_mkdir $DIR/$tdir/d$testnum.1
1003         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
1004         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
1005         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
1006 }
1007 run_test 24c "rename directory to non-existent target"
1008
1009 test_24d() {
1010         test_mkdir -c1 $DIR/$tdir
1011         test_mkdir -c1 $DIR/$tdir/d$testnum.1
1012         test_mkdir -c1 $DIR/$tdir/d$testnum.2
1013         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
1014         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
1015         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
1016 }
1017 run_test 24d "rename directory to existing target"
1018
1019 test_24e() {
1020         echo '-- cross directory renames --'
1021         test_mkdir $DIR/R5a
1022         test_mkdir $DIR/R5b
1023         touch $DIR/R5a/f
1024         mv $DIR/R5a/f $DIR/R5b/g
1025         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
1026         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
1027 }
1028 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
1029
1030 test_24f() {
1031         test_mkdir $DIR/R6a
1032         test_mkdir $DIR/R6b
1033         touch $DIR/R6a/f $DIR/R6b/g
1034         mv $DIR/R6a/f $DIR/R6b/g
1035         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1036         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1037 }
1038 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1039
1040 test_24g() {
1041         test_mkdir $DIR/R7a
1042         test_mkdir $DIR/R7b
1043         test_mkdir $DIR/R7a/d
1044         mv $DIR/R7a/d $DIR/R7b/e
1045         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1046         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1047 }
1048 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1049
1050 test_24h() {
1051         test_mkdir -c1 $DIR/R8a
1052         test_mkdir -c1 $DIR/R8b
1053         test_mkdir -c1 $DIR/R8a/d
1054         test_mkdir -c1 $DIR/R8b/e
1055         mrename $DIR/R8a/d $DIR/R8b/e
1056         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1057         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1058 }
1059 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1060
1061 test_24i() {
1062         echo "-- rename error cases"
1063         test_mkdir $DIR/R9
1064         test_mkdir $DIR/R9/a
1065         touch $DIR/R9/f
1066         mrename $DIR/R9/f $DIR/R9/a
1067         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1068         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1069         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1070 }
1071 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1072
1073 test_24j() {
1074         test_mkdir $DIR/R10
1075         mrename $DIR/R10/f $DIR/R10/g
1076         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1077         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1078         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1079 }
1080 run_test 24j "source does not exist ============================"
1081
1082 test_24k() {
1083         test_mkdir $DIR/R11a
1084         test_mkdir $DIR/R11a/d
1085         touch $DIR/R11a/f
1086         mv $DIR/R11a/f $DIR/R11a/d
1087         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1088         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1089 }
1090 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1091
1092 # bug 2429 - rename foo foo foo creates invalid file
1093 test_24l() {
1094         f="$DIR/f24l"
1095         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1096 }
1097 run_test 24l "Renaming a file to itself ========================"
1098
1099 test_24m() {
1100         f="$DIR/f24m"
1101         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1102         # on ext3 this does not remove either the source or target files
1103         # though the "expected" operation would be to remove the source
1104         $CHECKSTAT -t file ${f} || error "${f} missing"
1105         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1106 }
1107 run_test 24m "Renaming a file to a hard link to itself ========="
1108
1109 test_24n() {
1110     f="$DIR/f24n"
1111     # this stats the old file after it was renamed, so it should fail
1112     touch ${f}
1113     $CHECKSTAT ${f} || error "${f} missing"
1114     mv ${f} ${f}.rename
1115     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1116     $CHECKSTAT -a ${f} || error "${f} exists"
1117 }
1118 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1119
1120 test_24o() {
1121         test_mkdir $DIR/$tdir
1122         rename_many -s random -v -n 10 $DIR/$tdir
1123 }
1124 run_test 24o "rename of files during htree split"
1125
1126 test_24p() {
1127         test_mkdir $DIR/R12a
1128         test_mkdir $DIR/R12b
1129         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1130         mrename $DIR/R12a $DIR/R12b
1131         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1132         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1133         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1134         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1135 }
1136 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1137
1138 cleanup_multiop_pause() {
1139         trap 0
1140         kill -USR1 $MULTIPID
1141 }
1142
1143 test_24q() {
1144         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1145
1146         test_mkdir $DIR/R13a
1147         test_mkdir $DIR/R13b
1148         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1149         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1150         MULTIPID=$!
1151
1152         trap cleanup_multiop_pause EXIT
1153         mrename $DIR/R13a $DIR/R13b
1154         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1155         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1156         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1157         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1158         cleanup_multiop_pause
1159         wait $MULTIPID || error "multiop close failed"
1160 }
1161 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1162
1163 test_24r() { #bug 3789
1164         test_mkdir $DIR/R14a
1165         test_mkdir $DIR/R14a/b
1166         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1167         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1168         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1169 }
1170 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1171
1172 test_24s() {
1173         test_mkdir $DIR/R15a
1174         test_mkdir $DIR/R15a/b
1175         test_mkdir $DIR/R15a/b/c
1176         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1177         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1178         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1179 }
1180 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1181
1182 test_24t() {
1183         test_mkdir $DIR/R16a
1184         test_mkdir $DIR/R16a/b
1185         test_mkdir $DIR/R16a/b/c
1186         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1187         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1188         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1189 }
1190 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1191
1192 test_24u() { # bug12192
1193         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1194         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1195 }
1196 run_test 24u "create stripe file"
1197
1198 simple_cleanup_common() {
1199         local createmany=$1
1200         local rc=0
1201
1202         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1203
1204         local start=$SECONDS
1205
1206         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1207         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1208         rc=$?
1209         wait_delete_completed
1210         echo "cleanup time $((SECONDS - start))"
1211         return $rc
1212 }
1213
1214 max_pages_per_rpc() {
1215         local mdtname="$(printf "MDT%04x" ${1:-0})"
1216         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1217 }
1218
1219 test_24v() {
1220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1221
1222         local nrfiles=${COUNT:-100000}
1223         local fname="$DIR/$tdir/$tfile"
1224
1225         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1226         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1227
1228         test_mkdir "$(dirname $fname)"
1229         # assume MDT0000 has the fewest inodes
1230         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1231         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1232         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1233
1234         stack_trap "simple_cleanup_common $nrfiles"
1235
1236         createmany -m "$fname" $nrfiles
1237
1238         cancel_lru_locks mdc
1239         lctl set_param mdc.*.stats clear
1240
1241         # was previously test_24D: LU-6101
1242         # readdir() returns correct number of entries after cursor reload
1243         local num_ls=$(ls $DIR/$tdir | wc -l)
1244         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1245         local num_all=$(ls -a $DIR/$tdir | wc -l)
1246         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1247                 [ $num_all -ne $((nrfiles + 2)) ]; then
1248                         error "Expected $nrfiles files, got $num_ls " \
1249                                 "($num_uniq unique $num_all .&..)"
1250         fi
1251         # LU-5 large readdir
1252         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1253         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1254         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1255         # take into account of overhead in lu_dirpage header and end mark in
1256         # each page, plus one in rpc_num calculation.
1257         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1258         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1259         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1260         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1261         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1262         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1263         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1264         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1265                 error "large readdir doesn't take effect: " \
1266                       "$mds_readpage should be about $rpc_max"
1267 }
1268 run_test 24v "list large directory (test hash collision, b=17560)"
1269
1270 test_24w() { # bug21506
1271         SZ1=234852
1272         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1273         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1274         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1275         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1276         [[ "$SZ1" -eq "$SZ2" ]] ||
1277                 error "Error reading at the end of the file $tfile"
1278 }
1279 run_test 24w "Reading a file larger than 4Gb"
1280
1281 test_24x() {
1282         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1283         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1284         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1285                 skip "Need MDS version at least 2.7.56"
1286
1287         local MDTIDX=1
1288         local remote_dir=$DIR/$tdir/remote_dir
1289
1290         test_mkdir $DIR/$tdir
1291         $LFS mkdir -i $MDTIDX $remote_dir ||
1292                 error "create remote directory failed"
1293
1294         test_mkdir $DIR/$tdir/src_dir
1295         touch $DIR/$tdir/src_file
1296         test_mkdir $remote_dir/tgt_dir
1297         touch $remote_dir/tgt_file
1298
1299         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1300                 error "rename dir cross MDT failed!"
1301
1302         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1303                 error "rename file cross MDT failed!"
1304
1305         touch $DIR/$tdir/ln_file
1306         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1307                 error "ln file cross MDT failed"
1308
1309         rm -rf $DIR/$tdir || error "Can not delete directories"
1310 }
1311 run_test 24x "cross MDT rename/link"
1312
1313 test_24y() {
1314         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1315         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1316
1317         local remote_dir=$DIR/$tdir/remote_dir
1318         local mdtidx=1
1319
1320         test_mkdir $DIR/$tdir
1321         $LFS mkdir -i $mdtidx $remote_dir ||
1322                 error "create remote directory failed"
1323
1324         test_mkdir $remote_dir/src_dir
1325         touch $remote_dir/src_file
1326         test_mkdir $remote_dir/tgt_dir
1327         touch $remote_dir/tgt_file
1328
1329         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1330                 error "rename subdir in the same remote dir failed!"
1331
1332         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1333                 error "rename files in the same remote dir failed!"
1334
1335         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1336                 error "link files in the same remote dir failed!"
1337
1338         rm -rf $DIR/$tdir || error "Can not delete directories"
1339 }
1340 run_test 24y "rename/link on the same dir should succeed"
1341
1342 test_24z() {
1343         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1344         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1345                 skip "Need MDS version at least 2.12.51"
1346
1347         local index
1348
1349         for index in 0 1; do
1350                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1351                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1352         done
1353
1354         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1355
1356         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1357         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1358
1359         local mdts=$(comma_list $(mdts_nodes))
1360
1361         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1362         stack_trap "do_nodes $mdts $LCTL \
1363                 set_param mdt.*.enable_remote_rename=1" EXIT
1364
1365         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1366
1367         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1368         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1369 }
1370 run_test 24z "cross-MDT rename is done as cp"
1371
1372 test_24A() { # LU-3182
1373         local NFILES=5000
1374
1375         test_mkdir $DIR/$tdir
1376         stack_trap "simple_cleanup_common $NFILES"
1377         createmany -m $DIR/$tdir/$tfile $NFILES
1378         local t=$(ls $DIR/$tdir | wc -l)
1379         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1380         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1381
1382         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1383                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1384 }
1385 run_test 24A "readdir() returns correct number of entries."
1386
1387 test_24B() { # LU-4805
1388         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1389
1390         local count
1391
1392         test_mkdir $DIR/$tdir
1393         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir/ ||
1394                 error "create striped dir failed"
1395
1396         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1397         [ $count -eq 2 ] || error "Expected 2, got $count"
1398
1399         touch $DIR/$tdir/striped_dir/a
1400
1401         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1402         [ $count -eq 3 ] || error "Expected 3, got $count"
1403
1404         touch $DIR/$tdir/striped_dir/.f
1405
1406         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1407         [ $count -eq 4 ] || error "Expected 4, got $count"
1408
1409         rm -rf $DIR/$tdir || error "Can not delete directories"
1410 }
1411 run_test 24B "readdir for striped dir return correct number of entries"
1412
1413 test_24C() {
1414         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1415
1416         mkdir $DIR/$tdir
1417         mkdir $DIR/$tdir/d0
1418         mkdir $DIR/$tdir/d1
1419
1420         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1421                 error "create striped dir failed"
1422
1423         cd $DIR/$tdir/d0/striped_dir
1424
1425         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1426         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1427         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1428
1429         [ "$d0_ino" = "$parent_ino" ] ||
1430                 error ".. wrong, expect $d0_ino, get $parent_ino"
1431
1432         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1433                 error "mv striped dir failed"
1434
1435         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1436
1437         [ "$d1_ino" = "$parent_ino" ] ||
1438                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1439 }
1440 run_test 24C "check .. in striped dir"
1441
1442 test_24E() {
1443         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1444         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1445
1446         mkdir -p $DIR/$tdir
1447         mkdir $DIR/$tdir/src_dir
1448         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1449                 error "create remote source failed"
1450
1451         touch $DIR/$tdir/src_dir/src_child/a
1452
1453         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1454                 error "create remote target dir failed"
1455
1456         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1457                 error "create remote target child failed"
1458
1459         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1460                 error "rename dir cross MDT failed!"
1461
1462         find $DIR/$tdir
1463
1464         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1465                 error "src_child still exists after rename"
1466
1467         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1468                 error "missing file(a) after rename"
1469
1470         rm -rf $DIR/$tdir || error "Can not delete directories"
1471 }
1472 run_test 24E "cross MDT rename/link"
1473
1474 test_24F () {
1475         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1476
1477         local repeats=1000
1478         [ "$SLOW" = "no" ] && repeats=100
1479
1480         mkdir -p $DIR/$tdir
1481
1482         echo "$repeats repeats"
1483         for ((i = 0; i < repeats; i++)); do
1484                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1485                 touch $DIR/$tdir/test/a || error "touch fails"
1486                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1487                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1488         done
1489
1490         true
1491 }
1492 run_test 24F "hash order vs readdir (LU-11330)"
1493
1494 test_24G () {
1495         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1496
1497         local ino1
1498         local ino2
1499
1500         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1501         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1502         touch $DIR/$tdir-0/f1 || error "touch f1"
1503         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1504         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1505         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1506         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1507         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1508 }
1509 run_test 24G "migrate symlink in rename"
1510
1511 test_24H() {
1512         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1513         [[ $(hostname) != $(facet_active_host mds2) ]] ||
1514                 skip "MDT1 should be on another node"
1515
1516         test_mkdir -i 1 -c 1 $DIR/$tdir
1517 #define OBD_FAIL_FLD_QUERY_REQ           0x1103
1518         do_facet mds2 $LCTL set_param fail_loc=0x80001103
1519         touch $DIR/$tdir/$tfile || error "touch failed"
1520 }
1521 run_test 24H "repeat FLD_QUERY rpc"
1522
1523 test_25a() {
1524         echo '== symlink sanity ============================================='
1525
1526         test_mkdir $DIR/d25
1527         ln -s d25 $DIR/s25
1528         touch $DIR/s25/foo ||
1529                 error "File creation in symlinked directory failed"
1530 }
1531 run_test 25a "create file in symlinked directory ==============="
1532
1533 test_25b() {
1534         [ ! -d $DIR/d25 ] && test_25a
1535         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1536 }
1537 run_test 25b "lookup file in symlinked directory ==============="
1538
1539 test_26a() {
1540         test_mkdir $DIR/d26
1541         test_mkdir $DIR/d26/d26-2
1542         ln -s d26/d26-2 $DIR/s26
1543         touch $DIR/s26/foo || error "File creation failed"
1544 }
1545 run_test 26a "multiple component symlink ======================="
1546
1547 test_26b() {
1548         test_mkdir -p $DIR/$tdir/d26-2
1549         ln -s $tdir/d26-2/foo $DIR/s26-2
1550         touch $DIR/s26-2 || error "File creation failed"
1551 }
1552 run_test 26b "multiple component symlink at end of lookup ======"
1553
1554 test_26c() {
1555         test_mkdir $DIR/d26.2
1556         touch $DIR/d26.2/foo
1557         ln -s d26.2 $DIR/s26.2-1
1558         ln -s s26.2-1 $DIR/s26.2-2
1559         ln -s s26.2-2 $DIR/s26.2-3
1560         chmod 0666 $DIR/s26.2-3/foo
1561 }
1562 run_test 26c "chain of symlinks"
1563
1564 # recursive symlinks (bug 439)
1565 test_26d() {
1566         ln -s d26-3/foo $DIR/d26-3
1567 }
1568 run_test 26d "create multiple component recursive symlink"
1569
1570 test_26e() {
1571         [ ! -h $DIR/d26-3 ] && test_26d
1572         rm $DIR/d26-3
1573 }
1574 run_test 26e "unlink multiple component recursive symlink"
1575
1576 # recursive symlinks (bug 7022)
1577 test_26f() {
1578         test_mkdir $DIR/$tdir
1579         test_mkdir $DIR/$tdir/$tfile
1580         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1581         test_mkdir -p lndir/bar1
1582         test_mkdir $DIR/$tdir/$tfile/$tfile
1583         cd $tfile                || error "cd $tfile failed"
1584         ln -s .. dotdot          || error "ln dotdot failed"
1585         ln -s dotdot/lndir lndir || error "ln lndir failed"
1586         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1587         output=`ls $tfile/$tfile/lndir/bar1`
1588         [ "$output" = bar1 ] && error "unexpected output"
1589         rm -r $tfile             || error "rm $tfile failed"
1590         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1591 }
1592 run_test 26f "rm -r of a directory which has recursive symlink"
1593
1594 test_27a() {
1595         test_mkdir $DIR/$tdir
1596         $LFS getstripe $DIR/$tdir
1597         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1598         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1599         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1600 }
1601 run_test 27a "one stripe file"
1602
1603 test_27b() {
1604         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1605
1606         test_mkdir $DIR/$tdir
1607         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1608         $LFS getstripe -c $DIR/$tdir/$tfile
1609         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1610                 error "two-stripe file doesn't have two stripes"
1611
1612         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1613 }
1614 run_test 27b "create and write to two stripe file"
1615
1616 # 27c family tests specific striping, setstripe -o
1617 test_27ca() {
1618         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1619         test_mkdir -p $DIR/$tdir
1620         local osts="1"
1621
1622         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1623         $LFS getstripe -i $DIR/$tdir/$tfile
1624         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1625                 error "stripe not on specified OST"
1626
1627         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1628 }
1629 run_test 27ca "one stripe on specified OST"
1630
1631 test_27cb() {
1632         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1633         test_mkdir -p $DIR/$tdir
1634         local osts="1,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 27cb "two stripes on specified OSTs"
1648
1649 test_27cc() {
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
1654         test_mkdir -p $DIR/$tdir
1655         local osts="0,0"
1656         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1657         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1658         echo "$getstripe"
1659
1660         # Strip getstripe output to a space separated list of OSTs
1661         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1662                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1663         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1664                 error "stripes not on specified OSTs"
1665
1666         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1667 }
1668 run_test 27cc "two stripes on the same OST"
1669
1670 test_27cd() {
1671         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1672         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1673                 skip "server does not support overstriping"
1674         test_mkdir -p $DIR/$tdir
1675         local osts="0,1,1,0"
1676         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1677         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1678         echo "$getstripe"
1679
1680         # Strip getstripe output to a space separated list of OSTs
1681         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1682                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1683         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1684                 error "stripes not on specified OSTs"
1685
1686         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1687 }
1688 run_test 27cd "four stripes on two OSTs"
1689
1690 test_27ce() {
1691         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1692                 skip_env "too many osts, skipping"
1693         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1694                 skip "server does not support overstriping"
1695         # We do one more stripe than we have OSTs
1696         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1697                 skip_env "ea_inode feature disabled"
1698
1699         test_mkdir -p $DIR/$tdir
1700         local osts=""
1701         for i in $(seq 0 $OSTCOUNT);
1702         do
1703                 osts=$osts"0"
1704                 if [ $i -ne $OSTCOUNT ]; then
1705                         osts=$osts","
1706                 fi
1707         done
1708         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1709         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1710         echo "$getstripe"
1711
1712         # Strip getstripe output to a space separated list of OSTs
1713         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1714                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1715         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1716                 error "stripes not on specified OSTs"
1717
1718         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1719 }
1720 run_test 27ce "more stripes than OSTs with -o"
1721
1722 test_27cf() {
1723         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1724         local pid=0
1725
1726         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1727         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1728         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1729         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1730                 error "failed to set $osp_proc=0"
1731
1732         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1733         pid=$!
1734         sleep 1
1735         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1736         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1737                 error "failed to set $osp_proc=1"
1738         wait $pid
1739         [[ $pid -ne 0 ]] ||
1740                 error "should return error due to $osp_proc=0"
1741 }
1742 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1743
1744 test_27cg() {
1745         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1746                 skip "server does not support overstriping"
1747         [[ $mds1_FSTYPE != "ldiskfs" ]] && skip_env "ldiskfs only test"
1748         large_xattr_enabled || skip_env "ea_inode feature disabled"
1749
1750         local osts="0"
1751
1752         for ((i=1;i<1000;i++)); do
1753                 osts+=",$((i % OSTCOUNT))"
1754         done
1755
1756         local mdts=$(comma_list $(mdts_nodes))
1757         local before=$(do_nodes $mdts \
1758                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1759                 awk '/many credits/{print $3}' |
1760                 calc_sum)
1761
1762         $LFS setstripe -o $osts $DIR/$tfile || error "setstripe failed"
1763         $LFS getstripe $DIR/$tfile | grep stripe
1764
1765         rm -f $DIR/$tfile || error "can't unlink"
1766
1767         after=$(do_nodes $mdts \
1768                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1769                 awk '/many credits/{print $3}' |
1770                 calc_sum)
1771
1772         (( before == after )) ||
1773                 error "too many credits happened: $after > $before"
1774 }
1775 run_test 27cg "1000 shouldn't cause too many credits"
1776
1777 test_27d() {
1778         test_mkdir $DIR/$tdir
1779         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1780                 error "setstripe failed"
1781         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1782         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1783 }
1784 run_test 27d "create file with default settings"
1785
1786 test_27e() {
1787         # LU-5839 adds check for existed layout before setting it
1788         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1789                 skip "Need MDS version at least 2.7.56"
1790
1791         test_mkdir $DIR/$tdir
1792         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1793         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1794         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1795 }
1796 run_test 27e "setstripe existing file (should return error)"
1797
1798 test_27f() {
1799         test_mkdir $DIR/$tdir
1800         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1801                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1802         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1803                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1804         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1805         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1806 }
1807 run_test 27f "setstripe with bad stripe size (should return error)"
1808
1809 test_27g() {
1810         test_mkdir $DIR/$tdir
1811         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1812         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1813                 error "$DIR/$tdir/$tfile has object"
1814 }
1815 run_test 27g "$LFS getstripe with no objects"
1816
1817 test_27ga() {
1818         test_mkdir $DIR/$tdir
1819         touch $DIR/$tdir/$tfile || error "touch failed"
1820         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1821         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1822         local rc=$?
1823         (( rc == 2 )) || error "getstripe did not return ENOENT"
1824
1825         local err_msg=$($LFS getstripe $DIR/$tdir/typo $DIR/$tdir/$tfile \
1826                         2>&1 > /dev/null)
1827         [[ $err_msg =~ "typo" ]] ||
1828                 error "expected message with correct filename, got '$err_msg'"
1829 }
1830 run_test 27ga "$LFS getstripe with missing file (should return error)"
1831
1832 test_27i() {
1833         test_mkdir $DIR/$tdir
1834         touch $DIR/$tdir/$tfile || error "touch failed"
1835         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1836                 error "missing objects"
1837 }
1838 run_test 27i "$LFS getstripe with some objects"
1839
1840 test_27j() {
1841         test_mkdir $DIR/$tdir
1842         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1843                 error "setstripe failed" || true
1844 }
1845 run_test 27j "setstripe with bad stripe offset (should return error)"
1846
1847 test_27k() { # bug 2844
1848         test_mkdir $DIR/$tdir
1849         local file=$DIR/$tdir/$tfile
1850         local ll_max_blksize=$((4 * 1024 * 1024))
1851         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1852         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1853         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1854         dd if=/dev/zero of=$file bs=4k count=1
1855         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1856         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1857 }
1858 run_test 27k "limit i_blksize for broken user apps"
1859
1860 test_27l() {
1861         mcreate $DIR/$tfile || error "creating file"
1862         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1863                 error "setstripe should have failed" || true
1864 }
1865 run_test 27l "check setstripe permissions (should return error)"
1866
1867 test_27m() {
1868         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1869
1870         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1871                 skip_env "multiple clients -- skipping"
1872
1873         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1874                    head -n1)
1875         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1876                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1877         fi
1878         stack_trap simple_cleanup_common
1879         test_mkdir $DIR/$tdir
1880         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1881         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1882                 error "dd should fill OST0"
1883         i=2
1884         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1885                 i=$((i + 1))
1886                 [ $i -gt 256 ] && break
1887         done
1888         i=$((i + 1))
1889         touch $DIR/$tdir/$tfile.$i
1890         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1891             awk '{print $1}'| grep -w "0") ] &&
1892                 error "OST0 was full but new created file still use it"
1893         i=$((i + 1))
1894         touch $DIR/$tdir/$tfile.$i
1895         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1896             awk '{print $1}'| grep -w "0") ] &&
1897                 error "OST0 was full but new created file still use it" || true
1898 }
1899 run_test 27m "create file while OST0 was full"
1900
1901 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1902 # if the OST isn't full anymore.
1903 reset_enospc() {
1904         local ostidx=${1:-""}
1905         local delay
1906         local ready
1907         local get_prealloc
1908
1909         local list=$(comma_list $(osts_nodes))
1910         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1911
1912         do_nodes $list lctl set_param fail_loc=0
1913         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1914         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1915                 awk '{print $1 * 2;exit;}')
1916         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1917                         grep -v \"^0$\""
1918         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1919 }
1920
1921 test_27n() {
1922         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1924         remote_mds_nodsh && skip "remote MDS with nodsh"
1925         remote_ost_nodsh && skip "remote OST with nodsh"
1926
1927         reset_enospc
1928         rm -f $DIR/$tdir/$tfile
1929         exhaust_precreations 0 0x80000215
1930         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1931         touch $DIR/$tdir/$tfile || error "touch failed"
1932         $LFS getstripe $DIR/$tdir/$tfile
1933         reset_enospc
1934 }
1935 run_test 27n "create file with some full OSTs"
1936
1937 test_27o() {
1938         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1940         remote_mds_nodsh && skip "remote MDS with nodsh"
1941         remote_ost_nodsh && skip "remote OST with nodsh"
1942
1943         reset_enospc
1944         rm -f $DIR/$tdir/$tfile
1945         exhaust_all_precreations 0x215
1946
1947         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1948
1949         reset_enospc
1950         rm -rf $DIR/$tdir/*
1951 }
1952 run_test 27o "create file with all full OSTs (should error)"
1953
1954 function create_and_checktime() {
1955         local fname=$1
1956         local loops=$2
1957         local i
1958
1959         for ((i=0; i < $loops; i++)); do
1960                 local start=$SECONDS
1961                 multiop $fname-$i Oc
1962                 ((SECONDS-start < TIMEOUT)) ||
1963                         error "creation took " $((SECONDS-$start)) && return 1
1964         done
1965 }
1966
1967 test_27oo() {
1968         local mdts=$(comma_list $(mdts_nodes))
1969
1970         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1971                 skip "Need MDS version at least 2.13.57"
1972
1973         local f0=$DIR/${tfile}-0
1974         local f1=$DIR/${tfile}-1
1975
1976         wait_delete_completed
1977
1978         # refill precreated objects
1979         $LFS setstripe -i0 -c1 $f0
1980
1981         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1982         # force QoS allocation policy
1983         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1984         stack_trap "do_nodes $mdts $LCTL set_param \
1985                 lov.*.qos_threshold_rr=$saved" EXIT
1986         sleep_maxage
1987
1988         # one OST is unavailable, but still have few objects preallocated
1989         stop ost1
1990         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1991                 rm -rf $f1 $DIR/$tdir*" EXIT
1992
1993         for ((i=0; i < 7; i++)); do
1994                 mkdir $DIR/$tdir$i || error "can't create dir"
1995                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1996                         error "can't set striping"
1997         done
1998         for ((i=0; i < 7; i++)); do
1999                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
2000         done
2001         wait
2002 }
2003 run_test 27oo "don't let few threads to reserve too many objects"
2004
2005 test_27p() {
2006         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2008         remote_mds_nodsh && skip "remote MDS with nodsh"
2009         remote_ost_nodsh && skip "remote OST with nodsh"
2010
2011         reset_enospc
2012         rm -f $DIR/$tdir/$tfile
2013         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
2014
2015         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
2016         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
2017         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
2018
2019         exhaust_precreations 0 0x80000215
2020         echo foo >> $DIR/$tdir/$tfile || error "append failed"
2021         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
2022         $LFS getstripe $DIR/$tdir/$tfile
2023
2024         reset_enospc
2025 }
2026 run_test 27p "append to a truncated file with some full OSTs"
2027
2028 test_27q() {
2029         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2030         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2031         remote_mds_nodsh && skip "remote MDS with nodsh"
2032         remote_ost_nodsh && skip "remote OST with nodsh"
2033
2034         reset_enospc
2035         rm -f $DIR/$tdir/$tfile
2036
2037         mkdir_on_mdt0 $DIR/$tdir
2038         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
2039         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
2040                 error "truncate $DIR/$tdir/$tfile failed"
2041         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
2042
2043         exhaust_all_precreations 0x215
2044
2045         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
2046         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
2047
2048         reset_enospc
2049 }
2050 run_test 27q "append to truncated file with all OSTs full (should error)"
2051
2052 test_27r() {
2053         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2055         remote_mds_nodsh && skip "remote MDS with nodsh"
2056         remote_ost_nodsh && skip "remote OST with nodsh"
2057
2058         reset_enospc
2059         rm -f $DIR/$tdir/$tfile
2060         exhaust_precreations 0 0x80000215
2061
2062         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2063
2064         reset_enospc
2065 }
2066 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2067
2068 test_27s() { # bug 10725
2069         test_mkdir $DIR/$tdir
2070         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2071         local stripe_count=0
2072         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2073         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2074                 error "stripe width >= 2^32 succeeded" || true
2075
2076 }
2077 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2078
2079 test_27t() { # bug 10864
2080         WDIR=$(pwd)
2081         WLFS=$(which lfs)
2082         cd $DIR
2083         touch $tfile
2084         $WLFS getstripe $tfile
2085         cd $WDIR
2086 }
2087 run_test 27t "check that utils parse path correctly"
2088
2089 test_27u() { # bug 4900
2090         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2091         remote_mds_nodsh && skip "remote MDS with nodsh"
2092
2093         local index
2094         local list=$(comma_list $(mdts_nodes))
2095
2096 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2097         do_nodes $list $LCTL set_param fail_loc=0x139
2098         test_mkdir -p $DIR/$tdir
2099         stack_trap "simple_cleanup_common 1000"
2100         createmany -o $DIR/$tdir/$tfile 1000
2101         do_nodes $list $LCTL set_param fail_loc=0
2102
2103         TLOG=$TMP/$tfile.getstripe
2104         $LFS getstripe $DIR/$tdir > $TLOG
2105         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2106         [[ $OBJS -gt 0 ]] &&
2107                 error "$OBJS objects created on OST-0. See $TLOG" ||
2108                 rm -f $TLOG
2109 }
2110 run_test 27u "skip object creation on OSC w/o objects"
2111
2112 test_27v() { # bug 4900
2113         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2114         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2115         remote_mds_nodsh && skip "remote MDS with nodsh"
2116         remote_ost_nodsh && skip "remote OST with nodsh"
2117
2118         exhaust_all_precreations 0x215
2119         reset_enospc
2120
2121         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2122
2123         touch $DIR/$tdir/$tfile
2124         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2125         # all except ost1
2126         for (( i=1; i < OSTCOUNT; i++ )); do
2127                 do_facet ost$i lctl set_param fail_loc=0x705
2128         done
2129         local START=`date +%s`
2130         createmany -o $DIR/$tdir/$tfile 32
2131
2132         local FINISH=`date +%s`
2133         local TIMEOUT=`lctl get_param -n timeout`
2134         local PROCESS=$((FINISH - START))
2135         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2136                error "$FINISH - $START >= $TIMEOUT / 2"
2137         sleep $((TIMEOUT / 2 - PROCESS))
2138         reset_enospc
2139 }
2140 run_test 27v "skip object creation on slow OST"
2141
2142 test_27w() { # bug 10997
2143         test_mkdir $DIR/$tdir
2144         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2145         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2146                 error "stripe size $size != 65536" || true
2147         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2148                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2149 }
2150 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2151
2152 test_27wa() {
2153         [[ $OSTCOUNT -lt 2 ]] &&
2154                 skip_env "skipping multiple stripe count/offset test"
2155
2156         test_mkdir $DIR/$tdir
2157         for i in $(seq 1 $OSTCOUNT); do
2158                 offset=$((i - 1))
2159                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2160                         error "setstripe -c $i -i $offset failed"
2161                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2162                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2163                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2164                 [ $index -ne $offset ] &&
2165                         error "stripe offset $index != $offset" || true
2166         done
2167 }
2168 run_test 27wa "check $LFS setstripe -c -i options"
2169
2170 test_27x() {
2171         remote_ost_nodsh && skip "remote OST with nodsh"
2172         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2174
2175         OFFSET=$(($OSTCOUNT - 1))
2176         OSTIDX=0
2177         local OST=$(ostname_from_index $OSTIDX)
2178
2179         test_mkdir $DIR/$tdir
2180         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2181         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2182         sleep_maxage
2183         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2184         for i in $(seq 0 $OFFSET); do
2185                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2186                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2187                 error "OST0 was degraded but new created file still use it"
2188         done
2189         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2190 }
2191 run_test 27x "create files while OST0 is degraded"
2192
2193 test_27y() {
2194         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2195         remote_mds_nodsh && skip "remote MDS with nodsh"
2196         remote_ost_nodsh && skip "remote OST with nodsh"
2197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2198
2199         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2200         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2201                 osp.$mdtosc.prealloc_last_id)
2202         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2203                 osp.$mdtosc.prealloc_next_id)
2204         local fcount=$((last_id - next_id))
2205         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2206         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2207
2208         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2209                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2210         local OST_DEACTIVE_IDX=-1
2211         local OSC
2212         local OSTIDX
2213         local OST
2214
2215         for OSC in $MDS_OSCS; do
2216                 OST=$(osc_to_ost $OSC)
2217                 OSTIDX=$(index_from_ostuuid $OST)
2218                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2219                         OST_DEACTIVE_IDX=$OSTIDX
2220                 fi
2221                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2222                         echo $OSC "is Deactivated:"
2223                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2224                 fi
2225         done
2226
2227         OSTIDX=$(index_from_ostuuid $OST)
2228         test_mkdir $DIR/$tdir
2229         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2230
2231         for OSC in $MDS_OSCS; do
2232                 OST=$(osc_to_ost $OSC)
2233                 OSTIDX=$(index_from_ostuuid $OST)
2234                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2235                         echo $OST "is degraded:"
2236                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2237                                                 obdfilter.$OST.degraded=1
2238                 fi
2239         done
2240
2241         sleep_maxage
2242         createmany -o $DIR/$tdir/$tfile $fcount
2243
2244         for OSC in $MDS_OSCS; do
2245                 OST=$(osc_to_ost $OSC)
2246                 OSTIDX=$(index_from_ostuuid $OST)
2247                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2248                         echo $OST "is recovered from degraded:"
2249                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2250                                                 obdfilter.$OST.degraded=0
2251                 else
2252                         do_facet $SINGLEMDS lctl --device %$OSC activate
2253                 fi
2254         done
2255
2256         # all osp devices get activated, hence -1 stripe count restored
2257         local stripe_count=0
2258
2259         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2260         # devices get activated.
2261         sleep_maxage
2262         $LFS setstripe -c -1 $DIR/$tfile
2263         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2264         rm -f $DIR/$tfile
2265         [ $stripe_count -ne $OSTCOUNT ] &&
2266                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2267         return 0
2268 }
2269 run_test 27y "create files while OST0 is degraded and the rest inactive"
2270
2271 check_seq_oid()
2272 {
2273         log "check file $1"
2274
2275         lmm_count=$($LFS getstripe -c $1)
2276         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2277         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2278
2279         local old_ifs="$IFS"
2280         IFS=$'[:]'
2281         fid=($($LFS path2fid $1))
2282         IFS="$old_ifs"
2283
2284         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2285         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2286
2287         # compare lmm_seq and lu_fid->f_seq
2288         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2289         # compare lmm_object_id and lu_fid->oid
2290         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2291
2292         # check the trusted.fid attribute of the OST objects of the file
2293         local have_obdidx=false
2294         local stripe_nr=0
2295         $LFS getstripe $1 | while read obdidx oid hex seq; do
2296                 # skip lines up to and including "obdidx"
2297                 [ -z "$obdidx" ] && break
2298                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2299                 $have_obdidx || continue
2300
2301                 local ost=$((obdidx + 1))
2302                 local dev=$(ostdevname $ost)
2303                 local oid_hex
2304
2305                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2306
2307                 seq=$(echo $seq | sed -e "s/^0x//g")
2308                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2309                         oid_hex=$(echo $oid)
2310                 else
2311                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2312                 fi
2313                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2314
2315                 local ff=""
2316                 #
2317                 # Don't unmount/remount the OSTs if we don't need to do that.
2318                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2319                 # update too, until that use mount/ll_decode_filter_fid/mount.
2320                 # Re-enable when debugfs will understand new filter_fid.
2321                 #
2322                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2323                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2324                                 $dev 2>/dev/null" | grep "parent=")
2325                 fi
2326                 if [ -z "$ff" ]; then
2327                         stop ost$ost
2328                         mount_fstype ost$ost
2329                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2330                                 $(facet_mntpt ost$ost)/$obj_file)
2331                         unmount_fstype ost$ost
2332                         start ost$ost $dev $OST_MOUNT_OPTS
2333                         clients_up
2334                 fi
2335
2336                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2337
2338                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2339
2340                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2341                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2342                 #
2343                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2344                 #       stripe_size=1048576 component_id=1 component_start=0 \
2345                 #       component_end=33554432
2346                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2347                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2348                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2349                 local ff_pstripe
2350                 if grep -q 'stripe=' <<<$ff; then
2351                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2352                 else
2353                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2354                         # into f_ver in this case.  See comment on ff_parent.
2355                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2356                 fi
2357
2358                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2359                 [ $ff_pseq = $lmm_seq ] ||
2360                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2361                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2362                 [ $ff_poid = $lmm_oid ] ||
2363                         error "FF parent OID $ff_poid != $lmm_oid"
2364                 (($ff_pstripe == $stripe_nr)) ||
2365                         error "FF stripe $ff_pstripe != $stripe_nr"
2366
2367                 stripe_nr=$((stripe_nr + 1))
2368                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2369                         continue
2370                 if grep -q 'stripe_count=' <<<$ff; then
2371                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2372                                             -e 's/ .*//' <<<$ff)
2373                         [ $lmm_count = $ff_scnt ] ||
2374                                 error "FF stripe count $lmm_count != $ff_scnt"
2375                 fi
2376         done
2377 }
2378
2379 test_27z() {
2380         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2381         remote_ost_nodsh && skip "remote OST with nodsh"
2382
2383         test_mkdir $DIR/$tdir
2384         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2385                 { error "setstripe -c -1 failed"; return 1; }
2386         # We need to send a write to every object to get parent FID info set.
2387         # This _should_ also work for setattr, but does not currently.
2388         # touch $DIR/$tdir/$tfile-1 ||
2389         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2390                 { error "dd $tfile-1 failed"; return 2; }
2391         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2392                 { error "setstripe -c -1 failed"; return 3; }
2393         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2394                 { error "dd $tfile-2 failed"; return 4; }
2395
2396         # make sure write RPCs have been sent to OSTs
2397         sync; sleep 5; sync
2398
2399         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2400         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2401 }
2402 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2403
2404 test_27A() { # b=19102
2405         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2406
2407         save_layout_restore_at_exit $MOUNT
2408         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2409         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2410                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2411         local default_size=$($LFS getstripe -S $MOUNT)
2412         local default_offset=$($LFS getstripe -i $MOUNT)
2413         local dsize=$(do_facet $SINGLEMDS \
2414                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2415         [ $default_size -eq $dsize ] ||
2416                 error "stripe size $default_size != $dsize"
2417         [ $default_offset -eq -1 ] ||
2418                 error "stripe offset $default_offset != -1"
2419 }
2420 run_test 27A "check filesystem-wide default LOV EA values"
2421
2422 test_27B() { # LU-2523
2423         test_mkdir $DIR/$tdir
2424         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2425         touch $DIR/$tdir/f0
2426         # open f1 with O_LOV_DELAY_CREATE
2427         # rename f0 onto f1
2428         # call setstripe ioctl on open file descriptor for f1
2429         # close
2430         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2431                 $DIR/$tdir/f0
2432
2433         rm -f $DIR/$tdir/f1
2434         # open f1 with O_LOV_DELAY_CREATE
2435         # unlink f1
2436         # call setstripe ioctl on open file descriptor for f1
2437         # close
2438         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2439
2440         # Allow multiop to fail in imitation of NFS's busted semantics.
2441         true
2442 }
2443 run_test 27B "call setstripe on open unlinked file/rename victim"
2444
2445 # 27C family tests full striping and overstriping
2446 test_27Ca() { #LU-2871
2447         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2448
2449         declare -a ost_idx
2450         local index
2451         local found
2452         local i
2453         local j
2454
2455         test_mkdir $DIR/$tdir
2456         cd $DIR/$tdir
2457         for i in $(seq 0 $((OSTCOUNT - 1))); do
2458                 # set stripe across all OSTs starting from OST$i
2459                 $LFS setstripe -i $i -c -1 $tfile$i
2460                 # get striping information
2461                 ost_idx=($($LFS getstripe $tfile$i |
2462                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2463                 echo "OST Index: ${ost_idx[*]}"
2464
2465                 # check the layout
2466                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2467                         error "${#ost_idx[@]} != $OSTCOUNT"
2468
2469                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2470                         found=0
2471                         for j in "${ost_idx[@]}"; do
2472                                 if [ $index -eq $j ]; then
2473                                         found=1
2474                                         break
2475                                 fi
2476                         done
2477                         [ $found = 1 ] ||
2478                                 error "Can not find $index in ${ost_idx[*]}"
2479                 done
2480         done
2481 }
2482 run_test 27Ca "check full striping across all OSTs"
2483
2484 test_27Cb() {
2485         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2486                 skip "server does not support overstriping"
2487         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2488                 skip_env "too many osts, skipping"
2489
2490         test_mkdir -p $DIR/$tdir
2491         local setcount=$(($OSTCOUNT * 2))
2492         [ $setcount -lt 160 ] || large_xattr_enabled ||
2493                 skip_env "ea_inode feature disabled"
2494
2495         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2496                 error "setstripe failed"
2497
2498         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2499         [ $count -eq $setcount ] ||
2500                 error "stripe count $count, should be $setcount"
2501
2502         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2503                 error "overstriped should be set in pattern"
2504
2505         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2506                 error "dd failed"
2507 }
2508 run_test 27Cb "more stripes than OSTs with -C"
2509
2510 test_27Cc() {
2511         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2512                 skip "server does not support overstriping"
2513         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2514
2515         test_mkdir -p $DIR/$tdir
2516         local setcount=$(($OSTCOUNT - 1))
2517
2518         [ $setcount -lt 160 ] || large_xattr_enabled ||
2519                 skip_env "ea_inode feature disabled"
2520
2521         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2522                 error "setstripe failed"
2523
2524         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2525         [ $count -eq $setcount ] ||
2526                 error "stripe count $count, should be $setcount"
2527
2528         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2529                 error "overstriped should not be set in pattern"
2530
2531         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2532                 error "dd failed"
2533 }
2534 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2535
2536 test_27Cd() {
2537         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2538                 skip "server does not support overstriping"
2539         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2540         large_xattr_enabled || skip_env "ea_inode feature disabled"
2541
2542         force_new_seq_all
2543
2544         test_mkdir -p $DIR/$tdir
2545         local setcount=$LOV_MAX_STRIPE_COUNT
2546
2547         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2548                 error "setstripe failed"
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 27Cd "test maximum stripe count"
2563
2564 test_27Ce() {
2565         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2566                 skip "server does not support overstriping"
2567         test_mkdir -p $DIR/$tdir
2568
2569         pool_add $TESTNAME || error "Pool creation failed"
2570         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2571
2572         local setcount=8
2573
2574         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2575                 error "setstripe failed"
2576
2577         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2578         [ $count -eq $setcount ] ||
2579                 error "stripe count $count, should be $setcount"
2580
2581         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2582                 error "overstriped should be set in pattern"
2583
2584         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2585                 error "dd failed"
2586
2587         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2588 }
2589 run_test 27Ce "test pool with overstriping"
2590
2591 test_27Cf() {
2592         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2593                 skip "server does not support overstriping"
2594         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2595                 skip_env "too many osts, skipping"
2596
2597         test_mkdir -p $DIR/$tdir
2598
2599         local setcount=$(($OSTCOUNT * 2))
2600         [ $setcount -lt 160 ] || large_xattr_enabled ||
2601                 skip_env "ea_inode feature disabled"
2602
2603         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2604                 error "setstripe failed"
2605
2606         echo 1 > $DIR/$tdir/$tfile
2607
2608         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2609         [ $count -eq $setcount ] ||
2610                 error "stripe count $count, should be $setcount"
2611
2612         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2613                 error "overstriped should be set in pattern"
2614
2615         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2616                 error "dd failed"
2617
2618         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2619 }
2620 run_test 27Cf "test default inheritance with overstriping"
2621
2622 test_27Cg() {
2623         (( MDS1_VERSION >= $(version_code v2_15_55-80-gd96b98ee6b) )) ||
2624                 skip "need MDS version at least v2_15_55-80-gd96b98ee6b for fix"
2625
2626         $LFS setstripe -o 0,$OSTCOUNT $DIR/$tfile
2627         (( $? != 0 )) || error "must be an error for not existent OST#"
2628 }
2629 run_test 27Cg "test setstripe with wrong OST idx"
2630
2631 test_27Ci() {
2632         local tf=$DIR/$tfile
2633
2634         stack_trap "rm -f $DIR/$tfile"
2635
2636         $LFS setstripe -E1M $tf || error "create $tf failed"
2637         $LFS setstripe -Eeof --component-add -C 100 $tf ||
2638                 error "add component failed"
2639
2640         $LFS getstripe -I2 $tf | awk '/lmm_pattern/ { print $2 }' |
2641                 grep "overstriped" || {
2642                 $LFS getstripe $tf
2643                 echo "lose overstriping setting"
2644         }
2645         sc=$($LFS getstripe -I2 --stripe-count $tf)
2646         (( $sc == 100 )) || {
2647                 $LFS getstripe $tf
2648                 echo "lose overstriping setting"
2649         }
2650
2651         stack_trap "rm -f $tf"
2652         dd if=/dev/zero of=$tf bs=1M count=10 || error "write $tf"
2653         sc=$($LFS getstripe -I2 --stripe-count $tf)
2654         (( $sc == 100 )) || {
2655                 $LFS getstripe $tf
2656                 echo "lose overstriping setting after instantiation"
2657         }
2658 }
2659 run_test 27Ci "add an overstriping component"
2660
2661 test_27D() {
2662         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2663         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2664         remote_mds_nodsh && skip "remote MDS with nodsh"
2665
2666         local POOL=${POOL:-testpool}
2667         local first_ost=0
2668         local last_ost=$(($OSTCOUNT - 1))
2669         local ost_step=1
2670         local ost_list=$(seq $first_ost $ost_step $last_ost)
2671         local ost_range="$first_ost $last_ost $ost_step"
2672
2673         test_mkdir $DIR/$tdir
2674         pool_add $POOL || error "pool_add failed"
2675         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2676
2677         local skip27D
2678         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2679                 skip27D+="-s 29"
2680         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2681                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2682                         skip27D+=" -s 30,31"
2683         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2684           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2685                 skip27D+=" -s 32,33"
2686         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2687                 skip27D+=" -s 34"
2688         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2689                 error "llapi_layout_test failed"
2690
2691         destroy_test_pools || error "destroy test pools failed"
2692 }
2693 run_test 27D "validate llapi_layout API"
2694
2695 # Verify that default_easize is increased from its initial value after
2696 # accessing a widely striped file.
2697 test_27E() {
2698         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2699         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2700                 skip "client does not have LU-3338 fix"
2701
2702         # 72 bytes is the minimum space required to store striping
2703         # information for a file striped across one OST:
2704         # (sizeof(struct lov_user_md_v3) +
2705         #  sizeof(struct lov_user_ost_data_v1))
2706         local min_easize=72
2707         $LCTL set_param -n llite.*.default_easize $min_easize ||
2708                 error "lctl set_param failed"
2709         local easize=$($LCTL get_param -n llite.*.default_easize)
2710
2711         [ $easize -eq $min_easize ] ||
2712                 error "failed to set default_easize"
2713
2714         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2715                 error "setstripe failed"
2716         # In order to ensure stat() call actually talks to MDS we need to
2717         # do something drastic to this file to shake off all lock, e.g.
2718         # rename it (kills lookup lock forcing cache cleaning)
2719         mv $DIR/$tfile $DIR/${tfile}-1
2720         ls -l $DIR/${tfile}-1
2721         rm $DIR/${tfile}-1
2722
2723         easize=$($LCTL get_param -n llite.*.default_easize)
2724
2725         [ $easize -gt $min_easize ] ||
2726                 error "default_easize not updated"
2727 }
2728 run_test 27E "check that default extended attribute size properly increases"
2729
2730 test_27F() { # LU-5346/LU-7975
2731         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2732         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2733         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2734                 skip "Need MDS version at least 2.8.51"
2735         remote_ost_nodsh && skip "remote OST with nodsh"
2736
2737         test_mkdir $DIR/$tdir
2738         rm -f $DIR/$tdir/f0
2739         $LFS setstripe -c 2 $DIR/$tdir
2740
2741         # stop all OSTs to reproduce situation for LU-7975 ticket
2742         for num in $(seq $OSTCOUNT); do
2743                 stop ost$num
2744         done
2745
2746         # open/create f0 with O_LOV_DELAY_CREATE
2747         # truncate f0 to a non-0 size
2748         # close
2749         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2750
2751         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2752         # open/write it again to force delayed layout creation
2753         cat /etc/hosts > $DIR/$tdir/f0 &
2754         catpid=$!
2755
2756         # restart OSTs
2757         for num in $(seq $OSTCOUNT); do
2758                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2759                         error "ost$num failed to start"
2760         done
2761
2762         wait $catpid || error "cat failed"
2763
2764         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2765         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2766                 error "wrong stripecount"
2767
2768 }
2769 run_test 27F "Client resend delayed layout creation with non-zero size"
2770
2771 test_27G() { #LU-10629
2772         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2773                 skip "Need MDS version at least 2.11.51"
2774         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2775         remote_mds_nodsh && skip "remote MDS with nodsh"
2776         local POOL=${POOL:-testpool}
2777         local ostrange="0 0 1"
2778
2779         test_mkdir $DIR/$tdir
2780         touch $DIR/$tdir/$tfile.nopool
2781         pool_add $POOL || error "pool_add failed"
2782         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2783         $LFS setstripe -p $POOL $DIR/$tdir
2784
2785         local pool=$($LFS getstripe -p $DIR/$tdir)
2786
2787         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2788         touch $DIR/$tdir/$tfile.default
2789         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2790         $LFS find $DIR/$tdir -type f --pool $POOL
2791         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2792         [[ "$found" == "2" ]] ||
2793                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2794
2795         $LFS setstripe -d $DIR/$tdir
2796
2797         pool=$($LFS getstripe -p -d $DIR/$tdir)
2798
2799         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2800 }
2801 run_test 27G "Clear OST pool from stripe"
2802
2803 test_27H() {
2804         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2805                 skip "Need MDS version newer than 2.11.54"
2806         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2807         test_mkdir $DIR/$tdir
2808         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2809         touch $DIR/$tdir/$tfile
2810         $LFS getstripe -c $DIR/$tdir/$tfile
2811         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2812                 error "two-stripe file doesn't have two stripes"
2813
2814         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2815         $LFS getstripe -y $DIR/$tdir/$tfile
2816         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2817              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2818                 error "expected l_ost_idx: [02]$ not matched"
2819
2820         # make sure ost list has been cleared
2821         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2822         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2823                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2824         touch $DIR/$tdir/f3
2825         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2826 }
2827 run_test 27H "Set specific OSTs stripe"
2828
2829 test_27I() {
2830         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2831         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2832         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2833                 skip "Need MDS version newer than 2.12.52"
2834         local pool=$TESTNAME
2835         local ostrange="1 1 1"
2836
2837         save_layout_restore_at_exit $MOUNT
2838         $LFS setstripe -c 2 -i 0 $MOUNT
2839         pool_add $pool || error "pool_add failed"
2840         pool_add_targets $pool $ostrange ||
2841                 error "pool_add_targets failed"
2842         test_mkdir $DIR/$tdir
2843         $LFS setstripe -p $pool $DIR/$tdir
2844         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2845         $LFS getstripe $DIR/$tdir/$tfile
2846 }
2847 run_test 27I "check that root dir striping does not break parent dir one"
2848
2849 test_27J() {
2850         (( $MDS1_VERSION > $(version_code 2.12.51) )) ||
2851                 skip "Need MDS version newer than 2.12.51"
2852
2853         # skip basic ops on file with foreign LOV tests on 5.12-6.2 kernels
2854         # until the filemap_read() issue is fixed by v6.2-rc4-61-g5956592ce337
2855         (( $LINUX_VERSION_CODE < $(version_code 5.12.0) ||
2856            $LINUX_VERSION_CODE >= $(version_code 6.2.0) )) ||
2857                 skip "Need kernel < 5.12.0 or >= 6.2.0 for filemap_read() fix"
2858
2859         test_mkdir $DIR/$tdir
2860         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2861         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2862
2863         # create foreign file (raw way)
2864         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2865                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2866
2867         ! $LFS setstripe --foreign --flags foo \
2868                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2869                         error "creating $tfile with '--flags foo' should fail"
2870
2871         ! $LFS setstripe --foreign --flags 0xffffffff \
2872                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2873                         error "creating $tfile w/ 0xffffffff flags should fail"
2874
2875         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2876                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2877
2878         # verify foreign file (raw way)
2879         parse_foreign_file -f $DIR/$tdir/$tfile |
2880                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2881                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2882         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2883                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2884         parse_foreign_file -f $DIR/$tdir/$tfile |
2885                 grep "lov_foreign_size: 73" ||
2886                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2887         parse_foreign_file -f $DIR/$tdir/$tfile |
2888                 grep "lov_foreign_type: 1" ||
2889                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2890         parse_foreign_file -f $DIR/$tdir/$tfile |
2891                 grep "lov_foreign_flags: 0x0000DA08" ||
2892                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2893         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2894                 grep "lov_foreign_value: 0x" |
2895                 sed -e 's/lov_foreign_value: 0x//')
2896         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2897         [[ $lov = ${lov2// /} ]] ||
2898                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2899
2900         # create foreign file (lfs + API)
2901         $LFS setstripe --foreign=none --flags 0xda08 \
2902                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2903                 error "$DIR/$tdir/${tfile}2: create failed"
2904
2905         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2906                 grep "lfm_magic:.*0x0BD70BD0" ||
2907                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2908         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2909         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2910                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2911         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2912                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2913         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2914                 grep "lfm_flags:.*0x0000DA08" ||
2915                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2916         $LFS getstripe $DIR/$tdir/${tfile}2 |
2917                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2918                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2919
2920         # modify striping should fail
2921         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2922                 error "$DIR/$tdir/$tfile: setstripe should fail"
2923         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2924                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2925
2926         # R/W should fail
2927         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2928         cat $DIR/$tdir/${tfile}2 &&
2929                 error "$DIR/$tdir/${tfile}2: read should fail"
2930         cat /etc/passwd > $DIR/$tdir/$tfile &&
2931                 error "$DIR/$tdir/$tfile: write should fail"
2932         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2933                 error "$DIR/$tdir/${tfile}2: write should fail"
2934
2935         # chmod should work
2936         chmod 222 $DIR/$tdir/$tfile ||
2937                 error "$DIR/$tdir/$tfile: chmod failed"
2938         chmod 222 $DIR/$tdir/${tfile}2 ||
2939                 error "$DIR/$tdir/${tfile}2: chmod failed"
2940
2941         # chown should work
2942         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2943                 error "$DIR/$tdir/$tfile: chown failed"
2944         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2945                 error "$DIR/$tdir/${tfile}2: chown failed"
2946
2947         # rename should work
2948         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2949                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2950         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2951                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2952
2953         #remove foreign file
2954         rm $DIR/$tdir/${tfile}.new ||
2955                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2956         rm $DIR/$tdir/${tfile}2.new ||
2957                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2958 }
2959 run_test 27J "basic ops on file with foreign LOV"
2960
2961 test_27K() {
2962         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2963                 skip "Need MDS version newer than 2.12.49"
2964
2965         test_mkdir $DIR/$tdir
2966         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2967         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2968
2969         # create foreign dir (raw way)
2970         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2971                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2972
2973         ! $LFS setdirstripe --foreign --flags foo \
2974                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2975                         error "creating $tdir with '--flags foo' should fail"
2976
2977         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2978                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2979                         error "creating $tdir w/ 0xffffffff flags should fail"
2980
2981         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2982                 error "create_foreign_dir FAILED"
2983
2984         # verify foreign dir (raw way)
2985         parse_foreign_dir -d $DIR/$tdir/$tdir |
2986                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2987                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2988         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2989                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2990         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2991                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2992         parse_foreign_dir -d $DIR/$tdir/$tdir |
2993                 grep "lmv_foreign_flags: 55813$" ||
2994                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2995         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2996                 grep "lmv_foreign_value: 0x" |
2997                 sed 's/lmv_foreign_value: 0x//')
2998         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2999                 sed 's/ //g')
3000         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
3001
3002         # create foreign dir (lfs + API)
3003         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
3004                 $DIR/$tdir/${tdir}2 ||
3005                 error "$DIR/$tdir/${tdir}2: create failed"
3006
3007         $LFS getdirstripe -v $DIR/$tdir/${tdir}2
3008
3009         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
3010                 grep "lfm_magic:.*0x0CD50CD0" ||
3011                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
3012         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
3013         # - sizeof(lfm_type) - sizeof(lfm_flags)
3014         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
3015                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
3016         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
3017                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
3018         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
3019                 grep "lfm_flags:.*0x0000DA05" ||
3020                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
3021         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
3022                 grep "lfm_value.*${uuid1}@${uuid2}" ||
3023                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
3024
3025         # file create in dir should fail
3026         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3027         touch $DIR/$tdir/${tdir}2/$tfile &&
3028                 error "$DIR/${tdir}2: file create should fail"
3029
3030         # chmod should work
3031         chmod 777 $DIR/$tdir/$tdir ||
3032                 error "$DIR/$tdir: chmod failed"
3033         chmod 777 $DIR/$tdir/${tdir}2 ||
3034                 error "$DIR/${tdir}2: chmod failed"
3035
3036         # chown should work
3037         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
3038                 error "$DIR/$tdir: chown failed"
3039         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
3040                 error "$DIR/${tdir}2: chown failed"
3041
3042         # rename should work
3043         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3044                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
3045         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
3046                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
3047
3048         #remove foreign dir
3049         rmdir $DIR/$tdir/${tdir}.new ||
3050                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
3051         rmdir $DIR/$tdir/${tdir}2.new ||
3052                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
3053 }
3054 run_test 27K "basic ops on dir with foreign LMV"
3055
3056 test_27L() {
3057         remote_mds_nodsh && skip "remote MDS with nodsh"
3058
3059         local POOL=${POOL:-$TESTNAME}
3060
3061         pool_add $POOL || error "pool_add failed"
3062
3063         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
3064                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
3065                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
3066 }
3067 run_test 27L "lfs pool_list gives correct pool name"
3068
3069 test_27M() {
3070         (( $MDS1_VERSION >= $(version_code 2.12.57) )) ||
3071                 skip "Need MDS version >= than 2.12.57"
3072         remote_mds_nodsh && skip "remote MDS with nodsh"
3073         (( $OSTCOUNT > 1 )) || skip "need > 1 OST"
3074
3075         # Set default striping on directory
3076         local setcount=4
3077         local stripe_opt
3078         local mdts=$(comma_list $(mdts_nodes))
3079
3080         # if we run against a 2.12 server which lacks overstring support
3081         # then the connect_flag will not report overstriping, even if client
3082         # is 2.14+
3083         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
3084                 stripe_opt="-C $setcount"
3085         elif (( $OSTCOUNT >= $setcount )); then
3086                 stripe_opt="-c $setcount"
3087         else
3088                 skip "server does not support overstriping"
3089         fi
3090
3091         test_mkdir $DIR/$tdir
3092
3093         # Validate existing append_* params and ensure restore
3094         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3095         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3096         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3097
3098         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3099         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
3100         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
3101
3102         $LFS setstripe $stripe_opt $DIR/$tdir
3103
3104         echo 1 > $DIR/$tdir/${tfile}.1
3105         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
3106         (( $count == $setcount )) ||
3107                 error "(1) stripe count $count, should be $setcount"
3108
3109         local appendcount=$orig_count
3110         echo 1 >> $DIR/$tdir/${tfile}.2_append
3111         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3112         (( $count == $appendcount )) ||
3113                 error "(2)stripe count $count, should be $appendcount for append"
3114
3115         # Disable O_APPEND striping, verify it works
3116         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3117
3118         # Should now get the default striping, which is 4
3119         setcount=4
3120         echo 1 >> $DIR/$tdir/${tfile}.3_append
3121         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3122         (( $count == $setcount )) ||
3123                 error "(3) stripe count $count, should be $setcount"
3124
3125         # Try changing the stripe count for append files
3126         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3127
3128         # Append striping is now 2 (directory default is still 4)
3129         appendcount=2
3130         echo 1 >> $DIR/$tdir/${tfile}.4_append
3131         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3132         (( $count == $appendcount )) ||
3133                 error "(4) stripe count $count, should be $appendcount for append"
3134
3135         # Test append stripe count of -1
3136         # Exercise LU-16872 patch with specific striping, only if MDS has fix
3137         (( $MDS1_VERSION > $(version_code 2.15.56.46) )) &&
3138                 $LFS setstripe -o 0,$((OSTCOUNT - 1)) $DIR/$tdir &&
3139                 touch $DIR/$tdir/$tfile.specific.{1..128}
3140         stack_trap "rm -f $DIR/$tdir/$tfile.*"
3141
3142         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3143         appendcount=$OSTCOUNT
3144         echo 1 >> $DIR/$tdir/${tfile}.5
3145         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3146         (( $count == $appendcount )) ||
3147                 error "(5) stripe count $count, should be $appendcount for append"
3148
3149         # Set append striping back to default of 1
3150         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3151
3152         # Try a new default striping, PFL + DOM
3153         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3154
3155         # Create normal DOM file, DOM returns stripe count == 0
3156         setcount=0
3157         touch $DIR/$tdir/${tfile}.6
3158         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3159         (( $count == $setcount )) ||
3160                 error "(6) stripe count $count, should be $setcount"
3161
3162         # Show
3163         appendcount=1
3164         echo 1 >> $DIR/$tdir/${tfile}.7_append
3165         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3166         (( $count == $appendcount )) ||
3167                 error "(7) stripe count $count, should be $appendcount for append"
3168
3169         # Clean up DOM layout
3170         $LFS setstripe -d $DIR/$tdir
3171
3172         save_layout_restore_at_exit $MOUNT
3173         # Now test that append striping works when layout is from root
3174         $LFS setstripe -c 2 $MOUNT
3175         # Make a special directory for this
3176         mkdir $DIR/${tdir}/${tdir}.2
3177
3178         # Verify for normal file
3179         setcount=2
3180         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3181         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3182         (( $count == $setcount )) ||
3183                 error "(8) stripe count $count, should be $setcount"
3184
3185         appendcount=1
3186         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3187         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3188         (( $count == $appendcount )) ||
3189                 error "(9) stripe count $count, should be $appendcount for append"
3190
3191         # Now test O_APPEND striping with pools
3192         pool_add $TESTNAME || error "pool creation failed"
3193         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3194         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3195
3196         echo 1 >> $DIR/$tdir/${tfile}.10_append
3197
3198         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3199         [[ "$pool" == "$TESTNAME" ]] || error "(10) incorrect pool: $pool"
3200
3201         # Check that count is still correct
3202         appendcount=1
3203         echo 1 >> $DIR/$tdir/${tfile}.11_append
3204         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3205         (( $count == $appendcount )) ||
3206                 error "(11) stripe count $count, should be $appendcount for append"
3207
3208         # Disable O_APPEND stripe count, verify pool works separately
3209         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3210
3211         echo 1 >> $DIR/$tdir/${tfile}.12_append
3212
3213         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3214         [[ "$pool" == "$TESTNAME" ]] || error "(12) incorrect pool: $pool"
3215
3216         # Remove pool setting, verify it's not applied
3217         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3218
3219         echo 1 >> $DIR/$tdir/${tfile}.13_append
3220
3221         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3222         [[ -z "$pool" ]] || error "(13) pool found: $pool"
3223 }
3224 run_test 27M "test O_APPEND striping"
3225
3226 test_27N() {
3227         combined_mgs_mds && skip "needs separate MGS/MDT"
3228
3229         pool_add $TESTNAME || error "pool_add failed"
3230         do_facet mgs "$LCTL pool_list $FSNAME" |
3231                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3232                 error "lctl pool_list on MGS failed"
3233 }
3234 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3235
3236 clean_foreign_symlink() {
3237         trap 0
3238         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3239         for i in $DIR/$tdir/* ; do
3240                 $LFS unlink_foreign $i || true
3241         done
3242 }
3243
3244 test_27O() {
3245         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3246                 skip "Need MDS version newer than 2.12.51"
3247
3248         test_mkdir $DIR/$tdir
3249         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3250         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3251
3252         trap clean_foreign_symlink EXIT
3253
3254         # enable foreign_symlink behaviour
3255         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3256
3257         # foreign symlink LOV format is a partial path by default
3258
3259         # create foreign file (lfs + API)
3260         $LFS setstripe --foreign=symlink --flags 0xda05 \
3261                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3262                 error "$DIR/$tdir/${tfile}: create failed"
3263
3264         $LFS getstripe -v $DIR/$tdir/${tfile} |
3265                 grep "lfm_magic:.*0x0BD70BD0" ||
3266                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3267         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3268                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3269         $LFS getstripe -v $DIR/$tdir/${tfile} |
3270                 grep "lfm_flags:.*0x0000DA05" ||
3271                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3272         $LFS getstripe $DIR/$tdir/${tfile} |
3273                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3274                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3275
3276         # modify striping should fail
3277         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3278                 error "$DIR/$tdir/$tfile: setstripe should fail"
3279
3280         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3281         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3282         cat /etc/passwd > $DIR/$tdir/$tfile &&
3283                 error "$DIR/$tdir/$tfile: write should fail"
3284
3285         # rename should succeed
3286         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3287                 error "$DIR/$tdir/$tfile: rename has failed"
3288
3289         #remove foreign_symlink file should fail
3290         rm $DIR/$tdir/${tfile}.new &&
3291                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3292
3293         #test fake symlink
3294         mkdir /tmp/${uuid1} ||
3295                 error "/tmp/${uuid1}: mkdir has failed"
3296         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3297                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3298         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3299         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3300                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3301         #read should succeed now
3302         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3303                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3304         #write should succeed now
3305         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3306                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3307         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3308                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3309         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3310                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3311
3312         #check that getstripe still works
3313         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3314                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3315
3316         # chmod should still succeed
3317         chmod 644 $DIR/$tdir/${tfile}.new ||
3318                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3319
3320         # chown should still succeed
3321         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3322                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3323
3324         # rename should still succeed
3325         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3326                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3327
3328         #remove foreign_symlink file should still fail
3329         rm $DIR/$tdir/${tfile} &&
3330                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3331
3332         #use special ioctl() to unlink foreign_symlink file
3333         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3334                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3335
3336 }
3337 run_test 27O "basic ops on foreign file of symlink type"
3338
3339 test_27P() {
3340         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3341                 skip "Need MDS version newer than 2.12.49"
3342
3343         test_mkdir $DIR/$tdir
3344         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3345         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3346
3347         trap clean_foreign_symlink EXIT
3348
3349         # enable foreign_symlink behaviour
3350         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3351
3352         # foreign symlink LMV format is a partial path by default
3353
3354         # create foreign dir (lfs + API)
3355         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3356                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3357                 error "$DIR/$tdir/${tdir}: create failed"
3358
3359         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3360
3361         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3362                 grep "lfm_magic:.*0x0CD50CD0" ||
3363                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3364         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3365                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3366         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3367                 grep "lfm_flags:.*0x0000DA05" ||
3368                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3369         $LFS getdirstripe $DIR/$tdir/${tdir} |
3370                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3371                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3372
3373         # file create in dir should fail
3374         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3375         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3376
3377         # rename should succeed
3378         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3379                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3380
3381         #remove foreign_symlink dir should fail
3382         rmdir $DIR/$tdir/${tdir}.new &&
3383                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3384
3385         #test fake symlink
3386         mkdir -p /tmp/${uuid1}/${uuid2} ||
3387                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3388         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3389                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3390         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3391         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3392                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3393         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3394                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3395
3396         #check that getstripe fails now that foreign_symlink enabled
3397         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3398                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3399
3400         # file create in dir should work now
3401         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3402                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3403         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3404                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3405         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3406                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3407
3408         # chmod should still succeed
3409         chmod 755 $DIR/$tdir/${tdir}.new ||
3410                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3411
3412         # chown should still succeed
3413         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3414                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3415
3416         # rename should still succeed
3417         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3418                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3419
3420         #remove foreign_symlink dir should still fail
3421         rmdir $DIR/$tdir/${tdir} &&
3422                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3423
3424         #use special ioctl() to unlink foreign_symlink file
3425         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3426                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3427
3428         #created file should still exist
3429         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3430                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3431         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3432                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3433 }
3434 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3435
3436 test_27Q() {
3437         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3438         stack_trap "rm -f $TMP/$tfile*"
3439
3440         test_mkdir $DIR/$tdir-1
3441         test_mkdir $DIR/$tdir-2
3442
3443         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3444         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3445
3446         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3447         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3448
3449         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3450         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3451
3452         # Create some bad symlinks and ensure that we don't loop
3453         # forever or something. These should return ELOOP (40) and
3454         # ENOENT (2) but I don't want to test for that because there's
3455         # always some weirdo architecture that needs to ruin
3456         # everything by defining these error numbers differently.
3457
3458         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3459         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3460
3461         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3462         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3463
3464         return 0
3465 }
3466 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3467
3468 test_27R() {
3469         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3470                 skip "need MDS 2.14.55 or later"
3471         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3472
3473         local testdir="$DIR/$tdir"
3474         test_mkdir -p $testdir
3475         stack_trap "rm -rf $testdir"
3476         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3477
3478         local f1="$testdir/f1"
3479         touch $f1 || error "failed to touch $f1"
3480         local count=$($LFS getstripe -c $f1)
3481         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3482
3483         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3484         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3485
3486         local maxcount=$(($OSTCOUNT - 1))
3487         local mdts=$(comma_list $(mdts_nodes))
3488         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3489         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3490
3491         local f2="$testdir/f2"
3492         touch $f2 || error "failed to touch $f2"
3493         local count=$($LFS getstripe -c $f2)
3494         (( $count == $maxcount )) || error "wrong stripe count"
3495 }
3496 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3497
3498 test_27T() {
3499         [ $(facet_host client) == $(facet_host ost1) ] &&
3500                 skip "need ost1 and client on different nodes"
3501
3502 #define OBD_FAIL_OSC_NO_GRANT            0x411
3503         $LCTL set_param fail_loc=0x20000411 fail_val=1
3504 #define OBD_FAIL_OST_ENOSPC              0x215
3505         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3506         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3507         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3508                 error "multiop failed"
3509 }
3510 run_test 27T "no eio on close on partial write due to enosp"
3511
3512 test_27U() {
3513         local dir=$DIR/$tdir
3514         local file=$dir/$tfile
3515         local append_pool=${TESTNAME}-append
3516         local normal_pool=${TESTNAME}-normal
3517         local pool
3518         local stripe_count
3519         local stripe_count2
3520         local mdts=$(comma_list $(mdts_nodes))
3521
3522         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
3523                 skip "Need MDS version at least 2.15.51 for append pool feature"
3524
3525         # Validate existing append_* params and ensure restore
3526         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3527         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3528         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3529
3530         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3531         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3532         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3533
3534         pool_add $append_pool || error "pool creation failed"
3535         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3536
3537         pool_add $normal_pool || error "pool creation failed"
3538         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3539
3540         test_mkdir $dir
3541         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3542
3543         echo XXX >> $file.1
3544         $LFS getstripe $file.1
3545
3546         pool=$($LFS getstripe -p $file.1)
3547         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3548
3549         stripe_count2=$($LFS getstripe -c $file.1)
3550         ((stripe_count2 == stripe_count)) ||
3551                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3552
3553         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3554
3555         echo XXX >> $file.2
3556         $LFS getstripe $file.2
3557
3558         pool=$($LFS getstripe -p $file.2)
3559         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3560
3561         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3562
3563         echo XXX >> $file.3
3564         $LFS getstripe $file.3
3565
3566         stripe_count2=$($LFS getstripe -c $file.3)
3567         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3568 }
3569 run_test 27U "append pool and stripe count work with composite default layout"
3570
3571 test_27V() {
3572         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3573         (( $OSTCOUNT >= 4 )) || skip_env "needs >= 4 OSTs"
3574
3575         local dir=$DIR/$tdir
3576         local osp_param=osp.$FSNAME-OST0000-osc-MDT0000.max_create_count
3577         local lod_param=lod.$FSNAME-MDT0000-mdtlov.qos_threshold_rr
3578         local saved_max=$(do_facet mds1 $LCTL get_param -n $osp_param)
3579         local saved_qos=$(do_facet mds1 $LCTL get_param -n $lod_param)
3580         local pid
3581
3582         stack_trap "do_facet mds1 $LCTL set_param $osp_param=$saved_max"
3583
3584         do_facet mds1 $LCTL set_param $lod_param=0
3585         stack_trap "do_facet mds1 $LCTL set_param $lod_param=$saved_qos"
3586
3587         $LFS setdirstripe --mdt-count=1 --mdt-index=0 $dir
3588         stack_trap "rm -rf $dir"
3589
3590         # exercise race in LU-16981 with deactivating OST while creating a file
3591         (
3592                 while true; do
3593                         do_facet mds1 $LCTL set_param $osp_param=0 > /dev/null
3594                         sleep 0.1
3595                         do_facet mds1 \
3596                                 $LCTL set_param $osp_param=$saved_max > /dev/null
3597                 done
3598         ) &
3599
3600         pid=$!
3601         stack_trap "kill -9 $pid"
3602
3603         # errors here are OK so ignore them (just don't want to crash)
3604         $LFS setstripe -c -1 $dir/f.{1..200} 2> /dev/null
3605
3606         return 0
3607 }
3608 run_test 27V "creating widely striped file races with deactivating OST"
3609
3610 # createtest also checks that device nodes are created and
3611 # then visible correctly (#2091)
3612 test_28() { # bug 2091
3613         test_mkdir $DIR/d28
3614         $CREATETEST $DIR/d28/ct || error "createtest failed"
3615 }
3616 run_test 28 "create/mknod/mkdir with bad file types ============"
3617
3618 test_29() {
3619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3620
3621         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3622                 disable_opencache
3623                 stack_trap "restore_opencache"
3624         }
3625
3626         sync; sleep 1; sync # flush out any dirty pages from previous tests
3627         cancel_lru_locks
3628         test_mkdir $DIR/d29
3629         touch $DIR/d29/foo
3630         log 'first d29'
3631         ls -l $DIR/d29
3632
3633         local locks_orig=$(total_used_locks mdc)
3634         (( $locks_orig != 0 )) || error "No mdc lock count"
3635
3636         local locks_unused_orig=$(total_unused_locks mdc)
3637
3638         log 'second d29'
3639         ls -l $DIR/d29
3640         log 'done'
3641
3642         local locks_current=$(total_used_locks mdc)
3643
3644         local locks_unused_current=$(total_unused_locks mdc)
3645
3646         if (( $locks_current > $locks_orig )); then
3647                 $LCTL set_param -n ldlm.dump_namespaces ""
3648                 error "CURRENT: $locks_current > $locks_orig"
3649         fi
3650         if (( $locks_unused_current > $locks_unused_orig )); then
3651                 error "UNUSED: $locks_unused_current > $locks_unused_orig"
3652         fi
3653 }
3654 run_test 29 "IT_GETATTR regression  ============================"
3655
3656 test_30a() { # was test_30
3657         cp $(which ls) $DIR || cp /bin/ls $DIR
3658         $DIR/ls / || error "Can't execute binary from lustre"
3659         rm $DIR/ls
3660 }
3661 run_test 30a "execute binary from Lustre (execve) =============="
3662
3663 test_30b() {
3664         cp `which ls` $DIR || cp /bin/ls $DIR
3665         chmod go+rx $DIR/ls
3666         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3667         rm $DIR/ls
3668 }
3669 run_test 30b "execute binary from Lustre as non-root ==========="
3670
3671 test_30c() { # b=22376
3672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3673
3674         cp $(which ls) $DIR || cp /bin/ls $DIR
3675         chmod a-rw $DIR/ls
3676         cancel_lru_locks mdc
3677         cancel_lru_locks osc
3678         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3679         rm -f $DIR/ls
3680 }
3681 run_test 30c "execute binary from Lustre without read perms ===="
3682
3683 test_30d() {
3684         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3685
3686         for i in {1..10}; do
3687                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3688                 local PID=$!
3689                 sleep 1
3690                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3691                 wait $PID || error "executing dd from Lustre failed"
3692                 rm -f $DIR/$tfile
3693         done
3694
3695         rm -f $DIR/dd
3696 }
3697 run_test 30d "execute binary from Lustre while clear locks"
3698
3699 test_31a() {
3700         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3701         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3702 }
3703 run_test 31a "open-unlink file =================================="
3704
3705 test_31b() {
3706         touch $DIR/f31 || error "touch $DIR/f31 failed"
3707         ln $DIR/f31 $DIR/f31b || error "ln failed"
3708         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3709         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3710 }
3711 run_test 31b "unlink file with multiple links while open ======="
3712
3713 test_31c() {
3714         touch $DIR/f31 || error "touch $DIR/f31 failed"
3715         ln $DIR/f31 $DIR/f31c || error "ln failed"
3716         multiop_bg_pause $DIR/f31 O_uc ||
3717                 error "multiop_bg_pause for $DIR/f31 failed"
3718         MULTIPID=$!
3719         $MULTIOP $DIR/f31c Ouc
3720         kill -USR1 $MULTIPID
3721         wait $MULTIPID
3722 }
3723 run_test 31c "open-unlink file with multiple links ============="
3724
3725 test_31d() {
3726         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3727         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3728 }
3729 run_test 31d "remove of open directory ========================="
3730
3731 test_31e() { # bug 2904
3732         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3733 }
3734 run_test 31e "remove of open non-empty directory ==============="
3735
3736 test_31f() { # bug 4554
3737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3738
3739         set -vx
3740         test_mkdir $DIR/d31f
3741         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3742         cp /etc/hosts $DIR/d31f
3743         ls -l $DIR/d31f
3744         $LFS getstripe $DIR/d31f/hosts
3745         multiop_bg_pause $DIR/d31f D_c || return 1
3746         MULTIPID=$!
3747
3748         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3749         test_mkdir $DIR/d31f
3750         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3751         cp /etc/hosts $DIR/d31f
3752         ls -l $DIR/d31f
3753         $LFS getstripe $DIR/d31f/hosts
3754         multiop_bg_pause $DIR/d31f D_c || return 1
3755         MULTIPID2=$!
3756
3757         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3758         wait $MULTIPID || error "first opendir $MULTIPID failed"
3759
3760         sleep 6
3761
3762         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3763         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3764         set +vx
3765 }
3766 run_test 31f "remove of open directory with open-unlink file ==="
3767
3768 test_31g() {
3769         echo "-- cross directory link --"
3770         test_mkdir -c1 $DIR/${tdir}ga
3771         test_mkdir -c1 $DIR/${tdir}gb
3772         touch $DIR/${tdir}ga/f
3773         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3774         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3775         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3776         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3777         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3778 }
3779 run_test 31g "cross directory link==============="
3780
3781 test_31h() {
3782         echo "-- cross directory link --"
3783         test_mkdir -c1 $DIR/${tdir}
3784         test_mkdir -c1 $DIR/${tdir}/dir
3785         touch $DIR/${tdir}/f
3786         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3787         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3788         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3789         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3790         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3791 }
3792 run_test 31h "cross directory link under child==============="
3793
3794 test_31i() {
3795         echo "-- cross directory link --"
3796         test_mkdir -c1 $DIR/$tdir
3797         test_mkdir -c1 $DIR/$tdir/dir
3798         touch $DIR/$tdir/dir/f
3799         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3800         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3801         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3802         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3803         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3804 }
3805 run_test 31i "cross directory link under parent==============="
3806
3807 test_31j() {
3808         test_mkdir -c1 -p $DIR/$tdir
3809         test_mkdir -c1 -p $DIR/$tdir/dir1
3810         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3811         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3812         link $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "link to the same dir"
3813         return 0
3814 }
3815 run_test 31j "link for directory"
3816
3817 test_31k() {
3818         test_mkdir -c1 -p $DIR/$tdir
3819         touch $DIR/$tdir/s
3820         touch $DIR/$tdir/exist
3821         link $DIR/$tdir/s $DIR/$tdir/t || error "link"
3822         link $DIR/$tdir/s $DIR/$tdir/exist && error "link to exist file"
3823         link $DIR/$tdir/s $DIR/$tdir/s && error "link to the same file"
3824         link $DIR/$tdir/s $DIR/$tdir && error "link to parent dir"
3825         link $DIR/$tdir $DIR/$tdir/s && error "link parent dir to target"
3826         link $DIR/$tdir/not-exist $DIR/$tdir/foo && error "link non-existing to new"
3827         link $DIR/$tdir/not-exist $DIR/$tdir/s && error "link non-existing to exist"
3828         return 0
3829 }
3830 run_test 31k "link to file: the same, non-existing, dir"
3831
3832 test_31l() {
3833         local ln_ver=$(ln --version | awk '/coreutils/ { print $4 }')
3834
3835         (( $(version_code $ln_ver) < $(version_code 8.31) )) ||
3836         (( $(version_code $(uname -r)) >= $(version_code 5.18) )) ||
3837                 skip "need coreutils < 8.31 or kernel >= 5.18 for ln"
3838
3839         touch $DIR/$tfile || error "create failed"
3840         mkdir $DIR/$tdir || error "mkdir failed"
3841         ln $DIR/$tfile $DIR/$tdir/ || error "ln to '$tdir/' failed"
3842 }
3843 run_test 31l "link to file: target dir has trailing slash"
3844
3845 test_31m() {
3846         mkdir $DIR/d31m
3847         touch $DIR/d31m/s
3848         mkdir $DIR/d31m2
3849         touch $DIR/d31m2/exist
3850         link $DIR/d31m/s $DIR/d31m2/t || error "link"
3851         link $DIR/d31m/s $DIR/d31m2/exist && error "link to exist file"
3852         link $DIR/d31m/s $DIR/d31m2 && error "link to parent dir"
3853         link $DIR/d31m2 $DIR/d31m/s && error "link parent dir to target"
3854         link $DIR/d31m/not-exist $DIR/d31m2/foo && error "link non-existing to new"
3855         link $DIR/d31m/not-exist $DIR/d31m2/s && error "link non-existing to exist"
3856         return 0
3857 }
3858 run_test 31m "link to file: the same, non-existing, dir"
3859
3860 test_31n() {
3861         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3862         nlink=$(stat --format=%h $DIR/$tfile)
3863         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3864         local fd=$(free_fd)
3865         local cmd="exec $fd<$DIR/$tfile"
3866         eval $cmd
3867         cmd="exec $fd<&-"
3868         trap "eval $cmd" EXIT
3869         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3870         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3871         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3872         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3873         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3874         eval $cmd
3875 }
3876 run_test 31n "check link count of unlinked file"
3877
3878 link_one() {
3879         local tempfile=$(mktemp $1_XXXXXX)
3880         link $tempfile $1 2> /dev/null &&
3881                 echo "$BASHPID: link $tempfile to $1 succeeded"
3882         unlink $tempfile
3883 }
3884
3885 test_31o() { # LU-2901
3886         test_mkdir $DIR/$tdir
3887         for LOOP in $(seq 100); do
3888                 rm -f $DIR/$tdir/$tfile*
3889                 for THREAD in $(seq 8); do
3890                         link_one $DIR/$tdir/$tfile.$LOOP &
3891                 done
3892                 wait
3893                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3894                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3895                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3896                         break || true
3897         done
3898 }
3899 run_test 31o "duplicate hard links with same filename"
3900
3901 test_31p() {
3902         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3903
3904         test_mkdir $DIR/$tdir
3905         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3906         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3907
3908         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3909                 error "open unlink test1 failed"
3910         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3911                 error "open unlink test2 failed"
3912
3913         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3914                 error "test1 still exists"
3915         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3916                 error "test2 still exists"
3917 }
3918 run_test 31p "remove of open striped directory"
3919
3920 test_31q() {
3921         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3922
3923         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3924         index=$($LFS getdirstripe -i $DIR/$tdir)
3925         [ $index -eq 3 ] || error "first stripe index $index != 3"
3926         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3927         [ $index -eq 1 ] || error "second stripe index $index != 1"
3928
3929         # when "-c <stripe_count>" is set, the number of MDTs specified after
3930         # "-i" should equal to the stripe count
3931         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3932 }
3933 run_test 31q "create striped directory on specific MDTs"
3934
3935 #LU-14949
3936 test_31r() {
3937         touch $DIR/$tfile.target
3938         touch $DIR/$tfile.source
3939
3940         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3941         $LCTL set_param fail_loc=0x1419 fail_val=3
3942         cat $DIR/$tfile.target &
3943         CATPID=$!
3944
3945         # Guarantee open is waiting before we get here
3946         sleep 1
3947         mv $DIR/$tfile.source $DIR/$tfile.target
3948
3949         wait $CATPID
3950         RC=$?
3951         if [[ $RC -ne 0 ]]; then
3952                 error "open with cat failed, rc=$RC"
3953         fi
3954 }
3955 run_test 31r "open-rename(replace) race"
3956
3957 cleanup_test32_mount() {
3958         local rc=0
3959         trap 0
3960         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3961         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3962         losetup -d $loopdev || true
3963         rm -rf $DIR/$tdir
3964         return $rc
3965 }
3966
3967 test_32a() {
3968         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3969
3970         echo "== more mountpoints and symlinks ================="
3971         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3972         trap cleanup_test32_mount EXIT
3973         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3974         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3975                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3976         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3977                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3978         cleanup_test32_mount
3979 }
3980 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3981
3982 test_32b() {
3983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3984
3985         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3986         trap cleanup_test32_mount EXIT
3987         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3988         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3989                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3990         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3991                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3992         cleanup_test32_mount
3993 }
3994 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3995
3996 test_32c() {
3997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3998
3999         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4000         trap cleanup_test32_mount EXIT
4001         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4002         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4003                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4004         test_mkdir -p $DIR/$tdir/d2/test_dir
4005         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
4006                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
4007         cleanup_test32_mount
4008 }
4009 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
4010
4011 test_32d() {
4012         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4013
4014         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4015         trap cleanup_test32_mount EXIT
4016         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4017         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4018                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4019         test_mkdir -p $DIR/$tdir/d2/test_dir
4020         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
4021                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
4022         cleanup_test32_mount
4023 }
4024 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
4025
4026 test_32e() {
4027         rm -fr $DIR/$tdir
4028         test_mkdir -p $DIR/$tdir/tmp
4029         local tmp_dir=$DIR/$tdir/tmp
4030         ln -s $DIR/$tdir $tmp_dir/symlink11
4031         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
4032         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
4033         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
4034 }
4035 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
4036
4037 test_32f() {
4038         rm -fr $DIR/$tdir
4039         test_mkdir -p $DIR/$tdir/tmp
4040         local tmp_dir=$DIR/$tdir/tmp
4041         ln -s $DIR/$tdir $tmp_dir/symlink11
4042         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
4043         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
4044         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
4045 }
4046 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
4047
4048 test_32g() {
4049         local tmp_dir=$DIR/$tdir/tmp
4050         test_mkdir -p $tmp_dir
4051         test_mkdir $DIR/${tdir}2
4052         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
4053         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
4054         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
4055         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
4056         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
4057         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
4058 }
4059 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
4060
4061 test_32h() {
4062         rm -fr $DIR/$tdir $DIR/${tdir}2
4063         tmp_dir=$DIR/$tdir/tmp
4064         test_mkdir -p $tmp_dir
4065         test_mkdir $DIR/${tdir}2
4066         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
4067         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
4068         ls $tmp_dir/symlink12 || error "listing symlink12"
4069         ls $DIR/$tdir/symlink02  || error "listing symlink02"
4070 }
4071 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
4072
4073 test_32i() {
4074         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4075
4076         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4077         trap cleanup_test32_mount EXIT
4078         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4079         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4080                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4081         touch $DIR/$tdir/test_file
4082         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
4083                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
4084         cleanup_test32_mount
4085 }
4086 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
4087
4088 test_32j() {
4089         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4090
4091         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4092         trap cleanup_test32_mount EXIT
4093         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4094         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4095                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4096         touch $DIR/$tdir/test_file
4097         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
4098                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
4099         cleanup_test32_mount
4100 }
4101 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
4102
4103 test_32k() {
4104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4105
4106         rm -fr $DIR/$tdir
4107         trap cleanup_test32_mount EXIT
4108         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4109         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4110                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4111         test_mkdir -p $DIR/$tdir/d2
4112         touch $DIR/$tdir/d2/test_file || error "touch failed"
4113         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4114                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
4115         cleanup_test32_mount
4116 }
4117 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
4118
4119 test_32l() {
4120         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4121
4122         rm -fr $DIR/$tdir
4123         trap cleanup_test32_mount EXIT
4124         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4125         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4126                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4127         test_mkdir -p $DIR/$tdir/d2
4128         touch $DIR/$tdir/d2/test_file || error "touch failed"
4129         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4130                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
4131         cleanup_test32_mount
4132 }
4133 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
4134
4135 test_32m() {
4136         rm -fr $DIR/d32m
4137         test_mkdir -p $DIR/d32m/tmp
4138         TMP_DIR=$DIR/d32m/tmp
4139         ln -s $DIR $TMP_DIR/symlink11
4140         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4141         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
4142                 error "symlink11 not a link"
4143         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
4144                 error "symlink01 not a link"
4145 }
4146 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
4147
4148 test_32n() {
4149         rm -fr $DIR/d32n
4150         test_mkdir -p $DIR/d32n/tmp
4151         TMP_DIR=$DIR/d32n/tmp
4152         ln -s $DIR $TMP_DIR/symlink11
4153         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4154         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4155         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4156 }
4157 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4158
4159 test_32o() {
4160         touch $DIR/$tfile
4161         test_mkdir -p $DIR/d32o/tmp
4162         TMP_DIR=$DIR/d32o/tmp
4163         ln -s $DIR/$tfile $TMP_DIR/symlink12
4164         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4165         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4166                 error "symlink12 not a link"
4167         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4168         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4169                 error "$DIR/d32o/tmp/symlink12 not file type"
4170         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4171                 error "$DIR/d32o/symlink02 not file type"
4172 }
4173 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4174
4175 test_32p() {
4176         log 32p_1
4177         rm -fr $DIR/d32p
4178         log 32p_2
4179         rm -f $DIR/$tfile
4180         log 32p_3
4181         touch $DIR/$tfile
4182         log 32p_4
4183         test_mkdir -p $DIR/d32p/tmp
4184         log 32p_5
4185         TMP_DIR=$DIR/d32p/tmp
4186         log 32p_6
4187         ln -s $DIR/$tfile $TMP_DIR/symlink12
4188         log 32p_7
4189         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4190         log 32p_8
4191         cat $DIR/d32p/tmp/symlink12 ||
4192                 error "Can't open $DIR/d32p/tmp/symlink12"
4193         log 32p_9
4194         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4195         log 32p_10
4196 }
4197 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4198
4199 test_32q() {
4200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4201
4202         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4203         trap cleanup_test32_mount EXIT
4204         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4205         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4206         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4207                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4208         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4209         cleanup_test32_mount
4210 }
4211 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4212
4213 test_32r() {
4214         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4215
4216         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4217         trap cleanup_test32_mount EXIT
4218         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4219         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4220         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4221                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4222         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4223         cleanup_test32_mount
4224 }
4225 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4226
4227 test_33aa() {
4228         rm -f $DIR/$tfile
4229         touch $DIR/$tfile
4230         chmod 444 $DIR/$tfile
4231         chown $RUNAS_ID $DIR/$tfile
4232         log 33_1
4233         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4234         log 33_2
4235 }
4236 run_test 33aa "write file with mode 444 (should return error)"
4237
4238 test_33a() {
4239         rm -fr $DIR/$tdir
4240         test_mkdir $DIR/$tdir
4241         chown $RUNAS_ID $DIR/$tdir
4242         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4243                 error "$RUNAS create $tdir/$tfile failed"
4244         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4245                 error "open RDWR" || true
4246 }
4247 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4248
4249 test_33b() {
4250         rm -fr $DIR/$tdir
4251         test_mkdir $DIR/$tdir
4252         chown $RUNAS_ID $DIR/$tdir
4253         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4254 }
4255 run_test 33b "test open file with malformed flags (No panic)"
4256
4257 test_33c() {
4258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4259         remote_ost_nodsh && skip "remote OST with nodsh"
4260
4261         local ostnum
4262         local ostname
4263         local write_bytes
4264         local all_zeros
4265
4266         all_zeros=true
4267         test_mkdir $DIR/$tdir
4268         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4269
4270         sync
4271         for ostnum in $(seq $OSTCOUNT); do
4272                 # test-framework's OST numbering is one-based, while Lustre's
4273                 # is zero-based
4274                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4275                 # check if at least some write_bytes stats are counted
4276                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4277                               obdfilter.$ostname.stats |
4278                               awk '/^write_bytes/ {print $7}' )
4279                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4280                 if (( ${write_bytes:-0} > 0 )); then
4281                         all_zeros=false
4282                         break
4283                 fi
4284         done
4285
4286         $all_zeros || return 0
4287
4288         # Write four bytes
4289         echo foo > $DIR/$tdir/bar
4290         # Really write them
4291         sync
4292
4293         # Total up write_bytes after writing.  We'd better find non-zeros.
4294         for ostnum in $(seq $OSTCOUNT); do
4295                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4296                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4297                               obdfilter/$ostname/stats |
4298                               awk '/^write_bytes/ {print $7}' )
4299                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4300                 if (( ${write_bytes:-0} > 0 )); then
4301                         all_zeros=false
4302                         break
4303                 fi
4304         done
4305
4306         if $all_zeros; then
4307                 for ostnum in $(seq $OSTCOUNT); do
4308                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4309                         echo "Check write_bytes is in obdfilter.*.stats:"
4310                         do_facet ost$ostnum lctl get_param -n \
4311                                 obdfilter.$ostname.stats
4312                 done
4313                 error "OST not keeping write_bytes stats (b=22312)"
4314         fi
4315 }
4316 run_test 33c "test write_bytes stats"
4317
4318 test_33d() {
4319         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4320         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4321
4322         local MDTIDX=1
4323         local remote_dir=$DIR/$tdir/remote_dir
4324
4325         test_mkdir $DIR/$tdir
4326         $LFS mkdir -i $MDTIDX $remote_dir ||
4327                 error "create remote directory failed"
4328
4329         touch $remote_dir/$tfile
4330         chmod 444 $remote_dir/$tfile
4331         chown $RUNAS_ID $remote_dir/$tfile
4332
4333         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4334
4335         chown $RUNAS_ID $remote_dir
4336         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4337                                         error "create" || true
4338         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4339                                     error "open RDWR" || true
4340         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4341 }
4342 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4343
4344 test_33e() {
4345         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4346
4347         mkdir $DIR/$tdir
4348
4349         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4350         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4351         mkdir $DIR/$tdir/local_dir
4352
4353         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4354         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4355         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4356
4357         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4358                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4359
4360         rmdir $DIR/$tdir/* || error "rmdir failed"
4361
4362         umask 777
4363         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4364         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4365         mkdir $DIR/$tdir/local_dir
4366
4367         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4368         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4369         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4370
4371         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4372                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4373
4374         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4375
4376         umask 000
4377         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4378         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4379         mkdir $DIR/$tdir/local_dir
4380
4381         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4382         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4383         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4384
4385         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4386                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4387 }
4388 run_test 33e "mkdir and striped directory should have same mode"
4389
4390 cleanup_33f() {
4391         trap 0
4392         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4393 }
4394
4395 test_33f() {
4396         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4397         remote_mds_nodsh && skip "remote MDS with nodsh"
4398
4399         mkdir $DIR/$tdir
4400         chmod go+rwx $DIR/$tdir
4401         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4402         trap cleanup_33f EXIT
4403
4404         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4405                 error "cannot create striped directory"
4406
4407         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4408                 error "cannot create files in striped directory"
4409
4410         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4411                 error "cannot remove files in striped directory"
4412
4413         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4414                 error "cannot remove striped directory"
4415
4416         cleanup_33f
4417 }
4418 run_test 33f "nonroot user can create, access, and remove a striped directory"
4419
4420 test_33g() {
4421         mkdir -p $DIR/$tdir/dir2
4422
4423         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4424         echo $err
4425         [[ $err =~ "exists" ]] || error "Not exists error"
4426 }
4427 run_test 33g "nonroot user create already existing root created file"
4428
4429 sub_33h() {
4430         local hash_type=$1
4431         local count=250
4432
4433         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4434                 error "lfs mkdir -H $hash_type $tdir failed"
4435         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4436
4437         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4438         local index2
4439         local fname
4440
4441         for fname in $DIR/$tdir/$tfile.bak \
4442                      $DIR/$tdir/$tfile.SAV \
4443                      $DIR/$tdir/$tfile.orig \
4444                      $DIR/$tdir/$tfile~; do
4445                 touch $fname || error "touch $fname failed"
4446                 index2=$($LFS getstripe -m $fname)
4447                 (( $index == $index2 )) ||
4448                         error "$fname MDT index mismatch $index != $index2"
4449         done
4450
4451         local failed=0
4452         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4453         local pattern
4454
4455         for pattern in ${patterns[*]}; do
4456                 echo "pattern $pattern"
4457                 fname=$DIR/$tdir/$pattern
4458                 for (( i = 0; i < $count; i++ )); do
4459                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4460                                 error "mktemp $DIR/$tdir/$pattern failed"
4461                         index2=$($LFS getstripe -m $fname)
4462                         (( $index == $index2 )) && continue
4463
4464                         failed=$((failed + 1))
4465                         echo "$fname MDT index mismatch $index != $index2"
4466                 done
4467         done
4468
4469         echo "$failed/$count MDT index mismatches, expect ~2-4"
4470         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4471
4472         local same=0
4473         local expect
4474
4475         # verify that "crush" is still broken with all files on same MDT,
4476         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4477         [[ "$hash_type" == "crush" ]] && expect=$count ||
4478                 expect=$((count / MDSCOUNT))
4479
4480         # crush2 doesn't put all-numeric suffixes on the same MDT,
4481         # filename like $tfile.12345678 should *not* be considered temp
4482         for pattern in ${patterns[*]}; do
4483                 local base=${pattern%%X*}
4484                 local suff=${pattern#$base}
4485
4486                 echo "pattern $pattern"
4487                 for (( i = 0; i < $count; i++ )); do
4488                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4489                         touch $fname || error "touch $fname failed"
4490                         index2=$($LFS getstripe -m $fname)
4491                         (( $index != $index2 )) && continue
4492
4493                         same=$((same + 1))
4494                 done
4495         done
4496
4497         # the number of "bad" hashes is random, as it depends on the random
4498         # filenames generated by "mktemp".  Allow some margin in the results.
4499         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4500         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4501            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4502                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4503         same=0
4504
4505         # crush2 doesn't put suffixes with special characters on the same MDT
4506         # filename like $tfile.txt.1234 should *not* be considered temp
4507         for pattern in ${patterns[*]}; do
4508                 local base=${pattern%%X*}
4509                 local suff=${pattern#$base}
4510
4511                 pattern=$base...${suff/XXX}
4512                 echo "pattern=$pattern"
4513                 for (( i = 0; i < $count; i++ )); do
4514                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4515                                 error "touch $fname failed"
4516                         index2=$($LFS getstripe -m $fname)
4517                         (( $index != $index2 )) && continue
4518
4519                         same=$((same + 1))
4520                 done
4521         done
4522
4523         # the number of "bad" hashes is random, as it depends on the random
4524         # filenames generated by "mktemp".  Allow some margin in the results.
4525         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4526         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4527            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4528                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4529 }
4530
4531 test_33h() {
4532         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4533         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4534                 skip "Need MDS version at least 2.13.50"
4535
4536         sub_33h crush
4537 }
4538 run_test 33h "temp file is located on the same MDT as target (crush)"
4539
4540 test_33hh() {
4541         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4542         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4543         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4544                 skip "Need MDS version at least 2.15.0 for crush2"
4545
4546         sub_33h crush2
4547 }
4548 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4549
4550 test_33i()
4551 {
4552         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4553
4554         local FNAME=$(str_repeat 'f' 250)
4555
4556         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4557         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4558
4559         local count
4560         local total
4561
4562         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4563
4564         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4565
4566         lctl --device %$MDC deactivate
4567         stack_trap "lctl --device %$MDC activate"
4568         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4569         total=$(\ls -l $DIR/$tdir | wc -l)
4570         # "ls -l" will list total in the first line
4571         total=$((total - 1))
4572         (( total + count == 1000 )) ||
4573                 error "ls list $total files, $count files on MDT1"
4574 }
4575 run_test 33i "striped directory can be accessed when one MDT is down"
4576
4577 test_33j() {
4578         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4579
4580         mkdir -p $DIR/$tdir/
4581
4582         $LFS setdirstripe -D -i0,1 $DIR/$tdir/striped_dir_a &&
4583                 error "setdirstripe -D -i0,1 incorrectly succeeded"
4584
4585         $LFS setdirstripe -D -i0,1 -c1 $DIR/$tdir/striped_dir_b &&
4586                 error "setdirstripe -D -i0,1 -c1 incorrectly succeeded"
4587
4588         $LFS setdirstripe -D -i0,1 -c3 $DIR/$tdir/striped_dir_c &&
4589                 error "setdirstripe -D -i0,1 -c3 incorrectly succeeded"
4590
4591         $LFS setdirstripe -i0,1 $DIR/$tdir/striped_dir_e ||
4592                 error "-D was not specified, but still failed"
4593 }
4594 run_test 33j "lfs setdirstripe -D -i x,y,x should fail"
4595
4596 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4597 test_34a() {
4598         rm -f $DIR/f34
4599         $MCREATE $DIR/f34 || error "mcreate failed"
4600         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4601                 error "getstripe failed"
4602         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4603         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4604                 error "getstripe failed"
4605         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4606                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4607 }
4608 run_test 34a "truncate file that has not been opened ==========="
4609
4610 test_34b() {
4611         [ ! -f $DIR/f34 ] && test_34a
4612         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4613                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4614         $OPENFILE -f O_RDONLY $DIR/f34
4615         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4616                 error "getstripe failed"
4617         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4618                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4619 }
4620 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4621
4622 test_34c() {
4623         [ ! -f $DIR/f34 ] && test_34a
4624         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4625                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4626         $OPENFILE -f O_RDWR $DIR/f34
4627         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4628                 error "$LFS getstripe failed"
4629         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4630                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4631 }
4632 run_test 34c "O_RDWR opening file-with-size works =============="
4633
4634 test_34d() {
4635         [ ! -f $DIR/f34 ] && test_34a
4636         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4637                 error "dd failed"
4638         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4639                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4640         rm $DIR/f34
4641 }
4642 run_test 34d "write to sparse file ============================="
4643
4644 test_34e() {
4645         rm -f $DIR/f34e
4646         $MCREATE $DIR/f34e || error "mcreate failed"
4647         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4648         $CHECKSTAT -s 1000 $DIR/f34e ||
4649                 error "Size of $DIR/f34e not equal to 1000 bytes"
4650         $OPENFILE -f O_RDWR $DIR/f34e
4651         $CHECKSTAT -s 1000 $DIR/f34e ||
4652                 error "Size of $DIR/f34e not equal to 1000 bytes"
4653 }
4654 run_test 34e "create objects, some with size and some without =="
4655
4656 test_34f() { # bug 6242, 6243
4657         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4658
4659         SIZE34F=48000
4660         rm -f $DIR/f34f
4661         $MCREATE $DIR/f34f || error "mcreate failed"
4662         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4663         dd if=$DIR/f34f of=$TMP/f34f
4664         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4665         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4666         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4667         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4668         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4669 }
4670 run_test 34f "read from a file with no objects until EOF ======="
4671
4672 test_34g() {
4673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4674
4675         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4676                 error "dd failed"
4677         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4678         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4679                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4680         cancel_lru_locks osc
4681         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4682                 error "wrong size after lock cancel"
4683
4684         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4685         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4686                 error "expanding truncate failed"
4687         cancel_lru_locks osc
4688         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4689                 error "wrong expanded size after lock cancel"
4690 }
4691 run_test 34g "truncate long file ==============================="
4692
4693 test_34h() {
4694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4695
4696         local gid=10
4697         local sz=1000
4698
4699         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4700         sync # Flush the cache so that multiop below does not block on cache
4701              # flush when getting the group lock
4702         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4703         MULTIPID=$!
4704
4705         # Since just timed wait is not good enough, let's do a sync write
4706         # that way we are sure enough time for a roundtrip + processing
4707         # passed + 2 seconds of extra margin.
4708         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4709         rm $DIR/${tfile}-1
4710         sleep 2
4711
4712         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4713                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4714                 kill -9 $MULTIPID
4715         fi
4716         wait $MULTIPID
4717         local nsz=`stat -c %s $DIR/$tfile`
4718         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4719 }
4720 run_test 34h "ftruncate file under grouplock should not block"
4721
4722 test_35a() {
4723         cp /bin/sh $DIR/f35a
4724         chmod 444 $DIR/f35a
4725         chown $RUNAS_ID $DIR/f35a
4726         $RUNAS $DIR/f35a && error || true
4727         rm $DIR/f35a
4728 }
4729 run_test 35a "exec file with mode 444 (should return and not leak)"
4730
4731 test_36a() {
4732         rm -f $DIR/f36
4733         utime $DIR/f36 || error "utime failed for MDS"
4734 }
4735 run_test 36a "MDS utime check (mknod, utime)"
4736
4737 test_36b() {
4738         echo "" > $DIR/f36
4739         utime $DIR/f36 || error "utime failed for OST"
4740 }
4741 run_test 36b "OST utime check (open, utime)"
4742
4743 test_36c() {
4744         rm -f $DIR/d36/f36
4745         test_mkdir $DIR/d36
4746         chown $RUNAS_ID $DIR/d36
4747         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4748 }
4749 run_test 36c "non-root MDS utime check (mknod, utime)"
4750
4751 test_36d() {
4752         [ ! -d $DIR/d36 ] && test_36c
4753         echo "" > $DIR/d36/f36
4754         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4755 }
4756 run_test 36d "non-root OST utime check (open, utime)"
4757
4758 test_36e() {
4759         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4760
4761         test_mkdir $DIR/$tdir
4762         touch $DIR/$tdir/$tfile
4763         $RUNAS utime $DIR/$tdir/$tfile &&
4764                 error "utime worked, expected failure" || true
4765 }
4766 run_test 36e "utime on non-owned file (should return error)"
4767
4768 subr_36fh() {
4769         local fl="$1"
4770         local LANG_SAVE=$LANG
4771         local LC_LANG_SAVE=$LC_LANG
4772         export LANG=C LC_LANG=C # for date language
4773
4774         DATESTR="Dec 20  2000"
4775         test_mkdir $DIR/$tdir
4776         lctl set_param fail_loc=$fl
4777         date; date +%s
4778         cp /etc/hosts $DIR/$tdir/$tfile
4779         sync & # write RPC generated with "current" inode timestamp, but delayed
4780         sleep 1
4781         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4782         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4783         cancel_lru_locks $OSC
4784         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4785         date; date +%s
4786         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4787                 echo "BEFORE: $LS_BEFORE" && \
4788                 echo "AFTER : $LS_AFTER" && \
4789                 echo "WANT  : $DATESTR" && \
4790                 error "$DIR/$tdir/$tfile timestamps changed" || true
4791
4792         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4793 }
4794
4795 test_36f() {
4796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4797
4798         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4799         subr_36fh "0x80000214"
4800 }
4801 run_test 36f "utime on file racing with OST BRW write =========="
4802
4803 test_36g() {
4804         remote_ost_nodsh && skip "remote OST with nodsh"
4805         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4806         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4807                 skip "Need MDS version at least 2.12.51"
4808
4809         local fmd_max_age
4810         local fmd
4811         local facet="ost1"
4812         local tgt="obdfilter"
4813
4814         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4815
4816         test_mkdir $DIR/$tdir
4817         fmd_max_age=$(do_facet $facet \
4818                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4819                 head -n 1")
4820
4821         echo "FMD max age: ${fmd_max_age}s"
4822         touch $DIR/$tdir/$tfile
4823         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4824                 gawk '{cnt=cnt+$1}  END{print cnt}')
4825         echo "FMD before: $fmd"
4826         [[ $fmd == 0 ]] &&
4827                 error "FMD wasn't create by touch"
4828         sleep $((fmd_max_age + 12))
4829         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4830                 gawk '{cnt=cnt+$1}  END{print cnt}')
4831         echo "FMD after: $fmd"
4832         [[ $fmd == 0 ]] ||
4833                 error "FMD wasn't expired by ping"
4834 }
4835 run_test 36g "FMD cache expiry ====================="
4836
4837 test_36h() {
4838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4839
4840         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4841         subr_36fh "0x80000227"
4842 }
4843 run_test 36h "utime on file racing with OST BRW write =========="
4844
4845 test_36i() {
4846         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4847
4848         test_mkdir $DIR/$tdir
4849         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4850
4851         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4852         local new_mtime=$((mtime + 200))
4853
4854         #change Modify time of striped dir
4855         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4856                         error "change mtime failed"
4857
4858         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4859
4860         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4861 }
4862 run_test 36i "change mtime on striped directory"
4863
4864 # test_37 - duplicate with tests 32q 32r
4865
4866 test_38() {
4867         local file=$DIR/$tfile
4868         touch $file
4869         openfile -f O_DIRECTORY $file
4870         local RC=$?
4871         local ENOTDIR=20
4872         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4873         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4874 }
4875 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4876
4877 test_39a() { # was test_39
4878         touch $DIR/$tfile
4879         touch $DIR/${tfile}2
4880 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4881 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4882 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4883         sleep 2
4884         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4885         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4886                 echo "mtime"
4887                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4888                 echo "atime"
4889                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4890                 echo "ctime"
4891                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4892                 error "O_TRUNC didn't change timestamps"
4893         fi
4894 }
4895 run_test 39a "mtime changed on create"
4896
4897 test_39b() {
4898         test_mkdir -c1 $DIR/$tdir
4899         cp -p /etc/passwd $DIR/$tdir/fopen
4900         cp -p /etc/passwd $DIR/$tdir/flink
4901         cp -p /etc/passwd $DIR/$tdir/funlink
4902         cp -p /etc/passwd $DIR/$tdir/frename
4903         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4904
4905         sleep 1
4906         echo "aaaaaa" >> $DIR/$tdir/fopen
4907         echo "aaaaaa" >> $DIR/$tdir/flink
4908         echo "aaaaaa" >> $DIR/$tdir/funlink
4909         echo "aaaaaa" >> $DIR/$tdir/frename
4910
4911         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4912         local link_new=`stat -c %Y $DIR/$tdir/flink`
4913         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4914         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4915
4916         cat $DIR/$tdir/fopen > /dev/null
4917         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4918         rm -f $DIR/$tdir/funlink2
4919         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4920
4921         for (( i=0; i < 2; i++ )) ; do
4922                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4923                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4924                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4925                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4926
4927                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4928                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4929                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4930                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4931
4932                 cancel_lru_locks $OSC
4933                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4934         done
4935 }
4936 run_test 39b "mtime change on open, link, unlink, rename  ======"
4937
4938 # this should be set to past
4939 TEST_39_MTIME=`date -d "1 year ago" +%s`
4940
4941 # bug 11063
4942 test_39c() {
4943         touch $DIR1/$tfile
4944         sleep 2
4945         local mtime0=`stat -c %Y $DIR1/$tfile`
4946
4947         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4948         local mtime1=`stat -c %Y $DIR1/$tfile`
4949         [ "$mtime1" = $TEST_39_MTIME ] || \
4950                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4951
4952         local d1=`date +%s`
4953         echo hello >> $DIR1/$tfile
4954         local d2=`date +%s`
4955         local mtime2=`stat -c %Y $DIR1/$tfile`
4956         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4957                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4958
4959         mv $DIR1/$tfile $DIR1/$tfile-1
4960
4961         for (( i=0; i < 2; i++ )) ; do
4962                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4963                 [ "$mtime2" = "$mtime3" ] || \
4964                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4965
4966                 cancel_lru_locks $OSC
4967                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4968         done
4969 }
4970 run_test 39c "mtime change on rename ==========================="
4971
4972 # bug 21114
4973 test_39d() {
4974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4975
4976         touch $DIR1/$tfile
4977         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4978
4979         for (( i=0; i < 2; i++ )) ; do
4980                 local mtime=`stat -c %Y $DIR1/$tfile`
4981                 [ $mtime = $TEST_39_MTIME ] || \
4982                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4983
4984                 cancel_lru_locks $OSC
4985                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4986         done
4987 }
4988 run_test 39d "create, utime, stat =============================="
4989
4990 # bug 21114
4991 test_39e() {
4992         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4993
4994         touch $DIR1/$tfile
4995         local mtime1=`stat -c %Y $DIR1/$tfile`
4996
4997         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4998
4999         for (( i=0; i < 2; i++ )) ; do
5000                 local mtime2=`stat -c %Y $DIR1/$tfile`
5001                 [ $mtime2 = $TEST_39_MTIME ] || \
5002                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
5003
5004                 cancel_lru_locks $OSC
5005                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5006         done
5007 }
5008 run_test 39e "create, stat, utime, stat ========================"
5009
5010 # bug 21114
5011 test_39f() {
5012         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5013
5014         touch $DIR1/$tfile
5015         mtime1=`stat -c %Y $DIR1/$tfile`
5016
5017         sleep 2
5018         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5019
5020         for (( i=0; i < 2; i++ )) ; do
5021                 local mtime2=`stat -c %Y $DIR1/$tfile`
5022                 [ $mtime2 = $TEST_39_MTIME ] || \
5023                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
5024
5025                 cancel_lru_locks $OSC
5026                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5027         done
5028 }
5029 run_test 39f "create, stat, sleep, utime, stat ================="
5030
5031 # bug 11063
5032 test_39g() {
5033         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5034
5035         echo hello >> $DIR1/$tfile
5036         local mtime1=`stat -c %Y $DIR1/$tfile`
5037
5038         sleep 2
5039         chmod o+r $DIR1/$tfile
5040
5041         for (( i=0; i < 2; i++ )) ; do
5042                 local mtime2=`stat -c %Y $DIR1/$tfile`
5043                 [ "$mtime1" = "$mtime2" ] || \
5044                         error "lost mtime: $mtime2, should be $mtime1"
5045
5046                 cancel_lru_locks $OSC
5047                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5048         done
5049 }
5050 run_test 39g "write, chmod, stat ==============================="
5051
5052 # bug 11063
5053 test_39h() {
5054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5055
5056         touch $DIR1/$tfile
5057         sleep 1
5058
5059         local d1=`date`
5060         echo hello >> $DIR1/$tfile
5061         local mtime1=`stat -c %Y $DIR1/$tfile`
5062
5063         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5064         local d2=`date`
5065         if [ "$d1" != "$d2" ]; then
5066                 echo "write and touch not within one second"
5067         else
5068                 for (( i=0; i < 2; i++ )) ; do
5069                         local mtime2=`stat -c %Y $DIR1/$tfile`
5070                         [ "$mtime2" = $TEST_39_MTIME ] || \
5071                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
5072
5073                         cancel_lru_locks $OSC
5074                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5075                 done
5076         fi
5077 }
5078 run_test 39h "write, utime within one second, stat ============="
5079
5080 test_39i() {
5081         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5082
5083         touch $DIR1/$tfile
5084         sleep 1
5085
5086         echo hello >> $DIR1/$tfile
5087         local mtime1=`stat -c %Y $DIR1/$tfile`
5088
5089         mv $DIR1/$tfile $DIR1/$tfile-1
5090
5091         for (( i=0; i < 2; i++ )) ; do
5092                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5093
5094                 [ "$mtime1" = "$mtime2" ] || \
5095                         error "lost mtime: $mtime2, should be $mtime1"
5096
5097                 cancel_lru_locks $OSC
5098                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5099         done
5100 }
5101 run_test 39i "write, rename, stat =============================="
5102
5103 test_39j() {
5104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5105
5106         start_full_debug_logging
5107         touch $DIR1/$tfile
5108         sleep 1
5109
5110         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
5111         lctl set_param fail_loc=0x80000412
5112         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
5113                 error "multiop failed"
5114         local multipid=$!
5115         local mtime1=`stat -c %Y $DIR1/$tfile`
5116
5117         mv $DIR1/$tfile $DIR1/$tfile-1
5118
5119         kill -USR1 $multipid
5120         wait $multipid || error "multiop close failed"
5121
5122         for (( i=0; i < 2; i++ )) ; do
5123                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5124                 [ "$mtime1" = "$mtime2" ] ||
5125                         error "mtime is lost on close: $mtime2, " \
5126                               "should be $mtime1"
5127
5128                 cancel_lru_locks
5129                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5130         done
5131         lctl set_param fail_loc=0
5132         stop_full_debug_logging
5133 }
5134 run_test 39j "write, rename, close, stat ======================="
5135
5136 test_39k() {
5137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5138
5139         touch $DIR1/$tfile
5140         sleep 1
5141
5142         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
5143         local multipid=$!
5144         local mtime1=`stat -c %Y $DIR1/$tfile`
5145
5146         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5147
5148         kill -USR1 $multipid
5149         wait $multipid || error "multiop close failed"
5150
5151         for (( i=0; i < 2; i++ )) ; do
5152                 local mtime2=`stat -c %Y $DIR1/$tfile`
5153
5154                 [ "$mtime2" = $TEST_39_MTIME ] || \
5155                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
5156
5157                 cancel_lru_locks
5158                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5159         done
5160 }
5161 run_test 39k "write, utime, close, stat ========================"
5162
5163 # this should be set to future
5164 TEST_39_ATIME=`date -d "1 year" +%s`
5165
5166 test_39l() {
5167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5168         remote_mds_nodsh && skip "remote MDS with nodsh"
5169
5170         local atime_diff=$(do_facet $SINGLEMDS \
5171                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5172         rm -rf $DIR/$tdir
5173         mkdir_on_mdt0 $DIR/$tdir
5174
5175         # test setting directory atime to future
5176         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5177         local atime=$(stat -c %X $DIR/$tdir)
5178         [ "$atime" = $TEST_39_ATIME ] ||
5179                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5180
5181         # test setting directory atime from future to now
5182         local now=$(date +%s)
5183         touch -a -d @$now $DIR/$tdir
5184
5185         atime=$(stat -c %X $DIR/$tdir)
5186         [ "$atime" -eq "$now"  ] ||
5187                 error "atime is not updated from future: $atime, $now"
5188
5189         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5190         sleep 3
5191
5192         # test setting directory atime when now > dir atime + atime_diff
5193         local d1=$(date +%s)
5194         ls $DIR/$tdir
5195         local d2=$(date +%s)
5196         cancel_lru_locks mdc
5197         atime=$(stat -c %X $DIR/$tdir)
5198         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5199                 error "atime is not updated  : $atime, should be $d2"
5200
5201         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5202         sleep 3
5203
5204         # test not setting directory atime when now < dir atime + atime_diff
5205         ls $DIR/$tdir
5206         cancel_lru_locks mdc
5207         atime=$(stat -c %X $DIR/$tdir)
5208         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5209                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5210
5211         do_facet $SINGLEMDS \
5212                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5213 }
5214 run_test 39l "directory atime update ==========================="
5215
5216 test_39m() {
5217         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5218
5219         touch $DIR1/$tfile
5220         sleep 2
5221         local far_past_mtime=$(date -d "May 29 1953" +%s)
5222         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5223
5224         touch -m -d @$far_past_mtime $DIR1/$tfile
5225         touch -a -d @$far_past_atime $DIR1/$tfile
5226
5227         for (( i=0; i < 2; i++ )) ; do
5228                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5229                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5230                         error "atime or mtime set incorrectly"
5231
5232                 cancel_lru_locks $OSC
5233                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5234         done
5235 }
5236 run_test 39m "test atime and mtime before 1970"
5237
5238 test_39n() { # LU-3832
5239         remote_mds_nodsh && skip "remote MDS with nodsh"
5240
5241         local atime_diff=$(do_facet $SINGLEMDS \
5242                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5243         local atime0
5244         local atime1
5245         local atime2
5246
5247         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5248
5249         rm -rf $DIR/$tfile
5250         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5251         atime0=$(stat -c %X $DIR/$tfile)
5252
5253         sleep 5
5254         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5255         atime1=$(stat -c %X $DIR/$tfile)
5256
5257         sleep 5
5258         cancel_lru_locks mdc
5259         cancel_lru_locks osc
5260         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5261         atime2=$(stat -c %X $DIR/$tfile)
5262
5263         do_facet $SINGLEMDS \
5264                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5265
5266         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5267         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5268 }
5269 run_test 39n "check that O_NOATIME is honored"
5270
5271 test_39o() {
5272         TESTDIR=$DIR/$tdir/$tfile
5273         [ -e $TESTDIR ] && rm -rf $TESTDIR
5274         mkdir -p $TESTDIR
5275         cd $TESTDIR
5276         links1=2
5277         ls
5278         mkdir a b
5279         ls
5280         links2=$(stat -c %h .)
5281         [ $(($links1 + 2)) != $links2 ] &&
5282                 error "wrong links count $(($links1 + 2)) != $links2"
5283         rmdir b
5284         links3=$(stat -c %h .)
5285         [ $(($links1 + 1)) != $links3 ] &&
5286                 error "wrong links count $links1 != $links3"
5287         return 0
5288 }
5289 run_test 39o "directory cached attributes updated after create"
5290
5291 test_39p() {
5292         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5293
5294         local MDTIDX=1
5295         TESTDIR=$DIR/$tdir/$tdir
5296         [ -e $TESTDIR ] && rm -rf $TESTDIR
5297         test_mkdir -p $TESTDIR
5298         cd $TESTDIR
5299         links1=2
5300         ls
5301         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5302         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5303         ls
5304         links2=$(stat -c %h .)
5305         [ $(($links1 + 2)) != $links2 ] &&
5306                 error "wrong links count $(($links1 + 2)) != $links2"
5307         rmdir remote_dir2
5308         links3=$(stat -c %h .)
5309         [ $(($links1 + 1)) != $links3 ] &&
5310                 error "wrong links count $links1 != $links3"
5311         return 0
5312 }
5313 run_test 39p "remote directory cached attributes updated after create ========"
5314
5315 test_39r() {
5316         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5317                 skip "no atime update on old OST"
5318         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5319                 skip_env "ldiskfs only test"
5320         fi
5321
5322         local saved_adiff
5323         local ahost=$(facet_active_host ost1)
5324         saved_adiff=$(do_facet ost1 \
5325                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5326         stack_trap "do_facet ost1 \
5327                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5328
5329         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5330
5331         $LFS setstripe -i 0 $DIR/$tfile
5332         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5333                 error "can't write initial file"
5334         cancel_lru_locks osc
5335
5336         # exceed atime_diff and access file
5337         sleep 10
5338         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5339                 error "can't udpate atime"
5340
5341         # atime_cli value is in decimal
5342         local atime_cli=$(stat -c %X $DIR/$tfile)
5343         echo "client atime: $atime_cli"
5344
5345         local ostdev=$(ostdevname 1)
5346         local fid=($($LFS getstripe $DIR/$tfile | grep 0x))
5347         local seq=${fid[3]#0x}
5348         local oid=${fid[1]}
5349         local oid_hex
5350
5351         if [ $seq == 0 ]; then
5352                 oid_hex=${fid[1]}
5353         else
5354                 oid_hex=${fid[2]#0x}
5355         fi
5356         local objpath="O/$seq/d$(($oid % 32))/$oid_hex"
5357         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5358
5359         # allow atime update to be written to device
5360         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync=1"
5361         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5362
5363         # Give enough time for server to get updated. Until then
5364         # the value read is defaulted to "0x00000000:00000000"
5365         # Wait until atime read via debugfs is not equal to zero.
5366         # Max limit to wait is 30 seconds.
5367         wait_update_cond $ahost                                         \
5368                 "$cmd |& awk -F'[: ]' '/atime:/ { print \\\$4 }'"       \
5369                 "-gt" "0" 30 || error "atime on ost is still 0 after 30 seconds"
5370         # atime_ost value is in hex
5371         local atime_ost=$(do_facet ost1 "$cmd" |&
5372                           awk -F'[: ]' '/atime:/ { print $4 }')
5373         # debugfs returns atime in 0xNNNNNNNN:00000000 format
5374         # convert Hex to decimal before comparing
5375         local atime_ost_dec=$((atime_ost))
5376
5377         # The test pass criteria is that the client time and server should
5378         # be same (2s gap accepted). This gap could arise due to VFS updating
5379         # the atime after the read(dd), stat and the updated time from the
5380         # inode
5381         (( $((atime_cli - atime_ost_dec)) <= 2 )) ||
5382                 error "atime on client $atime_cli != ost $atime_ost_dec"
5383 }
5384 run_test 39r "lazy atime update on OST"
5385
5386 test_39q() { # LU-8041
5387         local testdir=$DIR/$tdir
5388         mkdir -p $testdir
5389         multiop_bg_pause $testdir D_c || error "multiop failed"
5390         local multipid=$!
5391         cancel_lru_locks mdc
5392         kill -USR1 $multipid
5393         local atime=$(stat -c %X $testdir)
5394         [ "$atime" -ne 0 ] || error "atime is zero"
5395 }
5396 run_test 39q "close won't zero out atime"
5397
5398 test_39s() {
5399         local atime0
5400         local atime1
5401         local atime2
5402         local atime3
5403         local atime4
5404
5405         umount_client $MOUNT
5406         mount_client $MOUNT relatime
5407
5408         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer conv=fsync
5409         atime0=$(stat -c %X $DIR/$tfile)
5410
5411         # First read updates atime
5412         sleep 1
5413         cat $DIR/$tfile >/dev/null
5414         atime1=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5415
5416         # Next reads do not update atime
5417         sleep 1
5418         cat $DIR/$tfile >/dev/null
5419         atime2=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5420
5421         # If mtime is greater than atime, atime is updated
5422         sleep 1
5423         touch -m $DIR/$tfile # (mtime = now)
5424         sleep 1
5425         cat $DIR/$tfile >/dev/null # (atime is updated because atime < mtime)
5426         atime3=$(stat -c %X $DIR/$tfile) # (atime = mtime = atime0 + 3)
5427
5428         # Next reads do not update atime
5429         sleep 1
5430         cat $DIR/$tfile >/dev/null
5431         atime4=$(stat -c %X $DIR/$tfile)
5432
5433         # Remount the client to clear 'relatime' option
5434         remount_client $MOUNT
5435
5436         (( atime0 < atime1 )) ||
5437                 error "atime $atime0 should be smaller than $atime1"
5438         (( atime1 == atime2 )) ||
5439                 error "atime $atime1 was updated to $atime2"
5440         (( atime1 < atime3 )) || error "atime1 $atime1 != atime3 $atime3"
5441         (( atime3 == atime4 )) || error "atime3 $atime3 != atime4 $atime4"
5442 }
5443 run_test 39s "relatime is supported"
5444
5445 test_40() {
5446         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5447         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5448                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5449         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5450                 error "$tfile is not 4096 bytes in size"
5451 }
5452 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5453
5454 test_41() {
5455         # bug 1553
5456         small_write $DIR/f41 18
5457 }
5458 run_test 41 "test small file write + fstat ====================="
5459
5460 count_ost_writes() {
5461         lctl get_param -n ${OSC}.*.stats |
5462                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5463                         END { printf("%0.0f", writes) }'
5464 }
5465
5466 # decent default
5467 WRITEBACK_SAVE=500
5468 DIRTY_RATIO_SAVE=40
5469 MAX_DIRTY_RATIO=50
5470 BG_DIRTY_RATIO_SAVE=10
5471 MAX_BG_DIRTY_RATIO=25
5472
5473 start_writeback() {
5474         trap 0
5475         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5476         # dirty_ratio, dirty_background_ratio
5477         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5478                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5479                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5480                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5481         else
5482                 # if file not here, we are a 2.4 kernel
5483                 kill -CONT `pidof kupdated`
5484         fi
5485 }
5486
5487 stop_writeback() {
5488         # setup the trap first, so someone cannot exit the test at the
5489         # exact wrong time and mess up a machine
5490         trap start_writeback EXIT
5491         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5492         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5493                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5494                 sysctl -w vm.dirty_writeback_centisecs=0
5495                 sysctl -w vm.dirty_writeback_centisecs=0
5496                 # save and increase /proc/sys/vm/dirty_ratio
5497                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5498                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5499                 # save and increase /proc/sys/vm/dirty_background_ratio
5500                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5501                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5502         else
5503                 # if file not here, we are a 2.4 kernel
5504                 kill -STOP `pidof kupdated`
5505         fi
5506 }
5507
5508 # ensure that all stripes have some grant before we test client-side cache
5509 setup_test42() {
5510         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5511                 dd if=/dev/zero of=$i bs=4k count=1
5512                 rm $i
5513         done
5514 }
5515
5516 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5517 # file truncation, and file removal.
5518 test_42a() {
5519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5520
5521         setup_test42
5522         cancel_lru_locks $OSC
5523         stop_writeback
5524         sync; sleep 1; sync # just to be safe
5525         BEFOREWRITES=`count_ost_writes`
5526         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5527         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5528         AFTERWRITES=`count_ost_writes`
5529         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5530                 error "$BEFOREWRITES < $AFTERWRITES"
5531         start_writeback
5532 }
5533 run_test 42a "ensure that we don't flush on close"
5534
5535 test_42b() {
5536         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5537
5538         setup_test42
5539         cancel_lru_locks $OSC
5540         stop_writeback
5541         sync
5542         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5543         BEFOREWRITES=$(count_ost_writes)
5544         unlink $DIR/f42b || error "unlink $DIR/f42b: $?"
5545         AFTERWRITES=$(count_ost_writes)
5546         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5547                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5548         fi
5549         BEFOREWRITES=$(count_ost_writes)
5550         sync || error "sync: $?"
5551         AFTERWRITES=$(count_ost_writes)
5552         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5553                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5554         fi
5555         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5556         start_writeback
5557         return 0
5558 }
5559 run_test 42b "test destroy of file with cached dirty data ======"
5560
5561 # if these tests just want to test the effect of truncation,
5562 # they have to be very careful.  consider:
5563 # - the first open gets a {0,EOF}PR lock
5564 # - the first write conflicts and gets a {0, count-1}PW
5565 # - the rest of the writes are under {count,EOF}PW
5566 # - the open for truncate tries to match a {0,EOF}PR
5567 #   for the filesize and cancels the PWs.
5568 # any number of fixes (don't get {0,EOF} on open, match
5569 # composite locks, do smarter file size management) fix
5570 # this, but for now we want these tests to verify that
5571 # the cancellation with truncate intent works, so we
5572 # start the file with a full-file pw lock to match against
5573 # until the truncate.
5574 trunc_test() {
5575         test=$1
5576         file=$DIR/$test
5577         offset=$2
5578         cancel_lru_locks $OSC
5579         stop_writeback
5580         # prime the file with 0,EOF PW to match
5581         touch $file
5582         $TRUNCATE $file 0
5583         sync; sync
5584         # now the real test..
5585         dd if=/dev/zero of=$file bs=1024 count=100
5586         BEFOREWRITES=`count_ost_writes`
5587         $TRUNCATE $file $offset
5588         cancel_lru_locks $OSC
5589         AFTERWRITES=`count_ost_writes`
5590         start_writeback
5591 }
5592
5593 test_42c() {
5594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5595
5596         trunc_test 42c 1024
5597         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5598                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5599         rm $file
5600 }
5601 run_test 42c "test partial truncate of file with cached dirty data"
5602
5603 test_42d() {
5604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5605
5606         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5607         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5608         $LCTL set_param debug=+cache
5609
5610         trunc_test 42d 0
5611         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5612                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5613         rm $file
5614 }
5615 run_test 42d "test complete truncate of file with cached dirty data"
5616
5617 test_42e() { # bug22074
5618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5619
5620         local TDIR=$DIR/${tdir}e
5621         local pages=16 # hardcoded 16 pages, don't change it.
5622         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5623         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5624         local max_dirty_mb
5625         local warmup_files
5626
5627         test_mkdir $DIR/${tdir}e
5628         $LFS setstripe -c 1 $TDIR
5629         createmany -o $TDIR/f $files
5630
5631         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5632
5633         # we assume that with $OSTCOUNT files, at least one of them will
5634         # be allocated on OST0.
5635         warmup_files=$((OSTCOUNT * max_dirty_mb))
5636         createmany -o $TDIR/w $warmup_files
5637
5638         # write a large amount of data into one file and sync, to get good
5639         # avail_grant number from OST.
5640         for ((i=0; i<$warmup_files; i++)); do
5641                 idx=$($LFS getstripe -i $TDIR/w$i)
5642                 [ $idx -ne 0 ] && continue
5643                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5644                 break
5645         done
5646         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5647         sync
5648         $LCTL get_param $proc_osc0/cur_dirty_bytes
5649         $LCTL get_param $proc_osc0/cur_grant_bytes
5650
5651         # create as much dirty pages as we can while not to trigger the actual
5652         # RPCs directly. but depends on the env, VFS may trigger flush during this
5653         # period, hopefully we are good.
5654         for ((i=0; i<$warmup_files; i++)); do
5655                 idx=$($LFS getstripe -i $TDIR/w$i)
5656                 [ $idx -ne 0 ] && continue
5657                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5658         done
5659         $LCTL get_param $proc_osc0/cur_dirty_bytes
5660         $LCTL get_param $proc_osc0/cur_grant_bytes
5661
5662         # perform the real test
5663         $LCTL set_param $proc_osc0/rpc_stats 0
5664         for ((;i<$files; i++)); do
5665                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5666                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5667         done
5668         sync
5669         $LCTL get_param $proc_osc0/rpc_stats
5670
5671         local percent=0
5672         local have_ppr=false
5673         $LCTL get_param $proc_osc0/rpc_stats |
5674                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5675                         # skip lines until we are at the RPC histogram data
5676                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5677                         $have_ppr || continue
5678
5679                         # we only want the percent stat for < 16 pages
5680                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5681
5682                         percent=$((percent + WPCT))
5683                         if [[ $percent -gt 15 ]]; then
5684                                 error "less than 16-pages write RPCs" \
5685                                       "$percent% > 15%"
5686                                 break
5687                         fi
5688                 done
5689         rm -rf $TDIR
5690 }
5691 run_test 42e "verify sub-RPC writes are not done synchronously"
5692
5693 test_43A() { # was test_43
5694         test_mkdir $DIR/$tdir
5695         cp -p /bin/ls $DIR/$tdir/$tfile
5696         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5697         pid=$!
5698         # give multiop a chance to open
5699         sleep 1
5700
5701         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5702         kill -USR1 $pid
5703         # Wait for multiop to exit
5704         wait $pid
5705 }
5706 run_test 43A "execution of file opened for write should return -ETXTBSY"
5707
5708 test_43a() {
5709         test_mkdir $DIR/$tdir
5710         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5711         $DIR/$tdir/sleep 60 &
5712         SLEEP_PID=$!
5713         # Make sure exec of $tdir/sleep wins race with truncate
5714         sleep 1
5715         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5716         kill $SLEEP_PID
5717 }
5718 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5719
5720 test_43b() {
5721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5722
5723         test_mkdir $DIR/$tdir
5724         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5725         $DIR/$tdir/sleep 60 &
5726         SLEEP_PID=$!
5727         # Make sure exec of $tdir/sleep wins race with truncate
5728         sleep 1
5729         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5730         kill $SLEEP_PID
5731 }
5732 run_test 43b "truncate of file being executed should return -ETXTBSY"
5733
5734 test_43c() {
5735         local testdir="$DIR/$tdir"
5736         test_mkdir $testdir
5737         cp $SHELL $testdir/
5738         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5739                 ( cd $testdir && md5sum -c )
5740 }
5741 run_test 43c "md5sum of copy into lustre"
5742
5743 test_44A() { # was test_44
5744         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5745
5746         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5747         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5748 }
5749 run_test 44A "zero length read from a sparse stripe"
5750
5751 test_44a() {
5752         local nstripe=$($LFS getstripe -c -d $DIR)
5753         [ -z "$nstripe" ] && skip "can't get stripe info"
5754         [[ $nstripe -gt $OSTCOUNT ]] &&
5755                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5756
5757         local stride=$($LFS getstripe -S -d $DIR)
5758         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5759                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5760         fi
5761
5762         OFFSETS="0 $((stride/2)) $((stride-1))"
5763         for offset in $OFFSETS; do
5764                 for i in $(seq 0 $((nstripe-1))); do
5765                         local GLOBALOFFSETS=""
5766                         # size in Bytes
5767                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5768                         local myfn=$DIR/d44a-$size
5769                         echo "--------writing $myfn at $size"
5770                         ll_sparseness_write $myfn $size ||
5771                                 error "ll_sparseness_write"
5772                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5773                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5774                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5775
5776                         for j in $(seq 0 $((nstripe-1))); do
5777                                 # size in Bytes
5778                                 size=$((((j + $nstripe )*$stride + $offset)))
5779                                 ll_sparseness_write $myfn $size ||
5780                                         error "ll_sparseness_write"
5781                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5782                         done
5783                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5784                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5785                         rm -f $myfn
5786                 done
5787         done
5788 }
5789 run_test 44a "test sparse pwrite ==============================="
5790
5791 dirty_osc_total() {
5792         tot=0
5793         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5794                 tot=$(($tot + $d))
5795         done
5796         echo $tot
5797 }
5798 do_dirty_record() {
5799         before=`dirty_osc_total`
5800         echo executing "\"$*\""
5801         eval $*
5802         after=`dirty_osc_total`
5803         echo before $before, after $after
5804 }
5805 test_45() {
5806         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5807
5808         f="$DIR/f45"
5809         # Obtain grants from OST if it supports it
5810         echo blah > ${f}_grant
5811         stop_writeback
5812         sync
5813         do_dirty_record "echo blah > $f"
5814         [[ $before -eq $after ]] && error "write wasn't cached"
5815         do_dirty_record "> $f"
5816         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5817         do_dirty_record "echo blah > $f"
5818         [[ $before -eq $after ]] && error "write wasn't cached"
5819         do_dirty_record "sync"
5820         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5821         do_dirty_record "echo blah > $f"
5822         [[ $before -eq $after ]] && error "write wasn't cached"
5823         do_dirty_record "cancel_lru_locks osc"
5824         [[ $before -gt $after ]] ||
5825                 error "lock cancellation didn't lower dirty count"
5826         start_writeback
5827 }
5828 run_test 45 "osc io page accounting ============================"
5829
5830 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5831 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5832 # objects offset and an assert hit when an rpc was built with 1023's mapped
5833 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5834 test_46() {
5835         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5836
5837         f="$DIR/f46"
5838         stop_writeback
5839         sync
5840         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5841         sync
5842         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5843         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5844         sync
5845         start_writeback
5846 }
5847 run_test 46 "dirtying a previously written page ================"
5848
5849 # test_47 is removed "Device nodes check" is moved to test_28
5850
5851 test_48a() { # bug 2399
5852         [ "$mds1_FSTYPE" = "zfs" ] &&
5853         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5854                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5855
5856         test_mkdir $DIR/$tdir
5857         cd $DIR/$tdir
5858         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5859         test_mkdir $DIR/$tdir
5860         touch foo || error "'touch foo' failed after recreating cwd"
5861         test_mkdir bar
5862         touch .foo || error "'touch .foo' failed after recreating cwd"
5863         test_mkdir .bar
5864         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5865         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5866         cd . || error "'cd .' failed after recreating cwd"
5867         mkdir . && error "'mkdir .' worked after recreating cwd"
5868         rmdir . && error "'rmdir .' worked after recreating cwd"
5869         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5870         cd .. || error "'cd ..' failed after recreating cwd"
5871 }
5872 run_test 48a "Access renamed working dir (should return errors)="
5873
5874 test_48b() { # bug 2399
5875         rm -rf $DIR/$tdir
5876         test_mkdir $DIR/$tdir
5877         cd $DIR/$tdir
5878         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5879         touch foo && error "'touch foo' worked after removing cwd"
5880         mkdir foo && error "'mkdir foo' worked after removing cwd"
5881         touch .foo && error "'touch .foo' worked after removing cwd"
5882         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5883         ls . > /dev/null && error "'ls .' worked after removing cwd"
5884         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5885         mkdir . && error "'mkdir .' worked after removing cwd"
5886         rmdir . && error "'rmdir .' worked after removing cwd"
5887         ln -s . foo && error "'ln -s .' worked after removing cwd"
5888         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5889 }
5890 run_test 48b "Access removed working dir (should return errors)="
5891
5892 test_48c() { # bug 2350
5893         #lctl set_param debug=-1
5894         #set -vx
5895         rm -rf $DIR/$tdir
5896         test_mkdir -p $DIR/$tdir/dir
5897         cd $DIR/$tdir/dir
5898         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5899         $TRACE touch foo && error "touch foo worked after removing cwd"
5900         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5901         touch .foo && error "touch .foo worked after removing cwd"
5902         mkdir .foo && error "mkdir .foo worked after removing cwd"
5903         $TRACE ls . && error "'ls .' worked after removing cwd"
5904         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5905         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5906         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5907         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5908         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5909 }
5910 run_test 48c "Access removed working subdir (should return errors)"
5911
5912 test_48d() { # bug 2350
5913         #lctl set_param debug=-1
5914         #set -vx
5915         rm -rf $DIR/$tdir
5916         test_mkdir -p $DIR/$tdir/dir
5917         cd $DIR/$tdir/dir
5918         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5919         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5920         $TRACE touch foo && error "'touch foo' worked after removing parent"
5921         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5922         touch .foo && error "'touch .foo' worked after removing parent"
5923         mkdir .foo && error "mkdir .foo worked after removing parent"
5924         $TRACE ls . && error "'ls .' worked after removing parent"
5925         $TRACE ls .. && error "'ls ..' worked after removing parent"
5926         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5927         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5928         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5929         true
5930 }
5931 run_test 48d "Access removed parent subdir (should return errors)"
5932
5933 test_48e() { # bug 4134
5934         #lctl set_param debug=-1
5935         #set -vx
5936         rm -rf $DIR/$tdir
5937         test_mkdir -p $DIR/$tdir/dir
5938         cd $DIR/$tdir/dir
5939         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5940         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5941         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5942         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5943         # On a buggy kernel addition of "touch foo" after cd .. will
5944         # produce kernel oops in lookup_hash_it
5945         touch ../foo && error "'cd ..' worked after recreate parent"
5946         cd $DIR
5947         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5948 }
5949 run_test 48e "Access to recreated parent subdir (should return errors)"
5950
5951 test_48f() {
5952         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5953                 skip "need MDS >= 2.13.55"
5954         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5955         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5956                 skip "needs different host for mdt1 mdt2"
5957         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5958
5959         $LFS mkdir -i0 $DIR/$tdir
5960         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5961
5962         for d in sub1 sub2 sub3; do
5963                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5964                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5965                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5966         done
5967
5968         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5969 }
5970 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5971
5972 test_49() { # LU-1030
5973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5974         remote_ost_nodsh && skip "remote OST with nodsh"
5975
5976         # get ost1 size - $FSNAME-OST0000
5977         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5978                 awk '{ print $4 }')
5979         # write 800M at maximum
5980         [[ $ost1_size -lt 2 ]] && ost1_size=2
5981         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5982
5983         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5984         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5985         local dd_pid=$!
5986
5987         # change max_pages_per_rpc while writing the file
5988         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5989         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5990         # loop until dd process exits
5991         while ps ax -opid | grep -wq $dd_pid; do
5992                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5993                 sleep $((RANDOM % 5 + 1))
5994         done
5995         # restore original max_pages_per_rpc
5996         $LCTL set_param $osc1_mppc=$orig_mppc
5997         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5998 }
5999 run_test 49 "Change max_pages_per_rpc won't break osc extent"
6000
6001 test_50() {
6002         # bug 1485
6003         test_mkdir $DIR/$tdir
6004         cd $DIR/$tdir
6005         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
6006 }
6007 run_test 50 "special situations: /proc symlinks  ==============="
6008
6009 test_51a() {    # was test_51
6010         # bug 1516 - create an empty entry right after ".." then split dir
6011         test_mkdir -c1 $DIR/$tdir
6012         touch $DIR/$tdir/foo
6013         $MCREATE $DIR/$tdir/bar
6014         rm $DIR/$tdir/foo
6015         createmany -m $DIR/$tdir/longfile 201
6016         FNUM=202
6017         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
6018                 $MCREATE $DIR/$tdir/longfile$FNUM
6019                 FNUM=$(($FNUM + 1))
6020                 echo -n "+"
6021         done
6022         echo
6023         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
6024 }
6025 run_test 51a "special situations: split htree with empty entry =="
6026
6027 cleanup_print_lfs_df () {
6028         trap 0
6029         $LFS df
6030         $LFS df -i
6031 }
6032
6033 test_51b() {
6034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6035
6036         local dir=$DIR/$tdir
6037         local nrdirs=$((65536 + 100))
6038
6039         # cleanup the directory
6040         rm -fr $dir
6041
6042         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
6043
6044         $LFS df
6045         $LFS df -i
6046         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
6047         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
6048         [[ $numfree -lt $nrdirs ]] &&
6049                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
6050
6051         # need to check free space for the directories as well
6052         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
6053         numfree=$(( blkfree / $(fs_inode_ksize) ))
6054         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
6055
6056         trap cleanup_print_lfs_df EXIT
6057
6058         # create files
6059         createmany -d $dir/d $nrdirs || {
6060                 unlinkmany $dir/d $nrdirs
6061                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
6062         }
6063
6064         # really created :
6065         nrdirs=$(ls -U $dir | wc -l)
6066
6067         # unlink all but 100 subdirectories, then check it still works
6068         local left=100
6069         local delete=$((nrdirs - left))
6070
6071         $LFS df
6072         $LFS df -i
6073
6074         # for ldiskfs the nlink count should be 1, but this is OSD specific
6075         # and so this is listed for informational purposes only
6076         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
6077         unlinkmany -d $dir/d $delete ||
6078                 error "unlink of first $delete subdirs failed"
6079
6080         echo "nlink between: $(stat -c %h $dir)"
6081         local found=$(ls -U $dir | wc -l)
6082         [ $found -ne $left ] &&
6083                 error "can't find subdirs: found only $found, expected $left"
6084
6085         unlinkmany -d $dir/d $delete $left ||
6086                 error "unlink of second $left subdirs failed"
6087         # regardless of whether the backing filesystem tracks nlink accurately
6088         # or not, the nlink count shouldn't be more than "." and ".." here
6089         local after=$(stat -c %h $dir)
6090         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
6091                 echo "nlink after: $after"
6092
6093         cleanup_print_lfs_df
6094 }
6095 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
6096
6097 test_51d_sub() {
6098         local stripecount=$1
6099         local nfiles=$2
6100
6101         log "create files with stripecount=$stripecount"
6102         $LFS setstripe -C $stripecount $DIR/$tdir
6103         createmany -o $DIR/$tdir/t- $nfiles
6104         $LFS getstripe $DIR/$tdir > $TMP/$tfile
6105         for ((n = 0; n < $OSTCOUNT; n++)); do
6106                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
6107                            END { printf("%0.0f", objs) }' $TMP/$tfile)
6108                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
6109                             '($1 == '$n') { objs += 1 } \
6110                             END { printf("%0.0f", objs) }')
6111                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
6112         done
6113         unlinkmany $DIR/$tdir/t- $nfiles
6114         rm  -f $TMP/$tfile
6115
6116         local nlast
6117         local min=4
6118         local max=6 # allow variance of (1 - $min/$max) = 33% by default
6119
6120         # For some combinations of stripecount and OSTCOUNT current code
6121         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
6122         # than others. Rather than skipping this test entirely, check that
6123         # and keep testing to ensure imbalance does not get worse. LU-15282
6124         (( (OSTCOUNT == 6 && stripecount == 4) ||
6125            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
6126            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
6127         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
6128                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
6129                         { $LFS df && $LFS df -i &&
6130                         error "stripecount=$stripecount: " \
6131                               "OST $n has fewer objects vs. OST $nlast " \
6132                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
6133                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
6134                         { $LFS df && $LFS df -i &&
6135                         error "stripecount=$stripecount: " \
6136                               "OST $n has more objects vs. OST $nlast " \
6137                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
6138
6139                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
6140                         { $LFS df && $LFS df -i &&
6141                         error "stripecount=$stripecount: " \
6142                               "OST $n has fewer #0 objects vs. OST $nlast " \
6143                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
6144                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
6145                         { $LFS df && $LFS df -i &&
6146                         error "stripecount=$stripecount: " \
6147                               "OST $n has more #0 objects vs. OST $nlast " \
6148                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
6149         done
6150 }
6151
6152 test_51d() {
6153         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6154         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
6155
6156         local stripecount
6157         local per_ost=100
6158         local nfiles=$((per_ost * OSTCOUNT))
6159         local mdts=$(comma_list $(mdts_nodes))
6160         local param="osp.*.create_count"
6161         local qos_old=$(do_facet mds1 \
6162                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
6163
6164         do_nodes $mdts \
6165                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
6166         stack_trap "do_nodes $mdts \
6167                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
6168
6169         test_mkdir $DIR/$tdir
6170         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
6171         (( dirstripes > 0 )) || dirstripes=1
6172
6173         # Ensure enough OST objects precreated for tests to pass without
6174         # running out of objects.  This is an LOV r-r OST algorithm test,
6175         # not an OST object precreation test.
6176         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
6177         (( old >= nfiles )) ||
6178         {
6179                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
6180
6181                 do_nodes $mdts "$LCTL set_param $param=$create_count"
6182                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
6183
6184                 # trigger precreation from all MDTs for all OSTs
6185                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
6186                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
6187                 done
6188         }
6189
6190         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
6191                 sleep 8  # allow object precreation to catch up
6192                 test_51d_sub $stripecount $nfiles
6193         done
6194 }
6195 run_test 51d "check LOV round-robin OST object distribution"
6196
6197 test_51e() {
6198         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6199                 skip_env "ldiskfs only test"
6200         fi
6201
6202         test_mkdir -c1 $DIR/$tdir
6203         test_mkdir -c1 $DIR/$tdir/d0
6204
6205         touch $DIR/$tdir/d0/foo
6206         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
6207                 error "file exceed 65000 nlink limit!"
6208         unlinkmany $DIR/$tdir/d0/f- 65001
6209         return 0
6210 }
6211 run_test 51e "check file nlink limit"
6212
6213 test_51f() {
6214         test_mkdir $DIR/$tdir
6215
6216         local max=100000
6217         local ulimit_old=$(ulimit -n)
6218         local spare=20 # number of spare fd's for scripts/libraries, etc.
6219         local mdt=$($LFS getstripe -m $DIR/$tdir)
6220         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
6221
6222         echo "MDT$mdt numfree=$numfree, max=$max"
6223         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
6224         if [ $((numfree + spare)) -gt $ulimit_old ]; then
6225                 while ! ulimit -n $((numfree + spare)); do
6226                         numfree=$((numfree * 3 / 4))
6227                 done
6228                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
6229         else
6230                 echo "left ulimit at $ulimit_old"
6231         fi
6232
6233         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
6234                 unlinkmany $DIR/$tdir/f $numfree
6235                 error "create+open $numfree files in $DIR/$tdir failed"
6236         }
6237         ulimit -n $ulimit_old
6238
6239         # if createmany exits at 120s there will be fewer than $numfree files
6240         unlinkmany $DIR/$tdir/f $numfree || true
6241 }
6242 run_test 51f "check many open files limit"
6243
6244 test_52a() {
6245         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
6246         test_mkdir $DIR/$tdir
6247         touch $DIR/$tdir/foo
6248         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6249         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6250         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6251         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6252         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6253                                         error "link worked"
6254         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6255         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6256         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6257                                                      error "lsattr"
6258         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6259         cp -r $DIR/$tdir $TMP/
6260         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6261 }
6262 run_test 52a "append-only flag test (should return errors)"
6263
6264 test_52b() {
6265         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6266         test_mkdir $DIR/$tdir
6267         touch $DIR/$tdir/foo
6268         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6269         cat test > $DIR/$tdir/foo && error "cat test worked"
6270         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6271         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6272         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6273                                         error "link worked"
6274         echo foo >> $DIR/$tdir/foo && error "echo worked"
6275         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6276         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6277         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6278         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6279                                                         error "lsattr"
6280         chattr -i $DIR/$tdir/foo || error "chattr failed"
6281
6282         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6283 }
6284 run_test 52b "immutable flag test (should return errors) ======="
6285
6286 test_53() {
6287         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6288         remote_mds_nodsh && skip "remote MDS with nodsh"
6289         remote_ost_nodsh && skip "remote OST with nodsh"
6290
6291         local param
6292         local param_seq
6293         local ostname
6294         local mds_last
6295         local mds_last_seq
6296         local ost_last
6297         local ost_last_seq
6298         local ost_last_id
6299         local ostnum
6300         local node
6301         local found=false
6302         local support_last_seq=true
6303
6304         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6305                 support_last_seq=false
6306
6307         # only test MDT0000
6308         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6309         local value
6310         for value in $(do_facet $SINGLEMDS \
6311                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6312                 param=$(echo ${value[0]} | cut -d "=" -f1)
6313                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6314
6315                 if $support_last_seq; then
6316                         param_seq=$(echo $param |
6317                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6318                         mds_last_seq=$(do_facet $SINGLEMDS \
6319                                        $LCTL get_param -n $param_seq)
6320                 fi
6321                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6322
6323                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6324                 node=$(facet_active_host ost$((ostnum+1)))
6325                 param="obdfilter.$ostname.last_id"
6326                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6327                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6328                         ost_last_id=$ost_last
6329
6330                         if $support_last_seq; then
6331                                 ost_last_id=$(echo $ost_last |
6332                                               awk -F':' '{print $2}' |
6333                                               sed -e "s/^0x//g")
6334                                 ost_last_seq=$(echo $ost_last |
6335                                                awk -F':' '{print $1}')
6336                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6337                         fi
6338
6339                         if [[ $ost_last_id != $mds_last ]]; then
6340                                 error "$ost_last_id != $mds_last"
6341                         else
6342                                 found=true
6343                                 break
6344                         fi
6345                 done
6346         done
6347         $found || error "can not match last_seq/last_id for $mdtosc"
6348         return 0
6349 }
6350 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6351
6352 test_54a() {
6353         LANG=C perl -MSocket -e ';' || skip "no Socket perl module installed"
6354
6355         LANG=C $SOCKETSERVER $DIR/socket ||
6356                 error "$SOCKETSERVER $DIR/socket failed: $?"
6357         LANG=C $SOCKETCLIENT $DIR/socket ||
6358                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6359         unlink $DIR/socket || error "unlink $DIR/socket failed: $?"
6360 }
6361 run_test 54a "unix domain socket test =========================="
6362
6363 test_54b() {
6364         f="$DIR/f54b"
6365         mknod $f c 1 3
6366         chmod 0666 $f
6367         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6368 }
6369 run_test 54b "char device works in lustre ======================"
6370
6371 find_loop_dev() {
6372         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6373         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6374         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6375
6376         for i in $(seq 3 7); do
6377                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6378                 LOOPDEV=$LOOPBASE$i
6379                 LOOPNUM=$i
6380                 break
6381         done
6382 }
6383
6384 cleanup_54c() {
6385         local rc=0
6386         loopdev="$DIR/loop54c"
6387
6388         trap 0
6389         $UMOUNT $DIR/$tdir || rc=$?
6390         losetup -d $loopdev || true
6391         losetup -d $LOOPDEV || true
6392         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6393         return $rc
6394 }
6395
6396 test_54c() {
6397         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6398
6399         loopdev="$DIR/loop54c"
6400
6401         find_loop_dev
6402         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6403         trap cleanup_54c EXIT
6404         mknod $loopdev b 7 $LOOPNUM
6405         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6406         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6407         losetup $loopdev $DIR/$tfile ||
6408                 error "can't set up $loopdev for $DIR/$tfile"
6409         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6410         test_mkdir $DIR/$tdir
6411         mount -t ext2 $loopdev $DIR/$tdir ||
6412                 error "error mounting $loopdev on $DIR/$tdir"
6413         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6414                 error "dd write"
6415         df $DIR/$tdir
6416         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6417                 error "dd read"
6418         cleanup_54c
6419 }
6420 run_test 54c "block device works in lustre ====================="
6421
6422 test_54d() {
6423         local pipe="$DIR/$tfile.pipe"
6424         local string="aaaaaa"
6425
6426         mknod $pipe p
6427         echo -n "$string" > $pipe &
6428         local result=$(cat $pipe)
6429         [[ "$result" == "$string" ]] || error "$result != $string"
6430 }
6431 run_test 54d "fifo device works in lustre ======================"
6432
6433 test_54e() {
6434         f="$DIR/f54e"
6435         string="aaaaaa"
6436         cp -aL /dev/console $f
6437         echo $string > $f || error "echo $string to $f failed"
6438 }
6439 run_test 54e "console/tty device works in lustre ======================"
6440
6441 test_55a() {
6442         local dev_path="/sys/kernel/debug/lustre/devices"
6443
6444         load_module kunit/obd_test verbose=2 || error "load_module failed"
6445
6446         # This must be run in iteractive mode, since attach and setup
6447         # are stateful
6448         eval "$LCTL <<-EOF || error 'OBD device creation failed'
6449                 attach obd_test obd_name obd_uuid
6450                 setup obd_test
6451         EOF"
6452
6453         echo "Devices:"
6454         cat "$dev_path" | tail -n 10
6455
6456         $LCTL --device "obd_name" cleanup
6457         $LCTL --device "obd_name" detach
6458
6459         dmesg | tail -n 25 | grep "Lustre: OBD:.*FAIL" &&
6460                 error "OBD unit test failed"
6461
6462         rmmod -v obd_test ||
6463                 error "rmmod failed (may trigger a failure in a later test)"
6464 }
6465 run_test 55a "OBD device life cycle unit tests"
6466
6467 test_55b() {
6468         local dev_path="/sys/kernel/debug/lustre/devices"
6469         local dev_count="$(wc -l $dev_path | awk '{print $1}')"
6470
6471         # Set up a large number of devices, using the number
6472         # that can be set up in about a minute (based on prior
6473         # testing). We don't want to run this test forever.
6474         local num_dev_to_create="$(( 24000 - $dev_count))"
6475
6476         load_module kunit/obd_test || error "load_module failed"
6477
6478         local start=$SECONDS
6479
6480         # This must be run in iteractive mode, since attach and setup
6481         # are stateful
6482         for ((i = 1; i <= num_dev_to_create; i++)); do
6483                 echo "attach obd_test obd_name_$i obd_uuid_$i"
6484                 echo "setup obd_test_$i"
6485         done | $LCTL || error "OBD device creation failed"
6486
6487         echo "Load time: $((SECONDS - start))"
6488         echo "Devices:"
6489         cat "$dev_path" | tail -n 10
6490
6491         for ((i = 1; i <= num_dev_to_create; i++)); do
6492                 echo "--device obd_name_$i cleanup"
6493                 echo "--device obd_name_$i detach"
6494         done | $LCTL || error "OBD device cleanup failed"
6495
6496         echo "Unload time: $((SECONDS - start))"
6497
6498         rmmod -v obd_test ||
6499                 error "rmmod failed (may trigger a failure in a later test)"
6500 }
6501 run_test 55b "Load and unload max OBD devices"
6502
6503 test_56a() {
6504         local numfiles=3
6505         local numdirs=2
6506         local dir=$DIR/$tdir
6507
6508         rm -rf $dir
6509         test_mkdir -p $dir/dir
6510         for i in $(seq $numfiles); do
6511                 touch $dir/file$i
6512                 touch $dir/dir/file$i
6513         done
6514
6515         local numcomp=$($LFS getstripe --component-count $dir)
6516
6517         [[ $numcomp == 0 ]] && numcomp=1
6518
6519         # test lfs getstripe with --recursive
6520         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6521
6522         [[ $filenum -eq $((numfiles * 2)) ]] ||
6523                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6524         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6525         [[ $filenum -eq $numfiles ]] ||
6526                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6527         echo "$LFS getstripe showed obdidx or l_ost_idx"
6528
6529         # test lfs getstripe with file instead of dir
6530         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6531         [[ $filenum -eq 1 ]] ||
6532                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6533         echo "$LFS getstripe file1 passed"
6534
6535         #test lfs getstripe with --verbose
6536         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6537         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6538                 error "$LFS getstripe --verbose $dir: "\
6539                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6540         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6541                 error "$LFS getstripe $dir: showed lmm_magic"
6542
6543         #test lfs getstripe with -v prints lmm_fid
6544         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6545         local countfids=$((numdirs + numfiles * numcomp))
6546         [[ $filenum -eq $countfids ]] ||
6547                 error "$LFS getstripe -v $dir: "\
6548                       "got $filenum want $countfids lmm_fid"
6549         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6550                 error "$LFS getstripe $dir: showed lmm_fid by default"
6551         echo "$LFS getstripe --verbose passed"
6552
6553         #check for FID information
6554         local fid1=$($LFS getstripe --fid $dir/file1)
6555         local fid2=$($LFS getstripe --verbose $dir/file1 |
6556                      awk '/lmm_fid: / { print $2; exit; }')
6557         local fid3=$($LFS path2fid $dir/file1)
6558
6559         [ "$fid1" != "$fid2" ] &&
6560                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6561         [ "$fid1" != "$fid3" ] &&
6562                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6563         echo "$LFS getstripe --fid passed"
6564
6565         #test lfs getstripe with --obd
6566         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6567                 error "$LFS getstripe --obd wrong_uuid: should return error"
6568
6569         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6570
6571         local ostidx=1
6572         local obduuid=$(ostuuid_from_index $ostidx)
6573         local found=$($LFS getstripe -r --obd $obduuid $dir |
6574                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6575
6576         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6577         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6578                 ((filenum--))
6579         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6580                 ((filenum--))
6581
6582         [[ $found -eq $filenum ]] ||
6583                 error "$LFS getstripe --obd: found $found expect $filenum"
6584         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6585                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6586                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6587                 error "$LFS getstripe --obd: should not show file on other obd"
6588         echo "$LFS getstripe --obd passed"
6589 }
6590 run_test 56a "check $LFS getstripe"
6591
6592 test_56b() {
6593         local dir=$DIR/$tdir
6594         local numdirs=3
6595
6596         test_mkdir $dir
6597         for i in $(seq $numdirs); do
6598                 test_mkdir $dir/dir$i
6599         done
6600
6601         # test lfs getdirstripe default mode is non-recursion, which is
6602         # different from lfs getstripe
6603         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6604
6605         [[ $dircnt -eq 1 ]] ||
6606                 error "$LFS getdirstripe: found $dircnt, not 1"
6607         dircnt=$($LFS getdirstripe --recursive $dir |
6608                 grep -c lmv_stripe_count)
6609         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6610                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6611 }
6612 run_test 56b "check $LFS getdirstripe"
6613
6614 test_56bb() {
6615         verify_yaml_available || skip_env "YAML verification not installed"
6616         local output_file=$DIR/$tfile.out
6617
6618         $LFS getdirstripe -v -D -y $DIR 1> $output_file
6619
6620         cat $output_file
6621         cat $output_file | verify_yaml || error "layout is not valid YAML"
6622 }
6623 run_test 56bb "check $LFS getdirstripe layout is YAML"
6624
6625 test_56c() {
6626         remote_ost_nodsh && skip "remote OST with nodsh"
6627
6628         local ost_idx=0
6629         local ost_name=$(ostname_from_index $ost_idx)
6630         local old_status=$(ost_dev_status $ost_idx)
6631         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6632
6633         [[ -z "$old_status" ]] ||
6634                 skip_env "OST $ost_name is in $old_status status"
6635
6636         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6637         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6638                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6639         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6640                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6641                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6642         fi
6643
6644         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6645                 error "$LFS df -v showing inactive devices"
6646         sleep_maxage
6647
6648         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6649
6650         [[ "$new_status" =~ "D" ]] ||
6651                 error "$ost_name status is '$new_status', missing 'D'"
6652         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6653                 [[ "$new_status" =~ "N" ]] ||
6654                         error "$ost_name status is '$new_status', missing 'N'"
6655         fi
6656         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6657                 [[ "$new_status" =~ "f" ]] ||
6658                         error "$ost_name status is '$new_status', missing 'f'"
6659         fi
6660
6661         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6662         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6663                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6664         [[ -z "$p" ]] && restore_lustre_params < $p || true
6665         sleep_maxage
6666
6667         new_status=$(ost_dev_status $ost_idx)
6668         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6669                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6670         # can't check 'f' as devices may actually be on flash
6671 }
6672 run_test 56c "check 'lfs df' showing device status"
6673
6674 test_56d() {
6675         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6676         local osts=$($LFS df -v $MOUNT | grep -c OST)
6677
6678         $LFS df $MOUNT
6679
6680         (( mdts == MDSCOUNT )) ||
6681                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6682         (( osts == OSTCOUNT )) ||
6683                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6684 }
6685 run_test 56d "'lfs df -v' prints only configured devices"
6686
6687 test_56e() {
6688         err_enoent=2 # No such file or directory
6689         err_eopnotsupp=95 # Operation not supported
6690
6691         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6692         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6693
6694         # Check for handling of path not exists
6695         output=$($LFS df $enoent_mnt 2>&1)
6696         ret=$?
6697
6698         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6699         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6700                 error "expect failure $err_enoent, not $ret"
6701
6702         # Check for handling of non-Lustre FS
6703         output=$($LFS df $notsup_mnt)
6704         ret=$?
6705
6706         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6707         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6708                 error "expect success $err_eopnotsupp, not $ret"
6709
6710         # Check for multiple LustreFS argument
6711         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6712         ret=$?
6713
6714         [[ $output -eq 3 && $ret -eq 0 ]] ||
6715                 error "expect success 3, not $output, rc = $ret"
6716
6717         # Check for correct non-Lustre FS handling among multiple
6718         # LustreFS argument
6719         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6720                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6721         ret=$?
6722
6723         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6724                 error "expect success 2, not $output, rc = $ret"
6725 }
6726 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6727
6728 NUMFILES=3
6729 NUMDIRS=3
6730 setup_56() {
6731         local local_tdir="$1"
6732         local local_numfiles="$2"
6733         local local_numdirs="$3"
6734         local dir_params="$4"
6735         local dir_stripe_params="$5"
6736
6737         if [ ! -d "$local_tdir" ] ; then
6738                 test_mkdir -p $dir_stripe_params $local_tdir
6739                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6740                 for i in $(seq $local_numfiles) ; do
6741                         touch $local_tdir/file$i
6742                 done
6743                 for i in $(seq $local_numdirs) ; do
6744                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6745                         for j in $(seq $local_numfiles) ; do
6746                                 touch $local_tdir/dir$i/file$j
6747                         done
6748                 done
6749         fi
6750 }
6751
6752 setup_56_special() {
6753         local local_tdir=$1
6754         local local_numfiles=$2
6755         local local_numdirs=$3
6756
6757         setup_56 $local_tdir $local_numfiles $local_numdirs
6758
6759         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6760                 for i in $(seq $local_numfiles) ; do
6761                         mknod $local_tdir/loop${i}b b 7 $i
6762                         mknod $local_tdir/null${i}c c 1 3
6763                         ln -s $local_tdir/file1 $local_tdir/link${i}
6764                 done
6765                 for i in $(seq $local_numdirs) ; do
6766                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6767                         mknod $local_tdir/dir$i/null${i}c c 1 3
6768                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6769                 done
6770         fi
6771 }
6772
6773 test_56g() {
6774         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6775         local expected=$(($NUMDIRS + 2))
6776
6777         setup_56 $dir $NUMFILES $NUMDIRS
6778
6779         # test lfs find with -name
6780         for i in $(seq $NUMFILES) ; do
6781                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6782
6783                 [ $nums -eq $expected ] ||
6784                         error "lfs find -name '*$i' $dir wrong: "\
6785                               "found $nums, expected $expected"
6786         done
6787 }
6788 run_test 56g "check lfs find -name"
6789
6790 test_56h() {
6791         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6792         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6793
6794         setup_56 $dir $NUMFILES $NUMDIRS
6795
6796         # test lfs find with ! -name
6797         for i in $(seq $NUMFILES) ; do
6798                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6799
6800                 [ $nums -eq $expected ] ||
6801                         error "lfs find ! -name '*$i' $dir wrong: "\
6802                               "found $nums, expected $expected"
6803         done
6804 }
6805 run_test 56h "check lfs find ! -name"
6806
6807 test_56i() {
6808         local dir=$DIR/$tdir
6809
6810         test_mkdir $dir
6811
6812         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6813         local out=$($cmd)
6814
6815         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6816 }
6817 run_test 56i "check 'lfs find -ost UUID' skips directories"
6818
6819 test_56j() {
6820         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6821
6822         setup_56_special $dir $NUMFILES $NUMDIRS
6823
6824         local expected=$((NUMDIRS + 1))
6825         local cmd="$LFS find -type d $dir"
6826         local nums=$($cmd | wc -l)
6827
6828         [ $nums -eq $expected ] ||
6829                 error "'$cmd' wrong: found $nums, expected $expected"
6830 }
6831 run_test 56j "check lfs find -type d"
6832
6833 test_56k() {
6834         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6835
6836         setup_56_special $dir $NUMFILES $NUMDIRS
6837
6838         local expected=$(((NUMDIRS + 1) * NUMFILES))
6839         local cmd="$LFS find -type f $dir"
6840         local nums=$($cmd | wc -l)
6841
6842         [ $nums -eq $expected ] ||
6843                 error "'$cmd' wrong: found $nums, expected $expected"
6844 }
6845 run_test 56k "check lfs find -type f"
6846
6847 test_56l() {
6848         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6849
6850         setup_56_special $dir $NUMFILES $NUMDIRS
6851
6852         local expected=$((NUMDIRS + NUMFILES))
6853         local cmd="$LFS find -type b $dir"
6854         local nums=$($cmd | wc -l)
6855
6856         [ $nums -eq $expected ] ||
6857                 error "'$cmd' wrong: found $nums, expected $expected"
6858 }
6859 run_test 56l "check lfs find -type b"
6860
6861 test_56m() {
6862         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6863
6864         setup_56_special $dir $NUMFILES $NUMDIRS
6865
6866         local expected=$((NUMDIRS + NUMFILES))
6867         local cmd="$LFS find -type c $dir"
6868         local nums=$($cmd | wc -l)
6869         [ $nums -eq $expected ] ||
6870                 error "'$cmd' wrong: found $nums, expected $expected"
6871 }
6872 run_test 56m "check lfs find -type c"
6873
6874 test_56n() {
6875         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6876         setup_56_special $dir $NUMFILES $NUMDIRS
6877
6878         local expected=$((NUMDIRS + NUMFILES))
6879         local cmd="$LFS find -type l $dir"
6880         local nums=$($cmd | wc -l)
6881
6882         [ $nums -eq $expected ] ||
6883                 error "'$cmd' wrong: found $nums, expected $expected"
6884 }
6885 run_test 56n "check lfs find -type l"
6886
6887 test_56o() {
6888         local dir=$DIR/$tdir
6889
6890         setup_56 $dir $NUMFILES $NUMDIRS
6891         utime $dir/file1 > /dev/null || error "utime (1)"
6892         utime $dir/file2 > /dev/null || error "utime (2)"
6893         utime $dir/dir1 > /dev/null || error "utime (3)"
6894         utime $dir/dir2 > /dev/null || error "utime (4)"
6895         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6896         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6897
6898         local expected=4
6899         local nums=$($LFS find -mtime +0 $dir | wc -l)
6900
6901         [ $nums -eq $expected ] ||
6902                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6903
6904         expected=12
6905         cmd="$LFS find -mtime 0 $dir"
6906         nums=$($cmd | wc -l)
6907         [ $nums -eq $expected ] ||
6908                 error "'$cmd' wrong: found $nums, expected $expected"
6909 }
6910 run_test 56o "check lfs find -mtime for old files"
6911
6912 test_56ob() {
6913         local dir=$DIR/$tdir
6914         local expected=1
6915         local count=0
6916
6917         # just to make sure there is something that won't be found
6918         test_mkdir $dir
6919         touch $dir/$tfile.now
6920
6921         for age in year week day hour min; do
6922                 count=$((count + 1))
6923
6924                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6925                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6926                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6927
6928                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6929                 local nums=$($cmd | wc -l)
6930                 [ $nums -eq $expected ] ||
6931                         error "'$cmd' wrong: found $nums, expected $expected"
6932
6933                 cmd="$LFS find $dir -atime $count${age:0:1}"
6934                 nums=$($cmd | wc -l)
6935                 [ $nums -eq $expected ] ||
6936                         error "'$cmd' wrong: found $nums, expected $expected"
6937         done
6938
6939         sleep 2
6940         cmd="$LFS find $dir -ctime +1s -type f"
6941         nums=$($cmd | wc -l)
6942         (( $nums == $count * 2 + 1)) ||
6943                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6944 }
6945 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6946
6947 test_newerXY_base() {
6948         local x=$1
6949         local y=$2
6950         local dir=$DIR/$tdir
6951         local ref
6952         local negref
6953
6954         if [ $y == "t" ]; then
6955                 if [ $x == "b" ]; then
6956                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6957                 else
6958                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6959                 fi
6960         else
6961                 ref=$DIR/$tfile.newer.$x$y
6962                 touch $ref || error "touch $ref failed"
6963         fi
6964
6965         echo "before = $ref"
6966         sleep 2
6967         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6968         sleep 2
6969         if [ $y == "t" ]; then
6970                 if [ $x == "b" ]; then
6971                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6972                 else
6973                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6974                 fi
6975         else
6976                 negref=$DIR/$tfile.negnewer.$x$y
6977                 touch $negref || error "touch $negref failed"
6978         fi
6979
6980         echo "after = $negref"
6981         local cmd="$LFS find $dir -newer$x$y $ref"
6982         local nums=$(eval $cmd | wc -l)
6983         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6984
6985         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6986                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6987
6988         cmd="$LFS find $dir ! -newer$x$y $negref"
6989         nums=$(eval $cmd | wc -l)
6990         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6991                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6992
6993         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6994         nums=$(eval $cmd | wc -l)
6995         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6996                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6997
6998         rm -rf $DIR/*
6999 }
7000
7001 test_56oc() {
7002         test_newerXY_base "a" "a"
7003         test_newerXY_base "a" "m"
7004         test_newerXY_base "a" "c"
7005         test_newerXY_base "m" "a"
7006         test_newerXY_base "m" "m"
7007         test_newerXY_base "m" "c"
7008         test_newerXY_base "c" "a"
7009         test_newerXY_base "c" "m"
7010         test_newerXY_base "c" "c"
7011
7012         test_newerXY_base "a" "t"
7013         test_newerXY_base "m" "t"
7014         test_newerXY_base "c" "t"
7015
7016         (( $MDS1_VERSION >= $(version_code v2_13_53-145-g186b97e68a) &&
7017            $CLIENT_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
7018                 { echo "btime needs v2_13_53-145-g186b97e68a"; return 0; }
7019
7020         test_newerXY_base "b" "b"
7021         test_newerXY_base "b" "t"
7022 }
7023 run_test 56oc "check lfs find -newerXY work"
7024
7025 test_56od() {
7026         (( $MDS1_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
7027                 skip "btime unsupported on MDS < v2_13_53-145-g186b97e68a"
7028
7029         (( $CLIENT_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
7030                 skip "btime unsupported on clients < v2_13_53-145-g186b97e68a"
7031
7032         local dir=$DIR/$tdir
7033         local ref=$DIR/$tfile.ref
7034         local negref=$DIR/$tfile.negref
7035
7036         mkdir $dir || error "mkdir $dir failed"
7037         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
7038         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
7039         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
7040         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
7041         touch $ref || error "touch $ref failed"
7042         # sleep 3 seconds at least
7043         sleep 3
7044
7045         local before=$(do_facet mds1 date +%s)
7046         local skew=$(($(date +%s) - before + 1))
7047
7048         if (( skew < 0 && skew > -5 )); then
7049                 sleep $((0 - skew + 1))
7050                 skew=0
7051         fi
7052
7053         # Set the dir stripe params to limit files all on MDT0,
7054         # otherwise we need to calc the max clock skew between
7055         # the client and MDTs.
7056         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
7057         sleep 2
7058         touch $negref || error "touch $negref failed"
7059
7060         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
7061         local nums=$($cmd | wc -l)
7062         local expected=$(((NUMFILES + 1) * NUMDIRS))
7063
7064         [ $nums -eq $expected ] ||
7065                 error "'$cmd' wrong: found $nums, expected $expected"
7066
7067         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
7068         nums=$($cmd | wc -l)
7069         expected=$((NUMFILES + 1))
7070         [ $nums -eq $expected ] ||
7071                 error "'$cmd' wrong: found $nums, expected $expected"
7072
7073         [ $skew -lt 0 ] && return
7074
7075         local after=$(do_facet mds1 date +%s)
7076         local age=$((after - before + 1 + skew))
7077
7078         cmd="$LFS find $dir -btime -${age}s -type f"
7079         nums=$($cmd | wc -l)
7080         expected=$(((NUMFILES + 1) * NUMDIRS))
7081
7082         echo "Clock skew between client and server: $skew, age:$age"
7083         [ $nums -eq $expected ] ||
7084                 error "'$cmd' wrong: found $nums, expected $expected"
7085
7086         expected=$(($NUMDIRS + 1))
7087         cmd="$LFS find $dir -btime -${age}s -type d"
7088         nums=$($cmd | wc -l)
7089         [ $nums -eq $expected ] ||
7090                 error "'$cmd' wrong: found $nums, expected $expected"
7091         rm -f $ref $negref || error "Failed to remove $ref $negref"
7092 }
7093 run_test 56od "check lfs find -btime with units"
7094
7095 test_56p() {
7096         [ $RUNAS_ID -eq $UID ] &&
7097                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7098
7099         local dir=$DIR/$tdir
7100
7101         setup_56 $dir $NUMFILES $NUMDIRS
7102         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
7103
7104         local expected=$NUMFILES
7105         local cmd="$LFS find -uid $RUNAS_ID $dir"
7106         local nums=$($cmd | wc -l)
7107
7108         [ $nums -eq $expected ] ||
7109                 error "'$cmd' wrong: found $nums, expected $expected"
7110
7111         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
7112         cmd="$LFS find ! -uid $RUNAS_ID $dir"
7113         nums=$($cmd | wc -l)
7114         [ $nums -eq $expected ] ||
7115                 error "'$cmd' wrong: found $nums, expected $expected"
7116 }
7117 run_test 56p "check lfs find -uid and ! -uid"
7118
7119 test_56q() {
7120         [ $RUNAS_ID -eq $UID ] &&
7121                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7122
7123         local dir=$DIR/$tdir
7124
7125         setup_56 $dir $NUMFILES $NUMDIRS
7126         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
7127
7128         local expected=$NUMFILES
7129         local cmd="$LFS find -gid $RUNAS_GID $dir"
7130         local nums=$($cmd | wc -l)
7131
7132         [ $nums -eq $expected ] ||
7133                 error "'$cmd' wrong: found $nums, expected $expected"
7134
7135         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
7136         cmd="$LFS find ! -gid $RUNAS_GID $dir"
7137         nums=$($cmd | wc -l)
7138         [ $nums -eq $expected ] ||
7139                 error "'$cmd' wrong: found $nums, expected $expected"
7140 }
7141 run_test 56q "check lfs find -gid and ! -gid"
7142
7143 test_56r() {
7144         local dir=$DIR/$tdir
7145
7146         setup_56 $dir $NUMFILES $NUMDIRS
7147
7148         local expected=12
7149         local cmd="$LFS find -size 0 -type f -lazy $dir"
7150         local nums=$($cmd | wc -l)
7151
7152         [ $nums -eq $expected ] ||
7153                 error "'$cmd' wrong: found $nums, expected $expected"
7154         cmd="$LFS find -size 0 -type f $dir"
7155         nums=$($cmd | wc -l)
7156         [ $nums -eq $expected ] ||
7157                 error "'$cmd' wrong: found $nums, expected $expected"
7158
7159         expected=0
7160         cmd="$LFS find ! -size 0 -type f -lazy $dir"
7161         nums=$($cmd | wc -l)
7162         [ $nums -eq $expected ] ||
7163                 error "'$cmd' wrong: found $nums, expected $expected"
7164         cmd="$LFS find ! -size 0 -type f $dir"
7165         nums=$($cmd | wc -l)
7166         [ $nums -eq $expected ] ||
7167                 error "'$cmd' wrong: found $nums, expected $expected"
7168
7169         echo "test" > $dir/$tfile
7170         echo "test2" > $dir/$tfile.2 && sync
7171         expected=1
7172         cmd="$LFS find -size 5c -type f -lazy $dir"
7173         nums=$($cmd | wc -l)
7174         [ $nums -eq $expected ] ||
7175                 error "'$cmd' wrong: found $nums, expected $expected"
7176         cmd="$LFS find -size 5c -type f $dir"
7177         nums=$($cmd | wc -l)
7178         [ $nums -eq $expected ] ||
7179                 error "'$cmd' wrong: found $nums, expected $expected"
7180
7181         expected=1
7182         cmd="$LFS find -size +5c -type f -lazy $dir"
7183         nums=$($cmd | wc -l)
7184         [ $nums -eq $expected ] ||
7185                 error "'$cmd' wrong: found $nums, expected $expected"
7186         cmd="$LFS find -size +5c -type f $dir"
7187         nums=$($cmd | wc -l)
7188         [ $nums -eq $expected ] ||
7189                 error "'$cmd' wrong: found $nums, expected $expected"
7190
7191         expected=2
7192         cmd="$LFS find -size +0 -type f -lazy $dir"
7193         nums=$($cmd | wc -l)
7194         [ $nums -eq $expected ] ||
7195                 error "'$cmd' wrong: found $nums, expected $expected"
7196         cmd="$LFS find -size +0 -type f $dir"
7197         nums=$($cmd | wc -l)
7198         [ $nums -eq $expected ] ||
7199                 error "'$cmd' wrong: found $nums, expected $expected"
7200
7201         expected=2
7202         cmd="$LFS find ! -size -5c -type f -lazy $dir"
7203         nums=$($cmd | wc -l)
7204         [ $nums -eq $expected ] ||
7205                 error "'$cmd' wrong: found $nums, expected $expected"
7206         cmd="$LFS find ! -size -5c -type f $dir"
7207         nums=$($cmd | wc -l)
7208         [ $nums -eq $expected ] ||
7209                 error "'$cmd' wrong: found $nums, expected $expected"
7210
7211         expected=12
7212         cmd="$LFS find -size -5c -type f -lazy $dir"
7213         nums=$($cmd | wc -l)
7214         [ $nums -eq $expected ] ||
7215                 error "'$cmd' wrong: found $nums, expected $expected"
7216         cmd="$LFS find -size -5c -type f $dir"
7217         nums=$($cmd | wc -l)
7218         [ $nums -eq $expected ] ||
7219                 error "'$cmd' wrong: found $nums, expected $expected"
7220 }
7221 run_test 56r "check lfs find -size works"
7222
7223 test_56ra_sub() {
7224         local expected=$1
7225         local glimpses=$2
7226         local cmd="$3"
7227
7228         cancel_lru_locks $OSC
7229
7230         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7231         local nums=$($cmd | wc -l)
7232
7233         [ $nums -eq $expected ] ||
7234                 error "'$cmd' wrong: found $nums, expected $expected"
7235
7236         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7237
7238         if (( rpcs_before + glimpses != rpcs_after )); then
7239                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
7240                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
7241
7242                 if [[ $glimpses == 0 ]]; then
7243                         error "'$cmd' should not send glimpse RPCs to OST"
7244                 else
7245                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
7246                 fi
7247         fi
7248 }
7249
7250 test_56ra() {
7251         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
7252                 skip "MDS < 2.12.58 doesn't return LSOM data"
7253         local dir=$DIR/$tdir
7254         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
7255
7256         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
7257
7258         # statahead_agl may cause extra glimpse which confuses results. LU-13017
7259         $LCTL set_param -n llite.*.statahead_agl=0
7260         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
7261
7262         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7263         # open and close all files to ensure LSOM is updated
7264         cancel_lru_locks $OSC
7265         find $dir -type f | xargs cat > /dev/null
7266
7267         #   expect_found  glimpse_rpcs  command_to_run
7268         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
7269         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
7270         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
7271         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
7272
7273         echo "test" > $dir/$tfile
7274         echo "test2" > $dir/$tfile.2 && sync
7275         cancel_lru_locks $OSC
7276         cat $dir/$tfile $dir/$tfile.2 > /dev/null
7277
7278         test_56ra_sub  1  0 "$LFS find -size 5c -type f -lazy $dir"
7279         test_56ra_sub  1 14 "$LFS find -size 5c -type f $dir"
7280         test_56ra_sub  1  0 "$LFS find -size +5c -type f -lazy $dir"
7281         test_56ra_sub  1 14 "$LFS find -size +5c -type f $dir"
7282
7283         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
7284         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
7285         test_56ra_sub  2  0 "$LFS find ! -size -5c -type f -lazy $dir"
7286         test_56ra_sub  2 14 "$LFS find ! -size -5c -type f $dir"
7287         test_56ra_sub 12  0 "$LFS find -size -5c -type f -lazy $dir"
7288         test_56ra_sub 12 14 "$LFS find -size -5c -type f $dir"
7289 }
7290 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
7291
7292 test_56rb() {
7293         local dir=$DIR/$tdir
7294         local tmp=$TMP/$tfile.log
7295         local mdt_idx;
7296
7297         test_mkdir -p $dir || error "failed to mkdir $dir"
7298         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
7299                 error "failed to setstripe $dir/$tfile"
7300         mdt_idx=$($LFS getdirstripe -i $dir)
7301         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
7302
7303         stack_trap "rm -f $tmp" EXIT
7304         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7305         ! grep -q obd_uuid $tmp ||
7306                 error "failed to find --size +100K --ost 0 $dir"
7307         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7308         ! grep -q obd_uuid $tmp ||
7309                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7310 }
7311 run_test 56rb "check lfs find --size --ost/--mdt works"
7312
7313 test_56rc() {
7314         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7315         local dir=$DIR/$tdir
7316         local found
7317
7318         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7319         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7320         (( $MDSCOUNT > 2 )) &&
7321                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7322         mkdir $dir/$tdir-{1..10}
7323         touch $dir/$tfile-{1..10}
7324
7325         found=$($LFS find $dir --mdt-count 2 | wc -l)
7326         expect=11
7327         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7328
7329         found=$($LFS find $dir -T +1 | wc -l)
7330         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7331         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7332
7333         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7334         expect=11
7335         (( $found == $expect )) || error "found $found all_char, expect $expect"
7336
7337         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7338         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7339         (( $found == $expect )) || error "found $found all_char, expect $expect"
7340 }
7341 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7342
7343 test_56rd() {
7344         local dir=$DIR/$tdir
7345
7346         test_mkdir $dir
7347         rm -f $dir/*
7348
7349         mkfifo $dir/fifo || error "failed to create fifo file"
7350         $LFS find $dir -t p --printf "%p %y %LP\n" ||
7351                 error "should not fail even cannot get projid from pipe file"
7352         found=$($LFS find $dir -t p --printf "%y")
7353         [[ "p" == $found ]] || error "found $found, expect p"
7354
7355         mknod $dir/chardev c 1 5 ||
7356                 error "failed to create character device file"
7357         $LFS find $dir -t c --printf "%p %y %LP\n" ||
7358                 error "should not fail even cannot get projid from chardev file"
7359         found=$($LFS find $dir -t c --printf "%y")
7360         [[ "c" == $found ]] || error "found $found, expect c"
7361
7362         found=$($LFS find $dir ! -type d --printf "%p %y %LP\n" | wc -l)
7363         (( found == 2 )) || error "unable to list all files"
7364 }
7365 run_test 56rd "check lfs find --printf special files"
7366
7367 test_56s() { # LU-611 #LU-9369
7368         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7369
7370         local dir=$DIR/$tdir
7371         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7372
7373         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7374         for i in $(seq $NUMDIRS); do
7375                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7376         done
7377
7378         local expected=$NUMDIRS
7379         local cmd="$LFS find -c $OSTCOUNT $dir"
7380         local nums=$($cmd | wc -l)
7381
7382         [ $nums -eq $expected ] || {
7383                 $LFS getstripe -R $dir
7384                 error "'$cmd' wrong: found $nums, expected $expected"
7385         }
7386
7387         expected=$((NUMDIRS + onestripe))
7388         cmd="$LFS find -stripe-count +0 -type f $dir"
7389         nums=$($cmd | wc -l)
7390         [ $nums -eq $expected ] || {
7391                 $LFS getstripe -R $dir
7392                 error "'$cmd' wrong: found $nums, expected $expected"
7393         }
7394
7395         expected=$onestripe
7396         cmd="$LFS find -stripe-count 1 -type f $dir"
7397         nums=$($cmd | wc -l)
7398         [ $nums -eq $expected ] || {
7399                 $LFS getstripe -R $dir
7400                 error "'$cmd' wrong: found $nums, expected $expected"
7401         }
7402
7403         cmd="$LFS find -stripe-count -2 -type f $dir"
7404         nums=$($cmd | wc -l)
7405         [ $nums -eq $expected ] || {
7406                 $LFS getstripe -R $dir
7407                 error "'$cmd' wrong: found $nums, expected $expected"
7408         }
7409
7410         expected=0
7411         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7412         nums=$($cmd | wc -l)
7413         [ $nums -eq $expected ] || {
7414                 $LFS getstripe -R $dir
7415                 error "'$cmd' wrong: found $nums, expected $expected"
7416         }
7417 }
7418 run_test 56s "check lfs find -stripe-count works"
7419
7420 test_56t() { # LU-611 #LU-9369
7421         local dir=$DIR/$tdir
7422
7423         setup_56 $dir 0 $NUMDIRS
7424         for i in $(seq $NUMDIRS); do
7425                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7426         done
7427
7428         local expected=$NUMDIRS
7429         local cmd="$LFS find -S 8M $dir"
7430         local nums=$($cmd | wc -l)
7431
7432         [ $nums -eq $expected ] || {
7433                 $LFS getstripe -R $dir
7434                 error "'$cmd' wrong: found $nums, expected $expected"
7435         }
7436         rm -rf $dir
7437
7438         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7439
7440         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7441
7442         expected=$(((NUMDIRS + 1) * NUMFILES))
7443         cmd="$LFS find -stripe-size 512k -type f $dir"
7444         nums=$($cmd | wc -l)
7445         [ $nums -eq $expected ] ||
7446                 error "'$cmd' wrong: found $nums, expected $expected"
7447
7448         cmd="$LFS find -stripe-size +320k -type f $dir"
7449         nums=$($cmd | wc -l)
7450         [ $nums -eq $expected ] ||
7451                 error "'$cmd' wrong: found $nums, expected $expected"
7452
7453         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7454         cmd="$LFS find -stripe-size +200k -type f $dir"
7455         nums=$($cmd | wc -l)
7456         [ $nums -eq $expected ] ||
7457                 error "'$cmd' wrong: found $nums, expected $expected"
7458
7459         cmd="$LFS find -stripe-size -640k -type f $dir"
7460         nums=$($cmd | wc -l)
7461         [ $nums -eq $expected ] ||
7462                 error "'$cmd' wrong: found $nums, expected $expected"
7463
7464         expected=4
7465         cmd="$LFS find -stripe-size 256k -type f $dir"
7466         nums=$($cmd | wc -l)
7467         [ $nums -eq $expected ] ||
7468                 error "'$cmd' wrong: found $nums, expected $expected"
7469
7470         cmd="$LFS find -stripe-size -320k -type f $dir"
7471         nums=$($cmd | wc -l)
7472         [ $nums -eq $expected ] ||
7473                 error "'$cmd' wrong: found $nums, expected $expected"
7474
7475         expected=0
7476         cmd="$LFS find -stripe-size 1024k -type f $dir"
7477         nums=$($cmd | wc -l)
7478         [ $nums -eq $expected ] ||
7479                 error "'$cmd' wrong: found $nums, expected $expected"
7480 }
7481 run_test 56t "check lfs find -stripe-size works"
7482
7483 test_56u() { # LU-611
7484         local dir=$DIR/$tdir
7485
7486         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7487
7488         if [[ $OSTCOUNT -gt 1 ]]; then
7489                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7490                 onestripe=4
7491         else
7492                 onestripe=0
7493         fi
7494
7495         local expected=$(((NUMDIRS + 1) * NUMFILES))
7496         local cmd="$LFS find -stripe-index 0 -type f $dir"
7497         local nums=$($cmd | wc -l)
7498
7499         [ $nums -eq $expected ] ||
7500                 error "'$cmd' wrong: found $nums, expected $expected"
7501
7502         expected=$onestripe
7503         cmd="$LFS find -stripe-index 1 -type f $dir"
7504         nums=$($cmd | wc -l)
7505         [ $nums -eq $expected ] ||
7506                 error "'$cmd' wrong: found $nums, expected $expected"
7507
7508         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7509         nums=$($cmd | wc -l)
7510         [ $nums -eq $expected ] ||
7511                 error "'$cmd' wrong: found $nums, expected $expected"
7512
7513         expected=0
7514         # This should produce an error and not return any files
7515         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7516         nums=$($cmd 2>/dev/null | wc -l)
7517         [ $nums -eq $expected ] ||
7518                 error "'$cmd' wrong: found $nums, expected $expected"
7519
7520         if [[ $OSTCOUNT -gt 1 ]]; then
7521                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7522                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7523                 nums=$($cmd | wc -l)
7524                 [ $nums -eq $expected ] ||
7525                         error "'$cmd' wrong: found $nums, expected $expected"
7526         fi
7527 }
7528 run_test 56u "check lfs find -stripe-index works"
7529
7530 test_56v() {
7531         local mdt_idx=0
7532         local dir=$DIR/$tdir
7533
7534         setup_56 $dir $NUMFILES $NUMDIRS
7535
7536         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7537         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7538
7539         for file in $($LFS find -m $UUID $dir); do
7540                 file_midx=$($LFS getstripe -m $file)
7541                 [ $file_midx -eq $mdt_idx ] ||
7542                         error "lfs find -m $UUID != getstripe -m $file_midx"
7543         done
7544 }
7545 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7546
7547 test_56wa() {
7548         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7550
7551         local dir=$DIR/$tdir
7552
7553         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7554         stack_trap "rm -rf $dir"
7555
7556         local stripe_size=$($LFS getstripe -S -d $dir) ||
7557                 error "$LFS getstripe -S -d $dir failed"
7558         stripe_size=${stripe_size%% *}
7559
7560         local file_size=$((stripe_size * OSTCOUNT))
7561         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7562         local required_space=$((file_num * file_size))
7563         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7564                            head -n1)
7565         (( free_space >= required_space / 1024 )) ||
7566                 skip_env "need $required_space, have $free_space kbytes"
7567
7568         local dd_bs=65536
7569         local dd_count=$((file_size / dd_bs))
7570
7571         # write data into the files
7572         local i
7573         local j
7574         local file
7575
7576         for ((i = 1; i <= NUMFILES; i++ )); do
7577                 file=$dir/file$i
7578                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7579                         error "write data into $file failed"
7580         done
7581         for ((i = 1; i <= NUMDIRS; i++ )); do
7582                 for ((j = 1; j <= NUMFILES; j++ )); do
7583                         file=$dir/dir$i/file$j
7584                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7585                                 error "write data into $file failed"
7586                 done
7587         done
7588
7589         # $LFS_MIGRATE will fail if hard link migration is unsupported
7590         if (( MDS1_VERSION > $(version_code 2.5.55) )); then
7591                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7592                         error "creating links to $dir/dir1/file1 failed"
7593         fi
7594
7595         local expected=-1
7596
7597         (( OSTCOUNT <= 1 )) || expected=$((OSTCOUNT - 1))
7598
7599         # lfs_migrate file
7600         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7601
7602         echo "$cmd"
7603         eval $cmd || error "$cmd failed"
7604
7605         check_stripe_count $dir/file1 $expected
7606
7607         if (( $MDS1_VERSION >= $(version_code 2.6.90) )); then
7608                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7609                 # OST 1 if it is on OST 0. This file is small enough to
7610                 # be on only one stripe.
7611                 file=$dir/migr_1_ost
7612                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7613                         error "write data into $file failed"
7614                 local obdidx=$($LFS getstripe -i $file)
7615                 local oldmd5=$(md5sum $file)
7616                 local newobdidx=0
7617
7618                 (( obdidx != 0 )) || newobdidx=1
7619                 cmd="$LFS migrate -i $newobdidx $file"
7620                 echo $cmd
7621                 eval $cmd || error "$cmd failed"
7622
7623                 local realobdix=$($LFS getstripe -i $file)
7624                 local newmd5=$(md5sum $file)
7625
7626                 (( $newobdidx == $realobdix )) ||
7627                         error "new OST is different (was=$obdidx, wanted=$newobdidx, got=$realobdix)"
7628                 [[ "$oldmd5" == "$newmd5" ]] ||
7629                         error "md5sum differ: $oldmd5, $newmd5"
7630         fi
7631
7632         # lfs_migrate dir
7633         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7634         echo "$cmd"
7635         eval $cmd || error "$cmd failed"
7636
7637         for (( j = 1; j <= NUMFILES; j++ )); do
7638                 check_stripe_count $dir/dir1/file$j $expected
7639         done
7640
7641         # lfs_migrate works with lfs find
7642         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7643              $LFS_MIGRATE -y -c $expected"
7644         echo "$cmd"
7645         eval $cmd || error "$cmd failed"
7646
7647         for (( i = 2; i <= NUMFILES; i++ )); do
7648                 check_stripe_count $dir/file$i $expected
7649         done
7650         for (( i = 2; i <= NUMDIRS; i++ )); do
7651                 for (( j = 1; j <= NUMFILES; j++ )); do
7652                         check_stripe_count $dir/dir$i/file$j $expected
7653                 done
7654         done
7655 }
7656 run_test 56wa "check lfs_migrate -c stripe_count works"
7657
7658 test_56wb() {
7659         local file1=$DIR/$tdir/file1
7660         local create_pool=false
7661         local initial_pool=$($LFS getstripe -p $DIR)
7662         local pool_list=()
7663         local pool=""
7664
7665         echo -n "Creating test dir..."
7666         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7667         echo "done."
7668
7669         echo -n "Creating test file..."
7670         touch $file1 || error "cannot create file"
7671         echo "done."
7672
7673         echo -n "Detecting existing pools..."
7674         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7675
7676         if [ ${#pool_list[@]} -gt 0 ]; then
7677                 echo "${pool_list[@]}"
7678                 for thispool in "${pool_list[@]}"; do
7679                         if [[ -z "$initial_pool" ||
7680                               "$initial_pool" != "$thispool" ]]; then
7681                                 pool="$thispool"
7682                                 echo "Using existing pool '$pool'"
7683                                 break
7684                         fi
7685                 done
7686         else
7687                 echo "none detected."
7688         fi
7689         if [ -z "$pool" ]; then
7690                 pool=${POOL:-testpool}
7691                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7692                 echo -n "Creating pool '$pool'..."
7693                 create_pool=true
7694                 pool_add $pool &> /dev/null ||
7695                         error "pool_add failed"
7696                 echo "done."
7697
7698                 echo -n "Adding target to pool..."
7699                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7700                         error "pool_add_targets failed"
7701                 echo "done."
7702         fi
7703
7704         echo -n "Setting pool using -p option..."
7705         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7706                 error "migrate failed rc = $?"
7707         echo "done."
7708
7709         echo -n "Verifying test file is in pool after migrating..."
7710         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7711                 error "file was not migrated to pool $pool"
7712         echo "done."
7713
7714         echo -n "Removing test file from pool '$pool'..."
7715         # "lfs migrate $file" won't remove the file from the pool
7716         # until some striping information is changed.
7717         $LFS migrate -c 1 $file1 &> /dev/null ||
7718                 error "cannot remove from pool"
7719         [ "$($LFS getstripe -p $file1)" ] &&
7720                 error "pool still set"
7721         echo "done."
7722
7723         echo -n "Setting pool using --pool option..."
7724         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7725                 error "migrate failed rc = $?"
7726         echo "done."
7727
7728         # Clean up
7729         rm -f $file1
7730         if $create_pool; then
7731                 destroy_test_pools 2> /dev/null ||
7732                         error "destroy test pools failed"
7733         fi
7734 }
7735 run_test 56wb "check lfs_migrate pool support"
7736
7737 test_56wc() {
7738         local file1="$DIR/$tdir/$tfile"
7739         local md5
7740         local parent_ssize
7741         local parent_scount
7742         local cur_ssize
7743         local cur_scount
7744         local orig_ssize
7745         local new_scount
7746         local cur_comp
7747
7748         echo -n "Creating test dir..."
7749         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7750         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7751                 error "cannot set stripe by '-S 1M -c 1'"
7752         echo "done"
7753
7754         echo -n "Setting initial stripe for test file..."
7755         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7756                 error "cannot set stripe"
7757         cur_ssize=$($LFS getstripe -S "$file1")
7758         (( cur_ssize == 524288 )) || error "setstripe -S $cur_ssize != 524288"
7759         echo "done."
7760
7761         dd if=/dev/urandom of=$file1 bs=1M count=12 || error "dd $file1 failed"
7762         stack_trap "rm -f $file1"
7763         md5="$(md5sum $file1)"
7764
7765         # File currently set to -S 512K -c 1
7766
7767         # Ensure -c and -S options are rejected when -R is set
7768         echo -n "Verifying incompatible options are detected..."
7769         $LFS_MIGRATE -R -c 1 "$file1" &&
7770                 error "incompatible -R and -c options not detected"
7771         $LFS_MIGRATE -R -S 1M "$file1" &&
7772                 error "incompatible -R and -S options not detected"
7773         $LFS_MIGRATE -R -p pool "$file1" &&
7774                 error "incompatible -R and -p options not detected"
7775         $LFS_MIGRATE -R -E eof -c 1 "$file1" &&
7776                 error "incompatible -R and -E options not detected"
7777         $LFS_MIGRATE -R -A "$file1" &&
7778                 error "incompatible -R and -A options not detected"
7779         $LFS_MIGRATE -A -c 1 "$file1" &&
7780                 error "incompatible -A and -c options not detected"
7781         $LFS_MIGRATE -A -S 1M "$file1" &&
7782                 error "incompatible -A and -S options not detected"
7783         $LFS_MIGRATE -A -p pool "$file1" &&
7784                 error "incompatible -A and -p options not detected"
7785         $LFS_MIGRATE -A -E eof -c 1 "$file1" &&
7786                 error "incompatible -A and -E options not detected"
7787         echo "done."
7788
7789         # Ensure unrecognized options are passed through to 'lfs migrate'
7790         echo -n "Verifying -S option is passed through to lfs migrate..."
7791         $LFS_MIGRATE -y -S 1M "$file1" || error "migration failed"
7792         cur_ssize=$($LFS getstripe -S "$file1")
7793         (( cur_ssize == 1048576 )) || error "migrate -S $cur_ssize != 1048576"
7794         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (1)"
7795         echo "done."
7796
7797         # File currently set to -S 1M -c 1
7798
7799         # Ensure long options are supported
7800         echo -n "Verifying long options supported..."
7801         $LFS_MIGRATE --non-block "$file1" ||
7802                 error "long option without argument not supported"
7803         $LFS_MIGRATE --stripe-size 512K "$file1" ||
7804                 error "long option with argument not supported"
7805         cur_ssize=$($LFS getstripe -S "$file1")
7806         (( cur_ssize == 524288 )) ||
7807                 error "migrate --stripe-size $cur_ssize != 524288"
7808         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (2)"
7809         echo "done."
7810
7811         # File currently set to -S 512K -c 1
7812
7813         if (( OSTCOUNT > 1 )); then
7814                 echo -n "Verifying explicit stripe count can be set..."
7815                 $LFS_MIGRATE -c 2 "$file1" || error "migrate failed"
7816                 cur_scount=$($LFS getstripe -c "$file1")
7817                 (( cur_scount == 2 )) || error "migrate -c $cur_scount != 2"
7818                 [[ "$(md5sum $file1)" == "$md5" ]] ||
7819                         error "file data has changed (3)"
7820                 echo "done."
7821         fi
7822
7823         # File currently set to -S 512K -c 1 or -S 512K -c 2
7824
7825         # Ensure parent striping is used if -R is set, and no stripe
7826         # count or size is specified
7827         echo -n "Setting stripe for parent directory..."
7828         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7829                 error "cannot set stripe '-S 2M -c 1'"
7830         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (4)"
7831         echo "done."
7832
7833         echo -n "Verifying restripe option uses parent stripe settings..."
7834         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7835         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7836         $LFS_MIGRATE -R "$file1" || error "migrate failed"
7837         cur_ssize=$($LFS getstripe -S "$file1")
7838         (( cur_ssize == parent_ssize )) ||
7839                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7840         cur_scount=$($LFS getstripe -c "$file1")
7841         (( cur_scount == parent_scount )) ||
7842                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7843         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (5)"
7844         echo "done."
7845
7846         # File currently set to -S 1M -c 1
7847
7848         # Ensure striping is preserved if -R is not set, and no stripe
7849         # count or size is specified
7850         echo -n "Verifying striping size preserved when not specified..."
7851         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7852         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7853                 error "cannot set stripe on parent directory"
7854         $LFS_MIGRATE "$file1" || error "migrate failed"
7855         cur_ssize=$($LFS getstripe -S "$file1")
7856         (( cur_ssize == orig_ssize )) ||
7857                 error "migrate by default $cur_ssize != $orig_ssize"
7858         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (6)"
7859         echo "done."
7860
7861         # Ensure file name properly detected when final option has no argument
7862         echo -n "Verifying file name properly detected..."
7863         $LFS_MIGRATE "$file1" ||
7864                 error "file name interpreted as option argument"
7865         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (7)"
7866         echo "done."
7867
7868         # Ensure PFL arguments are passed through properly
7869         echo -n "Verifying PFL options passed through..."
7870         new_scount=$(((OSTCOUNT + 1) / 2))
7871         $LFS_MIGRATE -E 1M -c 1 -E 16M -c $new_scount -E eof -c -1 "$file1" ||
7872                 error "migrate PFL arguments failed"
7873         cur_comp=$($LFS getstripe --comp-count $file1)
7874         (( cur_comp == 3 )) || error "component count '$cur_comp' != 3"
7875         cur_scount=$($LFS getstripe --stripe-count $file1)
7876         (( cur_scount == new_scount)) ||
7877                 error "PFL stripe count $cur_scount != $new_scount"
7878         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (8)"
7879         echo "done."
7880 }
7881 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7882
7883 test_56wd() {
7884         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7885
7886         local file1=$DIR/$tdir/$tfile
7887
7888         echo -n "Creating test dir..."
7889         test_mkdir $DIR/$tdir || error "cannot create dir"
7890         echo "done."
7891
7892         echo -n "Creating test file..."
7893         echo "$tfile" > $file1
7894         echo "done."
7895
7896         # Ensure 'lfs migrate' will fail by using a non-existent option,
7897         # and make sure rsync is not called to recover
7898         echo -n "Make sure --no-rsync option works..."
7899         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7900                 grep -q 'refusing to fall back to rsync' ||
7901                 error "rsync was called with --no-rsync set"
7902         echo "done."
7903
7904         # Ensure rsync is called without trying 'lfs migrate' first
7905         echo -n "Make sure --rsync option works..."
7906         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7907                 grep -q 'falling back to rsync' &&
7908                 error "lfs migrate was called with --rsync set"
7909         echo "done."
7910 }
7911 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7912
7913 test_56we() {
7914         local td=$DIR/$tdir
7915         local tf=$td/$tfile
7916
7917         test_mkdir $td || error "cannot create $td"
7918         touch $tf || error "cannot touch $tf"
7919
7920         echo -n "Make sure --non-direct|-D works..."
7921         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7922                 grep -q "lfs migrate --non-direct" ||
7923                 error "--non-direct option cannot work correctly"
7924         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7925                 grep -q "lfs migrate -D" ||
7926                 error "-D option cannot work correctly"
7927         echo "done."
7928 }
7929 run_test 56we "check lfs_migrate --non-direct|-D support"
7930
7931 test_56x() {
7932         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7933         check_swap_layouts_support
7934
7935         local dir=$DIR/$tdir
7936         local ref1=/etc/passwd
7937         local file1=$dir/file1
7938
7939         test_mkdir $dir || error "creating dir $dir"
7940         $LFS setstripe -c 2 $file1
7941         cp $ref1 $file1
7942         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7943         stripe=$($LFS getstripe -c $file1)
7944         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7945         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7946
7947         # clean up
7948         rm -f $file1
7949 }
7950 run_test 56x "lfs migration support"
7951
7952 test_56xa() {
7953         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7954         check_swap_layouts_support
7955
7956         local dir=$DIR/$tdir/$testnum
7957
7958         test_mkdir -p $dir
7959
7960         local ref1=/etc/passwd
7961         local file1=$dir/file1
7962
7963         $LFS setstripe -c 2 $file1
7964         cp $ref1 $file1
7965         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7966
7967         local stripe=$($LFS getstripe -c $file1)
7968
7969         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7970         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7971
7972         # clean up
7973         rm -f $file1
7974 }
7975 run_test 56xa "lfs migration --block support"
7976
7977 check_migrate_links() {
7978         [[ "$1" == "--rsync" ]] && local opts="--rsync -y" && shift
7979         local dir="$1"
7980         local file1="$dir/file1"
7981         local begin="$2"
7982         local count="$3"
7983         local runas="$4"
7984         local total_count=$(($begin + $count - 1))
7985         local symlink_count=10
7986         local uniq_count=10
7987
7988         if [ ! -f "$file1" ]; then
7989                 echo -n "creating initial file..."
7990                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7991                         error "cannot setstripe initial file"
7992                 echo "done"
7993
7994                 echo -n "creating symlinks..."
7995                 for s in $(seq 1 $symlink_count); do
7996                         ln -s "$file1" "$dir/slink$s" ||
7997                                 error "cannot create symlinks"
7998                 done
7999                 echo "done"
8000
8001                 echo -n "creating nonlinked files..."
8002                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
8003                         error "cannot create nonlinked files"
8004                 echo "done"
8005         fi
8006
8007         # create hard links
8008         if [ ! -f "$dir/file$total_count" ]; then
8009                 echo -n "creating hard links $begin:$total_count..."
8010                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
8011                         /dev/null || error "cannot create hard links"
8012                 echo "done"
8013         fi
8014
8015         echo -n "checking number of hard links listed in xattrs..."
8016         local fid=$($LFS getstripe -F "$file1")
8017         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
8018
8019         echo "${#paths[*]}"
8020         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
8021                         skip "hard link list has unexpected size, skipping test"
8022         fi
8023         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
8024                         error "link names should exceed xattrs size"
8025         fi
8026
8027         echo -n "migrating files..."
8028         local migrate_out=$($runas $LFS_MIGRATE $opts -S '1m' $dir)
8029         local rc=$?
8030         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
8031         echo "done"
8032
8033         # make sure all links have been properly migrated
8034         echo -n "verifying files..."
8035         fid=$($LFS getstripe -F "$file1") ||
8036                 error "cannot get fid for file $file1"
8037         for i in $(seq 2 $total_count); do
8038                 local fid2=$($LFS getstripe -F $dir/file$i)
8039
8040                 [ "$fid2" == "$fid" ] ||
8041                         error "migrated hard link has mismatched FID"
8042         done
8043
8044         # make sure hard links were properly detected, and migration was
8045         # performed only once for the entire link set; nonlinked files should
8046         # also be migrated
8047         local actual=$(grep -c 'done' <<< "$migrate_out")
8048         local expected=$(($uniq_count + 1))
8049
8050         [ "$actual" -eq  "$expected" ] ||
8051                 error "hard links individually migrated ($actual != $expected)"
8052
8053         # make sure the correct number of hard links are present
8054         local hardlinks=$(stat -c '%h' "$file1")
8055
8056         [ $hardlinks -eq $total_count ] ||
8057                 error "num hard links $hardlinks != $total_count"
8058         echo "done"
8059
8060         return 0
8061 }
8062
8063 test_56xb() {
8064         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
8065                 skip "Need MDS version at least 2.10.55"
8066
8067         local dir="$DIR/$tdir"
8068
8069         test_mkdir "$dir" || error "cannot create dir $dir"
8070
8071         echo "testing lfs migrate mode when all links fit within xattrs"
8072         check_migrate_links "$dir" 2 99
8073
8074         echo "testing rsync mode when all links fit within xattrs"
8075         check_migrate_links --rsync "$dir" 2 99
8076
8077         echo "testing lfs migrate mode when all links do not fit within xattrs"
8078         check_migrate_links "$dir" 101 100
8079
8080         echo "testing rsync mode when all links do not fit within xattrs"
8081         check_migrate_links --rsync "$dir" 101 100
8082
8083         chown -R $RUNAS_ID $dir
8084         echo "testing non-root lfs migrate mode when not all links are in xattr"
8085         check_migrate_links "$dir" 101 100 "$RUNAS"
8086
8087         # clean up
8088         rm -rf $dir
8089 }
8090 run_test 56xb "lfs migration hard link support"
8091
8092 test_56xc() {
8093         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8094
8095         local dir="$DIR/$tdir"
8096
8097         test_mkdir "$dir" || error "cannot create dir $dir"
8098
8099         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
8100         echo -n "Setting initial stripe for 20MB test file..."
8101         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
8102                 error "cannot setstripe 20MB file"
8103         echo "done"
8104         echo -n "Sizing 20MB test file..."
8105         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
8106         echo "done"
8107         echo -n "Verifying small file autostripe count is 1..."
8108         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
8109                 error "cannot migrate 20MB file"
8110         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
8111                 error "cannot get stripe for $dir/20mb"
8112         [ $stripe_count -eq 1 ] ||
8113                 error "unexpected stripe count $stripe_count for 20MB file"
8114         rm -f "$dir/20mb"
8115         echo "done"
8116
8117         # Test 2: File is small enough to fit within the available space on
8118         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
8119         # have at least an additional 1KB for each desired stripe for test 3
8120         echo -n "Setting stripe for 1GB test file..."
8121         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
8122         echo "done"
8123         echo -n "Sizing 1GB test file..."
8124         # File size is 1GB + 3KB
8125         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
8126         echo "done"
8127
8128         # need at least 512MB per OST for 1GB file to fit in 2 stripes
8129         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
8130         if (( avail > 524288 * OSTCOUNT )); then
8131                 echo -n "Migrating 1GB file..."
8132                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
8133                         error "cannot migrate 1GB file"
8134                 echo "done"
8135                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
8136                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
8137                         error "cannot getstripe for 1GB file"
8138                 [ $stripe_count -eq 2 ] ||
8139                         error "unexpected stripe count $stripe_count != 2"
8140                 echo "done"
8141         fi
8142
8143         # Test 3: File is too large to fit within the available space on
8144         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
8145         if [ $OSTCOUNT -ge 3 ]; then
8146                 # The required available space is calculated as
8147                 # file size (1GB + 3KB) / OST count (3).
8148                 local kb_per_ost=349526
8149
8150                 echo -n "Migrating 1GB file with limit..."
8151                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
8152                         error "cannot migrate 1GB file with limit"
8153                 echo "done"
8154
8155                 stripe_count=$($LFS getstripe -c "$dir/1gb")
8156                 echo -n "Verifying 1GB autostripe count with limited space..."
8157                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
8158                         error "unexpected stripe count $stripe_count (min 3)"
8159                 echo "done"
8160         fi
8161
8162         # clean up
8163         rm -rf $dir
8164 }
8165 run_test 56xc "lfs migration autostripe"
8166
8167 test_56xd() {
8168         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8169
8170         local dir=$DIR/$tdir
8171         local f_mgrt=$dir/$tfile.mgrt
8172         local f_yaml=$dir/$tfile.yaml
8173         local f_copy=$dir/$tfile.copy
8174         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8175         local layout_copy="-c 2 -S 2M -i 1"
8176         local yamlfile=$dir/yamlfile
8177         local layout_before;
8178         local layout_after;
8179
8180         test_mkdir "$dir" || error "cannot create dir $dir"
8181         stack_trap "rm -rf $dir"
8182         $LFS setstripe $layout_yaml $f_yaml ||
8183                 error "cannot setstripe $f_yaml with layout $layout_yaml"
8184         $LFS getstripe --yaml $f_yaml > $yamlfile
8185         $LFS setstripe $layout_copy $f_copy ||
8186                 error "cannot setstripe $f_copy with layout $layout_copy"
8187         touch $f_mgrt
8188         dd if=/dev/zero of=$f_mgrt bs=1M count=4
8189
8190         # 1. test option --yaml
8191         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
8192                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
8193         layout_before=$(get_layout_param $f_yaml)
8194         layout_after=$(get_layout_param $f_mgrt)
8195         [ "$layout_after" == "$layout_before" ] ||
8196                 error "lfs_migrate --yaml: $layout_after != $layout_before"
8197
8198         # 2. test option --copy
8199         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
8200                 error "cannot migrate $f_mgrt with --copy $f_copy"
8201         layout_before=$(SKIP_INDEX=yes get_layout_param $f_copy)
8202         layout_after=$(SKIP_INDEX=yes get_layout_param $f_mgrt)
8203         [ "$layout_after" == "$layout_before" ] ||
8204                 error "lfs_migrate --copy: $layout_after != $layout_before"
8205 }
8206 run_test 56xd "check lfs_migrate --yaml and --copy support"
8207
8208 test_56xe() {
8209         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8210
8211         local dir=$DIR/$tdir
8212         local f_comp=$dir/$tfile
8213         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8214         local layout_before=""
8215         local layout_after=""
8216
8217         test_mkdir "$dir" || error "cannot create dir $dir"
8218         stack_trap "rm -rf $dir"
8219         $LFS setstripe $layout $f_comp ||
8220                 error "cannot setstripe $f_comp with layout $layout"
8221         layout_before=$(SKIP_INDEX=yes get_layout_param $f_comp)
8222         dd if=/dev/zero of=$f_comp bs=1M count=4
8223
8224         # 1. migrate a comp layout file by lfs_migrate
8225         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
8226         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8227         [ "$layout_before" == "$layout_after" ] ||
8228                 error "lfs_migrate: $layout_before != $layout_after"
8229
8230         # 2. migrate a comp layout file by lfs migrate
8231         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8232         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8233         [ "$layout_before" == "$layout_after" ] ||
8234                 error "lfs migrate: $layout_before != $layout_after"
8235 }
8236 run_test 56xe "migrate a composite layout file"
8237
8238 test_56xf() {
8239         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8240
8241         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
8242                 skip "Need server version at least 2.13.53"
8243
8244         local dir=$DIR/$tdir
8245         local f_comp=$dir/$tfile
8246         local layout="-E 1M -c1 -E -1 -c2"
8247         local fid_before=""
8248         local fid_after=""
8249
8250         test_mkdir "$dir" || error "cannot create dir $dir"
8251         stack_trap "rm -rf $dir"
8252         $LFS setstripe $layout $f_comp ||
8253                 error "cannot setstripe $f_comp with layout $layout"
8254         fid_before=$($LFS getstripe --fid $f_comp)
8255         dd if=/dev/zero of=$f_comp bs=1M count=4
8256
8257         # 1. migrate a comp layout file to a comp layout
8258         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8259         fid_after=$($LFS getstripe --fid $f_comp)
8260         [ "$fid_before" == "$fid_after" ] ||
8261                 error "comp-to-comp migrate: $fid_before != $fid_after"
8262
8263         # 2. migrate a comp layout file to a plain layout
8264         $LFS migrate -c2 $f_comp ||
8265                 error "cannot migrate $f_comp by lfs migrate"
8266         fid_after=$($LFS getstripe --fid $f_comp)
8267         [ "$fid_before" == "$fid_after" ] ||
8268                 error "comp-to-plain migrate: $fid_before != $fid_after"
8269
8270         # 3. migrate a plain layout file to a comp layout
8271         $LFS migrate $layout $f_comp ||
8272                 error "cannot migrate $f_comp by lfs migrate"
8273         fid_after=$($LFS getstripe --fid $f_comp)
8274         [ "$fid_before" == "$fid_after" ] ||
8275                 error "plain-to-comp migrate: $fid_before != $fid_after"
8276 }
8277 run_test 56xf "FID is not lost during migration of a composite layout file"
8278
8279 check_file_ost_range() {
8280         local file="$1"
8281         shift
8282         local range="$*"
8283         local -a file_range
8284         local idx
8285
8286         file_range=($($LFS getstripe -y "$file" |
8287                 awk '/l_ost_idx:/ { print $NF }'))
8288
8289         if [[ "${#file_range[@]}" = 0 ]]; then
8290                 echo "No osts found for $file"
8291                 return 1
8292         fi
8293
8294         for idx in "${file_range[@]}"; do
8295                 [[ " $range " =~ " $idx " ]] ||
8296                         return 1
8297         done
8298
8299         return 0
8300 }
8301
8302 sub_test_56xg() {
8303         local stripe_opt="$1"
8304         local pool="$2"
8305         shift 2
8306         local pool_ostidx="$(seq $* | tr '\n' ' ')"
8307
8308         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
8309                 error "Fail to migrate $tfile on $pool"
8310         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
8311                 error "$tfile is not in pool $pool"
8312         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
8313                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
8314 }
8315
8316 test_56xg() {
8317         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8318         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
8319         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
8320                 skip "Need MDS version newer than 2.14.52"
8321
8322         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
8323         local -a pool_ranges=("0 0" "1 1" "0 1")
8324
8325         # init pools
8326         for i in "${!pool_names[@]}"; do
8327                 pool_add ${pool_names[$i]} ||
8328                         error "pool_add failed (pool: ${pool_names[$i]})"
8329                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
8330                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
8331         done
8332
8333         # init the file to migrate
8334         $LFS setstripe -c1 -i1 $DIR/$tfile ||
8335                 error "Unable to create $tfile on OST1"
8336         stack_trap "rm -f $DIR/$tfile"
8337         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
8338                 error "Unable to write on $tfile"
8339
8340         echo "1. migrate $tfile on pool ${pool_names[0]}"
8341         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
8342
8343         echo "2. migrate $tfile on pool ${pool_names[2]}"
8344         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
8345
8346         echo "3. migrate $tfile on pool ${pool_names[1]}"
8347         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
8348
8349         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
8350         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
8351         echo
8352
8353         # Clean pools
8354         destroy_test_pools ||
8355                 error "pool_destroy failed"
8356 }
8357 run_test 56xg "lfs migrate pool support"
8358
8359 test_56xh() {
8360         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8361
8362         local size_mb=25
8363         local file1=$DIR/$tfile
8364         local tmp1=$TMP/$tfile.tmp
8365
8366         $LFS setstripe -c 2 $file1
8367
8368         stack_trap "rm -f $file1 $tmp1"
8369         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8370                         error "error creating $tmp1"
8371         ls -lsh $tmp1
8372         cp $tmp1 $file1
8373
8374         local start=$SECONDS
8375
8376         $LFS migrate --stats --stats-interval=1 -W 1M -c 1 $file1 ||
8377                 error "migrate failed rc = $?"
8378
8379         local elapsed=$((SECONDS - start))
8380
8381         # with 1MB/s, elapsed should equal size_mb
8382         (( elapsed >= size_mb * 95 / 100 )) ||
8383                 error "'lfs migrate -W' too fast ($elapsed < 0.95 * $size_mb)?"
8384
8385         (( elapsed <= size_mb * 120 / 100 )) ||
8386                 error_not_in_vm "'lfs migrate -W' slow ($elapsed > 1.2 * $size_mb)"
8387
8388         (( elapsed <= size_mb * 350 / 100 )) ||
8389                 error "'lfs migrate -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8390
8391         stripe=$($LFS getstripe -c $file1)
8392         (( $stripe == 1 )) || error "stripe of $file1 is $stripe != 1"
8393         cmp $file1 $tmp1 || error "content mismatch $file1 differs from $tmp1"
8394
8395         # Clean up file (since it is multiple MB)
8396         rm -f $file1 $tmp1
8397 }
8398 run_test 56xh "lfs migrate bandwidth limitation support"
8399
8400 test_56xi() {
8401         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8402         verify_yaml_available || skip_env "YAML verification not installed"
8403
8404         local size_mb=5
8405         local file1=$DIR/$tfile.1
8406         local file2=$DIR/$tfile.2
8407         local file3=$DIR/$tfile.3
8408         local output_file=$DIR/$tfile.out
8409         local tmp1=$TMP/$tfile.tmp
8410
8411         $LFS setstripe -c 2 $file1
8412         $LFS setstripe -c 2 $file2
8413         $LFS setstripe -c 2 $file3
8414
8415         stack_trap "rm -f $file1 $file2 $file3 $tmp1 $output_file"
8416         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8417                         error "error creating $tmp1"
8418         ls -lsh $tmp1
8419         cp $tmp1 $file1
8420         cp $tmp1 $file2
8421         cp $tmp1 $file3
8422
8423         $LFS migrate --stats --stats-interval=1 \
8424                 -c 1 $file1 $file2 $file3 1> $output_file ||
8425                 error "migrate failed rc = $?"
8426
8427         cat $output_file
8428         cat $output_file | verify_yaml || error "rename_stats is not valid YAML"
8429
8430         # Clean up file (since it is multiple MB)
8431         rm -f $file1 $file2 $file3 $tmp1 $output_file
8432 }
8433 run_test 56xi "lfs migrate stats support"
8434
8435 test_56xj() { # LU-16571 "lfs migrate -b" can cause thread starvation on OSS
8436         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8437
8438         local file=$DIR/$tfile
8439         local linkdir=$DIR/$tdir
8440
8441         test_mkdir $linkdir || error "fail to create $linkdir"
8442         $LFS setstripe -i 0 -c 1 -S1M $file
8443         stack_trap "rm -rf $file $linkdir"
8444         dd if=/dev/urandom of=$file bs=1M count=10 ||
8445                 error "fail to create $file"
8446
8447         # Create file links
8448         local cpts
8449         local threads_max
8450         local nlinks
8451
8452         thread_max=$(do_facet ost1 "$LCTL get_param -n ost.OSS.ost.threads_max")
8453         cpts=$(do_facet ost1 "$LCTL get_param -n cpu_partition_table | wc -l")
8454         (( nlinks = thread_max * 3 / 2 / cpts))
8455
8456         echo "create $nlinks hard links of $file"
8457         createmany -l $file $linkdir/link $nlinks
8458
8459         # Parallel migrates (should not block)
8460         local i
8461         for ((i = 0; i < nlinks; i++)); do
8462                 echo $linkdir/link$i
8463         done | xargs -n1 -P $nlinks $LFS migrate -c2
8464
8465         local stripe_count
8466         stripe_count=$($LFS getstripe -c $file) ||
8467                 error "fail to get stripe count on $file"
8468
8469         ((stripe_count == 2)) ||
8470                 error "fail to migrate $file (stripe_count = $stripe_count)"
8471 }
8472 run_test 56xj "lfs migrate -b should not cause starvation of threads on OSS"
8473
8474 test_56xk() {
8475         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8476
8477         local size_mb=5
8478         local file1=$DIR/$tfile
8479
8480         stack_trap "rm -f $file1"
8481         $LFS setstripe -c 1 $file1
8482         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8483                 error "error creating $file1"
8484         $LFS mirror extend -N $file1 || error "can't mirror"
8485         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8486                 error "can't dd"
8487         $LFS getstripe $file1 | grep stale ||
8488                 error "one component must be stale"
8489
8490         local start=$SECONDS
8491         $LFS mirror resync --stats --stats-interval=1 -W 1M $file1 ||
8492                 error "migrate failed rc = $?"
8493         local elapsed=$((SECONDS - start))
8494         $LFS getstripe $file1 | grep stale &&
8495                 error "all components must be sync"
8496
8497         # with 1MB/s, elapsed should equal size_mb
8498         (( elapsed >= size_mb * 95 / 100 )) ||
8499                 error "'lfs mirror resync -W' too fast ($elapsed < 0.95 * $size_mb)?"
8500
8501         (( elapsed <= size_mb * 120 / 100 )) ||
8502                 error_not_in_vm "'lfs mirror resync -W' slow ($elapsed > 1.2 * $size_mb)"
8503
8504         (( elapsed <= size_mb * 350 / 100 )) ||
8505                 error "'lfs mirror resync -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8506 }
8507 run_test 56xk "lfs mirror resync bandwidth limitation support"
8508
8509 test_56xl() {
8510         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8511         verify_yaml_available || skip_env "YAML verification not installed"
8512
8513         local size_mb=5
8514         local file1=$DIR/$tfile.1
8515         local output_file=$DIR/$tfile.out
8516
8517         stack_trap "rm -f $file1"
8518         $LFS setstripe -c 1 $file1
8519         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8520                 error "error creating $file1"
8521         $LFS mirror extend -N $file1 || error "can't mirror"
8522         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8523                 error "can't dd"
8524         $LFS getstripe $file1 | grep stale ||
8525                 error "one component must be stale"
8526         $LFS getstripe $file1
8527
8528         $LFS mirror resync --stats --stats-interval=1 $file1 >$output_file ||
8529                 error "resync failed rc = $?"
8530         $LFS getstripe $file1 | grep stale &&
8531                 error "all components must be sync"
8532
8533         cat $output_file
8534         cat $output_file | verify_yaml || error "stats is not valid YAML"
8535 }
8536 run_test 56xl "lfs mirror resync stats support"
8537
8538 test_56y() {
8539         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8540                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8541
8542         local res=""
8543         local dir=$DIR/$tdir
8544         local f1=$dir/file1
8545         local f2=$dir/file2
8546
8547         test_mkdir -p $dir || error "creating dir $dir"
8548         touch $f1 || error "creating std file $f1"
8549         $MULTIOP $f2 H2c || error "creating released file $f2"
8550
8551         # a directory can be raid0, so ask only for files
8552         res=$($LFS find $dir -L raid0 -type f | wc -l)
8553         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8554
8555         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8556         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8557
8558         # only files can be released, so no need to force file search
8559         res=$($LFS find $dir -L released)
8560         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8561
8562         res=$($LFS find $dir -type f \! -L released)
8563         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8564 }
8565 run_test 56y "lfs find -L raid0|released"
8566
8567 test_56z() { # LU-4824
8568         # This checks to make sure 'lfs find' continues after errors
8569         # There are two classes of errors that should be caught:
8570         # - If multiple paths are provided, all should be searched even if one
8571         #   errors out
8572         # - If errors are encountered during the search, it should not terminate
8573         #   early
8574         local dir=$DIR/$tdir
8575         local i
8576
8577         test_mkdir $dir
8578         for i in d{0..9}; do
8579                 test_mkdir $dir/$i
8580                 touch $dir/$i/$tfile
8581         done
8582         $LFS find $DIR/non_existent_dir $dir &&
8583                 error "$LFS find did not return an error"
8584         # Make a directory unsearchable. This should NOT be the last entry in
8585         # directory order.  Arbitrarily pick the 6th entry
8586         chmod 700 $($LFS find $dir -type d | sed '6!d')
8587
8588         $RUNAS $LFS find $DIR/non_existent $dir
8589         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8590
8591         # The user should be able to see 10 directories and 9 files
8592         (( count == 19 )) ||
8593                 error "$LFS find found $count != 19 entries after error"
8594 }
8595 run_test 56z "lfs find should continue after an error"
8596
8597 test_56aa() { # LU-5937
8598         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8599
8600         local dir=$DIR/$tdir
8601
8602         mkdir $dir
8603         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8604
8605         createmany -o $dir/striped_dir/${tfile}- 1024
8606         local dirs=$($LFS find --size +8k $dir/)
8607
8608         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8609 }
8610 run_test 56aa "lfs find --size under striped dir"
8611
8612 test_56ab() { # LU-10705
8613         test_mkdir $DIR/$tdir
8614         dd if=/dev/urandom of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8615         dd if=/dev/urandom of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8616         dd if=/dev/urandom of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8617         # Flush writes to ensure valid blocks.  Need to be more thorough for
8618         # ZFS, since blocks are not allocated/returned to client immediately.
8619         sync_all_data
8620         wait_zfs_commit ost1 2
8621         cancel_lru_locks osc
8622         ls -ls $DIR/$tdir
8623
8624         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8625
8626         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8627
8628         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8629         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8630
8631         rm -f $DIR/$tdir/$tfile.[123]
8632 }
8633 run_test 56ab "lfs find --blocks"
8634
8635 # LU-11188
8636 test_56aca() {
8637         local dir="$DIR/$tdir"
8638         local perms=(001 002 003 004 005 006 007
8639                      010 020 030 040 050 060 070
8640                      100 200 300 400 500 600 700
8641                      111 222 333 444 555 666 777)
8642         local perm_minus=(8 8 4 8 4 4 2
8643                           8 8 4 8 4 4 2
8644                           8 8 4 8 4 4 2
8645                           4 4 2 4 2 2 1)
8646         local perm_slash=(8  8 12  8 12 12 14
8647                           8  8 12  8 12 12 14
8648                           8  8 12  8 12 12 14
8649                          16 16 24 16 24 24 28)
8650
8651         test_mkdir "$dir"
8652         for perm in ${perms[*]}; do
8653                 touch "$dir/$tfile.$perm"
8654                 chmod $perm "$dir/$tfile.$perm"
8655         done
8656
8657         for ((i = 0; i < ${#perms[*]}; i++)); do
8658                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8659                 (( $num == 1 )) ||
8660                         error "lfs find -perm ${perms[i]}:"\
8661                               "$num != 1"
8662
8663                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8664                 (( $num == ${perm_minus[i]} )) ||
8665                         error "lfs find -perm -${perms[i]}:"\
8666                               "$num != ${perm_minus[i]}"
8667
8668                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8669                 (( $num == ${perm_slash[i]} )) ||
8670                         error "lfs find -perm /${perms[i]}:"\
8671                               "$num != ${perm_slash[i]}"
8672         done
8673 }
8674 run_test 56aca "check lfs find -perm with octal representation"
8675
8676 test_56acb() {
8677         local dir=$DIR/$tdir
8678         # p is the permission of write and execute for user, group and other
8679         # without the umask. It is used to test +wx.
8680         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8681         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8682         local symbolic=(+t  a+t u+t g+t o+t
8683                         g+s u+s o+s +s o+sr
8684                         o=r,ug+o,u+w
8685                         u+ g+ o+ a+ ugo+
8686                         u- g- o- a- ugo-
8687                         u= g= o= a= ugo=
8688                         o=r,ug+o,u+w u=r,a+u,u+w
8689                         g=r,ugo=g,u+w u+x,+X +X
8690                         u+x,u+X u+X u+x,g+X o+r,+X
8691                         u+x,go+X +wx +rwx)
8692
8693         test_mkdir $dir
8694         for perm in ${perms[*]}; do
8695                 touch "$dir/$tfile.$perm"
8696                 chmod $perm "$dir/$tfile.$perm"
8697         done
8698
8699         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8700                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8701
8702                 (( $num == 1 )) ||
8703                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8704         done
8705 }
8706 run_test 56acb "check lfs find -perm with symbolic representation"
8707
8708 test_56acc() {
8709         local dir=$DIR/$tdir
8710         local tests="17777 787 789 abcd
8711                 ug=uu ug=a ug=gu uo=ou urw
8712                 u+xg+x a=r,u+x,"
8713
8714         test_mkdir $dir
8715         for err in $tests; do
8716                 if $LFS find $dir -perm $err 2>/dev/null; then
8717                         error "lfs find -perm $err: parsing should have failed"
8718                 fi
8719         done
8720 }
8721 run_test 56acc "check parsing error for lfs find -perm"
8722
8723 test_56ba() {
8724         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8725                 skip "Need MDS version at least 2.10.50"
8726
8727         # Create composite files with one component
8728         local dir=$DIR/$tdir
8729
8730         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8731         # Create composite files with three components
8732         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8733         # LU-16904 Create plain layout files
8734         lfs setstripe -c 1 $dir/$tfile-{1..10}
8735
8736         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8737
8738         [[ $nfiles == 10 ]] ||
8739                 error "lfs find -E 1M found $nfiles != 10 files"
8740
8741         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8742         [[ $nfiles == 25 ]] ||
8743                 error "lfs find ! -E 1M found $nfiles != 25 files"
8744
8745         # All files have a component that starts at 0
8746         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8747         [[ $nfiles == 35 ]] ||
8748                 error "lfs find --component-start 0 - $nfiles != 35 files"
8749
8750         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8751         [[ $nfiles == 15 ]] ||
8752                 error "lfs find --component-start 2M - $nfiles != 15 files"
8753
8754         # All files created here have a componenet that does not starts at 2M
8755         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8756         [[ $nfiles == 35 ]] ||
8757                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8758
8759         # Find files with a specified number of components
8760         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8761         [[ $nfiles == 15 ]] ||
8762                 error "lfs find --component-count 3 - $nfiles != 15 files"
8763
8764         # Remember non-composite files have a component count of zero
8765         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8766         [[ $nfiles == 10 ]] ||
8767                 error "lfs find --component-count 0 - $nfiles != 10 files"
8768
8769         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8770         [[ $nfiles == 20 ]] ||
8771                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8772
8773         # All files have a flag called "init"
8774         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8775         [[ $nfiles == 35 ]] ||
8776                 error "lfs find --component-flags init - $nfiles != 35 files"
8777
8778         # Multi-component files will have a component not initialized
8779         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8780         [[ $nfiles == 15 ]] ||
8781                 error "lfs find !--component-flags init - $nfiles != 15 files"
8782
8783         rm -rf $dir
8784
8785 }
8786 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8787
8788 test_56ca() {
8789         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8790                 skip "Need MDS version at least 2.10.57"
8791
8792         local td=$DIR/$tdir
8793         local tf=$td/$tfile
8794         local dir
8795         local nfiles
8796         local cmd
8797         local i
8798         local j
8799
8800         # create mirrored directories and mirrored files
8801         mkdir $td || error "mkdir $td failed"
8802         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8803         createmany -o $tf- 10 || error "create $tf- failed"
8804
8805         for i in $(seq 2); do
8806                 dir=$td/dir$i
8807                 mkdir $dir || error "mkdir $dir failed"
8808                 $LFS mirror create -N$((3 + i)) $dir ||
8809                         error "create mirrored dir $dir failed"
8810                 createmany -o $dir/$tfile- 10 ||
8811                         error "create $dir/$tfile- failed"
8812         done
8813
8814         # change the states of some mirrored files
8815         echo foo > $tf-6
8816         for i in $(seq 2); do
8817                 dir=$td/dir$i
8818                 for j in $(seq 4 9); do
8819                         echo foo > $dir/$tfile-$j
8820                 done
8821         done
8822
8823         # find mirrored files with specific mirror count
8824         cmd="$LFS find --mirror-count 3 --type f $td"
8825         nfiles=$($cmd | wc -l)
8826         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8827
8828         cmd="$LFS find ! --mirror-count 3 --type f $td"
8829         nfiles=$($cmd | wc -l)
8830         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8831
8832         cmd="$LFS find --mirror-count +2 --type f $td"
8833         nfiles=$($cmd | wc -l)
8834         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8835
8836         cmd="$LFS find --mirror-count -6 --type f $td"
8837         nfiles=$($cmd | wc -l)
8838         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8839
8840         # find mirrored files with specific file state
8841         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8842         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8843
8844         cmd="$LFS find --mirror-state=ro --type f $td"
8845         nfiles=$($cmd | wc -l)
8846         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8847
8848         cmd="$LFS find ! --mirror-state=ro --type f $td"
8849         nfiles=$($cmd | wc -l)
8850         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8851
8852         cmd="$LFS find --mirror-state=wp --type f $td"
8853         nfiles=$($cmd | wc -l)
8854         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8855
8856         cmd="$LFS find ! --mirror-state=sp --type f $td"
8857         nfiles=$($cmd | wc -l)
8858         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8859 }
8860 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8861
8862 test_56da() { # LU-14179
8863         local path=$DIR/$tdir
8864
8865         test_mkdir $path
8866         cd $path
8867
8868         local longdir=$(str_repeat 'a' 255)
8869
8870         for i in {1..15}; do
8871                 path=$path/$longdir
8872                 test_mkdir $longdir
8873                 cd $longdir
8874         done
8875
8876         local len=${#path}
8877         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8878
8879         test_mkdir $lastdir
8880         cd $lastdir
8881         # PATH_MAX-1
8882         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8883
8884         # NAME_MAX
8885         touch $(str_repeat 'f' 255)
8886
8887         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8888                 error "lfs find reported an error"
8889
8890         rm -rf $DIR/$tdir
8891 }
8892 run_test 56da "test lfs find with long paths"
8893
8894 test_56ea() { #LU-10378
8895         local path=$DIR/$tdir
8896         local pool=$TESTNAME
8897
8898         # Create ost pool
8899         pool_add $pool || error "pool_add $pool failed"
8900         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8901                 error "adding targets to $pool failed"
8902
8903         # Set default pool on directory before creating file
8904         mkdir $path || error "mkdir $path failed"
8905         $LFS setstripe -p $pool $path ||
8906                 error "set OST pool on $pool failed"
8907         touch $path/$tfile || error "touch $path/$tfile failed"
8908
8909         # Compare basic file attributes from -printf and stat
8910         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G %n")
8911         local attr_stat=$(stat -c "%X %Y %Z %u %g %h" $path/$tfile)
8912
8913         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8914                 error "Attrs from lfs find and stat don't match"
8915
8916         # Compare Lustre attributes from lfs find and lfs getstripe
8917         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8918         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8919         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8920         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8921         local fpool=$($LFS getstripe --pool $path/$tfile)
8922         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8923
8924         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8925                 error "Attrs from lfs find and lfs getstripe don't match"
8926
8927         # Verify behavior for unknown escape/format sequences
8928         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8929
8930         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8931                 error "Escape/format codes don't match"
8932 }
8933 run_test 56ea "test lfs find -printf option"
8934
8935 test_56eb() {
8936         local dir=$DIR/$tdir
8937         local subdir_1=$dir/subdir_1
8938
8939         test_mkdir -p $subdir_1
8940         ln -s subdir_1 $dir/link_1
8941
8942         $LFS getstripe $dir | grep "^$dir/link_1$" -A1 ||
8943                 error "symlink is not followed"
8944
8945         $LFS getstripe --no-follow $dir |
8946                 grep "^$dir/link_1 has no stripe info$" ||
8947                 error "symlink should not have stripe info"
8948
8949         touch $dir/testfile
8950         ln -s testfile $dir/file_link_2
8951
8952         $LFS getstripe $dir | grep "^$dir/file_link_2$" -A1 ||
8953                 error "symlink is not followed"
8954
8955         $LFS getstripe --no-follow $dir |
8956                 grep "^$dir/file_link_2 has no stripe info$" ||
8957                 error "symlink should not have stripe info"
8958 }
8959 run_test 56eb "check lfs getstripe on symlink"
8960
8961 test_56ec() {
8962         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8963         local dir=$DIR/$tdir
8964         local srcfile=$dir/srcfile
8965         local srcyaml=$dir/srcyaml
8966         local destfile=$dir/destfile
8967
8968         test_mkdir -p $dir
8969
8970         $LFS setstripe -i 1 $srcfile
8971         $LFS getstripe --hex-idx --yaml $srcfile > $srcyaml
8972         # if the setstripe yaml parsing fails for any reason, the command can
8973         # randomly assign the correct OST index, leading to an erroneous
8974         # success. but the chance of false success is low enough that a
8975         # regression should still be quickly caught.
8976         $LFS setstripe --yaml=$srcyaml $destfile
8977
8978         local srcindex=$($LFS getstripe -i $srcfile)
8979         local destindex=$($LFS getstripe -i $destfile)
8980
8981         if [[ ! $srcindex -eq $destindex ]]; then
8982                 error "setstripe did not set OST index correctly"
8983         fi
8984 }
8985 run_test 56ec "check lfs getstripe,setstripe --hex --yaml"
8986
8987 test_56eda() {
8988         local dir=$DIR/$tdir
8989         local subdir=$dir/subdir
8990         local file1=$dir/$tfile
8991         local file2=$dir/$tfile\2
8992         local link=$dir/$tfile-link
8993         local nfiles
8994
8995         test_mkdir -p $dir
8996         $LFS setdirstripe -c1 $subdir
8997         touch $file1
8998         touch $file2
8999         ln $file2 $link
9000
9001         nfiles=$($LFS find --links 1 $dir | wc -l)
9002         (( $nfiles == 1 )) ||
9003                 error "lfs find --links expected 1 file, got $nfiles"
9004
9005         nfiles=$($LFS find --type f --links 2 $dir | wc -l)
9006         (( $nfiles == 2 )) ||
9007                 error "lfs find --links expected 2 files, got $nfiles"
9008
9009         nfiles=$($LFS find --type d --links 2 $dir | wc -l)
9010         (( $nfiles == 1 )) ||
9011                 error "lfs find --links expected 1 directory, got $nfiles"
9012 }
9013 run_test 56eda "check lfs find --links"
9014
9015 test_56edb() {
9016         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
9017
9018         local dir=$DIR/$tdir
9019         local stripedir=$dir/stripedir
9020         local nfiles
9021
9022         test_mkdir -p $dir
9023
9024         $LFS setdirstripe -c2 $stripedir
9025
9026         $LFS getdirstripe $stripedir
9027
9028         nfiles=$($LFS find --type d --links 2 $stripedir | wc -l)
9029         (( $nfiles == 1 )) ||
9030                 error "lfs find --links expected 1 directory, got $nfiles"
9031 }
9032 run_test 56edb "check lfs find --links for directory striped on multiple MDTs"
9033
9034 test_56ef() {
9035         local dir=$DIR/$tdir
9036         local dir1=$dir/d1
9037         local dir2=$dir/d2
9038         local nfiles
9039         local err_msg
9040
9041         test_mkdir -p $dir
9042
9043         mkdir $dir1
9044         mkdir $dir2
9045
9046         touch $dir1/f
9047         touch $dir2/f
9048
9049         nfiles=$($LFS find $dir1 $dir2 ! -type d | wc -l)
9050         (( $nfiles == 2 )) ||
9051                 error "(1) lfs find expected 2 files, got $nfiles"
9052
9053         nfiles=$($LFS find $dir1 $dir2 -type f | wc -l)
9054         (( $nfiles == 2 )) ||
9055                 error "(2) lfs find expected 2 files, got $nfiles"
9056
9057         nfiles=$($LFS find -type f $dir1 $dir2 | wc -l)
9058         (( $nfiles == 2 )) ||
9059                 error "(3) lfs find expected 2 files, got $nfiles"
9060
9061         err_msg=$($LFS find $dir1/typo $dir1/f 2>&1 > /dev/null)
9062         [[ $err_msg =~ "No such file or directory" ]] ||
9063                 error "expected standard error message, got: '$err_msg'"
9064 }
9065 run_test 56ef "lfs find with multiple paths"
9066
9067 test_57a() {
9068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9069         # note test will not do anything if MDS is not local
9070         if [ "$mds1_FSTYPE" != ldiskfs ]; then
9071                 skip_env "ldiskfs only test"
9072         fi
9073         remote_mds_nodsh && skip "remote MDS with nodsh"
9074
9075         local MNTDEV="osd*.*MDT*.mntdev"
9076         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
9077         [ -z "$DEV" ] && error "can't access $MNTDEV"
9078         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
9079                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
9080                         error "can't access $DEV"
9081                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
9082                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
9083                 rm $TMP/t57a.dump
9084         done
9085 }
9086 run_test 57a "verify MDS filesystem created with large inodes =="
9087
9088 test_57b() {
9089         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9090         if [ "$mds1_FSTYPE" != ldiskfs ]; then
9091                 skip_env "ldiskfs only test"
9092         fi
9093         remote_mds_nodsh && skip "remote MDS with nodsh"
9094
9095         local dir=$DIR/$tdir
9096         local filecount=100
9097         local file1=$dir/f1
9098         local fileN=$dir/f$filecount
9099
9100         rm -rf $dir || error "removing $dir"
9101         test_mkdir -c1 $dir
9102         local mdtidx=$($LFS getstripe -m $dir)
9103         local mdtname=MDT$(printf %04x $mdtidx)
9104         local facet=mds$((mdtidx + 1))
9105
9106         echo "mcreating $filecount files"
9107         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
9108
9109         # verify that files do not have EAs yet
9110         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
9111                 error "$file1 has an EA"
9112         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
9113                 error "$fileN has an EA"
9114
9115         sync
9116         sleep 1
9117         df $dir  #make sure we get new statfs data
9118         local mdsfree=$(do_facet $facet \
9119                         lctl get_param -n osd*.*$mdtname.kbytesfree)
9120         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
9121         local file
9122
9123         echo "opening files to create objects/EAs"
9124         for file in $(seq -f $dir/f%g 1 $filecount); do
9125                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
9126                         error "opening $file"
9127         done
9128
9129         # verify that files have EAs now
9130         $LFS getstripe -y $file1 | grep -q "l_ost_idx" ||
9131                 error "$file1 missing EA"
9132         $LFS getstripe -y $fileN | grep -q "l_ost_idx" ||
9133                 error "$fileN missing EA"
9134
9135         sleep 1  #make sure we get new statfs data
9136         df $dir
9137         local mdsfree2=$(do_facet $facet \
9138                          lctl get_param -n osd*.*$mdtname.kbytesfree)
9139         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
9140
9141         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
9142                 if [ "$mdsfree" != "$mdsfree2" ]; then
9143                         error "MDC before $mdcfree != after $mdcfree2"
9144                 else
9145                         echo "MDC before $mdcfree != after $mdcfree2"
9146                         echo "unable to confirm if MDS has large inodes"
9147                 fi
9148         fi
9149         rm -rf $dir
9150 }
9151 run_test 57b "default LOV EAs are stored inside large inodes ==="
9152
9153 test_58() {
9154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9155         [ -z "$(which wiretest 2>/dev/null)" ] &&
9156                         skip_env "could not find wiretest"
9157
9158         wiretest
9159 }
9160 run_test 58 "verify cross-platform wire constants =============="
9161
9162 test_59() {
9163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9164
9165         echo "touch 130 files"
9166         createmany -o $DIR/f59- 130
9167         echo "rm 130 files"
9168         unlinkmany $DIR/f59- 130
9169         sync
9170         # wait for commitment of removal
9171         wait_delete_completed
9172 }
9173 run_test 59 "verify cancellation of llog records async ========="
9174
9175 TEST60_HEAD="test_60 run $RANDOM"
9176 test_60a() {
9177         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9178         remote_mgs_nodsh && skip "remote MGS with nodsh"
9179         do_facet mgs "! which run-llog.sh &> /dev/null" &&
9180                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
9181                         skip_env "missing subtest run-llog.sh"
9182
9183         log "$TEST60_HEAD - from kernel mode"
9184         do_facet mgs "$LCTL dk > /dev/null"
9185         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
9186         do_facet mgs $LCTL dk > $TMP/$tfile
9187
9188         # LU-6388: test llog_reader
9189         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
9190         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
9191         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
9192                         skip_env "missing llog_reader"
9193         local fstype=$(facet_fstype mgs)
9194         [ $fstype != ldiskfs -a $fstype != zfs ] &&
9195                 skip_env "Only for ldiskfs or zfs type mgs"
9196
9197         local mntpt=$(facet_mntpt mgs)
9198         local mgsdev=$(mgsdevname 1)
9199         local fid_list
9200         local fid
9201         local rec_list
9202         local rec
9203         local rec_type
9204         local obj_file
9205         local path
9206         local seq
9207         local oid
9208         local pass=true
9209
9210         #get fid and record list
9211         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
9212                 tail -n 4))
9213         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
9214                 tail -n 4))
9215         #remount mgs as ldiskfs or zfs type
9216         stop mgs || error "stop mgs failed"
9217         mount_fstype mgs || error "remount mgs failed"
9218         for ((i = 0; i < ${#fid_list[@]}; i++)); do
9219                 fid=${fid_list[i]}
9220                 rec=${rec_list[i]}
9221                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
9222                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
9223                 oid=$((16#$oid))
9224
9225                 case $fstype in
9226                         ldiskfs )
9227                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
9228                         zfs )
9229                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
9230                 esac
9231                 echo "obj_file is $obj_file"
9232                 do_facet mgs $llog_reader $obj_file
9233
9234                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
9235                         awk '{ print $3 }' | sed -e "s/^type=//g")
9236                 if [ $rec_type != $rec ]; then
9237                         echo "FAILED test_60a wrong record type $rec_type," \
9238                               "should be $rec"
9239                         pass=false
9240                         break
9241                 fi
9242
9243                 #check obj path if record type is LLOG_LOGID_MAGIC
9244                 if [ "$rec" == "1064553b" ]; then
9245                         path=$(do_facet mgs $llog_reader $obj_file |
9246                                 grep "path=" | awk '{ print $NF }' |
9247                                 sed -e "s/^path=//g")
9248                         if [ $obj_file != $mntpt/$path ]; then
9249                                 echo "FAILED test_60a wrong obj path" \
9250                                       "$montpt/$path, should be $obj_file"
9251                                 pass=false
9252                                 break
9253                         fi
9254                 fi
9255         done
9256         rm -f $TMP/$tfile
9257         #restart mgs before "error", otherwise it will block the next test
9258         stop mgs || error "stop mgs failed"
9259         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
9260         $pass || error "test failed, see FAILED test_60a messages for specifics"
9261 }
9262 run_test 60a "llog_test run from kernel module and test llog_reader"
9263
9264 test_60b() { # bug 6411
9265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9266
9267         dmesg > $DIR/$tfile
9268         LLOG_COUNT=$(do_facet mgs dmesg |
9269                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
9270                           /llog_[a-z]*.c:[0-9]/ {
9271                                 if (marker)
9272                                         from_marker++
9273                                 from_begin++
9274                           }
9275                           END {
9276                                 if (marker)
9277                                         print from_marker
9278                                 else
9279                                         print from_begin
9280                           }")
9281
9282         [[ $LLOG_COUNT -gt 120 ]] &&
9283                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
9284 }
9285 run_test 60b "limit repeated messages from CERROR/CWARN"
9286
9287 test_60c() {
9288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9289
9290         echo "create 5000 files"
9291         createmany -o $DIR/f60c- 5000
9292 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
9293         lctl set_param fail_loc=0x80000137
9294         unlinkmany $DIR/f60c- 5000
9295         lctl set_param fail_loc=0
9296 }
9297 run_test 60c "unlink file when mds full"
9298
9299 test_60d() {
9300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9301
9302         SAVEPRINTK=$(lctl get_param -n printk)
9303         # verify "lctl mark" is even working"
9304         MESSAGE="test message ID $RANDOM $$"
9305         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9306         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
9307
9308         lctl set_param printk=0 || error "set lnet.printk failed"
9309         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
9310         MESSAGE="new test message ID $RANDOM $$"
9311         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
9312         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9313         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
9314
9315         lctl set_param -n printk="$SAVEPRINTK"
9316 }
9317 run_test 60d "test printk console message masking"
9318
9319 test_60e() {
9320         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9321         remote_mds_nodsh && skip "remote MDS with nodsh"
9322
9323         touch $DIR/$tfile
9324 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
9325         do_facet mds1 lctl set_param fail_loc=0x15b
9326         rm $DIR/$tfile
9327 }
9328 run_test 60e "no space while new llog is being created"
9329
9330 test_60f() {
9331         local old_path=$($LCTL get_param -n debug_path)
9332
9333         stack_trap "$LCTL set_param debug_path=$old_path"
9334         stack_trap "rm -f $TMP/$tfile*"
9335         rm -f $TMP/$tfile* 2> /dev/null
9336         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
9337         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
9338         test_mkdir $DIR/$tdir
9339         # retry in case the open is cached and not released
9340         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
9341                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
9342                 sleep 0.1
9343         done
9344         ls $TMP/$tfile*
9345         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
9346 }
9347 run_test 60f "change debug_path works"
9348
9349 test_60g() {
9350         local pid
9351         local i
9352
9353         test_mkdir -c $MDSCOUNT $DIR/$tdir
9354
9355         (
9356                 local index=0
9357                 while true; do
9358                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
9359                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
9360                                 2>/dev/null
9361                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
9362                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
9363                         index=$((index + 1))
9364                 done
9365         ) &
9366
9367         pid=$!
9368
9369         for i in {0..100}; do
9370                 # define OBD_FAIL_OSD_TXN_START    0x19a
9371                 local index=$((i % MDSCOUNT + 1))
9372
9373                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
9374                         > /dev/null
9375                 sleep 0.01
9376         done
9377
9378         kill -9 $pid
9379
9380         for i in $(seq $MDSCOUNT); do
9381                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
9382         done
9383
9384         mkdir $DIR/$tdir/new || error "mkdir failed"
9385         rmdir $DIR/$tdir/new || error "rmdir failed"
9386
9387         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
9388                 -t namespace
9389         for i in $(seq $MDSCOUNT); do
9390                 wait_update_facet mds$i "$LCTL get_param -n \
9391                         mdd.$(facet_svc mds$i).lfsck_namespace |
9392                         awk '/^status/ { print \\\$2 }'" "completed"
9393         done
9394
9395         ls -R $DIR/$tdir
9396         rm -rf $DIR/$tdir || error "rmdir failed"
9397 }
9398 run_test 60g "transaction abort won't cause MDT hung"
9399
9400 test_60h() {
9401         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
9402                 skip "Need MDS version at least 2.12.52"
9403         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
9404
9405         local f
9406
9407         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
9408         #define OBD_FAIL_MDS_STRIPE_FID          0x189
9409         for fail_loc in 0x80000188 0x80000189; do
9410                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
9411                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
9412                         error "mkdir $dir-$fail_loc failed"
9413                 for i in {0..10}; do
9414                         # create may fail on missing stripe
9415                         echo $i > $DIR/$tdir-$fail_loc/$i
9416                 done
9417                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9418                         error "getdirstripe $tdir-$fail_loc failed"
9419                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
9420                         error "migrate $tdir-$fail_loc failed"
9421                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9422                         error "getdirstripe $tdir-$fail_loc failed"
9423                 pushd $DIR/$tdir-$fail_loc
9424                 for f in *; do
9425                         echo $f | cmp $f - || error "$f data mismatch"
9426                 done
9427                 popd
9428                 rm -rf $DIR/$tdir-$fail_loc
9429         done
9430 }
9431 run_test 60h "striped directory with missing stripes can be accessed"
9432
9433 function t60i_load() {
9434         mkdir $DIR/$tdir
9435         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
9436         $LCTL set_param fail_loc=0x131c fail_val=1
9437         for ((i=0; i<5000; i++)); do
9438                 touch $DIR/$tdir/f$i
9439         done
9440 }
9441
9442 test_60i() {
9443         changelog_register || error "changelog_register failed"
9444         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
9445         changelog_users $SINGLEMDS | grep -q $cl_user ||
9446                 error "User $cl_user not found in changelog_users"
9447         changelog_chmask "ALL"
9448         t60i_load &
9449         local PID=$!
9450         for((i=0; i<100; i++)); do
9451                 changelog_dump >/dev/null ||
9452                         error "can't read changelog"
9453         done
9454         kill $PID
9455         wait $PID
9456         changelog_deregister || error "changelog_deregister failed"
9457         $LCTL set_param fail_loc=0
9458 }
9459 run_test 60i "llog: new record vs reader race"
9460
9461 test_60j() {
9462         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
9463                 skip "need MDS version at least 2.15.50"
9464         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9465         remote_mds_nodsh && skip "remote MDS with nodsh"
9466         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
9467
9468         changelog_users $SINGLEMDS | grep "^cl" &&
9469                 skip "active changelog user"
9470
9471         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
9472
9473         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
9474                 skip_env "missing llog_reader"
9475
9476         mkdir_on_mdt0 $DIR/$tdir
9477
9478         local f=$DIR/$tdir/$tfile
9479         local mdt_dev
9480         local tmpfile
9481         local plain
9482
9483         changelog_register || error "cannot register changelog user"
9484
9485         # set changelog_mask to ALL
9486         changelog_chmask "ALL"
9487         changelog_clear
9488
9489         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
9490         unlinkmany ${f}- 100 || error "unlinkmany failed"
9491
9492         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
9493         mdt_dev=$(facet_device $SINGLEMDS)
9494
9495         do_facet $SINGLEMDS sync
9496         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
9497                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
9498                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
9499
9500         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
9501
9502         # if $tmpfile is not on EXT3 filesystem for some reason
9503         [[ ${plain:0:1} == 'O' ]] ||
9504                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
9505
9506         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
9507                 $mdt_dev; stat -c %s $tmpfile")
9508         echo "Truncate llog from $size to $((size - size % 8192))"
9509         size=$((size - size % 8192))
9510         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
9511         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9512                 grep -c 'in bitmap only')
9513         (( $errs > 0 )) || error "llog_reader didn't find lost records"
9514
9515         size=$((size - 9000))
9516         echo "Corrupt llog in the middle at $size"
9517         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
9518                 count=333 conv=notrunc
9519         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9520                 grep -c 'next chunk')
9521         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
9522 }
9523 run_test 60j "llog_reader reports corruptions"
9524
9525 test_61a() {
9526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9527
9528         f="$DIR/f61"
9529         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
9530         cancel_lru_locks osc
9531         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
9532         sync
9533 }
9534 run_test 61a "mmap() writes don't make sync hang ================"
9535
9536 test_61b() {
9537         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
9538 }
9539 run_test 61b "mmap() of unstriped file is successful"
9540
9541 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
9542 # Though this test is irrelevant anymore, it helped to reveal some
9543 # other grant bugs (LU-4482), let's keep it.
9544 test_63a() {   # was test_63
9545         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9546
9547         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
9548
9549         for i in `seq 10` ; do
9550                 dd if=/dev/zero of=$DIR/f63 bs=8k &
9551                 sleep 5
9552                 kill $!
9553                 sleep 1
9554         done
9555
9556         rm -f $DIR/f63 || true
9557 }
9558 run_test 63a "Verify oig_wait interruption does not crash ======="
9559
9560 # bug 2248 - async write errors didn't return to application on sync
9561 # bug 3677 - async write errors left page locked
9562 test_63b() {
9563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9564
9565         debugsave
9566         lctl set_param debug=-1
9567
9568         # ensure we have a grant to do async writes
9569         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
9570         rm $DIR/$tfile
9571
9572         sync    # sync lest earlier test intercept the fail_loc
9573
9574         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9575         lctl set_param fail_loc=0x80000406
9576         $MULTIOP $DIR/$tfile Owy && \
9577                 error "sync didn't return ENOMEM"
9578         sync; sleep 2; sync     # do a real sync this time to flush page
9579         lctl get_param -n llite.*.dump_page_cache | grep locked && \
9580                 error "locked page left in cache after async error" || true
9581         debugrestore
9582 }
9583 run_test 63b "async write errors should be returned to fsync ==="
9584
9585 test_64a () {
9586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9587
9588         lfs df $DIR
9589         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
9590 }
9591 run_test 64a "verify filter grant calculations (in kernel) ====="
9592
9593 test_64b () {
9594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9595
9596         bash oos.sh $MOUNT || error "oos.sh failed: $?"
9597 }
9598 run_test 64b "check out-of-space detection on client"
9599
9600 test_64c() {
9601         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
9602 }
9603 run_test 64c "verify grant shrink"
9604
9605 import_param() {
9606         local tgt=$1
9607         local param=$2
9608
9609         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
9610 }
9611
9612 # this does exactly what osc_request.c:osc_announce_cached() does in
9613 # order to calculate max amount of grants to ask from server
9614 want_grant() {
9615         local tgt=$1
9616
9617         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
9618         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
9619
9620         ((rpc_in_flight++));
9621         nrpages=$((nrpages * rpc_in_flight))
9622
9623         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
9624
9625         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
9626
9627         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
9628         local undirty=$((nrpages * PAGE_SIZE))
9629
9630         local max_extent_pages
9631         max_extent_pages=$(import_param $tgt grant_max_extent_size)
9632         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
9633         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
9634         local grant_extent_tax
9635         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9636
9637         undirty=$((undirty + nrextents * grant_extent_tax))
9638
9639         echo $undirty
9640 }
9641
9642 # this is size of unit for grant allocation. It should be equal to
9643 # what tgt_grant.c:tgt_grant_chunk() calculates
9644 grant_chunk() {
9645         local tgt=$1
9646         local max_brw_size
9647         local grant_extent_tax
9648
9649         max_brw_size=$(import_param $tgt max_brw_size)
9650
9651         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9652
9653         echo $(((max_brw_size + grant_extent_tax) * 2))
9654 }
9655
9656 test_64d() {
9657         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
9658                 skip "OST < 2.10.55 doesn't limit grants enough"
9659
9660         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9661
9662         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9663                 skip "no grant_param connect flag"
9664
9665         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9666
9667         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9668         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9669
9670
9671         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9672         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9673
9674         $LFS setstripe $DIR/$tfile -i 0 -c 1
9675         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9676         ddpid=$!
9677
9678         while kill -0 $ddpid; do
9679                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9680
9681                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9682                         kill $ddpid
9683                         error "cur_grant $cur_grant > $max_cur_granted"
9684                 fi
9685
9686                 sleep 1
9687         done
9688 }
9689 run_test 64d "check grant limit exceed"
9690
9691 check_grants() {
9692         local tgt=$1
9693         local expected=$2
9694         local msg=$3
9695         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9696
9697         ((cur_grants == expected)) ||
9698                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9699 }
9700
9701 round_up_p2() {
9702         echo $((($1 + $2 - 1) & ~($2 - 1)))
9703 }
9704
9705 test_64e() {
9706         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9707         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9708                 skip "Need OSS version at least 2.11.56"
9709
9710         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9711         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9712         $LCTL set_param debug=+cache
9713
9714         # Remount client to reset grant
9715         remount_client $MOUNT || error "failed to remount client"
9716         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9717
9718         local init_grants=$(import_param $osc_tgt initial_grant)
9719
9720         check_grants $osc_tgt $init_grants "init grants"
9721
9722         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9723         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9724         local gbs=$(import_param $osc_tgt grant_block_size)
9725
9726         # write random number of bytes from max_brw_size / 4 to max_brw_size
9727         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9728         # align for direct io
9729         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9730         # round to grant consumption unit
9731         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9732
9733         local grants=$((wb_round_up + extent_tax))
9734
9735         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9736         stack_trap "rm -f $DIR/$tfile"
9737
9738         # define OBD_FAIL_TGT_NO_GRANT 0x725
9739         # make the server not grant more back
9740         do_facet ost1 $LCTL set_param fail_loc=0x725
9741         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9742
9743         do_facet ost1 $LCTL set_param fail_loc=0
9744
9745         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9746
9747         rm -f $DIR/$tfile || error "rm failed"
9748
9749         # Remount client to reset grant
9750         remount_client $MOUNT || error "failed to remount client"
9751         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9752
9753         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9754
9755         # define OBD_FAIL_TGT_NO_GRANT 0x725
9756         # make the server not grant more back
9757         do_facet ost1 $LCTL set_param fail_loc=0x725
9758         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9759         do_facet ost1 $LCTL set_param fail_loc=0
9760
9761         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9762 }
9763 run_test 64e "check grant consumption (no grant allocation)"
9764
9765 test_64f() {
9766         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9767
9768         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9769         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9770         $LCTL set_param debug=+cache
9771
9772         # Remount client to reset grant
9773         remount_client $MOUNT || error "failed to remount client"
9774         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9775
9776         local init_grants=$(import_param $osc_tgt initial_grant)
9777         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9778         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9779         local gbs=$(import_param $osc_tgt grant_block_size)
9780         local chunk=$(grant_chunk $osc_tgt)
9781
9782         # write random number of bytes from max_brw_size / 4 to max_brw_size
9783         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9784         # align for direct io
9785         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9786         # round to grant consumption unit
9787         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9788
9789         local grants=$((wb_round_up + extent_tax))
9790
9791         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9792         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9793                 error "error writing to $DIR/$tfile"
9794
9795         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9796                 "direct io with grant allocation"
9797
9798         rm -f $DIR/$tfile || error "rm failed"
9799
9800         # Remount client to reset grant
9801         remount_client $MOUNT || error "failed to remount client"
9802         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9803
9804         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9805
9806         # Testing that buffered IO consumes grant on the client
9807
9808         # Delay the RPC on the server so it's guaranteed to not complete even
9809         # if the RPC is sent from the client
9810         #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
9811         $LCTL set_param fail_loc=0x50a fail_val=3
9812         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 conv=notrunc ||
9813                 error "error writing to $DIR/$tfile with buffered IO"
9814
9815         check_grants $osc_tgt $((init_grants - grants)) \
9816                 "buffered io, not write rpc"
9817
9818         # Clear the fail loc and do a sync on the client
9819         $LCTL set_param fail_loc=0 fail_val=0
9820         sync
9821
9822         # RPC is now known to have sent
9823         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9824                 "buffered io, one RPC"
9825 }
9826 run_test 64f "check grant consumption (with grant allocation)"
9827
9828 test_64g() {
9829         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9830                 skip "Need MDS version at least 2.14.56"
9831
9832         local mdts=$(comma_list $(mdts_nodes))
9833
9834         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9835                         tr '\n' ' ')
9836         stack_trap "$LCTL set_param $old"
9837
9838         # generate dirty pages and increase dirty granted on MDT
9839         stack_trap "rm -f $DIR/$tfile-*"
9840         for (( i = 0; i < 10; i++)); do
9841                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9842                         error "can't set stripe"
9843                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9844                         error "can't dd"
9845                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9846                         $LFS getstripe $DIR/$tfile-$i
9847                         error "not DoM file"
9848                 }
9849         done
9850
9851         # flush dirty pages
9852         sync
9853
9854         # wait until grant shrink reset grant dirty on MDTs
9855         for ((i = 0; i < 120; i++)); do
9856                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9857                         awk '{sum=sum+$1} END {print sum}')
9858                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9859                 echo "$grant_dirty grants, $vm_dirty pages"
9860                 (( grant_dirty + vm_dirty == 0 )) && break
9861                 (( i == 3 )) && sync &&
9862                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9863                 sleep 1
9864         done
9865
9866         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9867                 awk '{sum=sum+$1} END {print sum}')
9868         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9869 }
9870 run_test 64g "grant shrink on MDT"
9871
9872 test_64h() {
9873         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9874                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9875
9876         local instance=$($LFS getname -i $DIR)
9877         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9878         local num_exps=$(do_facet ost1 \
9879             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9880         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9881         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9882         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9883
9884         # 10MiB is for file to be written, max_brw_size * 16 *
9885         # num_exps is space reserve so that tgt_grant_shrink() decided
9886         # to not shrink
9887         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9888         (( avail * 1024 < expect )) &&
9889                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9890
9891         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9892         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9893         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9894         $LCTL set_param osc.*OST0000*.grant_shrink=1
9895         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9896
9897         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9898         stack_trap "rm -f $DIR/$tfile"
9899         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9900
9901         # drop cache so that coming read would do rpc
9902         cancel_lru_locks osc
9903
9904         # shrink interval is set to 10, pause for 7 seconds so that
9905         # grant thread did not wake up yet but coming read entered
9906         # shrink mode for rpc (osc_should_shrink_grant())
9907         sleep 7
9908
9909         declare -a cur_grant_bytes
9910         declare -a tot_granted
9911         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9912         tot_granted[0]=$(do_facet ost1 \
9913             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9914
9915         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9916
9917         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9918         tot_granted[1]=$(do_facet ost1 \
9919             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9920
9921         # grant change should be equal on both sides
9922         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9923                 tot_granted[0] - tot_granted[1])) ||
9924                 error "grant change mismatch, "                                \
9925                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9926                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9927 }
9928 run_test 64h "grant shrink on read"
9929
9930 test_64i() {
9931         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9932                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9933
9934         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9935         remote_ost_nodsh && skip "remote OSTs with nodsh"
9936
9937         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9938         stack_trap "rm -f $DIR/$tfile"
9939
9940         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9941
9942         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9943         local instance=$($LFS getname -i $DIR)
9944
9945         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9946         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9947
9948         # shrink grants and simulate rpc loss
9949         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9950         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9951         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9952
9953         fail ost1
9954
9955         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9956
9957         local testid=$(echo $TESTNAME | tr '_' ' ')
9958
9959         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9960                 grep "GRANT, real grant" &&
9961                 error "client has more grants then it owns" || true
9962 }
9963 run_test 64i "shrink on reconnect"
9964
9965 # bug 1414 - set/get directories' stripe info
9966 test_65a() {
9967         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9968
9969         test_mkdir $DIR/$tdir
9970         touch $DIR/$tdir/f1
9971         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9972 }
9973 run_test 65a "directory with no stripe info"
9974
9975 test_65b() {
9976         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9977
9978         test_mkdir $DIR/$tdir
9979         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9980
9981         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9982                                                 error "setstripe"
9983         touch $DIR/$tdir/f2
9984         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9985 }
9986 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9987
9988 test_65c() {
9989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9990         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9991
9992         test_mkdir $DIR/$tdir
9993         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9994
9995         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9996                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9997         touch $DIR/$tdir/f3
9998         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9999 }
10000 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
10001
10002 test_65d() {
10003         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10004
10005         test_mkdir $DIR/$tdir
10006         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
10007         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10008
10009         if [[ $STRIPECOUNT -le 0 ]]; then
10010                 sc=1
10011         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
10012                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
10013                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
10014         else
10015                 sc=$(($STRIPECOUNT - 1))
10016         fi
10017         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
10018         touch $DIR/$tdir/f4 $DIR/$tdir/f5
10019         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
10020                 error "lverify failed"
10021 }
10022 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
10023
10024 test_65e() {
10025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10026
10027         # LU-16904 delete layout when root is set as PFL layout
10028         save_layout_restore_at_exit $MOUNT
10029         $LFS setstripe -d $MOUNT || error "setstripe failed"
10030
10031         test_mkdir $DIR/$tdir
10032
10033         $LFS setstripe $DIR/$tdir || error "setstripe"
10034         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
10035                                         error "no stripe info failed"
10036         touch $DIR/$tdir/f6
10037         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
10038 }
10039 run_test 65e "directory setstripe defaults"
10040
10041 test_65f() {
10042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10043
10044         test_mkdir $DIR/${tdir}f
10045         $RUNAS $LFS setstripe $DIR/${tdir}f &&
10046                 error "setstripe succeeded" || true
10047 }
10048 run_test 65f "dir setstripe permission (should return error) ==="
10049
10050 test_65g() {
10051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10052
10053         # LU-16904 delete layout when root is set as PFL layout
10054         save_layout_restore_at_exit $MOUNT
10055         $LFS setstripe -d $MOUNT || error "setstripe failed"
10056
10057         test_mkdir $DIR/$tdir
10058         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10059
10060         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
10061                 error "setstripe -S failed"
10062         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
10063         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
10064                 error "delete default stripe failed"
10065 }
10066 run_test 65g "directory setstripe -d"
10067
10068 test_65h() {
10069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10070
10071         test_mkdir $DIR/$tdir
10072         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10073
10074         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
10075                 error "setstripe -S failed"
10076         test_mkdir $DIR/$tdir/dd1
10077         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
10078                 error "stripe info inherit failed"
10079 }
10080 run_test 65h "directory stripe info inherit ===================="
10081
10082 test_65i() {
10083         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10084
10085         save_layout_restore_at_exit $MOUNT
10086
10087         # bug6367: set non-default striping on root directory
10088         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
10089
10090         # bug12836: getstripe on -1 default directory striping
10091         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
10092
10093         # bug12836: getstripe -v on -1 default directory striping
10094         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
10095
10096         # bug12836: new find on -1 default directory striping
10097         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
10098 }
10099 run_test 65i "various tests to set root directory striping"
10100
10101 test_65j() { # bug6367
10102         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10103
10104         sync; sleep 1
10105
10106         # if we aren't already remounting for each test, do so for this test
10107         if [ "$I_MOUNTED" = "yes" ]; then
10108                 cleanup || error "failed to unmount"
10109                 setup
10110         fi
10111
10112         save_layout_restore_at_exit $MOUNT
10113
10114         $LFS setstripe -d $MOUNT || error "setstripe failed"
10115 }
10116 run_test 65j "set default striping on root directory (bug 6367)="
10117
10118 cleanup_65k() {
10119         rm -rf $DIR/$tdir
10120         wait_delete_completed
10121         do_facet $SINGLEMDS "lctl set_param -n \
10122                 osp.$ost*MDT0000.max_create_count=$max_count"
10123         do_facet $SINGLEMDS "lctl set_param -n \
10124                 osp.$ost*MDT0000.create_count=$count"
10125         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10126         echo $INACTIVE_OSC "is Activate"
10127
10128         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10129 }
10130
10131 test_65k() { # bug11679
10132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10133         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10134         remote_mds_nodsh && skip "remote MDS with nodsh"
10135
10136         local disable_precreate=true
10137         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
10138                 disable_precreate=false
10139
10140         echo "Check OST status: "
10141         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
10142                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
10143
10144         for OSC in $MDS_OSCS; do
10145                 echo $OSC "is active"
10146                 do_facet $SINGLEMDS lctl --device %$OSC activate
10147         done
10148
10149         for INACTIVE_OSC in $MDS_OSCS; do
10150                 local ost=$(osc_to_ost $INACTIVE_OSC)
10151                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
10152                                lov.*md*.target_obd |
10153                                awk -F: /$ost/'{ print $1 }' | head -n 1)
10154
10155                 mkdir -p $DIR/$tdir
10156                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
10157                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
10158
10159                 echo "Deactivate: " $INACTIVE_OSC
10160                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
10161
10162                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
10163                               osp.$ost*MDT0000.create_count")
10164                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
10165                                   osp.$ost*MDT0000.max_create_count")
10166                 $disable_precreate &&
10167                         do_facet $SINGLEMDS "lctl set_param -n \
10168                                 osp.$ost*MDT0000.max_create_count=0"
10169
10170                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
10171                         [ -f $DIR/$tdir/$idx ] && continue
10172                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
10173                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
10174                                 { cleanup_65k;
10175                                   error "setstripe $idx should succeed"; }
10176                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
10177                 done
10178                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
10179                 rmdir $DIR/$tdir
10180
10181                 do_facet $SINGLEMDS "lctl set_param -n \
10182                         osp.$ost*MDT0000.max_create_count=$max_count"
10183                 do_facet $SINGLEMDS "lctl set_param -n \
10184                         osp.$ost*MDT0000.create_count=$count"
10185                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10186                 echo $INACTIVE_OSC "is Activate"
10187
10188                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10189         done
10190 }
10191 run_test 65k "validate manual striping works properly with deactivated OSCs"
10192
10193 test_65l() { # bug 12836
10194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10195
10196         test_mkdir -p $DIR/$tdir/test_dir
10197         $LFS setstripe -c -1 $DIR/$tdir/test_dir
10198         $LFS find -mtime -1 $DIR/$tdir >/dev/null
10199 }
10200 run_test 65l "lfs find on -1 stripe dir ========================"
10201
10202 test_65m() {
10203         local layout=$(save_layout $MOUNT)
10204         $RUNAS $LFS setstripe -c 2 $MOUNT && {
10205                 restore_layout $MOUNT $layout
10206                 error "setstripe should fail by non-root users"
10207         }
10208         true
10209 }
10210 run_test 65m "normal user can't set filesystem default stripe"
10211
10212 test_65n() {
10213         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
10214         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
10215                 skip "Need MDS version at least 2.12.50"
10216         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
10217
10218         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
10219         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
10220         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
10221
10222         save_layout_restore_at_exit $MOUNT
10223
10224         # new subdirectory under root directory should not inherit
10225         # the default layout from root
10226         # LU-16904 check if the root is set as PFL layout
10227         local numcomp=$($LFS getstripe --component-count $MOUNT)
10228
10229         if [[ $numcomp -eq 0 ]]; then
10230                 local dir1=$MOUNT/$tdir-1
10231                 mkdir $dir1 || error "mkdir $dir1 failed"
10232                 ! getfattr -n trusted.lov $dir1 &> /dev/null ||
10233                         error "$dir1 shouldn't have LOV EA"
10234         fi
10235
10236         # delete the default layout on root directory
10237         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
10238
10239         local dir2=$MOUNT/$tdir-2
10240         mkdir $dir2 || error "mkdir $dir2 failed"
10241         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
10242                 error "$dir2 shouldn't have LOV EA"
10243
10244         # set a new striping pattern on root directory
10245         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10246         local new_def_stripe_size=$((def_stripe_size * 2))
10247         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
10248                 error "set stripe size on $MOUNT failed"
10249
10250         # new file created in $dir2 should inherit the new stripe size from
10251         # the filesystem default
10252         local file2=$dir2/$tfile-2
10253         touch $file2 || error "touch $file2 failed"
10254
10255         local file2_stripe_size=$($LFS getstripe -S $file2)
10256         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
10257         {
10258                 echo "file2_stripe_size: '$file2_stripe_size'"
10259                 echo "new_def_stripe_size: '$new_def_stripe_size'"
10260                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
10261         }
10262
10263         local dir3=$MOUNT/$tdir-3
10264         mkdir $dir3 || error "mkdir $dir3 failed"
10265         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
10266         # the root layout, which is the actual default layout that will be used
10267         # when new files are created in $dir3.
10268         local dir3_layout=$(get_layout_param $dir3)
10269         local root_dir_layout=$(get_layout_param $MOUNT)
10270         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
10271         {
10272                 echo "dir3_layout: '$dir3_layout'"
10273                 echo "root_dir_layout: '$root_dir_layout'"
10274                 error "$dir3 should show the default layout from $MOUNT"
10275         }
10276
10277         # set OST pool on root directory
10278         local pool=$TESTNAME
10279         pool_add $pool || error "add $pool failed"
10280         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10281                 error "add targets to $pool failed"
10282
10283         $LFS setstripe -p $pool $MOUNT ||
10284                 error "set OST pool on $MOUNT failed"
10285
10286         # new file created in $dir3 should inherit the pool from
10287         # the filesystem default
10288         local file3=$dir3/$tfile-3
10289         touch $file3 || error "touch $file3 failed"
10290
10291         local file3_pool=$($LFS getstripe -p $file3)
10292         [[ "$file3_pool" = "$pool" ]] ||
10293                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
10294
10295         local dir4=$MOUNT/$tdir-4
10296         mkdir $dir4 || error "mkdir $dir4 failed"
10297         local dir4_layout=$(get_layout_param $dir4)
10298         root_dir_layout=$(get_layout_param $MOUNT)
10299         echo "$LFS getstripe -d $dir4"
10300         $LFS getstripe -d $dir4
10301         echo "$LFS getstripe -d $MOUNT"
10302         $LFS getstripe -d $MOUNT
10303         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
10304         {
10305                 echo "dir4_layout: '$dir4_layout'"
10306                 echo "root_dir_layout: '$root_dir_layout'"
10307                 error "$dir4 should show the default layout from $MOUNT"
10308         }
10309
10310         # new file created in $dir4 should inherit the pool from
10311         # the filesystem default
10312         local file4=$dir4/$tfile-4
10313         touch $file4 || error "touch $file4 failed"
10314
10315         local file4_pool=$($LFS getstripe -p $file4)
10316         [[ "$file4_pool" = "$pool" ]] ||
10317                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
10318
10319         # new subdirectory under non-root directory should inherit
10320         # the default layout from its parent directory
10321         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
10322                 error "set directory layout on $dir4 failed"
10323
10324         local dir5=$dir4/$tdir-5
10325         mkdir $dir5 || error "mkdir $dir5 failed"
10326
10327         dir4_layout=$(get_layout_param $dir4)
10328         local dir5_layout=$(get_layout_param $dir5)
10329         [[ "$dir4_layout" = "$dir5_layout" ]] ||
10330         {
10331                 echo "dir4_layout: '$dir4_layout'"
10332                 echo "dir5_layout: '$dir5_layout'"
10333                 error "$dir5 should inherit the default layout from $dir4"
10334         }
10335
10336         # though subdir under ROOT doesn't inherit default layout, but
10337         # its sub dir/file should be created with default layout.
10338         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
10339         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
10340                 skip "Need MDS version at least 2.12.59"
10341
10342         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
10343         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
10344         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
10345
10346         if [ $default_lmv_hash == "none" ]; then
10347                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
10348         else
10349                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
10350                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
10351         fi
10352
10353         $LFS setdirstripe -D -c 2 $MOUNT ||
10354                 error "setdirstripe -D -c 2 failed"
10355         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
10356         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
10357         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
10358
10359         # $dir4 layout includes pool
10360         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
10361         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10362                 error "pool lost on setstripe"
10363         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
10364         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10365                 error "pool lost on compound layout setstripe"
10366 }
10367 run_test 65n "don't inherit default layout from root for new subdirectories"
10368
10369 test_65o() {
10370         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
10371                 skip "need MDS version at least 2.14.57"
10372
10373         # set OST pool on root directory
10374         local pool=$TESTNAME
10375
10376         pool_add $pool || error "add $pool failed"
10377         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10378                 error "add targets to $pool failed"
10379
10380         local dir1=$MOUNT/$tdir
10381
10382         mkdir $dir1 || error "mkdir $dir1 failed"
10383
10384         # set a new striping pattern on root directory
10385         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10386
10387         $LFS setstripe -p $pool $dir1 ||
10388                 error "set directory layout on $dir1 failed"
10389
10390         # $dir1 layout includes pool
10391         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
10392         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10393                 error "pool lost on setstripe"
10394         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
10395         $LFS getstripe $dir1
10396         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10397                 error "pool lost on compound layout setstripe"
10398
10399         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
10400                 error "setdirstripe failed on sub-dir with inherited pool"
10401         $LFS getstripe $dir1/dir2
10402         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
10403                 error "pool lost on compound layout setdirstripe"
10404
10405         $LFS setstripe -E -1 -c 1 $dir1
10406         $LFS getstripe -d $dir1
10407         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10408                 error "pool lost on setstripe"
10409 }
10410 run_test 65o "pool inheritance for mdt component"
10411
10412 test_65p () { # LU-16152
10413         local src_dir=$DIR/$tdir/src_dir
10414         local dst_dir=$DIR/$tdir/dst_dir
10415         local yaml_file=$DIR/$tdir/layout.yaml
10416         local border
10417
10418         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10419                 skip "Need at least version 2.15.51"
10420
10421         test_mkdir -p $src_dir
10422         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
10423                 error "failed to setstripe"
10424         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
10425                 error "failed to getstripe"
10426
10427         test_mkdir -p $dst_dir
10428         $LFS setstripe --yaml $yaml_file $dst_dir ||
10429                 error "failed to setstripe with yaml file"
10430         border=$($LFS getstripe -d $dst_dir |
10431                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
10432                 error "failed to getstripe"
10433
10434         # 2048M is 0x80000000, or 2147483648
10435         (( $border == 2147483648 )) ||
10436                 error "failed to handle huge number in yaml layout"
10437 }
10438 run_test 65p "setstripe with yaml file and huge number"
10439
10440 test_65p () { # LU-16194
10441         local src_dir=$DIR/$tdir/src_dir
10442
10443         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10444                 skip "Need at least version 2.15.51"
10445
10446         test_mkdir -p $src_dir
10447         # 8E is 0x8000 0000 0000 0000, which is negative as s64
10448         $LFS setstripe -E 8E -c 4 -E EOF -c 8 $src_dir &&
10449                 error "should fail if extent start/end >=8E"
10450
10451         # EOF should work as before
10452         $LFS setstripe -E 8M -c 4 -E EOF -c 8 $src_dir ||
10453                 error "failed to setstripe normally"
10454 }
10455 run_test 65p "setstripe with >=8E offset should fail"
10456
10457 # bug 2543 - update blocks count on client
10458 test_66() {
10459         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10460
10461         local COUNT=${COUNT:-8}
10462         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
10463         sync; sync_all_data; sync; sync_all_data
10464         cancel_lru_locks osc
10465         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
10466         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
10467 }
10468 run_test 66 "update inode blocks count on client ==============="
10469
10470 meminfo() {
10471         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
10472 }
10473
10474 swap_used() {
10475         swapon -s | awk '($1 == "'$1'") { print $4 }'
10476 }
10477
10478 # bug5265, obdfilter oa2dentry return -ENOENT
10479 # #define OBD_FAIL_SRV_ENOENT 0x217
10480 test_69() {
10481         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10482         remote_ost_nodsh && skip "remote OST with nodsh"
10483
10484         f="$DIR/$tfile"
10485         $LFS setstripe -c 1 -i 0 $f
10486         stack_trap "rm -f $f ${f}.2"
10487
10488         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
10489
10490         do_facet ost1 lctl set_param fail_loc=0x217
10491         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
10492         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
10493
10494         do_facet ost1 lctl set_param fail_loc=0
10495         $DIRECTIO write $f 0 2 || error "write error"
10496
10497         cancel_lru_locks osc
10498         $DIRECTIO read $f 0 1 || error "read error"
10499
10500         do_facet ost1 lctl set_param fail_loc=0x217
10501         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
10502
10503         do_facet ost1 lctl set_param fail_loc=0
10504 }
10505 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
10506
10507 test_70a() {
10508         # Perform a really simple test of health write and health check
10509         (( $OST1_VERSION >= $(version_code 2.15.59) )) ||
10510                 skip "OSTs < 2.15.59 doesn't have enable_health_write"
10511
10512         local orig_value="$(do_facet ost1 $LCTL get_param -n enable_health_write)"
10513
10514         stack_trap "do_facet ost1 $LCTL set_param enable_health_write $orig_value"
10515
10516         # Test with health write off
10517         do_facet ost1 $LCTL set_param enable_health_write off ||
10518                 error "can't set enable_health_write off"
10519         do_facet ost1 $LCTL get_param enable_health_write ||
10520                 error "can't get enable_health_write"
10521
10522         [[ "$(do_facet ost1 $LCTL get_param health_check)" =~ "healthy" ]] ||
10523                 error "not healthy (1)"
10524
10525         # Test with health write on
10526         do_facet ost1 $LCTL set_param enable_health_write on ||
10527                 error "can't set enable_health_write on"
10528         do_facet ost1 $LCTL get_param enable_health_write ||
10529                 error "can't get enable_health_write"
10530
10531         [[ "$(do_facet ost1 $LCTL get_param health_check)" =~ "healthy" ]] ||
10532                 error "not healthy (2)"
10533 }
10534 run_test 70a "verify health_check, health_write don't explode (on OST)"
10535
10536 test_71() {
10537         test_mkdir $DIR/$tdir
10538         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
10539         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
10540 }
10541 run_test 71 "Running dbench on lustre (don't segment fault) ===="
10542
10543 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
10544         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10545         [ "$RUNAS_ID" = "$UID" ] &&
10546                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10547         # Check that testing environment is properly set up. Skip if not
10548         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
10549                 skip_env "User $RUNAS_ID does not exist - skipping"
10550
10551         touch $DIR/$tfile
10552         chmod 777 $DIR/$tfile
10553         chmod ug+s $DIR/$tfile
10554         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
10555                 error "$RUNAS dd $DIR/$tfile failed"
10556         # See if we are still setuid/sgid
10557         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10558                 error "S/gid is not dropped on write"
10559         # Now test that MDS is updated too
10560         cancel_lru_locks mdc
10561         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10562                 error "S/gid is not dropped on MDS"
10563         rm -f $DIR/$tfile
10564 }
10565 run_test 72a "Test that remove suid works properly (bug5695) ===="
10566
10567 test_72b() { # bug 24226 -- keep mode setting when size is not changing
10568         local perm
10569
10570         [ "$RUNAS_ID" = "$UID" ] &&
10571                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10572         [ "$RUNAS_ID" -eq 0 ] &&
10573                 skip_env "RUNAS_ID = 0 -- skipping"
10574         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10575         # Check that testing environment is properly set up. Skip if not
10576         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
10577                 skip_env "User $RUNAS_ID does not exist - skipping"
10578
10579         touch $DIR/${tfile}-f{g,u}
10580         test_mkdir $DIR/${tfile}-dg
10581         test_mkdir $DIR/${tfile}-du
10582         chmod 770 $DIR/${tfile}-{f,d}{g,u}
10583         chmod g+s $DIR/${tfile}-{f,d}g
10584         chmod u+s $DIR/${tfile}-{f,d}u
10585         for perm in 777 2777 4777; do
10586                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
10587                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
10588                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
10589                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
10590         done
10591         true
10592 }
10593 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
10594
10595 # bug 3462 - multiple simultaneous MDC requests
10596 test_73() {
10597         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10598
10599         test_mkdir $DIR/d73-1
10600         test_mkdir $DIR/d73-2
10601         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
10602         pid1=$!
10603
10604         lctl set_param fail_loc=0x80000129
10605         $MULTIOP $DIR/d73-1/f73-2 Oc &
10606         sleep 1
10607         lctl set_param fail_loc=0
10608
10609         $MULTIOP $DIR/d73-2/f73-3 Oc &
10610         pid3=$!
10611
10612         kill -USR1 $pid1
10613         wait $pid1 || return 1
10614
10615         sleep 25
10616
10617         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
10618         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
10619         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
10620
10621         rm -rf $DIR/d73-*
10622 }
10623 run_test 73 "multiple MDC requests (should not deadlock)"
10624
10625 test_74a() { # bug 6149, 6184
10626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10627
10628         touch $DIR/f74a
10629         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10630         #
10631         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10632         # will spin in a tight reconnection loop
10633         $LCTL set_param fail_loc=0x8000030e
10634         # get any lock that won't be difficult - lookup works.
10635         ls $DIR/f74a
10636         $LCTL set_param fail_loc=0
10637         rm -f $DIR/f74a
10638         true
10639 }
10640 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
10641
10642 test_74b() { # bug 13310
10643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10644
10645         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10646         #
10647         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10648         # will spin in a tight reconnection loop
10649         $LCTL set_param fail_loc=0x8000030e
10650         # get a "difficult" lock
10651         touch $DIR/f74b
10652         $LCTL set_param fail_loc=0
10653         rm -f $DIR/f74b
10654         true
10655 }
10656 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
10657
10658 test_74c() {
10659         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10660
10661         #define OBD_FAIL_LDLM_NEW_LOCK
10662         $LCTL set_param fail_loc=0x319
10663         touch $DIR/$tfile && error "touch successful"
10664         $LCTL set_param fail_loc=0
10665         true
10666 }
10667 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
10668
10669 slab_lic=/sys/kernel/slab/lustre_inode_cache
10670 num_objects() {
10671         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
10672         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
10673                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
10674 }
10675
10676 test_76a() { # Now for b=20433, added originally in b=1443
10677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10678
10679         cancel_lru_locks osc
10680         # there may be some slab objects cached per core
10681         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10682         local before=$(num_objects)
10683         local count=$((512 * cpus))
10684         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10685         local margin=$((count / 10))
10686         if [[ -f $slab_lic/aliases ]]; then
10687                 local aliases=$(cat $slab_lic/aliases)
10688                 (( aliases > 0 )) && margin=$((margin * aliases))
10689         fi
10690
10691         echo "before slab objects: $before"
10692         for i in $(seq $count); do
10693                 touch $DIR/$tfile
10694                 rm -f $DIR/$tfile
10695         done
10696         cancel_lru_locks osc
10697         local after=$(num_objects)
10698         echo "created: $count, after slab objects: $after"
10699         # shared slab counts are not very accurate, allow significant margin
10700         # the main goal is that the cache growth is not permanently > $count
10701         while (( after > before + margin )); do
10702                 sleep 1
10703                 after=$(num_objects)
10704                 wait=$((wait + 1))
10705                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10706                 if (( wait > 60 )); then
10707                         error "inode slab grew from $before+$margin to $after"
10708                 fi
10709         done
10710 }
10711 run_test 76a "confirm clients recycle inodes properly ===="
10712
10713 test_76b() {
10714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10715         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10716
10717         local count=512
10718         local before=$(num_objects)
10719
10720         for i in $(seq $count); do
10721                 mkdir $DIR/$tdir
10722                 rmdir $DIR/$tdir
10723         done
10724
10725         local after=$(num_objects)
10726         local wait=0
10727
10728         while (( after > before )); do
10729                 sleep 1
10730                 after=$(num_objects)
10731                 wait=$((wait + 1))
10732                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10733                 if (( wait > 60 )); then
10734                         error "inode slab grew from $before to $after"
10735                 fi
10736         done
10737
10738         echo "slab objects before: $before, after: $after"
10739 }
10740 run_test 76b "confirm clients recycle directory inodes properly ===="
10741
10742 export ORIG_CSUM=""
10743 set_checksums()
10744 {
10745         # Note: in sptlrpc modes which enable its own bulk checksum, the
10746         # original crc32_le bulk checksum will be automatically disabled,
10747         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10748         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10749         # In this case set_checksums() will not be no-op, because sptlrpc
10750         # bulk checksum will be enabled all through the test.
10751
10752         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10753         lctl set_param -n osc.*.checksums $1
10754         return 0
10755 }
10756
10757 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10758                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10759 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10760                              tr -d [] | head -n1)}
10761 set_checksum_type()
10762 {
10763         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10764         rc=$?
10765         log "set checksum type to $1, rc = $rc"
10766         return $rc
10767 }
10768
10769 get_osc_checksum_type()
10770 {
10771         # arugment 1: OST name, like OST0000
10772         ost=$1
10773         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10774                         sed 's/.*\[\(.*\)\].*/\1/g')
10775         rc=$?
10776         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10777         echo $checksum_type
10778 }
10779
10780 F77_TMP=$TMP/f77-temp
10781 F77SZ=8
10782 setup_f77() {
10783         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10784                 error "error writing to $F77_TMP"
10785 }
10786
10787 test_77a() { # bug 10889
10788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10789         $GSS && skip_env "could not run with gss"
10790
10791         [ ! -f $F77_TMP ] && setup_f77
10792         set_checksums 1
10793         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10794         set_checksums 0
10795         rm -f $DIR/$tfile
10796 }
10797 run_test 77a "normal checksum read/write operation"
10798
10799 test_77b() { # bug 10889
10800         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10801         $GSS && skip_env "could not run with gss"
10802
10803         [ ! -f $F77_TMP ] && setup_f77
10804         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10805         $LCTL set_param fail_loc=0x80000409
10806         set_checksums 1
10807
10808         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10809                 error "dd error: $?"
10810         $LCTL set_param fail_loc=0
10811
10812         for algo in $CKSUM_TYPES; do
10813                 cancel_lru_locks osc
10814                 set_checksum_type $algo
10815                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10816                 $LCTL set_param fail_loc=0x80000408
10817                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10818                 $LCTL set_param fail_loc=0
10819         done
10820         set_checksums 0
10821         set_checksum_type $ORIG_CSUM_TYPE
10822         rm -f $DIR/$tfile
10823 }
10824 run_test 77b "checksum error on client write, read"
10825
10826 cleanup_77c() {
10827         trap 0
10828         set_checksums 0
10829         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10830         $check_ost &&
10831                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10832         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10833         $check_ost && [ -n "$ost_file_prefix" ] &&
10834                 do_facet ost1 rm -f ${ost_file_prefix}\*
10835 }
10836
10837 test_77c() {
10838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10839         $GSS && skip_env "could not run with gss"
10840         remote_ost_nodsh && skip "remote OST with nodsh"
10841
10842         local bad1
10843         local osc_file_prefix
10844         local osc_file
10845         local check_ost=false
10846         local ost_file_prefix
10847         local ost_file
10848         local orig_cksum
10849         local dump_cksum
10850         local fid
10851
10852         # ensure corruption will occur on first OSS/OST
10853         $LFS setstripe -i 0 $DIR/$tfile
10854
10855         [ ! -f $F77_TMP ] && setup_f77
10856         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10857                 error "dd write error: $?"
10858         fid=$($LFS path2fid $DIR/$tfile)
10859
10860         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10861         then
10862                 check_ost=true
10863                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10864                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10865         else
10866                 echo "OSS do not support bulk pages dump upon error"
10867         fi
10868
10869         osc_file_prefix=$($LCTL get_param -n debug_path)
10870         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10871
10872         trap cleanup_77c EXIT
10873
10874         set_checksums 1
10875         # enable bulk pages dump upon error on Client
10876         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10877         # enable bulk pages dump upon error on OSS
10878         $check_ost &&
10879                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10880
10881         # flush Client cache to allow next read to reach OSS
10882         cancel_lru_locks osc
10883
10884         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10885         $LCTL set_param fail_loc=0x80000408
10886         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10887         $LCTL set_param fail_loc=0
10888
10889         rm -f $DIR/$tfile
10890
10891         # check cksum dump on Client
10892         osc_file=$(ls ${osc_file_prefix}*)
10893         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10894         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10895         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10896         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10897         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10898                      cksum)
10899         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10900         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10901                 error "dump content does not match on Client"
10902
10903         $check_ost || skip "No need to check cksum dump on OSS"
10904
10905         # check cksum dump on OSS
10906         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10907         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10908         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10909         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10910         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10911                 error "dump content does not match on OSS"
10912
10913         cleanup_77c
10914 }
10915 run_test 77c "checksum error on client read with debug"
10916
10917 test_77d() { # bug 10889
10918         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10919         $GSS && skip_env "could not run with gss"
10920
10921         stack_trap "rm -f $DIR/$tfile"
10922         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10923         $LCTL set_param fail_loc=0x80000409
10924         set_checksums 1
10925         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10926                 error "direct write: rc=$?"
10927         $LCTL set_param fail_loc=0
10928         set_checksums 0
10929
10930         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10931         $LCTL set_param fail_loc=0x80000408
10932         set_checksums 1
10933         cancel_lru_locks osc
10934         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10935                 error "direct read: rc=$?"
10936         $LCTL set_param fail_loc=0
10937         set_checksums 0
10938 }
10939 run_test 77d "checksum error on OST direct write, read"
10940
10941 test_77f() { # bug 10889
10942         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10943         $GSS && skip_env "could not run with gss"
10944
10945         set_checksums 1
10946         stack_trap "rm -f $DIR/$tfile"
10947         for algo in $CKSUM_TYPES; do
10948                 cancel_lru_locks osc
10949                 set_checksum_type $algo
10950                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10951                 $LCTL set_param fail_loc=0x409
10952                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10953                         error "direct write succeeded"
10954                 $LCTL set_param fail_loc=0
10955         done
10956         set_checksum_type $ORIG_CSUM_TYPE
10957         set_checksums 0
10958 }
10959 run_test 77f "repeat checksum error on write (expect error)"
10960
10961 test_77g() { # bug 10889
10962         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10963         $GSS && skip_env "could not run with gss"
10964         remote_ost_nodsh && skip "remote OST with nodsh"
10965
10966         [ ! -f $F77_TMP ] && setup_f77
10967
10968         local file=$DIR/$tfile
10969         stack_trap "rm -f $file" EXIT
10970
10971         $LFS setstripe -c 1 -i 0 $file
10972         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10973         do_facet ost1 lctl set_param fail_loc=0x8000021a
10974         set_checksums 1
10975         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10976                 error "write error: rc=$?"
10977         do_facet ost1 lctl set_param fail_loc=0
10978         set_checksums 0
10979
10980         cancel_lru_locks osc
10981         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10982         do_facet ost1 lctl set_param fail_loc=0x8000021b
10983         set_checksums 1
10984         cmp $F77_TMP $file || error "file compare failed"
10985         do_facet ost1 lctl set_param fail_loc=0
10986         set_checksums 0
10987 }
10988 run_test 77g "checksum error on OST write, read"
10989
10990 test_77k() { # LU-10906
10991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10992         $GSS && skip_env "could not run with gss"
10993
10994         local cksum_param="osc.$FSNAME*.checksums"
10995         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10996         local checksum
10997         local i
10998
10999         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
11000         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
11001         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
11002
11003         for i in 0 1; do
11004                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
11005                         error "failed to set checksum=$i on MGS"
11006                 wait_update $HOSTNAME "$get_checksum" $i
11007                 #remount
11008                 echo "remount client, checksum should be $i"
11009                 remount_client $MOUNT || error "failed to remount client"
11010                 checksum=$(eval $get_checksum)
11011                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
11012         done
11013         # remove persistent param to avoid races with checksum mountopt below
11014         do_facet mgs $LCTL set_param -P -d $cksum_param ||
11015                 error "failed to delete checksum on MGS"
11016
11017         for opt in "checksum" "nochecksum"; do
11018                 #remount with mount option
11019                 echo "remount client with option $opt, checksum should be $i"
11020                 umount_client $MOUNT || error "failed to umount client"
11021                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
11022                         error "failed to mount client with option '$opt'"
11023                 checksum=$(eval $get_checksum)
11024                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
11025                 i=$((i - 1))
11026         done
11027
11028         remount_client $MOUNT || error "failed to remount client"
11029 }
11030 run_test 77k "enable/disable checksum correctly"
11031
11032 test_77l() {
11033         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11034         $GSS && skip_env "could not run with gss"
11035
11036         set_checksums 1
11037         stack_trap "set_checksums $ORIG_CSUM" EXIT
11038         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
11039
11040         set_checksum_type invalid && error "unexpected success of invalid checksum type"
11041
11042         $LFS setstripe -c 1 -i 0 $DIR/$tfile
11043         for algo in $CKSUM_TYPES; do
11044                 set_checksum_type $algo || error "fail to set checksum type $algo"
11045                 osc_algo=$(get_osc_checksum_type OST0000)
11046                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
11047
11048                 # no locks, no reqs to let the connection idle
11049                 cancel_lru_locks osc
11050                 lru_resize_disable osc
11051                 wait_osc_import_state client ost1 IDLE
11052
11053                 # ensure ost1 is connected
11054                 stat $DIR/$tfile >/dev/null || error "can't stat"
11055                 wait_osc_import_state client ost1 FULL
11056
11057                 osc_algo=$(get_osc_checksum_type OST0000)
11058                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
11059         done
11060         return 0
11061 }
11062 run_test 77l "preferred checksum type is remembered after reconnected"
11063
11064 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
11065 rm -f $F77_TMP
11066 unset F77_TMP
11067
11068 test_77m() {
11069         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
11070                 skip "Need at least version 2.14.52"
11071         local param=checksum_speed
11072
11073         $LCTL get_param $param || error "reading $param failed"
11074
11075         csum_speeds=$($LCTL get_param -n $param)
11076
11077         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
11078                 error "known checksum types are missing"
11079 }
11080 run_test 77m "Verify checksum_speed is correctly read"
11081
11082 check_filefrag_77n() {
11083         local nr_ext=0
11084         local starts=()
11085         local ends=()
11086
11087         while read extidx a b start end rest; do
11088                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
11089                         nr_ext=$(( $nr_ext + 1 ))
11090                         starts+=( ${start%..} )
11091                         ends+=( ${end%:} )
11092                 fi
11093         done < <( filefrag -sv $1 )
11094
11095         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
11096         return 1
11097 }
11098
11099 test_77n() {
11100         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
11101
11102         touch $DIR/$tfile
11103         $TRUNCATE $DIR/$tfile 0
11104         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
11105         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
11106         check_filefrag_77n $DIR/$tfile ||
11107                 skip "$tfile blocks not contiguous around hole"
11108
11109         set_checksums 1
11110         stack_trap "set_checksums $ORIG_CSUM" EXIT
11111         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
11112         stack_trap "rm -f $DIR/$tfile"
11113
11114         for algo in $CKSUM_TYPES; do
11115                 if [[ "$algo" =~ ^t10 ]]; then
11116                         set_checksum_type $algo ||
11117                                 error "fail to set checksum type $algo"
11118                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
11119                                 error "fail to read $tfile with $algo"
11120                 fi
11121         done
11122         rm -f $DIR/$tfile
11123         return 0
11124 }
11125 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
11126
11127 test_77o() {
11128         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
11129                 skip "Need MDS version at least 2.14.55"
11130         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
11131                 skip "Need OST version at least 2.14.55"
11132         local ofd=obdfilter
11133         local mdt=mdt
11134
11135         # print OST checksum_type
11136         echo "$ofd.$FSNAME-*.checksum_type:"
11137         do_nodes $(comma_list $(osts_nodes)) \
11138                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
11139
11140         # print MDT checksum_type
11141         echo "$mdt.$FSNAME-*.checksum_type:"
11142         do_nodes $(comma_list $(mdts_nodes)) \
11143                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
11144
11145         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
11146                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
11147
11148         (( $o_count == $OSTCOUNT )) ||
11149                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
11150
11151         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
11152                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
11153
11154         (( $m_count == $MDSCOUNT )) ||
11155                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
11156 }
11157 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
11158
11159 cleanup_test_78() {
11160         trap 0
11161         rm -f $DIR/$tfile
11162 }
11163
11164 test_78() { # bug 10901
11165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11166         remote_ost || skip_env "local OST"
11167
11168         NSEQ=5
11169         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
11170         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
11171         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
11172         echo "MemTotal: $MEMTOTAL"
11173
11174         # reserve 256MB of memory for the kernel and other running processes,
11175         # and then take 1/2 of the remaining memory for the read/write buffers.
11176         if [ $MEMTOTAL -gt 512 ] ;then
11177                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
11178         else
11179                 # for those poor memory-starved high-end clusters...
11180                 MEMTOTAL=$((MEMTOTAL / 2))
11181         fi
11182         echo "Mem to use for directio: $MEMTOTAL"
11183
11184         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
11185         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
11186         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
11187         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
11188                 head -n1)
11189         echo "Smallest OST: $SMALLESTOST"
11190         [[ $SMALLESTOST -lt 10240 ]] &&
11191                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
11192
11193         trap cleanup_test_78 EXIT
11194
11195         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
11196                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
11197
11198         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
11199         echo "File size: $F78SIZE"
11200         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
11201         for i in $(seq 1 $NSEQ); do
11202                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
11203                 echo directIO rdwr round $i of $NSEQ
11204                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
11205         done
11206
11207         cleanup_test_78
11208 }
11209 run_test 78 "handle large O_DIRECT writes correctly ============"
11210
11211 test_79() { # bug 12743
11212         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11213
11214         wait_delete_completed
11215
11216         BKTOTAL=$(calc_osc_kbytes kbytestotal)
11217         BKFREE=$(calc_osc_kbytes kbytesfree)
11218         BKAVAIL=$(calc_osc_kbytes kbytesavail)
11219
11220         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
11221         DFTOTAL=`echo $STRING | cut -d, -f1`
11222         DFUSED=`echo $STRING  | cut -d, -f2`
11223         DFAVAIL=`echo $STRING | cut -d, -f3`
11224         DFFREE=$(($DFTOTAL - $DFUSED))
11225
11226         ALLOWANCE=$((64 * $OSTCOUNT))
11227
11228         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
11229            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
11230                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
11231         fi
11232         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
11233            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
11234                 error "df free($DFFREE) mismatch OST free($BKFREE)"
11235         fi
11236         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
11237            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
11238                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
11239         fi
11240 }
11241 run_test 79 "df report consistency check ======================="
11242
11243 test_80() { # bug 10718
11244         remote_ost_nodsh && skip "remote OST with nodsh"
11245         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11246
11247         # relax strong synchronous semantics for slow backends like ZFS
11248         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
11249                 local soc="obdfilter.*.sync_lock_cancel"
11250                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11251
11252                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
11253                 if [ -z "$save" ]; then
11254                         soc="obdfilter.*.sync_on_lock_cancel"
11255                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11256                 fi
11257
11258                 if [ "$save" != "never" ]; then
11259                         local hosts=$(comma_list $(osts_nodes))
11260
11261                         do_nodes $hosts $LCTL set_param $soc=never
11262                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
11263                 fi
11264         fi
11265
11266         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
11267         sync; sleep 1; sync
11268         local before=$(date +%s)
11269         cancel_lru_locks osc
11270         local after=$(date +%s)
11271         local diff=$((after - before))
11272         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
11273
11274         rm -f $DIR/$tfile
11275 }
11276 run_test 80 "Page eviction is equally fast at high offsets too"
11277
11278 test_81a() { # LU-456
11279         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11280         remote_ost_nodsh && skip "remote OST with nodsh"
11281
11282         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11283         # MUST OR with the CFS_FAIL_ONCE (0x80000000)
11284         do_facet ost1 lctl set_param fail_loc=0x80000228
11285
11286         # write should trigger a retry and success
11287         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11288         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11289         RC=$?
11290         if [ $RC -ne 0 ] ; then
11291                 error "write should success, but failed for $RC"
11292         fi
11293 }
11294 run_test 81a "OST should retry write when get -ENOSPC ==============="
11295
11296 test_81b() { # LU-456
11297         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11298         remote_ost_nodsh && skip "remote OST with nodsh"
11299
11300         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11301         # Don't OR with the CFS_FAIL_ONCE (0x80000000)
11302         do_facet ost1 lctl set_param fail_loc=0x228
11303
11304         # write should retry several times and return -ENOSPC finally
11305         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11306         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11307         RC=$?
11308         ENOSPC=28
11309         if [ $RC -ne $ENOSPC ] ; then
11310                 error "dd should fail for -ENOSPC, but succeed."
11311         fi
11312 }
11313 run_test 81b "OST should return -ENOSPC when retry still fails ======="
11314
11315 test_99() {
11316         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
11317
11318         test_mkdir $DIR/$tdir.cvsroot
11319         chown $RUNAS_ID $DIR/$tdir.cvsroot
11320
11321         cd $TMP
11322         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
11323
11324         cd /etc/init.d
11325         # some versions of cvs import exit(1) when asked to import links or
11326         # files they can't read.  ignore those files.
11327         local toignore=$(find . -type l -printf '-I %f\n' -o \
11328                          ! -perm /4 -printf '-I %f\n')
11329         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
11330                 $tdir.reposname vtag rtag
11331
11332         cd $DIR
11333         test_mkdir $DIR/$tdir.reposname
11334         chown $RUNAS_ID $DIR/$tdir.reposname
11335         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
11336
11337         cd $DIR/$tdir.reposname
11338         $RUNAS touch foo99
11339         $RUNAS cvs add -m 'addmsg' foo99
11340         $RUNAS cvs update
11341         $RUNAS cvs commit -m 'nomsg' foo99
11342         rm -fr $DIR/$tdir.cvsroot
11343 }
11344 run_test 99 "cvs strange file/directory operations"
11345
11346 test_100() {
11347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11348         [[ "$NETTYPE" =~ tcp ]] ||
11349                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
11350         [[ -n "$(type -p ss)" ]] || skip_env "ss not available"
11351         remote_ost_nodsh && skip "remote OST with nodsh"
11352         remote_mds_nodsh && skip "remote MDS with nodsh"
11353         remote_servers || skip "useless for local single node setup"
11354
11355         ss -tna | ( rc=1; while read STATE SND RCV LOCAL REMOTE STAT; do
11356                 [[ "${REMOTE/*:/}" == "$ACCEPTOR_PORT" ]] || continue
11357
11358                 rc=0
11359                 if (( ${LOCAL/*:/} >= 1024 )); then
11360                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
11361                         ss -tna
11362                         error "local: ${LOCAL/*:/} > 1024 remote: ${REMOTE/*:/}"
11363                 fi
11364         done
11365         (( $rc == 0 )) || error "privileged port not found" )
11366 }
11367 run_test 100 "check local port using privileged port"
11368
11369 function get_named_value()
11370 {
11371     local tag=$1
11372
11373     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
11374 }
11375
11376 test_101a() {
11377         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11378
11379         local s
11380         local discard
11381         local nreads=10000
11382         local cache_limit=32
11383
11384         $LCTL set_param -n osc.*-osc*.rpc_stats=0
11385         $LCTL set_param -n llite.*.read_ahead_stats=0
11386         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
11387                               awk '/^max_cached_mb/ { print $2 }')
11388         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
11389         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
11390
11391         #
11392         # randomly read 10000 of 64K chunks from file 3x 32MB in size
11393         #
11394         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
11395         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
11396
11397         discard=0
11398         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
11399                    get_named_value 'read.but.discarded'); do
11400                         discard=$(($discard + $s))
11401         done
11402
11403         $LCTL get_param osc.*-osc*.rpc_stats
11404         $LCTL get_param llite.*.read_ahead_stats
11405
11406         # Discard is generally zero, but sometimes a few random reads line up
11407         # and trigger larger readahead, which is wasted & leads to discards.
11408         if [[ $(($discard)) -gt $nreads ]]; then
11409                 error "too many ($discard) discarded pages"
11410         fi
11411         rm -f $DIR/$tfile || true
11412 }
11413 run_test 101a "check read-ahead for random reads"
11414
11415 setup_test101bc() {
11416         test_mkdir $DIR/$tdir
11417         local ssize=$1
11418         local FILE_LENGTH=$2
11419         STRIPE_OFFSET=0
11420
11421         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
11422
11423         local list=$(comma_list $(osts_nodes))
11424         set_osd_param $list '' read_cache_enable 0
11425         set_osd_param $list '' writethrough_cache_enable 0
11426
11427         trap cleanup_test101bc EXIT
11428         # prepare the read-ahead file
11429         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
11430
11431         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
11432                                 count=$FILE_SIZE_MB 2> /dev/null
11433
11434 }
11435
11436 cleanup_test101bc() {
11437         trap 0
11438         rm -rf $DIR/$tdir
11439         rm -f $DIR/$tfile
11440
11441         local list=$(comma_list $(osts_nodes))
11442         set_osd_param $list '' read_cache_enable 1
11443         set_osd_param $list '' writethrough_cache_enable 1
11444 }
11445
11446 ra_check_101() {
11447         local read_size=$1
11448         local stripe_size=$2
11449         local stride_length=$((stripe_size / read_size))
11450         local stride_width=$((stride_length * OSTCOUNT))
11451         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
11452                                 (stride_width - stride_length) ))
11453         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
11454                   get_named_value 'read.but.discarded' | calc_sum)
11455
11456         if [[ $discard -gt $discard_limit ]]; then
11457                 $LCTL get_param llite.*.read_ahead_stats
11458                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
11459         else
11460                 echo "Read-ahead success for size ${read_size}"
11461         fi
11462 }
11463
11464 test_101b() {
11465         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11466         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11467
11468         local STRIPE_SIZE=1048576
11469         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
11470
11471         if [ $SLOW == "yes" ]; then
11472                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
11473         else
11474                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
11475         fi
11476
11477         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
11478
11479         # prepare the read-ahead file
11480         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11481         cancel_lru_locks osc
11482         for BIDX in 2 4 8 16 32 64 128 256
11483         do
11484                 local BSIZE=$((BIDX*4096))
11485                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
11486                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
11487                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
11488                 $LCTL set_param -n llite.*.read_ahead_stats=0
11489                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
11490                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
11491                 cancel_lru_locks osc
11492                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
11493         done
11494         cleanup_test101bc
11495         true
11496 }
11497 run_test 101b "check stride-io mode read-ahead ================="
11498
11499 test_101c() {
11500         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11501
11502         local STRIPE_SIZE=1048576
11503         local FILE_LENGTH=$((STRIPE_SIZE*100))
11504         local nreads=10000
11505         local rsize=65536
11506         local osc_rpc_stats
11507
11508         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11509
11510         cancel_lru_locks osc
11511         $LCTL set_param osc.*.rpc_stats=0
11512         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
11513         $LCTL get_param osc.*.rpc_stats
11514         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
11515                 local stats=$($LCTL get_param -n $osc_rpc_stats)
11516                 local lines=$(echo "$stats" | awk 'END {print NR;}')
11517                 local size
11518
11519                 if [ $lines -le 20 ]; then
11520                         echo "continue debug"
11521                         continue
11522                 fi
11523                 for size in 1 2 4 8; do
11524                         local rpc=$(echo "$stats" |
11525                                     awk '($1 == "'$size':") {print $2; exit; }')
11526                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
11527                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
11528                 done
11529                 echo "$osc_rpc_stats check passed!"
11530         done
11531         cleanup_test101bc
11532         true
11533 }
11534 run_test 101c "check stripe_size aligned read-ahead"
11535
11536 test_101d() {
11537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11538
11539         local file=$DIR/$tfile
11540         local sz_MB=${FILESIZE_101d:-80}
11541         local ra_MB=${READAHEAD_MB:-40}
11542
11543         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
11544         [ $free_MB -lt $sz_MB ] &&
11545                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
11546
11547         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
11548         $LFS setstripe -c -1 $file || error "setstripe failed"
11549
11550         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
11551         echo Cancel LRU locks on lustre client to flush the client cache
11552         cancel_lru_locks osc
11553
11554         echo Disable read-ahead
11555         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11556         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11557         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
11558         $LCTL get_param -n llite.*.max_read_ahead_mb
11559
11560         echo "Reading the test file $file with read-ahead disabled"
11561         local sz_KB=$((sz_MB * 1024 / 4))
11562         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
11563         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
11564         # 83886080 bytes (84 MB, 80 MiB) copied, 16 s, 5.2 MB/s
11565         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11566                       sed -e '/records/d' -e 's/.* \([0-9][0-9\.]*\) *s.*/\1/')
11567
11568         echo "Cancel LRU locks on lustre client to flush the client cache"
11569         cancel_lru_locks osc
11570         echo Enable read-ahead with ${ra_MB}MB
11571         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
11572
11573         echo "Reading the test file $file with read-ahead enabled"
11574         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11575                       sed -e '/records/d' -e 's/.* \([0-9][0-9\.]*\) *s.*/\1/')
11576
11577         echo "read-ahead disabled time read '$raOFF'"
11578         echo "read-ahead enabled time read '$raON'"
11579
11580         rm -f $file
11581         wait_delete_completed
11582
11583         # use awk for this check instead of bash because it handles decimals
11584         awk "{ exit !($raOFF < 0.5 || $raOFF > $raON) }" <<<"ignore_me" ||
11585                 error "readahead ${raON}s > no-readahead ${raOFF}s (${sz_MB}M)"
11586 }
11587 run_test 101d "file read with and without read-ahead enabled"
11588
11589 test_101e() {
11590         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11591
11592         local file=$DIR/$tfile
11593         local size_KB=500  #KB
11594         local count=100
11595         local bsize=1024
11596
11597         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
11598         local need_KB=$((count * size_KB))
11599         [[ $free_KB -le $need_KB ]] &&
11600                 skip_env "Need free space $need_KB, have $free_KB"
11601
11602         echo "Creating $count ${size_KB}K test files"
11603         for ((i = 0; i < $count; i++)); do
11604                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
11605         done
11606
11607         echo "Cancel LRU locks on lustre client to flush the client cache"
11608         cancel_lru_locks $OSC
11609
11610         echo "Reset readahead stats"
11611         $LCTL set_param -n llite.*.read_ahead_stats=0
11612
11613         for ((i = 0; i < $count; i++)); do
11614                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
11615         done
11616
11617         $LCTL get_param llite.*.max_cached_mb
11618         $LCTL get_param llite.*.read_ahead_stats
11619         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11620                      get_named_value 'misses' | calc_sum)
11621
11622         for ((i = 0; i < $count; i++)); do
11623                 rm -rf $file.$i 2>/dev/null
11624         done
11625
11626         #10000 means 20% reads are missing in readahead
11627         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
11628 }
11629 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
11630
11631 test_101f() {
11632         which iozone || skip_env "no iozone installed"
11633
11634         local old_debug=$($LCTL get_param debug)
11635         old_debug=${old_debug#*=}
11636         $LCTL set_param debug="reada mmap"
11637
11638         # create a test file
11639         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
11640
11641         echo Cancel LRU locks on lustre client to flush the client cache
11642         cancel_lru_locks osc
11643
11644         echo Reset readahead stats
11645         $LCTL set_param -n llite.*.read_ahead_stats=0
11646
11647         echo mmap read the file with small block size
11648         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
11649                 > /dev/null 2>&1
11650
11651         echo checking missing pages
11652         $LCTL get_param llite.*.read_ahead_stats
11653         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11654                         get_named_value 'misses' | calc_sum)
11655
11656         $LCTL set_param debug="$old_debug"
11657         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
11658         rm -f $DIR/$tfile
11659 }
11660 run_test 101f "check mmap read performance"
11661
11662 test_101g_brw_size_test() {
11663         local mb=$1
11664         local pages=$((mb * 1048576 / PAGE_SIZE))
11665         local file=$DIR/$tfile
11666
11667         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11668                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11669         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11670                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11671                         return 2
11672         done
11673
11674         stack_trap "rm -f $file" EXIT
11675         $LCTL set_param -n osc.*.rpc_stats=0
11676
11677         # 10 RPCs should be enough for the test
11678         local count=10
11679         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11680                 { error "dd write ${mb} MB blocks failed"; return 3; }
11681         cancel_lru_locks osc
11682         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11683                 { error "dd write ${mb} MB blocks failed"; return 4; }
11684
11685         # calculate number of full-sized read and write RPCs
11686         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11687                 sed -n '/pages per rpc/,/^$/p' |
11688                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11689                 END { print reads,writes }'))
11690         # allow one extra full-sized read RPC for async readahead
11691         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11692                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11693         [[ ${rpcs[1]} == $count ]] ||
11694                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11695 }
11696
11697 test_101g() {
11698         remote_ost_nodsh && skip "remote OST with nodsh"
11699
11700         local rpcs
11701         local osts=$(get_facets OST)
11702         local list=$(comma_list $(osts_nodes))
11703         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11704         local brw_size="obdfilter.*.brw_size"
11705
11706         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11707
11708         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11709
11710         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11711                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11712                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11713            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11714                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11715                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11716
11717                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11718                         suffix="M"
11719
11720                 if [[ $orig_mb -lt 16 ]]; then
11721                         save_lustre_params $osts "$brw_size" > $p
11722                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11723                                 error "set 16MB RPC size failed"
11724
11725                         echo "remount client to enable new RPC size"
11726                         remount_client $MOUNT || error "remount_client failed"
11727                 fi
11728
11729                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11730                 # should be able to set brw_size=12, but no rpc_stats for that
11731                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11732         fi
11733
11734         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11735
11736         if [[ $orig_mb -lt 16 ]]; then
11737                 restore_lustre_params < $p
11738                 remount_client $MOUNT || error "remount_client restore failed"
11739         fi
11740
11741         rm -f $p $DIR/$tfile
11742 }
11743 run_test 101g "Big bulk(4/16 MiB) readahead"
11744
11745 test_101h() {
11746         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11747
11748         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11749                 error "dd 70M file failed"
11750         echo Cancel LRU locks on lustre client to flush the client cache
11751         cancel_lru_locks osc
11752
11753         echo "Reset readahead stats"
11754         $LCTL set_param -n llite.*.read_ahead_stats 0
11755
11756         echo "Read 10M of data but cross 64M bundary"
11757         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11758         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11759                      get_named_value 'misses' | calc_sum)
11760         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11761         rm -f $p $DIR/$tfile
11762 }
11763 run_test 101h "Readahead should cover current read window"
11764
11765 test_101i() {
11766         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11767                 error "dd 10M file failed"
11768
11769         local max_per_file_mb=$($LCTL get_param -n \
11770                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11771         cancel_lru_locks osc
11772         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11773         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11774                 error "set max_read_ahead_per_file_mb to 1 failed"
11775
11776         echo "Reset readahead stats"
11777         $LCTL set_param llite.*.read_ahead_stats=0
11778
11779         dd if=$DIR/$tfile of=/dev/null bs=2M
11780
11781         $LCTL get_param llite.*.read_ahead_stats
11782         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11783                      awk '/misses/ { print $2 }')
11784         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11785         rm -f $DIR/$tfile
11786 }
11787 run_test 101i "allow current readahead to exceed reservation"
11788
11789 test_101j() {
11790         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11791                 error "setstripe $DIR/$tfile failed"
11792         local file_size=$((1048576 * 16))
11793         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11794         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11795
11796         echo Disable read-ahead
11797         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11798
11799         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11800         for blk in $PAGE_SIZE 1048576 $file_size; do
11801                 cancel_lru_locks osc
11802                 echo "Reset readahead stats"
11803                 $LCTL set_param -n llite.*.read_ahead_stats=0
11804                 local count=$(($file_size / $blk))
11805                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11806                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11807                              get_named_value 'failed.to.fast.read' | calc_sum)
11808                 $LCTL get_param -n llite.*.read_ahead_stats
11809                 [ $miss -eq $count ] || error "expected $count got $miss"
11810         done
11811
11812         rm -f $p $DIR/$tfile
11813 }
11814 run_test 101j "A complete read block should be submitted when no RA"
11815
11816 test_readahead_base() {
11817         local file=$DIR/$tfile
11818         local size=$1
11819         local iosz
11820         local ramax
11821         local ranum
11822
11823         $LCTL set_param -n llite.*.read_ahead_stats=0
11824         # The first page is not accounted into readahead
11825         ramax=$(((size + PAGE_SIZE - 1) / PAGE_SIZE - 1))
11826         iosz=$(((size + 1048575) / 1048576 * 1048576))
11827         echo "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11828
11829         $LCTL mark  "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11830         fallocate -l $size $file || error "failed to fallocate $file"
11831         cancel_lru_locks osc
11832         $MULTIOP $file or${iosz}c || error "failed to read $file"
11833         $LCTL get_param -n llite.*.read_ahead_stats
11834         ranum=$($LCTL get_param -n llite.*.read_ahead_stats |
11835                 awk '/readahead.pages/ { print $7 }' | calc_sum)
11836         (( $ranum <= $ramax )) ||
11837                 error "read-ahead pages is $ranum more than $ramax"
11838         rm -rf $file || error "failed to remove $file"
11839 }
11840
11841 test_101m()
11842 {
11843         local file=$DIR/$tfile
11844         local ramax
11845         local ranum
11846         local size
11847         local iosz
11848
11849         check_set_fallocate_or_skip
11850         stack_trap "rm -f $file" EXIT
11851
11852         test_readahead_base 4096
11853
11854         # file size: 16K = 16384
11855         test_readahead_base 16384
11856         test_readahead_base 16385
11857         test_readahead_base 16383
11858
11859         # file size: 1M + 1 = 1048576 + 1
11860         test_readahead_base 1048577
11861         # file size: 1M + 16K
11862         test_readahead_base $((1048576 + 16384))
11863
11864         # file size: stripe_size * (stripe_count - 1) + 16K
11865         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11866         test_readahead_base $((1048576 * (OSTCOUNT - 1) + 16384))
11867         # file size: stripe_size * stripe_count + 16K
11868         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11869         test_readahead_base $((1048576 * OSTCOUNT + 16384))
11870         # file size: 2 * stripe_size * stripe_count + 16K
11871         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11872         test_readahead_base $((2 * 1048576 * OSTCOUNT + 16384))
11873 }
11874 run_test 101m "read ahead for small file and last stripe of the file"
11875
11876 setup_test102() {
11877         test_mkdir $DIR/$tdir
11878         chown $RUNAS_ID $DIR/$tdir
11879         STRIPE_SIZE=65536
11880         STRIPE_OFFSET=1
11881         STRIPE_COUNT=$OSTCOUNT
11882         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11883
11884         trap cleanup_test102 EXIT
11885         cd $DIR
11886         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11887         cd $DIR/$tdir
11888         for num in 1 2 3 4; do
11889                 for count in $(seq 1 $STRIPE_COUNT); do
11890                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11891                                 local size=`expr $STRIPE_SIZE \* $num`
11892                                 local file=file"$num-$idx-$count"
11893                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11894                         done
11895                 done
11896         done
11897
11898         cd $DIR
11899         $1 tar cf $TMP/f102.tar $tdir --xattrs
11900 }
11901
11902 cleanup_test102() {
11903         trap 0
11904         rm -f $TMP/f102.tar
11905         rm -rf $DIR/d0.sanity/d102
11906 }
11907
11908 test_102a() {
11909         [ "$UID" != 0 ] && skip "must run as root"
11910         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11911                 skip_env "must have user_xattr"
11912
11913         [ -z "$(which setfattr 2>/dev/null)" ] &&
11914                 skip_env "could not find setfattr"
11915
11916         local testfile=$DIR/$tfile
11917
11918         touch $testfile
11919         echo "set/get xattr..."
11920         setfattr -n trusted.name1 -v value1 $testfile ||
11921                 error "setfattr -n trusted.name1=value1 $testfile failed"
11922         getfattr -n trusted.name1 $testfile 2> /dev/null |
11923           grep "trusted.name1=.value1" ||
11924                 error "$testfile missing trusted.name1=value1"
11925
11926         setfattr -n user.author1 -v author1 $testfile ||
11927                 error "setfattr -n user.author1=author1 $testfile failed"
11928         getfattr -n user.author1 $testfile 2> /dev/null |
11929           grep "user.author1=.author1" ||
11930                 error "$testfile missing trusted.author1=author1"
11931
11932         echo "listxattr..."
11933         setfattr -n trusted.name2 -v value2 $testfile ||
11934                 error "$testfile unable to set trusted.name2"
11935         setfattr -n trusted.name3 -v value3 $testfile ||
11936                 error "$testfile unable to set trusted.name3"
11937         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11938             grep "trusted.name" | wc -l) -eq 3 ] ||
11939                 error "$testfile missing 3 trusted.name xattrs"
11940
11941         setfattr -n user.author2 -v author2 $testfile ||
11942                 error "$testfile unable to set user.author2"
11943         setfattr -n user.author3 -v author3 $testfile ||
11944                 error "$testfile unable to set user.author3"
11945         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11946             grep "user.author" | wc -l) -eq 3 ] ||
11947                 error "$testfile missing 3 user.author xattrs"
11948
11949         echo "remove xattr..."
11950         setfattr -x trusted.name1 $testfile ||
11951                 error "$testfile error deleting trusted.name1"
11952         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11953                 error "$testfile did not delete trusted.name1 xattr"
11954
11955         setfattr -x user.author1 $testfile ||
11956                 error "$testfile error deleting user.author1"
11957         echo "set lustre special xattr ..."
11958         $LFS setstripe -c1 $testfile
11959         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11960                 awk -F "=" '/trusted.lov/ { print $2 }' )
11961         setfattr -n "trusted.lov" -v $lovea $testfile ||
11962                 error "$testfile doesn't ignore setting trusted.lov again"
11963         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11964                 error "$testfile allow setting invalid trusted.lov"
11965         rm -f $testfile
11966 }
11967 run_test 102a "user xattr test =================================="
11968
11969 check_102b_layout() {
11970         local layout="$*"
11971         local testfile=$DIR/$tfile
11972
11973         echo "test layout '$layout'"
11974         $LFS setstripe $layout $testfile || error "setstripe failed"
11975         $LFS getstripe -y $testfile
11976
11977         echo "get/set/list trusted.lov xattr ..." # b=10930
11978         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11979         [[ "$value" =~ "trusted.lov" ]] ||
11980                 error "can't get trusted.lov from $testfile"
11981         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11982                 error "getstripe failed"
11983
11984         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11985
11986         value=$(cut -d= -f2 <<<$value)
11987         # LU-13168: truncated xattr should fail if short lov_user_md header
11988         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11989                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11990         for len in $lens; do
11991                 echo "setfattr $len $testfile.2"
11992                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11993                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11994         done
11995         local stripe_size=$($LFS getstripe -S $testfile.2)
11996         local stripe_count=$($LFS getstripe -c $testfile.2)
11997         [[ $stripe_size -eq 65536 ]] ||
11998                 error "stripe size $stripe_size != 65536"
11999         [[ $stripe_count -eq $stripe_count_orig ]] ||
12000                 error "stripe count $stripe_count != $stripe_count_orig"
12001         rm $testfile $testfile.2
12002 }
12003
12004 test_102b() {
12005         [ -z "$(which setfattr 2>/dev/null)" ] &&
12006                 skip_env "could not find setfattr"
12007         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12008
12009         # check plain layout
12010         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
12011
12012         # and also check composite layout
12013         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
12014
12015 }
12016 run_test 102b "getfattr/setfattr for trusted.lov EAs"
12017
12018 test_102c() {
12019         [ -z "$(which setfattr 2>/dev/null)" ] &&
12020                 skip_env "could not find setfattr"
12021         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12022
12023         # b10930: get/set/list lustre.lov xattr
12024         echo "get/set/list lustre.lov xattr ..."
12025         test_mkdir $DIR/$tdir
12026         chown $RUNAS_ID $DIR/$tdir
12027         local testfile=$DIR/$tdir/$tfile
12028         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
12029                 error "setstripe failed"
12030         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
12031                 error "getstripe failed"
12032         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
12033         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
12034
12035         local testfile2=${testfile}2
12036         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
12037                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
12038
12039         $RUNAS $MCREATE $testfile2
12040         $RUNAS setfattr -n lustre.lov -v $value $testfile2
12041         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
12042         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
12043         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
12044         [ $stripe_count -eq $STRIPECOUNT ] ||
12045                 error "stripe count $stripe_count != $STRIPECOUNT"
12046 }
12047 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
12048
12049 compare_stripe_info1() {
12050         local stripe_index_all_zero=true
12051
12052         for num in 1 2 3 4; do
12053                 for count in $(seq 1 $STRIPE_COUNT); do
12054                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
12055                                 local size=$((STRIPE_SIZE * num))
12056                                 local file=file"$num-$offset-$count"
12057                                 stripe_size=$($LFS getstripe -S $PWD/$file)
12058                                 [[ $stripe_size -ne $size ]] &&
12059                                     error "$file: size $stripe_size != $size"
12060                                 stripe_count=$($LFS getstripe -c $PWD/$file)
12061                                 # allow fewer stripes to be created, ORI-601
12062                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
12063                                     error "$file: count $stripe_count != $count"
12064                                 stripe_index=$($LFS getstripe -i $PWD/$file)
12065                                 [[ $stripe_index -ne 0 ]] &&
12066                                         stripe_index_all_zero=false
12067                         done
12068                 done
12069         done
12070         $stripe_index_all_zero &&
12071                 error "all files are being extracted starting from OST index 0"
12072         return 0
12073 }
12074
12075 have_xattrs_include() {
12076         tar --help | grep -q xattrs-include &&
12077                 echo --xattrs-include="lustre.*"
12078 }
12079
12080 test_102d() {
12081         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12082         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12083
12084         XINC=$(have_xattrs_include)
12085         setup_test102
12086         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
12087         cd $DIR/$tdir/$tdir
12088         compare_stripe_info1
12089 }
12090 run_test 102d "tar restore stripe info from tarfile,not keep osts"
12091
12092 test_102f() {
12093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12094         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12095
12096         XINC=$(have_xattrs_include)
12097         setup_test102
12098         test_mkdir $DIR/$tdir.restore
12099         cd $DIR
12100         tar cf - --xattrs $tdir | tar xf - \
12101                 -C $DIR/$tdir.restore --xattrs $XINC
12102         cd $DIR/$tdir.restore/$tdir
12103         compare_stripe_info1
12104 }
12105 run_test 102f "tar copy files, not keep osts"
12106
12107 grow_xattr() {
12108         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
12109                 skip "must have user_xattr"
12110         [ -z "$(which setfattr 2>/dev/null)" ] &&
12111                 skip_env "could not find setfattr"
12112         [ -z "$(which getfattr 2>/dev/null)" ] &&
12113                 skip_env "could not find getfattr"
12114
12115         local xsize=${1:-1024}  # in bytes
12116         local file=$DIR/$tfile
12117         local value="$(generate_string $xsize)"
12118         local xbig=trusted.big
12119         local toobig=$2
12120
12121         touch $file
12122         log "save $xbig on $file"
12123         if [ -z "$toobig" ]
12124         then
12125                 setfattr -n $xbig -v $value $file ||
12126                         error "saving $xbig on $file failed"
12127         else
12128                 setfattr -n $xbig -v $value $file &&
12129                         error "saving $xbig on $file succeeded"
12130                 return 0
12131         fi
12132
12133         local orig=$(get_xattr_value $xbig $file)
12134         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
12135
12136         local xsml=trusted.sml
12137         log "save $xsml on $file"
12138         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
12139
12140         local new=$(get_xattr_value $xbig $file)
12141         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
12142
12143         log "grow $xsml on $file"
12144         setfattr -n $xsml -v "$value" $file ||
12145                 error "growing $xsml on $file failed"
12146
12147         new=$(get_xattr_value $xbig $file)
12148         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
12149         log "$xbig still valid after growing $xsml"
12150
12151         rm -f $file
12152 }
12153
12154 test_102h() { # bug 15777
12155         grow_xattr 1024
12156 }
12157 run_test 102h "grow xattr from inside inode to external block"
12158
12159 test_102ha() {
12160         large_xattr_enabled || skip_env "ea_inode feature disabled"
12161
12162         echo "setting xattr of max xattr size: $(max_xattr_size)"
12163         grow_xattr $(max_xattr_size)
12164
12165         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
12166         echo "This should fail:"
12167         grow_xattr $(($(max_xattr_size) + 10)) 1
12168 }
12169 run_test 102ha "grow xattr from inside inode to external inode"
12170
12171 test_102i() { # bug 17038
12172         [ -z "$(which getfattr 2>/dev/null)" ] &&
12173                 skip "could not find getfattr"
12174
12175         touch $DIR/$tfile
12176         ln -s $DIR/$tfile $DIR/${tfile}link
12177         getfattr -n trusted.lov $DIR/$tfile ||
12178                 error "lgetxattr on $DIR/$tfile failed"
12179         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
12180                 grep -i "no such attr" ||
12181                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
12182         rm -f $DIR/$tfile $DIR/${tfile}link
12183 }
12184 run_test 102i "lgetxattr test on symbolic link ============"
12185
12186 test_102j() {
12187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12188         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12189
12190         XINC=$(have_xattrs_include)
12191         setup_test102 "$RUNAS"
12192         chown $RUNAS_ID $DIR/$tdir
12193         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
12194         cd $DIR/$tdir/$tdir
12195         compare_stripe_info1 "$RUNAS"
12196 }
12197 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
12198
12199 test_102k() {
12200         [ -z "$(which setfattr 2>/dev/null)" ] &&
12201                 skip "could not find setfattr"
12202
12203         touch $DIR/$tfile
12204         # b22187 just check that does not crash for regular file.
12205         setfattr -n trusted.lov $DIR/$tfile
12206         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
12207         local test_kdir=$DIR/$tdir
12208         test_mkdir $test_kdir
12209         local default_size=$($LFS getstripe -S $test_kdir)
12210         local default_count=$($LFS getstripe -c $test_kdir)
12211         local default_offset=$($LFS getstripe -i $test_kdir)
12212         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
12213                 error 'dir setstripe failed'
12214         setfattr -n trusted.lov $test_kdir
12215         local stripe_size=$($LFS getstripe -S $test_kdir)
12216         local stripe_count=$($LFS getstripe -c $test_kdir)
12217         local stripe_offset=$($LFS getstripe -i $test_kdir)
12218         [ $stripe_size -eq $default_size ] ||
12219                 error "stripe size $stripe_size != $default_size"
12220         [ $stripe_count -eq $default_count ] ||
12221                 error "stripe count $stripe_count != $default_count"
12222         [ $stripe_offset -eq $default_offset ] ||
12223                 error "stripe offset $stripe_offset != $default_offset"
12224         rm -rf $DIR/$tfile $test_kdir
12225 }
12226 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
12227
12228 test_102l() {
12229         [ -z "$(which getfattr 2>/dev/null)" ] &&
12230                 skip "could not find getfattr"
12231
12232         # LU-532 trusted. xattr is invisible to non-root
12233         local testfile=$DIR/$tfile
12234
12235         touch $testfile
12236
12237         echo "listxattr as user..."
12238         chown $RUNAS_ID $testfile
12239         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
12240             grep -q "trusted" &&
12241                 error "$testfile trusted xattrs are user visible"
12242
12243         return 0;
12244 }
12245 run_test 102l "listxattr size test =================================="
12246
12247 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
12248         local path=$DIR/$tfile
12249         touch $path
12250
12251         listxattr_size_check $path || error "listattr_size_check $path failed"
12252 }
12253 run_test 102m "Ensure listxattr fails on small bufffer ========"
12254
12255 cleanup_test102
12256
12257 getxattr() { # getxattr path name
12258         # Return the base64 encoding of the value of xattr name on path.
12259         local path=$1
12260         local name=$2
12261
12262         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
12263         # file: $path
12264         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12265         #
12266         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12267
12268         getfattr --absolute-names --encoding=base64 --name=$name $path |
12269                 awk -F= -v name=$name '$1 == name {
12270                         print substr($0, index($0, "=") + 1);
12271         }'
12272 }
12273
12274 test_102n() { # LU-4101 mdt: protect internal xattrs
12275         [ -z "$(which setfattr 2>/dev/null)" ] &&
12276                 skip "could not find setfattr"
12277         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
12278         then
12279                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
12280         fi
12281
12282         local file0=$DIR/$tfile.0
12283         local file1=$DIR/$tfile.1
12284         local xattr0=$TMP/$tfile.0
12285         local xattr1=$TMP/$tfile.1
12286         local namelist="lov lma lmv link fid version som hsm"
12287         local name
12288         local value
12289
12290         rm -rf $file0 $file1 $xattr0 $xattr1
12291         touch $file0 $file1
12292
12293         # Get 'before' xattrs of $file1.
12294         getfattr --absolute-names --dump --match=- $file1 > $xattr0
12295
12296         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
12297                 namelist+=" lfsck_namespace"
12298         for name in $namelist; do
12299                 # Try to copy xattr from $file0 to $file1.
12300                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12301
12302                 setfattr --name=trusted.$name --value="$value" $file1 ||
12303                         error "setxattr 'trusted.$name' failed"
12304
12305                 # Try to set a garbage xattr.
12306                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12307
12308                 if [[ x$name == "xlov" ]]; then
12309                         setfattr --name=trusted.lov --value="$value" $file1 &&
12310                         error "setxattr invalid 'trusted.lov' success"
12311                 else
12312                         setfattr --name=trusted.$name --value="$value" $file1 ||
12313                                 error "setxattr invalid 'trusted.$name' failed"
12314                 fi
12315
12316                 # Try to remove the xattr from $file1. We don't care if this
12317                 # appears to succeed or fail, we just don't want there to be
12318                 # any changes or crashes.
12319                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12320         done
12321
12322         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
12323         then
12324                 name="lfsck_ns"
12325                 # Try to copy xattr from $file0 to $file1.
12326                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12327
12328                 setfattr --name=trusted.$name --value="$value" $file1 ||
12329                         error "setxattr 'trusted.$name' failed"
12330
12331                 # Try to set a garbage xattr.
12332                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12333
12334                 setfattr --name=trusted.$name --value="$value" $file1 ||
12335                         error "setxattr 'trusted.$name' failed"
12336
12337                 # Try to remove the xattr from $file1. We don't care if this
12338                 # appears to succeed or fail, we just don't want there to be
12339                 # any changes or crashes.
12340                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12341         fi
12342
12343         # Get 'after' xattrs of file1.
12344         getfattr --absolute-names --dump --match=- $file1 > $xattr1
12345
12346         if ! diff $xattr0 $xattr1; then
12347                 error "before and after xattrs of '$file1' differ"
12348         fi
12349
12350         rm -rf $file0 $file1 $xattr0 $xattr1
12351
12352         return 0
12353 }
12354 run_test 102n "silently ignore setxattr on internal trusted xattrs"
12355
12356 test_102p() { # LU-4703 setxattr did not check ownership
12357         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
12358                 skip "MDS needs to be at least 2.5.56"
12359
12360         local testfile=$DIR/$tfile
12361
12362         touch $testfile
12363
12364         echo "setfacl as user..."
12365         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
12366         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
12367
12368         echo "setfattr as user..."
12369         setfacl -m "u:$RUNAS_ID:---" $testfile
12370         $RUNAS setfattr -x system.posix_acl_access $testfile
12371         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
12372 }
12373 run_test 102p "check setxattr(2) correctly fails without permission"
12374
12375 test_102q() {
12376         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
12377                 skip "MDS needs to be at least 2.6.92"
12378
12379         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
12380 }
12381 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
12382
12383 test_102r() {
12384         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
12385                 skip "MDS needs to be at least 2.6.93"
12386
12387         touch $DIR/$tfile || error "touch"
12388         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
12389         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
12390         rm $DIR/$tfile || error "rm"
12391
12392         #normal directory
12393         mkdir -p $DIR/$tdir || error "mkdir"
12394         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12395         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12396         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12397                 error "$testfile error deleting user.author1"
12398         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12399                 grep "user.$(basename $tdir)" &&
12400                 error "$tdir did not delete user.$(basename $tdir)"
12401         rmdir $DIR/$tdir || error "rmdir"
12402
12403         #striped directory
12404         test_mkdir $DIR/$tdir
12405         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12406         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12407         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12408                 error "$testfile error deleting user.author1"
12409         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12410                 grep "user.$(basename $tdir)" &&
12411                 error "$tdir did not delete user.$(basename $tdir)"
12412         rmdir $DIR/$tdir || error "rm striped dir"
12413 }
12414 run_test 102r "set EAs with empty values"
12415
12416 test_102s() {
12417         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12418                 skip "MDS needs to be at least 2.11.52"
12419
12420         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12421
12422         save_lustre_params client "llite.*.xattr_cache" > $save
12423
12424         for cache in 0 1; do
12425                 lctl set_param llite.*.xattr_cache=$cache
12426
12427                 rm -f $DIR/$tfile
12428                 touch $DIR/$tfile || error "touch"
12429                 for prefix in lustre security system trusted user; do
12430                         # Note getxattr() may fail with 'Operation not
12431                         # supported' or 'No such attribute' depending
12432                         # on prefix and cache.
12433                         getfattr -n $prefix.n102s $DIR/$tfile &&
12434                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
12435                 done
12436         done
12437
12438         restore_lustre_params < $save
12439 }
12440 run_test 102s "getting nonexistent xattrs should fail"
12441
12442 test_102t() {
12443         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12444                 skip "MDS needs to be at least 2.11.52"
12445
12446         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12447
12448         save_lustre_params client "llite.*.xattr_cache" > $save
12449
12450         for cache in 0 1; do
12451                 lctl set_param llite.*.xattr_cache=$cache
12452
12453                 for buf_size in 0 256; do
12454                         rm -f $DIR/$tfile
12455                         touch $DIR/$tfile || error "touch"
12456                         setfattr -n user.multiop $DIR/$tfile
12457                         $MULTIOP $DIR/$tfile oa$buf_size ||
12458                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
12459                 done
12460         done
12461
12462         restore_lustre_params < $save
12463 }
12464 run_test 102t "zero length xattr values handled correctly"
12465
12466 run_acl_subtest()
12467 {
12468         local test=$LUSTRE/tests/acl/$1.test
12469         local tmp=$(mktemp -t $1-XXXXXX).test
12470         local bin=$2
12471         local dmn=$3
12472         local grp=$4
12473         local nbd=$5
12474         export LANG=C
12475
12476
12477         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
12478         local sedgroups="-e s/:users/:$grp/g"
12479         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
12480
12481         sed $sedusers $sedgroups < $test > $tmp
12482         stack_trap "rm -f $tmp"
12483         [[ -s $tmp ]] || error "sed failed to create test script"
12484
12485         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
12486         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
12487 }
12488
12489 test_103a() {
12490         [ "$UID" != 0 ] && skip "must run as root"
12491         $GSS && skip_env "could not run under gss"
12492         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
12493                 skip_env "must have acl enabled"
12494         which setfacl || skip_env "could not find setfacl"
12495         remote_mds_nodsh && skip "remote MDS with nodsh"
12496
12497         local mdts=$(comma_list $(mdts_nodes))
12498         local saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
12499
12500         [[ -z "$saved" ]] || do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE
12501         stack_trap "[[ -z \"$saved\" ]] || \
12502                     do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$saved" EXIT
12503
12504         ACLBIN=${ACLBIN:-"bin"}
12505         ACLDMN=${ACLDMN:-"daemon"}
12506         ACLGRP=${ACLGRP:-"users"}
12507         ACLNBD=${ACLNBD:-"nobody"}
12508
12509         if ! id $ACLBIN ||
12510            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
12511                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
12512                 ACLBIN=$USER0
12513                 if ! id $ACLBIN ; then
12514                         cat /etc/passwd
12515                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
12516                 fi
12517         fi
12518         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
12519            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
12520                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
12521                 ACLDMN=$USER1
12522                 if ! id $ACLDMN ; then
12523                         cat /etc/passwd
12524                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
12525                 fi
12526         fi
12527         if ! getent group $ACLGRP; then
12528                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
12529                 ACLGRP="$TSTUSR"
12530                 if ! getent group $ACLGRP; then
12531                         echo "cannot find group '$ACLGRP', adding it"
12532                         cat /etc/group
12533                         add_group 60000 $ACLGRP
12534                 fi
12535         fi
12536
12537         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
12538         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
12539         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12540
12541         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12542                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
12543                 ACLGRP="$TSTUSR"
12544                 if ! getent group $ACLGRP; then
12545                         echo "cannot find group '$ACLGRP', adding it"
12546                         cat /etc/group
12547                         add_group 60000 $ACLGRP
12548                 fi
12549                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12550                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12551                         cat /etc/group
12552                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
12553                 fi
12554         fi
12555
12556         gpasswd -a $ACLDMN $ACLBIN ||
12557                 error "setting client group failed"             # LU-5641
12558         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
12559                 error "setting MDS group failed"                # LU-5641
12560
12561         declare -a identity_old
12562
12563         for ((num = 1; num <= $MDSCOUNT; num++)); do
12564                 switch_identity $num true || identity_old[$num]=$?
12565         done
12566
12567         SAVE_UMASK=$(umask)
12568         umask 0022
12569         mkdir -p $DIR/$tdir
12570         cd $DIR/$tdir
12571
12572         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
12573         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
12574         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
12575         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
12576         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
12577         # CentOS7- uses nobody=99, while newer distros use nobody=65534
12578         if ! id -u $ACLNBD ||
12579            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
12580                 ACLNBD="nfsnobody"
12581                 if ! id -u $ACLNBD; then
12582                         ACLNBD=""
12583                 fi
12584         fi
12585         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
12586                 add_group $(id -u $ACLNBD) $ACLNBD
12587                 if ! getent group $ACLNBD; then
12588                         ACLNBD=""
12589                 fi
12590         fi
12591         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
12592            [[ -n "$ACLNBD" ]] && which setfattr; then
12593                 run_acl_subtest permissions_xattr \
12594                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
12595         elif [[ -z "$ACLNBD" ]]; then
12596                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
12597         else
12598                 echo "skip 'permission_xattr' test - missing setfattr command"
12599         fi
12600         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
12601
12602         # inheritance test got from HP
12603         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
12604         chmod +x make-tree || error "chmod +x failed"
12605         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
12606         rm -f make-tree
12607
12608         echo "LU-974 ignore umask when acl is enabled..."
12609         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
12610         if [ $MDSCOUNT -ge 2 ]; then
12611                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
12612         fi
12613
12614         echo "LU-2561 newly created file is same size as directory..."
12615         if [ "$mds1_FSTYPE" != "zfs" ]; then
12616                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
12617         else
12618                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
12619         fi
12620
12621         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
12622
12623         cd $SAVE_PWD
12624         umask $SAVE_UMASK
12625
12626         for ((num = 1; num <= $MDSCOUNT; num++)); do
12627                 if [[ "${identity_old[$num]}" == 1 ]]; then
12628                         switch_identity $num false || identity_old[$num]=$?
12629                 fi
12630         done
12631 }
12632 run_test 103a "acl test"
12633
12634 test_103b() {
12635         declare -a pids
12636         local U
12637
12638         stack_trap "rm -f $DIR/$tfile.*"
12639         for U in {0..511}; do
12640                 {
12641                 local O=$(printf "%04o" $U)
12642
12643                 umask $(printf "%04o" $((511 ^ $O)))
12644                 $LFS setstripe -c 1 $DIR/$tfile.s$O
12645                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
12646
12647                 (( $S == ($O & 0666) )) ||
12648                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
12649
12650                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
12651                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
12652                 (( $S == ($O & 0666) )) ||
12653                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
12654
12655                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
12656                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
12657                 (( $S == ($O & 0666) )) ||
12658                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
12659                 rm -f $DIR/$tfile.[smp]$0
12660                 } &
12661                 local pid=$!
12662
12663                 # limit the concurrently running threads to 64. LU-11878
12664                 local idx=$((U % 64))
12665                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
12666                 pids[idx]=$pid
12667         done
12668         wait
12669 }
12670 run_test 103b "umask lfs setstripe"
12671
12672 test_103c() {
12673         mkdir -p $DIR/$tdir
12674         cp -rp $DIR/$tdir $DIR/$tdir.bak
12675
12676         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
12677                 error "$DIR/$tdir shouldn't contain default ACL"
12678         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
12679                 error "$DIR/$tdir.bak shouldn't contain default ACL"
12680         true
12681 }
12682 run_test 103c "'cp -rp' won't set empty acl"
12683
12684 test_103e() {
12685         local numacl
12686         local fileacl
12687         local saved_debug=$($LCTL get_param -n debug)
12688
12689         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
12690                 skip "MDS needs to be at least 2.14.52"
12691
12692         large_xattr_enabled || skip_env "ea_inode feature disabled"
12693
12694         mkdir -p $DIR/$tdir
12695         # add big LOV EA to cause reply buffer overflow earlier
12696         $LFS setstripe -C 1000 $DIR/$tdir
12697         lctl set_param mdc.*-mdc*.stats=clear
12698
12699         $LCTL set_param debug=0
12700         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
12701         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
12702
12703         # add a large number of default ACLs (expect 8000+ for 2.13+)
12704         for U in {2..7000}; do
12705                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
12706                         error "Able to add just $U default ACLs"
12707         done
12708         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
12709         echo "$numacl default ACLs created"
12710
12711         stat $DIR/$tdir || error "Cannot stat directory"
12712         # check file creation
12713         touch $DIR/$tdir/$tfile ||
12714                 error "failed to create $tfile with $numacl default ACLs"
12715         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
12716         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12717         echo "$fileacl ACLs were inherited"
12718         (( $fileacl == $numacl )) ||
12719                 error "Not all default ACLs were inherited: $numacl != $fileacl"
12720         # check that new ACLs creation adds new ACLs to inherited ACLs
12721         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
12722                 error "Cannot set new ACL"
12723         numacl=$((numacl + 1))
12724         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12725         (( $fileacl == $numacl )) ||
12726                 error "failed to add new ACL: $fileacl != $numacl as expected"
12727         # adds more ACLs to a file to reach their maximum at 8000+
12728         numacl=0
12729         for U in {20000..25000}; do
12730                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12731                 numacl=$((numacl + 1))
12732         done
12733         echo "Added $numacl more ACLs to the file"
12734         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12735         echo "Total $fileacl ACLs in file"
12736         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12737         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12738         rmdir $DIR/$tdir || error "Cannot remove directory"
12739 }
12740 run_test 103e "inheritance of big amount of default ACLs"
12741
12742 test_103f() {
12743         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12744                 skip "MDS needs to be at least 2.14.51"
12745
12746         large_xattr_enabled || skip_env "ea_inode feature disabled"
12747
12748         # enable changelog to consume more internal MDD buffers
12749         changelog_register
12750
12751         mkdir -p $DIR/$tdir
12752         # add big LOV EA
12753         $LFS setstripe -C 1000 $DIR/$tdir
12754         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12755         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12756         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12757         rmdir $DIR/$tdir || error "Cannot remove directory"
12758 }
12759 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12760
12761 test_104a() {
12762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12763
12764         touch $DIR/$tfile
12765         lfs df || error "lfs df failed"
12766         lfs df -ih || error "lfs df -ih failed"
12767         lfs df -h $DIR || error "lfs df -h $DIR failed"
12768         lfs df -i $DIR || error "lfs df -i $DIR failed"
12769         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12770         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12771
12772         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12773         lctl --device %$OSC deactivate
12774         lfs df || error "lfs df with deactivated OSC failed"
12775         lctl --device %$OSC activate
12776         # wait the osc back to normal
12777         wait_osc_import_ready client ost
12778
12779         lfs df || error "lfs df with reactivated OSC failed"
12780         rm -f $DIR/$tfile
12781 }
12782 run_test 104a "lfs df [-ih] [path] test ========================="
12783
12784 test_104b() {
12785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12786         [ $RUNAS_ID -eq $UID ] &&
12787                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12788
12789         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12790                         grep "Permission denied" | wc -l)))
12791         if [ $denied_cnt -ne 0 ]; then
12792                 error "lfs check servers test failed"
12793         fi
12794 }
12795 run_test 104b "$RUNAS lfs check servers test ===================="
12796
12797 #
12798 # Verify $1 is within range of $2.
12799 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12800 # $1 is <= 2% of $2. Else Fail.
12801 #
12802 value_in_range() {
12803         # Strip all units (M, G, T)
12804         actual=$(echo $1 | tr -d A-Z)
12805         expect=$(echo $2 | tr -d A-Z)
12806
12807         expect_lo=$(($expect * 98 / 100)) # 2% below
12808         expect_hi=$(($expect * 102 / 100)) # 2% above
12809
12810         # permit 2% drift above and below
12811         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12812 }
12813
12814 test_104c() {
12815         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12816         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12817
12818         local ost_param="osd-zfs.$FSNAME-OST0000."
12819         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12820         local ofacets=$(get_facets OST)
12821         local mfacets=$(get_facets MDS)
12822         local saved_ost_blocks=
12823         local saved_mdt_blocks=
12824
12825         echo "Before recordsize change"
12826         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12827         df=($(df -h | grep "$MOUNT"$))
12828
12829         # For checking.
12830         echo "lfs output : ${lfs_df[*]}"
12831         echo "df  output : ${df[*]}"
12832
12833         for facet in ${ofacets//,/ }; do
12834                 if [ -z $saved_ost_blocks ]; then
12835                         saved_ost_blocks=$(do_facet $facet \
12836                                 lctl get_param -n $ost_param.blocksize)
12837                         echo "OST Blocksize: $saved_ost_blocks"
12838                 fi
12839                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12840                 do_facet $facet zfs set recordsize=32768 $ost
12841         done
12842
12843         # BS too small. Sufficient for functional testing.
12844         for facet in ${mfacets//,/ }; do
12845                 if [ -z $saved_mdt_blocks ]; then
12846                         saved_mdt_blocks=$(do_facet $facet \
12847                                 lctl get_param -n $mdt_param.blocksize)
12848                         echo "MDT Blocksize: $saved_mdt_blocks"
12849                 fi
12850                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12851                 do_facet $facet zfs set recordsize=32768 $mdt
12852         done
12853
12854         # Give new values chance to reflect change
12855         sleep 2
12856
12857         echo "After recordsize change"
12858         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12859         df_after=($(df -h | grep "$MOUNT"$))
12860
12861         # For checking.
12862         echo "lfs output : ${lfs_df_after[*]}"
12863         echo "df  output : ${df_after[*]}"
12864
12865         # Verify lfs df
12866         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12867                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12868         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12869                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12870         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12871                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12872
12873         # Verify df
12874         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12875                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12876         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12877                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12878         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12879                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12880
12881         # Restore MDT recordize back to original
12882         for facet in ${mfacets//,/ }; do
12883                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12884                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12885         done
12886
12887         # Restore OST recordize back to original
12888         for facet in ${ofacets//,/ }; do
12889                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12890                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12891         done
12892
12893         return 0
12894 }
12895 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12896
12897 test_104d() {
12898         (( $RUNAS_ID != $UID )) ||
12899                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12900
12901         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12902                 skip "lustre version doesn't support lctl dl with non-root"
12903
12904         # debugfs only allows root users to access files, so the
12905         # previous move of the "devices" file to debugfs broke
12906         # "lctl dl" for non-root users. The LU-9680 Netlink
12907         # interface again allows non-root users to list devices.
12908         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12909                 error "lctl dl doesn't work for non root"
12910
12911         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12912         [ "$ost_count" -eq $OSTCOUNT ]  ||
12913                 error "lctl dl reports wrong number of OST devices"
12914
12915         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12916         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12917                 error "lctl dl reports wrong number of MDT devices"
12918 }
12919 run_test 104d "$RUNAS lctl dl test"
12920
12921 test_105a() {
12922         # doesn't work on 2.4 kernels
12923         touch $DIR/$tfile
12924         if $(flock_is_enabled); then
12925                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12926         else
12927                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12928         fi
12929         rm -f $DIR/$tfile
12930 }
12931 run_test 105a "flock when mounted without -o flock test ========"
12932
12933 test_105b() {
12934         touch $DIR/$tfile
12935         if $(flock_is_enabled); then
12936                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12937         else
12938                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12939         fi
12940         rm -f $DIR/$tfile
12941 }
12942 run_test 105b "fcntl when mounted without -o flock test ========"
12943
12944 test_105c() {
12945         touch $DIR/$tfile
12946         if $(flock_is_enabled); then
12947                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
12948         else
12949                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
12950         fi
12951         rm -f $DIR/$tfile
12952 }
12953 run_test 105c "lockf when mounted without -o flock test"
12954
12955 test_105d() { # bug 15924
12956         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12957
12958         test_mkdir $DIR/$tdir
12959         flock_is_enabled || skip_env "mount w/o flock enabled"
12960         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
12961         $LCTL set_param fail_loc=0x80000315
12962         flocks_test 2 $DIR/$tdir
12963 }
12964 run_test 105d "flock race (should not freeze) ========"
12965
12966 test_105e() { # bug 22660 && 22040
12967         flock_is_enabled || skip_env "mount w/o flock enabled"
12968
12969         touch $DIR/$tfile
12970         flocks_test 3 $DIR/$tfile
12971 }
12972 run_test 105e "Two conflicting flocks from same process"
12973
12974 test_106() { #bug 10921
12975         test_mkdir $DIR/$tdir
12976         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
12977         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
12978 }
12979 run_test 106 "attempt exec of dir followed by chown of that dir"
12980
12981 test_107() {
12982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12983
12984         CDIR=`pwd`
12985         local file=core
12986
12987         cd $DIR
12988         rm -f $file
12989
12990         local save_pattern=$(sysctl -n kernel.core_pattern)
12991         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
12992         sysctl -w kernel.core_pattern=$file
12993         sysctl -w kernel.core_uses_pid=0
12994
12995         ulimit -c unlimited
12996         sleep 60 &
12997         SLEEPPID=$!
12998
12999         sleep 1
13000
13001         kill -s 11 $SLEEPPID
13002         wait $SLEEPPID
13003         if [ -e $file ]; then
13004                 size=`stat -c%s $file`
13005                 [ $size -eq 0 ] && error "Fail to create core file $file"
13006         else
13007                 error "Fail to create core file $file"
13008         fi
13009         rm -f $file
13010         sysctl -w kernel.core_pattern=$save_pattern
13011         sysctl -w kernel.core_uses_pid=$save_uses_pid
13012         cd $CDIR
13013 }
13014 run_test 107 "Coredump on SIG"
13015
13016 test_110() {
13017         test_mkdir $DIR/$tdir
13018         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
13019         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
13020                 error "mkdir with 256 char should fail, but did not"
13021         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
13022                 error "create with 255 char failed"
13023         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
13024                 error "create with 256 char should fail, but did not"
13025
13026         ls -l $DIR/$tdir
13027         rm -rf $DIR/$tdir
13028 }
13029 run_test 110 "filename length checking"
13030
13031 test_116a() { # was previously test_116()
13032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13033         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13034         remote_mds_nodsh && skip "remote MDS with nodsh"
13035
13036         echo -n "Free space priority "
13037         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
13038                 head -n1
13039         declare -a AVAIL
13040         free_min_max
13041
13042         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
13043         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
13044         stack_trap simple_cleanup_common
13045
13046         # Check if we need to generate uneven OSTs
13047         test_mkdir -p $DIR/$tdir/OST${MINI}
13048         local FILL=$((MINV / 4))
13049         local DIFF=$((MAXV - MINV))
13050         local DIFF2=$((DIFF * 100 / MINV))
13051
13052         local threshold=$(do_facet $SINGLEMDS \
13053                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
13054         threshold=${threshold%%%}
13055         echo -n "Check for uneven OSTs: "
13056         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
13057
13058         if [[ $DIFF2 -gt $threshold ]]; then
13059                 echo "ok"
13060                 echo "Don't need to fill OST$MINI"
13061         else
13062                 # generate uneven OSTs. Write 2% over the QOS threshold value
13063                 echo "no"
13064                 DIFF=$((threshold - DIFF2 + 2))
13065                 DIFF2=$((MINV * DIFF / 100))
13066                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
13067                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
13068                         error "setstripe failed"
13069                 DIFF=$((DIFF2 / 2048))
13070                 i=0
13071                 while [ $i -lt $DIFF ]; do
13072                         i=$((i + 1))
13073                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
13074                                 bs=2M count=1 2>/dev/null
13075                         echo -n .
13076                 done
13077                 echo .
13078                 sync
13079                 sleep_maxage
13080                 free_min_max
13081         fi
13082
13083         DIFF=$((MAXV - MINV))
13084         DIFF2=$((DIFF * 100 / MINV))
13085         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
13086         if [ $DIFF2 -gt $threshold ]; then
13087                 echo "ok"
13088         else
13089                 skip "QOS imbalance criteria not met"
13090         fi
13091
13092         MINI1=$MINI
13093         MINV1=$MINV
13094         MAXI1=$MAXI
13095         MAXV1=$MAXV
13096
13097         # now fill using QOS
13098         $LFS setstripe -c 1 $DIR/$tdir
13099         FILL=$((FILL / 200))
13100         if [ $FILL -gt 600 ]; then
13101                 FILL=600
13102         fi
13103         echo "writing $FILL files to QOS-assigned OSTs"
13104         i=0
13105         while [ $i -lt $FILL ]; do
13106                 i=$((i + 1))
13107                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
13108                         count=1 2>/dev/null
13109                 echo -n .
13110         done
13111         echo "wrote $i 200k files"
13112         sync
13113         sleep_maxage
13114
13115         echo "Note: free space may not be updated, so measurements might be off"
13116         free_min_max
13117         DIFF2=$((MAXV - MINV))
13118         echo "free space delta: orig $DIFF final $DIFF2"
13119         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
13120         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
13121         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
13122         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
13123         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
13124         if [[ $DIFF -gt 0 ]]; then
13125                 FILL=$((DIFF2 * 100 / DIFF - 100))
13126                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
13127         fi
13128
13129         # Figure out which files were written where
13130         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
13131                awk '/'$MINI1': / {print $2; exit}')
13132         echo $UUID
13133         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
13134         echo "$MINC files created on smaller OST $MINI1"
13135         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
13136                awk '/'$MAXI1': / {print $2; exit}')
13137         echo $UUID
13138         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
13139         echo "$MAXC files created on larger OST $MAXI1"
13140         if [[ $MINC -gt 0 ]]; then
13141                 FILL=$((MAXC * 100 / MINC - 100))
13142                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
13143         fi
13144         [[ $MAXC -gt $MINC ]] ||
13145                 error_ignore LU-9 "stripe QOS didn't balance free space"
13146 }
13147 run_test 116a "stripe QOS: free space balance ==================="
13148
13149 test_116b() { # LU-2093
13150         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13151         remote_mds_nodsh && skip "remote MDS with nodsh"
13152
13153 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
13154         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
13155                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
13156         [ -z "$old_rr" ] && skip "no QOS"
13157         do_facet $SINGLEMDS lctl set_param \
13158                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
13159         mkdir -p $DIR/$tdir
13160         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
13161         createmany -o $DIR/$tdir/f- 20 || error "can't create"
13162         do_facet $SINGLEMDS lctl set_param fail_loc=0
13163         rm -rf $DIR/$tdir
13164         do_facet $SINGLEMDS lctl set_param \
13165                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
13166 }
13167 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
13168
13169 test_117() # bug 10891
13170 {
13171         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13172
13173         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
13174         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
13175         lctl set_param fail_loc=0x21e
13176         > $DIR/$tfile || error "truncate failed"
13177         lctl set_param fail_loc=0
13178         echo "Truncate succeeded."
13179         rm -f $DIR/$tfile
13180 }
13181 run_test 117 "verify osd extend =========="
13182
13183 NO_SLOW_RESENDCOUNT=4
13184 export OLD_RESENDCOUNT=""
13185 set_resend_count () {
13186         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
13187         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
13188         lctl set_param -n $PROC_RESENDCOUNT $1
13189         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
13190 }
13191
13192 # for reduce test_118* time (b=14842)
13193 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13194
13195 # Reset async IO behavior after error case
13196 reset_async() {
13197         FILE=$DIR/reset_async
13198
13199         # Ensure all OSCs are cleared
13200         $LFS setstripe -c -1 $FILE
13201         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
13202         sync
13203         rm $FILE
13204 }
13205
13206 test_118a() #bug 11710
13207 {
13208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13209
13210         reset_async
13211
13212         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13213         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13214         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13215
13216         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13217                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13218                 return 1;
13219         fi
13220         rm -f $DIR/$tfile
13221 }
13222 run_test 118a "verify O_SYNC works =========="
13223
13224 test_118b()
13225 {
13226         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13227         remote_ost_nodsh && skip "remote OST with nodsh"
13228
13229         reset_async
13230
13231         #define OBD_FAIL_SRV_ENOENT 0x217
13232         set_nodes_failloc "$(osts_nodes)" 0x217
13233         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13234         RC=$?
13235         set_nodes_failloc "$(osts_nodes)" 0
13236         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13237         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13238                     grep -c writeback)
13239
13240         if [[ $RC -eq 0 ]]; then
13241                 error "Must return error due to dropped pages, rc=$RC"
13242                 return 1;
13243         fi
13244
13245         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13246                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13247                 return 1;
13248         fi
13249
13250         echo "Dirty pages not leaked on ENOENT"
13251
13252         # Due to the above error the OSC will issue all RPCs syncronously
13253         # until a subsequent RPC completes successfully without error.
13254         $MULTIOP $DIR/$tfile Ow4096yc
13255         rm -f $DIR/$tfile
13256
13257         return 0
13258 }
13259 run_test 118b "Reclaim dirty pages on fatal error =========="
13260
13261 test_118c()
13262 {
13263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13264
13265         # for 118c, restore the original resend count, LU-1940
13266         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
13267                                 set_resend_count $OLD_RESENDCOUNT
13268         remote_ost_nodsh && skip "remote OST with nodsh"
13269
13270         reset_async
13271
13272         #define OBD_FAIL_OST_EROFS               0x216
13273         set_nodes_failloc "$(osts_nodes)" 0x216
13274
13275         # multiop should block due to fsync until pages are written
13276         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13277         MULTIPID=$!
13278         sleep 1
13279
13280         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13281                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13282         fi
13283
13284         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13285                     grep -c writeback)
13286         if [[ $WRITEBACK -eq 0 ]]; then
13287                 error "No page in writeback, writeback=$WRITEBACK"
13288         fi
13289
13290         set_nodes_failloc "$(osts_nodes)" 0
13291         wait $MULTIPID
13292         RC=$?
13293         if [[ $RC -ne 0 ]]; then
13294                 error "Multiop fsync failed, rc=$RC"
13295         fi
13296
13297         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13298         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13299                     grep -c writeback)
13300         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13301                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13302         fi
13303
13304         rm -f $DIR/$tfile
13305         echo "Dirty pages flushed via fsync on EROFS"
13306         return 0
13307 }
13308 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
13309
13310 # continue to use small resend count to reduce test_118* time (b=14842)
13311 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13312
13313 test_118d()
13314 {
13315         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13316         remote_ost_nodsh && skip "remote OST with nodsh"
13317
13318         reset_async
13319
13320         #define OBD_FAIL_OST_BRW_PAUSE_BULK
13321         set_nodes_failloc "$(osts_nodes)" 0x214
13322         # multiop should block due to fsync until pages are written
13323         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13324         MULTIPID=$!
13325         sleep 1
13326
13327         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13328                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13329         fi
13330
13331         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13332                     grep -c writeback)
13333         if [[ $WRITEBACK -eq 0 ]]; then
13334                 error "No page in writeback, writeback=$WRITEBACK"
13335         fi
13336
13337         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
13338         set_nodes_failloc "$(osts_nodes)" 0
13339
13340         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13341         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13342                     grep -c writeback)
13343         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13344                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13345         fi
13346
13347         rm -f $DIR/$tfile
13348         echo "Dirty pages gaurenteed flushed via fsync"
13349         return 0
13350 }
13351 run_test 118d "Fsync validation inject a delay of the bulk =========="
13352
13353 test_118f() {
13354         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13355
13356         reset_async
13357
13358         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
13359         lctl set_param fail_loc=0x8000040a
13360
13361         # Should simulate EINVAL error which is fatal
13362         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13363         RC=$?
13364         if [[ $RC -eq 0 ]]; then
13365                 error "Must return error due to dropped pages, rc=$RC"
13366         fi
13367
13368         lctl set_param fail_loc=0x0
13369
13370         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13371         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13372         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13373                     grep -c writeback)
13374         if [[ $LOCKED -ne 0 ]]; then
13375                 error "Locked pages remain in cache, locked=$LOCKED"
13376         fi
13377
13378         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13379                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13380         fi
13381
13382         rm -f $DIR/$tfile
13383         echo "No pages locked after fsync"
13384
13385         reset_async
13386         return 0
13387 }
13388 run_test 118f "Simulate unrecoverable OSC side error =========="
13389
13390 test_118g() {
13391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13392
13393         reset_async
13394
13395         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
13396         lctl set_param fail_loc=0x406
13397
13398         # simulate local -ENOMEM
13399         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13400         RC=$?
13401
13402         lctl set_param fail_loc=0
13403         if [[ $RC -eq 0 ]]; then
13404                 error "Must return error due to dropped pages, rc=$RC"
13405         fi
13406
13407         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13408         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13409         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13410                         grep -c writeback)
13411         if [[ $LOCKED -ne 0 ]]; then
13412                 error "Locked pages remain in cache, locked=$LOCKED"
13413         fi
13414
13415         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13416                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13417         fi
13418
13419         rm -f $DIR/$tfile
13420         echo "No pages locked after fsync"
13421
13422         reset_async
13423         return 0
13424 }
13425 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
13426
13427 test_118h() {
13428         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13429         remote_ost_nodsh && skip "remote OST with nodsh"
13430
13431         reset_async
13432
13433         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13434         set_nodes_failloc "$(osts_nodes)" 0x20e
13435         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13436         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13437         RC=$?
13438
13439         set_nodes_failloc "$(osts_nodes)" 0
13440         if [[ $RC -eq 0 ]]; then
13441                 error "Must return error due to dropped pages, rc=$RC"
13442         fi
13443
13444         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13445         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13446         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13447                     grep -c writeback)
13448         if [[ $LOCKED -ne 0 ]]; then
13449                 error "Locked pages remain in cache, locked=$LOCKED"
13450         fi
13451
13452         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13453                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13454         fi
13455
13456         rm -f $DIR/$tfile
13457         echo "No pages locked after fsync"
13458
13459         return 0
13460 }
13461 run_test 118h "Verify timeout in handling recoverables errors  =========="
13462
13463 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13464
13465 test_118i() {
13466         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13467         remote_ost_nodsh && skip "remote OST with nodsh"
13468
13469         reset_async
13470
13471         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13472         set_nodes_failloc "$(osts_nodes)" 0x20e
13473
13474         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13475         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13476         PID=$!
13477         sleep 5
13478         set_nodes_failloc "$(osts_nodes)" 0
13479
13480         wait $PID
13481         RC=$?
13482         if [[ $RC -ne 0 ]]; then
13483                 error "got error, but should be not, rc=$RC"
13484         fi
13485
13486         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13487         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13488         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13489         if [[ $LOCKED -ne 0 ]]; then
13490                 error "Locked pages remain in cache, locked=$LOCKED"
13491         fi
13492
13493         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13494                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13495         fi
13496
13497         rm -f $DIR/$tfile
13498         echo "No pages locked after fsync"
13499
13500         return 0
13501 }
13502 run_test 118i "Fix error before timeout in recoverable error  =========="
13503
13504 [ "$SLOW" = "no" ] && set_resend_count 4
13505
13506 test_118j() {
13507         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13508         remote_ost_nodsh && skip "remote OST with nodsh"
13509
13510         reset_async
13511
13512         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
13513         set_nodes_failloc "$(osts_nodes)" 0x220
13514
13515         # return -EIO from OST
13516         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13517         RC=$?
13518         set_nodes_failloc "$(osts_nodes)" 0x0
13519         if [[ $RC -eq 0 ]]; then
13520                 error "Must return error due to dropped pages, rc=$RC"
13521         fi
13522
13523         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13524         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13525         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13526         if [[ $LOCKED -ne 0 ]]; then
13527                 error "Locked pages remain in cache, locked=$LOCKED"
13528         fi
13529
13530         # in recoverable error on OST we want resend and stay until it finished
13531         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13532                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13533         fi
13534
13535         rm -f $DIR/$tfile
13536         echo "No pages locked after fsync"
13537
13538         return 0
13539 }
13540 run_test 118j "Simulate unrecoverable OST side error =========="
13541
13542 test_118k()
13543 {
13544         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13545         remote_ost_nodsh && skip "remote OSTs with nodsh"
13546
13547         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13548         set_nodes_failloc "$(osts_nodes)" 0x20e
13549         test_mkdir $DIR/$tdir
13550
13551         for ((i=0;i<10;i++)); do
13552                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
13553                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
13554                 SLEEPPID=$!
13555                 sleep 0.500s
13556                 kill $SLEEPPID
13557                 wait $SLEEPPID
13558         done
13559
13560         set_nodes_failloc "$(osts_nodes)" 0
13561         rm -rf $DIR/$tdir
13562 }
13563 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
13564
13565 test_118l() # LU-646
13566 {
13567         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13568
13569         test_mkdir $DIR/$tdir
13570         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
13571         rm -rf $DIR/$tdir
13572 }
13573 run_test 118l "fsync dir"
13574
13575 test_118m() # LU-3066
13576 {
13577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13578
13579         test_mkdir $DIR/$tdir
13580         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
13581         rm -rf $DIR/$tdir
13582 }
13583 run_test 118m "fdatasync dir ========="
13584
13585 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13586
13587 test_118n()
13588 {
13589         local begin
13590         local end
13591
13592         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13593         remote_ost_nodsh && skip "remote OSTs with nodsh"
13594
13595         # Sleep to avoid a cached response.
13596         #define OBD_STATFS_CACHE_SECONDS 1
13597         sleep 2
13598
13599         # Inject a 10 second delay in the OST_STATFS handler.
13600         #define OBD_FAIL_OST_STATFS_DELAY 0x242
13601         set_nodes_failloc "$(osts_nodes)" 0x242
13602
13603         begin=$SECONDS
13604         stat --file-system $MOUNT > /dev/null
13605         end=$SECONDS
13606
13607         set_nodes_failloc "$(osts_nodes)" 0
13608
13609         if ((end - begin > 20)); then
13610             error "statfs took $((end - begin)) seconds, expected 10"
13611         fi
13612 }
13613 run_test 118n "statfs() sends OST_STATFS requests in parallel"
13614
13615 test_119a() # bug 11737
13616 {
13617         BSIZE=$((512 * 1024))
13618         directio write $DIR/$tfile 0 1 $BSIZE
13619         # We ask to read two blocks, which is more than a file size.
13620         # directio will indicate an error when requested and actual
13621         # sizes aren't equeal (a normal situation in this case) and
13622         # print actual read amount.
13623         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
13624         if [ "$NOB" != "$BSIZE" ]; then
13625                 error "read $NOB bytes instead of $BSIZE"
13626         fi
13627         rm -f $DIR/$tfile
13628 }
13629 run_test 119a "Short directIO read must return actual read amount"
13630
13631 test_119b() # bug 11737
13632 {
13633         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13634
13635         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
13636         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
13637         sync
13638         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
13639                 error "direct read failed"
13640         rm -f $DIR/$tfile
13641 }
13642 run_test 119b "Sparse directIO read must return actual read amount"
13643
13644 test_119c() # bug 13099
13645 {
13646         BSIZE=1048576
13647         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
13648         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
13649         rm -f $DIR/$tfile
13650 }
13651 run_test 119c "Testing for direct read hitting hole"
13652
13653 # Note: test 119d was removed, skipping 119d for new tests to avoid polluting
13654 # Maloo test history
13655
13656 test_119e()
13657 {
13658         (( $MDS1_VERSION >= $(version_code 2.15.58) )) ||
13659                 skip "Need server version at least 2.15.58"
13660         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13661
13662         local stripe_size=$((1024 * 1024)) #1 MiB
13663         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13664         local file_size=$((25 * stripe_size))
13665         local bsizes
13666
13667         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13668         stack_trap "rm -f $DIR/$tfile*"
13669
13670         # Just a bit bigger than the largest size in the test set below
13671         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13672                 error "buffered i/o to create file failed"
13673
13674         # trivial test of unaligned DIO
13675         dd if=$DIR/$tfile.1 bs=4095 of=$DIR/$tfile.2 count=4 \
13676                 iflag=direct oflag=direct ||
13677                 error "trivial unaligned dio failed"
13678
13679         # Test of disabling unaligned DIO support
13680         $LCTL set_param llite.*.unaligned_dio=0
13681         stack_trap "$LCTL set_param llite.*.unaligned_dio=1"
13682         echo "testing disabling unaligned DIO - 'invalid argument' expected:"
13683         dd if=$DIR/$tfile.1 bs=1024 of=$DIR/$tfile.2 count=4 \
13684                 iflag=direct oflag=direct &&
13685                 error "unaligned dio succeeded when disabled"
13686         $LCTL set_param llite.*.unaligned_dio=1
13687
13688         # Clean up before next part of test
13689         rm -f $DIR/$tfile.2
13690
13691         if zfs_or_rotational; then
13692                 # DIO on ZFS can take up to 2 seconds per IO
13693                 # rotational is better, but still slow.
13694                 # Limit testing on those media to larger sizes
13695                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13696                         $((stripe_size + 1024))"
13697         else
13698                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13699                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13700                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13701                         $((stripe_size - 1)) $stripe_size \
13702                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13703                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13704         fi
13705
13706         for bs in $bsizes; do
13707                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13708                 echo "Read/write with DIO at size $bs"
13709                 # Read and write with DIO from source to dest
13710                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 \
13711                         iflag=direct oflag=direct ||
13712                         error "dio failed"
13713
13714                 ls -la $DIR/$tfile.1 $DIR/$tfile.2
13715                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13716                         error "size incorrect, file copy read/write bsize: $bs"
13717                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13718                         error "files differ, bsize $bs"
13719                 rm -f $DIR/$tfile.2
13720         done
13721 }
13722 run_test 119e "Basic tests of dio read and write at various sizes"
13723
13724 test_119f()
13725 {
13726         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13727
13728         local stripe_size=$((1024 * 1024)) #1 MiB
13729         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13730         local file_size=$((25 * stripe_size))
13731         local bsizes
13732
13733         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13734         stack_trap "rm -f $DIR/$tfile*"
13735
13736         # Just a bit bigger than the largest size in the test set below
13737         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13738                 error "buffered i/o to create file failed"
13739
13740         if zfs_or_rotational; then
13741                 # DIO on ZFS can take up to 2 seconds per IO
13742                 # rotational is better, but still slow.
13743                 # Limit testing on those media to larger sizes
13744                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13745                         $((stripe_size + 1024))"
13746         else
13747                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13748                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13749                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13750                         $((stripe_size - 1)) $stripe_size \
13751                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13752                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13753         fi
13754
13755         for bs in $bsizes; do
13756                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13757                 # Read and write with DIO from source to dest in two
13758                 # threads - should give correct copy of file
13759
13760                 echo "bs: $bs"
13761                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13762                         oflag=direct conv=notrunc &
13763                 pid_dio1=$!
13764                 # Note block size is different here for a more interesting race
13765                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
13766                         iflag=direct oflag=direct conv=notrunc &
13767                 pid_dio2=$!
13768                 wait $pid_dio1
13769                 rc1=$?
13770                 wait $pid_dio2
13771                 rc2=$?
13772                 if (( rc1 != 0 )); then
13773                         error "dio copy 1 w/bsize $bs failed: $rc1"
13774                 fi
13775                 if (( rc2 != 0 )); then
13776                         error "dio copy 2 w/bsize $bs failed: $rc2"
13777                 fi
13778
13779
13780                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13781                         error "size incorrect, file copy read/write bsize: $bs"
13782                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13783                         error "files differ, bsize $bs"
13784                 rm -f $DIR/$tfile.2
13785         done
13786 }
13787 run_test 119f "dio vs dio race"
13788
13789 test_119g()
13790 {
13791         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13792
13793         local stripe_size=$((1024 * 1024)) #1 MiB
13794         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13795         local file_size=$((25 * stripe_size))
13796         local bsizes
13797
13798         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13799         stack_trap "rm -f $DIR/$tfile*"
13800
13801         # Just a bit bigger than the largest size in the test set below
13802         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13803                 error "buffered i/o to create file failed"
13804
13805         if zfs_or_rotational; then
13806                 # DIO on ZFS can take up to 2 seconds per IO
13807                 # rotational is better, but still slow.
13808                 # Limit testing on those media to larger sizes
13809                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13810                         $((stripe_size + 1024))"
13811         else
13812                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13813                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13814                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13815                         $((stripe_size - 1)) $stripe_size \
13816                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13817                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13818         fi
13819
13820         for bs in $bsizes; do
13821                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13822                 echo "bs: $bs"
13823                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13824                         oflag=direct conv=notrunc &
13825                 pid_dio1=$!
13826                 # Buffered I/O with similar but not the same block size
13827                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 &
13828                 pid_bio2=$!
13829                 wait $pid_dio1
13830                 rc1=$?
13831                 wait $pid_bio2
13832                 rc2=$?
13833                 if (( rc1 != 0 )); then
13834                         error "dio copy 1 w/bsize $bs failed: $rc1"
13835                 fi
13836                 if (( rc2 != 0 )); then
13837                         error "buffered copy 2 w/bsize $bs failed: $rc2"
13838                 fi
13839
13840                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13841                         error "size incorrect"
13842                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13843                         error "files differ, bsize $bs"
13844                 rm -f $DIR/$tfile.2
13845         done
13846 }
13847 run_test 119g "dio vs buffered I/O race"
13848
13849 test_119h()
13850 {
13851         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13852
13853         local stripe_size=$((1024 * 1024)) #1 MiB
13854         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13855         local file_size=$((25 * stripe_size))
13856         local bsizes
13857
13858         stack_trap "rm -f $DIR/$tfile.*"
13859
13860         if zfs_or_rotational; then
13861                 # DIO on ZFS can take up to 2 seconds per IO
13862                 # rotational is better, but still slow.
13863                 # Limit testing on those media to larger sizes
13864                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13865                         $((stripe_size + 1024))"
13866         else
13867                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13868                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13869                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13870                         $((stripe_size - 1)) $stripe_size \
13871                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13872                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13873         fi
13874
13875         for bs in $bsizes; do
13876                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13877                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13878                 echo "unaligned writes of blocksize: $bs"
13879                 # Write a file with unaligned DIO and regular DIO, and compare
13880                 # them
13881                 # with 'u', multiop randomly unaligns the io from the buffer
13882                 $MULTIOP $DIR/$tfile.1 \
13883                 oO_CREAT:O_RDWR:O_DIRECT:wu${bs}wu${bs}wu${bs}wu${bs}wu${bs} ||
13884                         error "multiop memory unaligned write failed, $bs"
13885                 $MULTIOP $DIR/$tfile.2 \
13886                 oO_CREAT:O_RDWR:O_DIRECT:w${bs}w${bs}w${bs}w${bs}w${bs} ||
13887                         error "multiop memory aligned write failed, $bs"
13888
13889                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13890                         error "files differ, bsize $bs"
13891                 rm -f $DIR/$tfile.*
13892         done
13893
13894         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13895         dd if=/dev/zero bs=$((stripe_size * 5)) of=$DIR/$tfile.1 count=5 ||
13896                 error "dd to create source file for read failed"
13897
13898         # Just a few quick tests to make sure unaligned DIO reads don't crash
13899         for bs in $bsizes; do
13900
13901                 echo "unaligned reads of blocksize: $bs"
13902                 # with 'u', multiop randomly unaligns the io from the buffer
13903                 $MULTIOP $DIR/$tfile.1 \
13904                 oO_CREAT:O_RDWR:O_DIRECT:ru${bs}ru${bs}ru${bs}ru${bs}ru${bs} ||
13905                         error "multiop memory unaligned read failed, $bs"
13906
13907         done
13908         rm -f $DIR/$tfile*
13909 }
13910 run_test 119h "basic tests of memory unaligned dio"
13911
13912 # aiocp with the '-a' option makes testing memory unaligned aio trivial
13913 test_119i()
13914 {
13915         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13916         which aiocp || skip_env "no aiocp installed"
13917
13918         local stripe_size=$((1024 * 1024)) #1 MiB
13919         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13920         local file_size=$((25 * stripe_size))
13921         local bsizes
13922
13923         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13924         stack_trap "rm -f $DIR/$tfile.*"
13925
13926         # Just a bit bigger than the largest size in the test set below
13927         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13928                 error "buffered i/o to create file failed"
13929
13930         if zfs_or_rotational; then
13931                 # DIO on ZFS can take up to 2 seconds per IO
13932                 # rotational is better, but still slow.
13933                 # Limit testing on those media to larger sizes
13934                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13935                         $((stripe_size + 1024))"
13936         else
13937                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13938                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13939                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13940                         $((stripe_size - 1)) $stripe_size \
13941                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13942                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13943         fi
13944
13945         # Do page aligned and NOT page aligned AIO
13946         for align in 8 512 $((PAGE_SIZE)); do
13947         # Deliberately includes a few aligned sizes
13948         for bs in $bsizes; do
13949                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13950
13951                 echo "bs: $bs, align: $align, file_size $file_size"
13952                 aiocp -a $align -b $bs -s $file_size -f O_DIRECT \
13953                         $DIR/$tfile.1 $DIR/$tfile.2 ||
13954                         error "unaligned aio failed, bs: $bs, align: $align"
13955
13956                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13957                         error "size incorrect"
13958                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13959                         error "files differ"
13960                 rm -f $DIR/$tfile.2
13961         done
13962         done
13963 }
13964 run_test 119i "test unaligned aio at varying sizes"
13965
13966 test_120a() {
13967         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13968         remote_mds_nodsh && skip "remote MDS with nodsh"
13969         test_mkdir -i0 -c1 $DIR/$tdir
13970         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13971                 skip_env "no early lock cancel on server"
13972
13973         lru_resize_disable mdc
13974         lru_resize_disable osc
13975         cancel_lru_locks mdc
13976         # asynchronous object destroy at MDT could cause bl ast to client
13977         cancel_lru_locks osc
13978
13979         stat $DIR/$tdir > /dev/null
13980         can1=$(do_facet mds1 \
13981                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13982                awk '/ldlm_cancel/ {print $2}')
13983         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13984                awk '/ldlm_bl_callback/ {print $2}')
13985         test_mkdir -i0 -c1 $DIR/$tdir/d1
13986         can2=$(do_facet mds1 \
13987                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13988                awk '/ldlm_cancel/ {print $2}')
13989         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13990                awk '/ldlm_bl_callback/ {print $2}')
13991         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13992         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13993         lru_resize_enable mdc
13994         lru_resize_enable osc
13995 }
13996 run_test 120a "Early Lock Cancel: mkdir test"
13997
13998 test_120b() {
13999         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14000         remote_mds_nodsh && skip "remote MDS with nodsh"
14001         test_mkdir $DIR/$tdir
14002         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14003                 skip_env "no early lock cancel on server"
14004
14005         lru_resize_disable mdc
14006         lru_resize_disable osc
14007         cancel_lru_locks mdc
14008         stat $DIR/$tdir > /dev/null
14009         can1=$(do_facet $SINGLEMDS \
14010                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14011                awk '/ldlm_cancel/ {print $2}')
14012         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14013                awk '/ldlm_bl_callback/ {print $2}')
14014         touch $DIR/$tdir/f1
14015         can2=$(do_facet $SINGLEMDS \
14016                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14017                awk '/ldlm_cancel/ {print $2}')
14018         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14019                awk '/ldlm_bl_callback/ {print $2}')
14020         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14021         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14022         lru_resize_enable mdc
14023         lru_resize_enable osc
14024 }
14025 run_test 120b "Early Lock Cancel: create test"
14026
14027 test_120c() {
14028         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14029         remote_mds_nodsh && skip "remote MDS with nodsh"
14030         test_mkdir -i0 -c1 $DIR/$tdir
14031         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14032                 skip "no early lock cancel on server"
14033
14034         lru_resize_disable mdc
14035         lru_resize_disable osc
14036         test_mkdir -i0 -c1 $DIR/$tdir/d1
14037         test_mkdir -i0 -c1 $DIR/$tdir/d2
14038         touch $DIR/$tdir/d1/f1
14039         cancel_lru_locks mdc
14040         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
14041         can1=$(do_facet mds1 \
14042                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14043                awk '/ldlm_cancel/ {print $2}')
14044         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14045                awk '/ldlm_bl_callback/ {print $2}')
14046         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
14047         can2=$(do_facet mds1 \
14048                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14049                awk '/ldlm_cancel/ {print $2}')
14050         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14051                awk '/ldlm_bl_callback/ {print $2}')
14052         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14053         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14054         lru_resize_enable mdc
14055         lru_resize_enable osc
14056 }
14057 run_test 120c "Early Lock Cancel: link test"
14058
14059 test_120d() {
14060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14061         remote_mds_nodsh && skip "remote MDS with nodsh"
14062         test_mkdir -i0 -c1 $DIR/$tdir
14063         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14064                 skip_env "no early lock cancel on server"
14065
14066         lru_resize_disable mdc
14067         lru_resize_disable osc
14068         touch $DIR/$tdir
14069         cancel_lru_locks mdc
14070         stat $DIR/$tdir > /dev/null
14071         can1=$(do_facet mds1 \
14072                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14073                awk '/ldlm_cancel/ {print $2}')
14074         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14075                awk '/ldlm_bl_callback/ {print $2}')
14076         chmod a+x $DIR/$tdir
14077         can2=$(do_facet mds1 \
14078                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14079                awk '/ldlm_cancel/ {print $2}')
14080         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14081                awk '/ldlm_bl_callback/ {print $2}')
14082         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14083         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14084         lru_resize_enable mdc
14085         lru_resize_enable osc
14086 }
14087 run_test 120d "Early Lock Cancel: setattr test"
14088
14089 test_120e() {
14090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14091         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14092                 skip_env "no early lock cancel on server"
14093         remote_mds_nodsh && skip "remote MDS with nodsh"
14094
14095         local dlmtrace_set=false
14096
14097         test_mkdir -i0 -c1 $DIR/$tdir
14098         lru_resize_disable mdc
14099         lru_resize_disable osc
14100         ! $LCTL get_param debug | grep -q dlmtrace &&
14101                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
14102         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
14103         cancel_lru_locks mdc
14104         cancel_lru_locks osc
14105         dd if=$DIR/$tdir/f1 of=/dev/null
14106         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
14107         # XXX client can not do early lock cancel of OST lock
14108         # during unlink (LU-4206), so cancel osc lock now.
14109         sleep 2
14110         cancel_lru_locks osc
14111         can1=$(do_facet mds1 \
14112                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14113                awk '/ldlm_cancel/ {print $2}')
14114         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14115                awk '/ldlm_bl_callback/ {print $2}')
14116         unlink $DIR/$tdir/f1
14117         sleep 5
14118         can2=$(do_facet mds1 \
14119                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14120                awk '/ldlm_cancel/ {print $2}')
14121         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14122                awk '/ldlm_bl_callback/ {print $2}')
14123         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
14124                 $LCTL dk $TMP/cancel.debug.txt
14125         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
14126                 $LCTL dk $TMP/blocking.debug.txt
14127         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
14128         lru_resize_enable mdc
14129         lru_resize_enable osc
14130 }
14131 run_test 120e "Early Lock Cancel: unlink test"
14132
14133 test_120f() {
14134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14135         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14136                 skip_env "no early lock cancel on server"
14137         remote_mds_nodsh && skip "remote MDS with nodsh"
14138
14139         test_mkdir -i0 -c1 $DIR/$tdir
14140         lru_resize_disable mdc
14141         lru_resize_disable osc
14142         test_mkdir -i0 -c1 $DIR/$tdir/d1
14143         test_mkdir -i0 -c1 $DIR/$tdir/d2
14144         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
14145         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
14146         cancel_lru_locks mdc
14147         cancel_lru_locks osc
14148         dd if=$DIR/$tdir/d1/f1 of=/dev/null
14149         dd if=$DIR/$tdir/d2/f2 of=/dev/null
14150         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
14151         # XXX client can not do early lock cancel of OST lock
14152         # during rename (LU-4206), so cancel osc lock now.
14153         sleep 2
14154         cancel_lru_locks osc
14155         can1=$(do_facet mds1 \
14156                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14157                awk '/ldlm_cancel/ {print $2}')
14158         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14159                awk '/ldlm_bl_callback/ {print $2}')
14160         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
14161         sleep 5
14162         can2=$(do_facet mds1 \
14163                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14164                awk '/ldlm_cancel/ {print $2}')
14165         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14166                awk '/ldlm_bl_callback/ {print $2}')
14167         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14168         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14169         lru_resize_enable mdc
14170         lru_resize_enable osc
14171 }
14172 run_test 120f "Early Lock Cancel: rename test"
14173
14174 test_120g() {
14175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14176         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14177                 skip_env "no early lock cancel on server"
14178         remote_mds_nodsh && skip "remote MDS with nodsh"
14179
14180         lru_resize_disable mdc
14181         lru_resize_disable osc
14182         count=10000
14183         echo create $count files
14184         test_mkdir $DIR/$tdir
14185         cancel_lru_locks mdc
14186         cancel_lru_locks osc
14187         t0=$(date +%s)
14188
14189         can0=$(do_facet $SINGLEMDS \
14190                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14191                awk '/ldlm_cancel/ {print $2}')
14192         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14193                awk '/ldlm_bl_callback/ {print $2}')
14194         createmany -o $DIR/$tdir/f $count
14195         sync
14196         can1=$(do_facet $SINGLEMDS \
14197                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14198                awk '/ldlm_cancel/ {print $2}')
14199         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14200                awk '/ldlm_bl_callback/ {print $2}')
14201         t1=$(date +%s)
14202         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
14203         echo rm $count files
14204         rm -r $DIR/$tdir
14205         sync
14206         can2=$(do_facet $SINGLEMDS \
14207                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14208                awk '/ldlm_cancel/ {print $2}')
14209         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14210                awk '/ldlm_bl_callback/ {print $2}')
14211         t2=$(date +%s)
14212         echo total: $count removes in $((t2-t1))
14213         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
14214         sleep 2
14215         # wait for commitment of removal
14216         lru_resize_enable mdc
14217         lru_resize_enable osc
14218 }
14219 run_test 120g "Early Lock Cancel: performance test"
14220
14221 test_121() { #bug #10589
14222         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14223
14224         rm -rf $DIR/$tfile
14225         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
14226 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
14227         lctl set_param fail_loc=0x310
14228         cancel_lru_locks osc > /dev/null
14229         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
14230         lctl set_param fail_loc=0
14231         [[ $reads -eq $writes ]] ||
14232                 error "read $reads blocks, must be $writes blocks"
14233 }
14234 run_test 121 "read cancel race ========="
14235
14236 test_123a_base() { # was test 123, statahead(bug 11401)
14237         local lsx="$1"
14238
14239         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
14240
14241         SLOWOK=0
14242         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
14243                 log "testing UP system. Performance may be lower than expected."
14244                 SLOWOK=1
14245         fi
14246         running_in_vm && SLOWOK=1
14247
14248         $LCTL set_param mdc.*.batch_stats=0
14249
14250         rm -rf $DIR/$tdir
14251         test_mkdir $DIR/$tdir
14252         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
14253         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
14254         MULT=10
14255         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
14256                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
14257
14258                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
14259                 lctl set_param -n llite.*.statahead_max 0
14260                 lctl get_param llite.*.statahead_max
14261                 cancel_lru_locks mdc
14262                 cancel_lru_locks osc
14263                 stime=$(date +%s)
14264                 time $lsx $DIR/$tdir | wc -l
14265                 etime=$(date +%s)
14266                 delta=$((etime - stime))
14267                 log "$lsx $i files without statahead: $delta sec"
14268                 lctl set_param llite.*.statahead_max=$max
14269
14270                 swrong=$(lctl get_param -n llite.*.statahead_stats |
14271                          awk '/statahead.wrong:/ { print $NF }')
14272                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
14273                 cancel_lru_locks mdc
14274                 cancel_lru_locks osc
14275                 stime=$(date +%s)
14276                 time $lsx $DIR/$tdir | wc -l
14277                 etime=$(date +%s)
14278                 delta_sa=$((etime - stime))
14279                 log "$lsx $i files with statahead: $delta_sa sec"
14280                 lctl get_param -n llite.*.statahead_stats
14281                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
14282                          awk '/statahead.wrong:/ { print $NF }')
14283
14284                 [[ $swrong -lt $ewrong ]] &&
14285                         log "statahead was stopped, maybe too many locks held!"
14286                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
14287
14288                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
14289                         max=$(lctl get_param -n llite.*.statahead_max |
14290                                 head -n 1)
14291                         lctl set_param -n llite.*.statahead_max 0
14292                         lctl get_param llite.*.statahead_max
14293                         cancel_lru_locks mdc
14294                         cancel_lru_locks osc
14295                         stime=$(date +%s)
14296                         time $lsx $DIR/$tdir | wc -l
14297                         etime=$(date +%s)
14298                         delta=$((etime - stime))
14299                         log "$lsx $i files again without statahead: $delta sec"
14300                         lctl set_param llite.*.statahead_max=$max
14301                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
14302                                 if [ $SLOWOK -eq 0 ]; then
14303                                         error "$lsx $i files is slower with statahead!"
14304                                 else
14305                                         log "$lsx $i files is slower with statahead!"
14306                                 fi
14307                                 break
14308                         fi
14309                 fi
14310
14311                 [ $delta -gt 20 ] && break
14312                 [ $delta -gt 8 ] && MULT=$((50 / delta))
14313                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
14314         done
14315         log "$lsx done"
14316
14317         stime=$(date +%s)
14318         rm -r $DIR/$tdir
14319         sync
14320         etime=$(date +%s)
14321         delta=$((etime - stime))
14322         log "rm -r $DIR/$tdir/: $delta seconds"
14323         log "rm done"
14324         lctl get_param -n llite.*.statahead_stats
14325         $LCTL get_param mdc.*.batch_stats
14326 }
14327
14328 test_123aa() {
14329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14330
14331         test_123a_base "ls -l"
14332 }
14333 run_test 123aa "verify statahead work"
14334
14335 test_123ab() {
14336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14337
14338         statx_supported || skip_env "Test must be statx() syscall supported"
14339
14340         test_123a_base "$STATX -l"
14341 }
14342 run_test 123ab "verify statahead work by using statx"
14343
14344 test_123ac() {
14345         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14346
14347         statx_supported || skip_env "Test must be statx() syscall supported"
14348
14349         local rpcs_before
14350         local rpcs_after
14351         local agl_before
14352         local agl_after
14353
14354         cancel_lru_locks $OSC
14355         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14356         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
14357                      awk '/agl.total:/ { print $NF }')
14358         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
14359         test_123a_base "$STATX --cached=always -D"
14360         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
14361                     awk '/agl.total:/ { print $NF }')
14362         [ $agl_before -eq $agl_after ] ||
14363                 error "Should not trigger AGL thread - $agl_before:$agl_after"
14364         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14365         [ $rpcs_after -eq $rpcs_before ] ||
14366                 error "$STATX should not send glimpse RPCs to $OSC"
14367 }
14368 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
14369
14370 test_batch_statahead() {
14371         local max=$1
14372         local batch_max=$2
14373         local num=10000
14374         local batch_rpcs
14375         local unbatch_rpcs
14376         local hit_total
14377
14378         echo -e "\nbatching: statahead_max=$max statahead_batch_max=$batch_max"
14379         $LCTL set_param mdc.*.batch_stats=0
14380         $LCTL set_param llite.*.statahead_max=$max
14381         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14382         # Verify that batched statahead is faster than one without statahead
14383         test_123a_base "ls -l"
14384
14385         stack_trap "rm -rf $DIR/$tdir" EXIT
14386         mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
14387         createmany -o $DIR/$tdir/$tfile $num || error "failed to create files"
14388
14389         # unbatched statahead
14390         $LCTL set_param llite.*.statahead_batch_max=0
14391         $LCTL set_param llite.*.statahead_stats=clear
14392         $LCTL set_param mdc.*.stats=clear
14393         cancel_lru_locks mdc
14394         cancel_lru_locks osc
14395         time ls -l $DIR/$tdir | wc -l
14396         unbatch_rpcs=$(calc_stats mdc.*.stats ldlm_ibits_enqueue)
14397         wait_update_facet client "pgrep ll_sa" "" 35 ||
14398                 error "ll_sa thread is still running"
14399         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14400                     awk '/hit.total:/ { print $NF }')
14401         # hit ratio should be larger than 75% (7500).
14402         (( $hit_total > 7500 )) ||
14403                 error "unbatched statahead hit count ($hit_total) is too low"
14404
14405         # batched statahead
14406         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14407         $LCTL set_param llite.*.statahead_stats=clear
14408         $LCTL set_param mdc.*.batch_stats=clear
14409         $LCTL set_param mdc.*.stats=clear
14410         cancel_lru_locks mdc
14411         cancel_lru_locks osc
14412         time ls -l $DIR/$tdir | wc -l
14413         batch_rpcs=$(calc_stats mdc.*.stats mds_batch)
14414         # wait for statahead thread to quit and update statahead stats
14415         wait_update_facet client "pgrep ll_sa" "" 35 ||
14416                 error "ll_sa thread is still running"
14417         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14418                     awk '/hit.total:/ { print $NF }')
14419         # hit ratio should be larger than 75% (7500).
14420         (( $hit_total > 7500 )) ||
14421                 error "batched statahead hit count ($hit_total) is too low"
14422
14423         echo "unbatched RPCs: $unbatch_rpcs, batched RPCs: $batch_rpcs"
14424         (( $unbatch_rpcs > $batch_rpcs )) ||
14425                 error "batched statahead does not reduce RPC count"
14426         $LCTL get_param mdc.*.batch_stats
14427 }
14428
14429 test_123ad() {
14430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14431
14432         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
14433                 skip "Need server version at least 2.15.53"
14434
14435         local max
14436         local batch_max
14437
14438         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14439         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14440
14441         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14442         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14443
14444         test_batch_statahead 32 32
14445         test_batch_statahead 2048 256
14446 }
14447 run_test 123ad "Verify batching statahead works correctly"
14448
14449 test_123b () { # statahead(bug 15027)
14450         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14451
14452         test_mkdir $DIR/$tdir
14453         createmany -o $DIR/$tdir/$tfile-%d 1000
14454
14455         cancel_lru_locks mdc
14456         cancel_lru_locks osc
14457
14458 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
14459         lctl set_param fail_loc=0x80000803
14460         ls -lR $DIR/$tdir > /dev/null
14461         log "ls done"
14462         lctl set_param fail_loc=0x0
14463         lctl get_param -n llite.*.statahead_stats
14464         rm -r $DIR/$tdir
14465         sync
14466
14467 }
14468 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
14469
14470 test_123c() {
14471         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
14472
14473         test_mkdir -i 0 -c 1 $DIR/$tdir.0
14474         test_mkdir -i 1 -c 1 $DIR/$tdir.1
14475         touch $DIR/$tdir.1/{1..3}
14476         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
14477
14478         remount_client $MOUNT
14479
14480         $MULTIOP $DIR/$tdir.0 Q
14481
14482         # let statahead to complete
14483         ls -l $DIR/$tdir.0 > /dev/null
14484
14485         testid=$(echo $TESTNAME | tr '_' ' ')
14486         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
14487                 error "statahead warning" || true
14488 }
14489 run_test 123c "Can not initialize inode warning on DNE statahead"
14490
14491 test_123d() {
14492         local num=100
14493         local swrong
14494         local ewrong
14495
14496         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
14497         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
14498                 error "setdirstripe $DIR/$tdir failed"
14499         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
14500         remount_client $MOUNT
14501         $LCTL get_param llite.*.statahead_max
14502         $LCTL set_param llite.*.statahead_stats=0 ||
14503                 error "clear statahead_stats failed"
14504         swrong=$(lctl get_param -n llite.*.statahead_stats |
14505                  awk '/statahead.wrong:/ { print $NF }')
14506         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
14507         # wait for statahead thread finished to update hit/miss stats.
14508         sleep 1
14509         $LCTL get_param -n llite.*.statahead_stats
14510         ewrong=$(lctl get_param -n llite.*.statahead_stats |
14511                  awk '/statahead.wrong:/ { print $NF }')
14512         (( $swrong == $ewrong )) ||
14513                 log "statahead was stopped, maybe too many locks held!"
14514 }
14515 run_test 123d "Statahead on striped directories works correctly"
14516
14517 test_123e() {
14518         local max
14519         local batch_max
14520         local dir=$DIR/$tdir
14521
14522         mkdir $dir || error "mkdir $dir failed"
14523         $LFS setstripe -C 32 $dir || error "setstripe $dir failed"
14524         stack_trap "rm -rf $dir"
14525
14526         touch $dir/$tfile.{0..1000} || error "touch 1000 files failed"
14527
14528         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14529         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14530         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14531         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14532
14533         $LCTL set_param llite.*.statahead_max=2048
14534         $LCTL set_param llite.*.statahead_batch_max=1024
14535
14536         ls -l $dir
14537         $LCTL get_param mdc.*.batch_stats
14538         $LCTL get_param llite.*.statahead_*
14539 }
14540 run_test 123e "statahead with large wide striping"
14541
14542 test_123f() {
14543         local max
14544         local batch_max
14545         local dir=$DIR/$tdir
14546
14547         mkdir $dir || error "mkdir $dir failed"
14548         $LFS setstripe -C 1000 $dir || error "setstripe $dir failed"
14549         stack_trap "rm -rf $dir"
14550
14551         touch $dir/$tfile.{0..200} || error "touch 200 files failed"
14552
14553         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14554         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14555
14556         $LCTL set_param llite.*.statahead_max=64
14557         $LCTL set_param llite.*.statahead_batch_max=64
14558
14559         ls -l $dir
14560         lctl get_param mdc.*.batch_stats
14561         lctl get_param llite.*.statahead_*
14562
14563         $LCTL set_param llite.*.statahead_max=$max
14564         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14565 }
14566 run_test 123f "Retry mechanism with large wide striping files"
14567
14568 test_123g() {
14569         local dir=$DIR/$tdir
14570         local num=1000
14571
14572         mkdir $dir || error "failed to mkdir $dir"
14573         createmany -o $dir/$tfile $num || error "failed creatmany files"
14574         cancel_lru_locks mdc
14575         cancel_lru_locks osc
14576
14577         $LCTL set_param llite.*.statahead_stats=clear
14578         $LCTL set_param mdc.*.batch_stats=clear
14579         aheadmany -c stat -s 0 -e $num -b $tfile -d $dir ||
14580                 error "aheadmany $dir with $tfile failed"
14581         wait_update_facet client "pgrep ll_sa" "" 35 ||
14582                 error "ll_sa thread is still running"
14583         $LCTL get_param -n llite.*.statahead_stats
14584         $LCTL get_param -n mdc.*.batch_stats
14585
14586         local count
14587
14588         count=$($LCTL get_param -n llite.*.statahead_stats |
14589                 awk '/hit.total:/ {print $2}')
14590         echo "Hit total: $count"
14591         # Hit ratio should be >= 75%
14592         (( $count > num * 75 / 100 )) ||
14593                 error "hit total $count is be > 75% of $num"
14594 }
14595 run_test 123g "Test for stat-ahead advise"
14596
14597 test_123h_base() {
14598         local dir=$DIR/$tdir
14599         local cmd="touch $dir/$tfile.{$1}"
14600         local fcnt=$2
14601
14602         stack_trap "rm -rf $dir"
14603         mkdir -p $dir || error "failed to mkdir $dir"
14604         eval $cmd
14605
14606         cancel_lru_locks mdc
14607         $LCTL set_param llite.*.statahead_stats=clear
14608         $LCTL set_param mdc.*.batch_stats=0
14609         $LCTL set_param llite.*.statahead_max=1024
14610         $LCTL set_param llite.*.statahead_batch_max=1024
14611         lctl get_param -n llite.*.statahead_stats
14612         du -a $dir > /dev/null
14613         echo "Wait statahead thread (ll_sa_xxx) to exit..."
14614         wait_update_facet client "pgrep ll_sa" "" 35 ||
14615                 error "ll_sa statahead thread does not quit in 35s"
14616         $LCTL get_param -n llite.*.statahead_stats
14617         $LCTL get_param -n mdc.*.batch_stats
14618
14619         local count=$($LCTL get_param -n llite.*.statahead_stats |
14620                         awk '/fname.total:/ {print $2}')
14621
14622         [ $count == 1 ] || error "File name pattern statahead not trigger"
14623         count=$($LCTL get_param -n llite.*.statahead_stats |
14624                 awk '/hit.total:/ {print $2}')
14625         # Hit ratio should be >= 75%
14626         (( $count > fcnt * 75 / 100 )) ||
14627                 error "hit total is too low: $count"
14628         rm -rf $dir || error "rm -rf $dir failed"
14629 }
14630
14631 test_123h() {
14632         local max
14633         local batch_max
14634         local enabled
14635
14636         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14637         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14638         enabled=$($LCTL get_param -n llite.*.enable_statahead_fname | head -n 1)
14639         stack_trap "$LCTL set_param llite.*.statahead_max=$max"
14640         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max"
14641         stack_trap "$LCTL set_param llite.*.enable_statahead_fname=$enabled"
14642
14643         $LCTL set_param llite.*.enable_statahead_fname=1
14644
14645         echo "Scan a directory with number regularized fname"
14646         test_123h_base "0..10000" 10000
14647
14648         echo "Scan a directory with zeroed padding number regularized fname"
14649         test_123h_base "000000..010000" 10000
14650 }
14651 run_test 123h "Verify statahead work with the fname pattern via du"
14652
14653 test_123i_base() {
14654         local fmt=$1
14655         local iocmd=$2
14656         local dir=$DIR/$tdir
14657         local cmd="createmany -m $fmt"
14658
14659         echo "Command:"
14660         echo "- $cmd"
14661         echo "- $iocmd"
14662         stack_trap "unlinkmany $fmt"
14663         mkdir -p $dir || error "failed to mkdir $dir"
14664         eval $cmd
14665
14666         cancel_lru_locks mdc
14667         $LCTL set_param llite.*.statahead_stats=clear
14668         $LCTL set_param mdc.*.batch_stats=0
14669
14670         echo "statahead_stats (Pre):"
14671         lctl get_param -n llite.*.statahead_stats
14672         eval $iocmd || error "$iocmd failed"
14673         echo "statahead_stats (Post):"
14674         $LCTL get_param -n llite.*.statahead_stats
14675         $LCTL get_param -n mdc.*.batch_stats
14676
14677         echo "Wait the statahead thread (ll_sa_xxx) to exit ..."
14678         wait_update_facet client "pgrep ll_sa" "" 35 ||
14679                 error "ll_sa statahead thread does not quit in 35s"
14680         $LCTL get_param -n llite.*.statahead_stats
14681         $LCTL get_param -n mdc.*.batch_stats
14682
14683         local count=$($LCTL get_param -n llite.*.statahead_stats |
14684                         awk '/fname.total:/ {print $2}')
14685
14686         [ $count == 1 ] || error "File name pattern statahead not trigger"
14687         count=$($LCTL get_param -n llite.*.statahead_stats |
14688                 awk '/hit.total:/ {print $2}')
14689         # Hit ratio should be >= 75%
14690         (( $count > 750 )) || error "hit total is too low: $count"
14691 }
14692
14693 test_123i() {
14694         local dir=$DIR/$tdir
14695         local cnt=1000
14696         local max
14697         local batch_max
14698         local enabled
14699         local min
14700
14701         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14702         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14703         min=$($LCTL get_param -n llite.*.statahead_min | head -n 1)
14704         enabled=$($LCTL get_param -n llite.*.enable_statahead_fname | head -n 1)
14705         stack_trap "$LCTL set_param llite.*.statahead_max=$max"
14706         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max"
14707         stack_trap "$LCTL set_param llite.*.statahead_min=$min"
14708         stack_trap "$LCTL set_param llite.*.enable_statahead_fname=$enabled"
14709         $LCTL set_param llite.*.statahead_max=1024
14710         $LCTL set_param llite.*.statahead_batch_max=32
14711         $LCTL set_param llite.*.statahead_min=64
14712         $LCTL set_param llite.*.enable_statahead_fname=1
14713
14714         test_123i_base "$dir/$tfile.%06d $cnt" "ls $dir/* > /dev/null"
14715         test_123i_base "$dir/$tfile $cnt" \
14716                 "aheadmany -c stat -N -s 0 -e $cnt -b $tfile -d $dir"
14717 }
14718 run_test 123i "Verify statahead work with the fname indexing pattern"
14719
14720 test_124a() {
14721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14722         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14723                 skip_env "no lru resize on server"
14724
14725         local NR=2000
14726
14727         test_mkdir $DIR/$tdir
14728
14729         log "create $NR files at $DIR/$tdir"
14730         createmany -o $DIR/$tdir/f $NR ||
14731                 error "failed to create $NR files in $DIR/$tdir"
14732
14733         cancel_lru_locks mdc
14734         ls -l $DIR/$tdir > /dev/null
14735
14736         local NSDIR=""
14737         local LRU_SIZE=0
14738         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
14739                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
14740                 LRU_SIZE=$($LCTL get_param -n $PARAM)
14741                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
14742                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
14743                         log "NSDIR=$NSDIR"
14744                         log "NS=$(basename $NSDIR)"
14745                         break
14746                 fi
14747         done
14748
14749         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
14750                 skip "Not enough cached locks created!"
14751         fi
14752         log "LRU=$LRU_SIZE"
14753
14754         local SLEEP=30
14755
14756         # We know that lru resize allows one client to hold $LIMIT locks
14757         # for 10h. After that locks begin to be killed by client.
14758         local MAX_HRS=10
14759         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
14760         log "LIMIT=$LIMIT"
14761         if [ $LIMIT -lt $LRU_SIZE ]; then
14762                 skip "Limit is too small $LIMIT"
14763         fi
14764
14765         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
14766         # killing locks. Some time was spent for creating locks. This means
14767         # that up to the moment of sleep finish we must have killed some of
14768         # them (10-100 locks). This depends on how fast ther were created.
14769         # Many of them were touched in almost the same moment and thus will
14770         # be killed in groups.
14771         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
14772
14773         # Use $LRU_SIZE_B here to take into account real number of locks
14774         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
14775         local LRU_SIZE_B=$LRU_SIZE
14776         log "LVF=$LVF"
14777         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
14778         log "OLD_LVF=$OLD_LVF"
14779         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
14780
14781         # Let's make sure that we really have some margin. Client checks
14782         # cached locks every 10 sec.
14783         SLEEP=$((SLEEP+20))
14784         log "Sleep ${SLEEP} sec"
14785         local SEC=0
14786         while ((SEC<$SLEEP)); do
14787                 echo -n "..."
14788                 sleep 5
14789                 SEC=$((SEC+5))
14790                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
14791                 echo -n "$LRU_SIZE"
14792         done
14793         echo ""
14794         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
14795         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
14796
14797         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
14798                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
14799                 unlinkmany $DIR/$tdir/f $NR
14800                 return
14801         }
14802
14803         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
14804         log "unlink $NR files at $DIR/$tdir"
14805         unlinkmany $DIR/$tdir/f $NR
14806 }
14807 run_test 124a "lru resize ======================================="
14808
14809 get_max_pool_limit()
14810 {
14811         local limit=$($LCTL get_param \
14812                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
14813         local max=0
14814         for l in $limit; do
14815                 if [[ $l -gt $max ]]; then
14816                         max=$l
14817                 fi
14818         done
14819         echo $max
14820 }
14821
14822 test_124b() {
14823         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14824         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14825                 skip_env "no lru resize on server"
14826
14827         LIMIT=$(get_max_pool_limit)
14828
14829         NR=$(($(default_lru_size)*20))
14830         if [[ $NR -gt $LIMIT ]]; then
14831                 log "Limit lock number by $LIMIT locks"
14832                 NR=$LIMIT
14833         fi
14834
14835         IFree=$(mdsrate_inodes_available)
14836         if [ $IFree -lt $NR ]; then
14837                 log "Limit lock number by $IFree inodes"
14838                 NR=$IFree
14839         fi
14840
14841         lru_resize_disable mdc
14842         test_mkdir -p $DIR/$tdir/disable_lru_resize
14843
14844         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
14845         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
14846         cancel_lru_locks mdc
14847         stime=`date +%s`
14848         PID=""
14849         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14850         PID="$PID $!"
14851         sleep 2
14852         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14853         PID="$PID $!"
14854         sleep 2
14855         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14856         PID="$PID $!"
14857         wait $PID
14858         etime=`date +%s`
14859         nolruresize_delta=$((etime-stime))
14860         log "ls -la time: $nolruresize_delta seconds"
14861         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14862         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
14863
14864         lru_resize_enable mdc
14865         test_mkdir -p $DIR/$tdir/enable_lru_resize
14866
14867         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
14868         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
14869         cancel_lru_locks mdc
14870         stime=`date +%s`
14871         PID=""
14872         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14873         PID="$PID $!"
14874         sleep 2
14875         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14876         PID="$PID $!"
14877         sleep 2
14878         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14879         PID="$PID $!"
14880         wait $PID
14881         etime=`date +%s`
14882         lruresize_delta=$((etime-stime))
14883         log "ls -la time: $lruresize_delta seconds"
14884         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14885
14886         if [ $lruresize_delta -gt $nolruresize_delta ]; then
14887                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
14888         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
14889                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
14890         else
14891                 log "lru resize performs the same with no lru resize"
14892         fi
14893         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
14894 }
14895 run_test 124b "lru resize (performance test) ======================="
14896
14897 test_124c() {
14898         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14899         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14900                 skip_env "no lru resize on server"
14901
14902         # cache ununsed locks on client
14903         local nr=100
14904         cancel_lru_locks mdc
14905         test_mkdir $DIR/$tdir
14906         createmany -o $DIR/$tdir/f $nr ||
14907                 error "failed to create $nr files in $DIR/$tdir"
14908         ls -l $DIR/$tdir > /dev/null
14909
14910         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14911         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14912         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14913         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14914         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14915
14916         # set lru_max_age to 1 sec
14917         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14918         echo "sleep $((recalc_p * 2)) seconds..."
14919         sleep $((recalc_p * 2))
14920
14921         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14922         # restore lru_max_age
14923         $LCTL set_param -n $nsdir.lru_max_age $max_age
14924         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14925         unlinkmany $DIR/$tdir/f $nr
14926 }
14927 run_test 124c "LRUR cancel very aged locks"
14928
14929 test_124d() {
14930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14931         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14932                 skip_env "no lru resize on server"
14933
14934         # cache ununsed locks on client
14935         local nr=100
14936
14937         lru_resize_disable mdc
14938         stack_trap "lru_resize_enable mdc" EXIT
14939
14940         cancel_lru_locks mdc
14941
14942         # asynchronous object destroy at MDT could cause bl ast to client
14943         test_mkdir $DIR/$tdir
14944         createmany -o $DIR/$tdir/f $nr ||
14945                 error "failed to create $nr files in $DIR/$tdir"
14946         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
14947
14948         ls -l $DIR/$tdir > /dev/null
14949
14950         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14951         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14952         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14953         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14954
14955         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14956
14957         # set lru_max_age to 1 sec
14958         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14959         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
14960
14961         echo "sleep $((recalc_p * 2)) seconds..."
14962         sleep $((recalc_p * 2))
14963
14964         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14965
14966         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14967 }
14968 run_test 124d "cancel very aged locks if lru-resize disabled"
14969
14970 test_125() { # 13358
14971         $LCTL get_param -n llite.*.client_type | grep -q local ||
14972                 skip "must run as local client"
14973         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
14974                 skip_env "must have acl enabled"
14975         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14976         id $USER0 || skip_env "missing user $USER0"
14977
14978         test_mkdir $DIR/$tdir
14979         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
14980         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
14981                 error "setfacl $DIR/$tdir failed"
14982         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
14983 }
14984 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
14985
14986 test_126() { # bug 12829/13455
14987         $GSS && skip_env "must run as gss disabled"
14988         $LCTL get_param -n llite.*.client_type | grep -q local ||
14989                 skip "must run as local client"
14990         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
14991
14992         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
14993         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
14994         rm -f $DIR/$tfile
14995         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
14996 }
14997 run_test 126 "check that the fsgid provided by the client is taken into account"
14998
14999 test_127a() { # bug 15521
15000         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15001         local name count samp unit min max sum sumsq
15002         local tmpfile=$TMP/$tfile.tmp
15003
15004         # enable stats header if it is disabled
15005         $LCTL set_param enable_stats_header=1
15006
15007         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
15008         echo "stats before reset"
15009         stack_trap "rm -f $tmpfile"
15010         local now=$(date +%s)
15011
15012         $LCTL get_param osc.*.stats | tee $tmpfile
15013
15014         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
15015         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
15016         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
15017         local uptime=$(awk '{ print $1 }' /proc/uptime)
15018
15019         # snapshot_time should match POSIX epoch time, allow some delta for VMs
15020         (( ${snapshot_time%\.*} >= $now - 5 &&
15021            ${snapshot_time%\.*} <= $now + 5 )) ||
15022                 error "snapshot_time=$snapshot_time != now=$now"
15023         # elapsed _should_ be from mount, but at least less than uptime
15024         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
15025                 error "elapsed=$elapsed > uptime=$uptime"
15026         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
15027            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
15028                 error "elapsed=$elapsed != $snapshot_time - $start_time"
15029
15030         $LCTL set_param osc.*.stats=0
15031         local reset=$(date +%s)
15032         local fsize=$((2048 * 1024))
15033
15034         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
15035         cancel_lru_locks osc
15036         dd if=$DIR/$tfile of=/dev/null bs=$fsize
15037
15038         now=$(date +%s)
15039         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
15040         while read name count samp unit min max sum sumsq; do
15041                 [[ "$samp" == "samples" ]] || continue
15042
15043                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
15044                 [ ! $min ] && error "Missing min value for $name proc entry"
15045                 eval $name=$count || error "Wrong proc format"
15046
15047                 case $name in
15048                 read_bytes|write_bytes)
15049                         [[ "$unit" =~ "bytes" ]] ||
15050                                 error "unit is not 'bytes': $unit"
15051                         (( $min >= 4096 )) || error "min is too small: $min"
15052                         (( $min <= $fsize )) || error "min is too big: $min"
15053                         (( $max >= 4096 )) || error "max is too small: $max"
15054                         (( $max <= $fsize )) || error "max is too big: $max"
15055                         (( $sum == $fsize )) || error "sum is wrong: $sum"
15056                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
15057                                 error "sumsquare is too small: $sumsq"
15058                         (( $sumsq <= $fsize * $fsize )) ||
15059                                 error "sumsquare is too big: $sumsq"
15060                         ;;
15061                 ost_read|ost_write)
15062                         [[ "$unit" =~ "usec" ]] ||
15063                                 error "unit is not 'usec': $unit"
15064                         ;;
15065                 *)      ;;
15066                 esac
15067         done < $tmpfile
15068
15069         #check that we actually got some stats
15070         [ "$read_bytes" ] || error "Missing read_bytes stats"
15071         [ "$write_bytes" ] || error "Missing write_bytes stats"
15072         [ "$read_bytes" != 0 ] || error "no read done"
15073         [ "$write_bytes" != 0 ] || error "no write done"
15074
15075         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
15076         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
15077         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
15078
15079         # snapshot_time should match POSIX epoch time, allow some delta for VMs
15080         (( ${snapshot_time%\.*} >= $now - 5 &&
15081            ${snapshot_time%\.*} <= $now + 5 )) ||
15082                 error "reset snapshot_time=$snapshot_time != now=$now"
15083         # elapsed should be from time of stats reset
15084         (( ${elapsed%\.*} >= $now - $reset - 2 &&
15085            ${elapsed%\.*} <= $now - $reset + 2 )) ||
15086                 error "reset elapsed=$elapsed > $now - $reset"
15087         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
15088            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
15089                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
15090 }
15091 run_test 127a "verify the client stats are sane"
15092
15093 test_127b() { # bug LU-333
15094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15095         local name count samp unit min max sum sumsq
15096
15097         echo "stats before reset"
15098         $LCTL get_param llite.*.stats
15099         $LCTL set_param llite.*.stats=0
15100
15101         # perform 2 reads and writes so MAX is different from SUM.
15102         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
15103         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
15104         cancel_lru_locks osc
15105         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
15106         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
15107
15108         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
15109         stack_trap "rm -f $TMP/$tfile.tmp"
15110         while read name count samp unit min max sum sumsq; do
15111                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
15112                 eval $name=$count || error "Wrong proc format"
15113
15114                 case $name in
15115                 read_bytes|write_bytes)
15116                         [[ "$unit" =~ "bytes" ]] ||
15117                                 error "unit is not 'bytes': $unit"
15118                         (( $count == 2 )) || error "count is not 2: $count"
15119                         (( $min == $PAGE_SIZE )) ||
15120                                 error "min is not $PAGE_SIZE: $min"
15121                         (( $max == $PAGE_SIZE )) ||
15122                                 error "max is not $PAGE_SIZE: $max"
15123                         (( $sum == $PAGE_SIZE * 2 )) ||
15124                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
15125                         ;;
15126                 read|write)
15127                         [[ "$unit" =~ "usec" ]] ||
15128                                 error "unit is not 'usec': $unit"
15129                         ;;
15130                 *)      ;;
15131                 esac
15132         done < $TMP/$tfile.tmp
15133
15134         #check that we actually got some stats
15135         [ "$read_bytes" ] || error "Missing read_bytes stats"
15136         [ "$write_bytes" ] || error "Missing write_bytes stats"
15137         [ "$read_bytes" != 0 ] || error "no read done"
15138         [ "$write_bytes" != 0 ] || error "no write done"
15139 }
15140 run_test 127b "verify the llite client stats are sane"
15141
15142 test_127c() { # LU-12394
15143         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
15144         local size
15145         local bsize
15146         local reads
15147         local writes
15148         local count
15149
15150         $LCTL set_param llite.*.extents_stats=1
15151         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
15152
15153         # Use two stripes so there is enough space in default config
15154         $LFS setstripe -c 2 $DIR/$tfile
15155
15156         # Extent stats start at 0-4K and go in power of two buckets
15157         # LL_HIST_START = 12 --> 2^12 = 4K
15158         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
15159         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
15160         # small configs
15161         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
15162                 do
15163                 # Write and read, 2x each, second time at a non-zero offset
15164                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
15165                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
15166                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
15167                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
15168                 rm -f $DIR/$tfile
15169         done
15170
15171         $LCTL get_param llite.*.extents_stats
15172
15173         count=2
15174         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
15175                 do
15176                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
15177                                 grep -m 1 $bsize)
15178                 reads=$(echo $bucket | awk '{print $5}')
15179                 writes=$(echo $bucket | awk '{print $9}')
15180                 [ "$reads" -eq $count ] ||
15181                         error "$reads reads in < $bsize bucket, expect $count"
15182                 [ "$writes" -eq $count ] ||
15183                         error "$writes writes in < $bsize bucket, expect $count"
15184         done
15185
15186         # Test mmap write and read
15187         $LCTL set_param llite.*.extents_stats=c
15188         size=512
15189         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
15190         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
15191         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
15192
15193         $LCTL get_param llite.*.extents_stats
15194
15195         count=$(((size*1024) / PAGE_SIZE))
15196
15197         bsize=$((2 * PAGE_SIZE / 1024))K
15198
15199         bucket=$($LCTL get_param -n llite.*.extents_stats |
15200                         grep -m 1 $bsize)
15201         reads=$(echo $bucket | awk '{print $5}')
15202         writes=$(echo $bucket | awk '{print $9}')
15203         # mmap writes fault in the page first, creating an additonal read
15204         [ "$reads" -eq $((2 * count)) ] ||
15205                 error "$reads reads in < $bsize bucket, expect $count"
15206         [ "$writes" -eq $count ] ||
15207                 error "$writes writes in < $bsize bucket, expect $count"
15208 }
15209 run_test 127c "test llite extent stats with regular & mmap i/o"
15210
15211 test_128() { # bug 15212
15212         touch $DIR/$tfile
15213         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
15214                 find $DIR/$tfile
15215                 find $DIR/$tfile
15216         EOF
15217
15218         result=$(grep error $TMP/$tfile.log)
15219         rm -f $DIR/$tfile $TMP/$tfile.log
15220         [ -z "$result" ] ||
15221                 error "consecutive find's under interactive lfs failed"
15222 }
15223 run_test 128 "interactive lfs for 2 consecutive find's"
15224
15225 set_dir_limits () {
15226         local mntdev
15227         local canondev
15228         local node
15229
15230         local ldproc=/proc/fs/ldiskfs
15231         local facets=$(get_facets MDS)
15232
15233         for facet in ${facets//,/ }; do
15234                 canondev=$(ldiskfs_canon \
15235                            *.$(convert_facet2label $facet).mntdev $facet)
15236                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
15237                         ldproc=/sys/fs/ldiskfs
15238                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
15239                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
15240         done
15241 }
15242
15243 check_mds_dmesg() {
15244         local facets=$(get_facets MDS)
15245         for facet in ${facets//,/ }; do
15246                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
15247         done
15248         return 1
15249 }
15250
15251 test_129() {
15252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15253         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
15254                 skip "Need MDS version with at least 2.5.56"
15255         if [ "$mds1_FSTYPE" != ldiskfs ]; then
15256                 skip_env "ldiskfs only test"
15257         fi
15258         remote_mds_nodsh && skip "remote MDS with nodsh"
15259
15260         local ENOSPC=28
15261         local has_warning=false
15262
15263         rm -rf $DIR/$tdir
15264         mkdir -p $DIR/$tdir
15265
15266         # block size of mds1
15267         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
15268         set_dir_limits $maxsize $((maxsize * 6 / 8))
15269         stack_trap "set_dir_limits 0 0"
15270         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
15271         local dirsize=$(stat -c%s "$DIR/$tdir")
15272         local nfiles=0
15273         while (( $dirsize <= $maxsize )); do
15274                 $MCREATE $DIR/$tdir/file_base_$nfiles
15275                 rc=$?
15276                 # check two errors:
15277                 # ENOSPC for ext4 max_dir_size, which has been used since
15278                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
15279                 if (( rc == ENOSPC )); then
15280                         set_dir_limits 0 0
15281                         echo "rc=$rc returned as expected after $nfiles files"
15282
15283                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
15284                                 error "create failed w/o dir size limit"
15285
15286                         # messages may be rate limited if test is run repeatedly
15287                         check_mds_dmesg '"is approaching max"' ||
15288                                 echo "warning message should be output"
15289                         check_mds_dmesg '"has reached max"' ||
15290                                 echo "reached message should be output"
15291
15292                         dirsize=$(stat -c%s "$DIR/$tdir")
15293
15294                         [[ $dirsize -ge $maxsize ]] && return 0
15295                         error "dirsize $dirsize < $maxsize after $nfiles files"
15296                 elif (( rc != 0 )); then
15297                         break
15298                 fi
15299                 nfiles=$((nfiles + 1))
15300                 dirsize=$(stat -c%s "$DIR/$tdir")
15301         done
15302
15303         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
15304 }
15305 run_test 129 "test directory size limit ========================"
15306
15307 OLDIFS="$IFS"
15308 cleanup_130() {
15309         trap 0
15310         IFS="$OLDIFS"
15311         rm -f $DIR/$tfile
15312 }
15313
15314 test_130a() {
15315         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
15316         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
15317
15318         trap cleanup_130 EXIT RETURN
15319
15320         local fm_file=$DIR/$tfile
15321         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
15322         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
15323                 error "dd failed for $fm_file"
15324
15325         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
15326         filefrag -ves $fm_file
15327         local rc=$?
15328         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15329                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15330         (( $rc == 0 )) || error "filefrag $fm_file failed"
15331
15332         filefrag_op=$(filefrag -ve -k $fm_file |
15333                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15334         local lun=$($LFS getstripe -i $fm_file)
15335
15336         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
15337         IFS=$'\n'
15338         local tot_len=0
15339         for line in $filefrag_op; do
15340                 local frag_lun=$(echo $line | cut -d: -f5)
15341                 local ext_len=$(echo $line | cut -d: -f4)
15342
15343                 if (( $frag_lun != $lun )); then
15344                         error "FIEMAP on 1-stripe file($fm_file) failed"
15345                         return
15346                 fi
15347                 (( tot_len += ext_len ))
15348         done
15349
15350         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
15351                 error "FIEMAP on 1-stripe file($fm_file) failed"
15352                 return
15353         fi
15354
15355         echo "FIEMAP on single striped file succeeded"
15356 }
15357 run_test 130a "FIEMAP (1-stripe file)"
15358
15359 test_130b() {
15360         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15361
15362         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15363         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15364         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15365                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15366
15367         trap cleanup_130 EXIT RETURN
15368
15369         local fm_file=$DIR/$tfile
15370         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15371                 error "setstripe on $fm_file"
15372
15373         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
15374                 error "dd failed on $fm_file"
15375
15376         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15377         filefrag_op=$(filefrag -ve -k $fm_file |
15378                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15379
15380         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15381                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15382
15383         IFS=$'\n'
15384         local tot_len=0
15385         local num_luns=1
15386
15387         for line in $filefrag_op; do
15388                 local frag_lun=$(echo $line | cut -d: -f5 |
15389                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15390                 local ext_len=$(echo $line | cut -d: -f4)
15391                 if (( $frag_lun != $last_lun )); then
15392                         if (( tot_len != 1024 )); then
15393                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15394                                 return
15395                         else
15396                                 (( num_luns += 1 ))
15397                                 tot_len=0
15398                         fi
15399                 fi
15400                 (( tot_len += ext_len ))
15401                 last_lun=$frag_lun
15402         done
15403         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
15404                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15405                 return
15406         fi
15407
15408         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
15409 }
15410 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
15411
15412 test_130c() {
15413         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15414
15415         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15416         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15417         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15418                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15419
15420         trap cleanup_130 EXIT RETURN
15421
15422         local fm_file=$DIR/$tfile
15423         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
15424
15425         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
15426                 error "dd failed on $fm_file"
15427
15428         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15429         filefrag_op=$(filefrag -ve -k $fm_file |
15430                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15431
15432         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15433                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15434
15435         IFS=$'\n'
15436         local tot_len=0
15437         local num_luns=1
15438         for line in $filefrag_op; do
15439                 local frag_lun=$(echo $line | cut -d: -f5 |
15440                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15441                 local ext_len=$(echo $line | cut -d: -f4)
15442                 if (( $frag_lun != $last_lun )); then
15443                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
15444                         if (( logical != 512 )); then
15445                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
15446                                 return
15447                         fi
15448                         if (( tot_len != 512 )); then
15449                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15450                                 return
15451                         else
15452                                 (( num_luns += 1 ))
15453                                 tot_len=0
15454                         fi
15455                 fi
15456                 (( tot_len += ext_len ))
15457                 last_lun=$frag_lun
15458         done
15459         if (( num_luns != 2 || tot_len != 512 )); then
15460                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15461                 return
15462         fi
15463
15464         echo "FIEMAP on 2-stripe file with hole succeeded"
15465 }
15466 run_test 130c "FIEMAP (2-stripe file with hole)"
15467
15468 test_130d() {
15469         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
15470
15471         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15472         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15473         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15474                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15475
15476         trap cleanup_130 EXIT RETURN
15477
15478         local fm_file=$DIR/$tfile
15479         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15480                         error "setstripe on $fm_file"
15481
15482         local actual_stripe_count=$($LFS getstripe -c $fm_file)
15483         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
15484                 error "dd failed on $fm_file"
15485
15486         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15487         filefrag_op=$(filefrag -ve -k $fm_file |
15488                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15489
15490         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15491                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15492
15493         IFS=$'\n'
15494         local tot_len=0
15495         local num_luns=1
15496         for line in $filefrag_op; do
15497                 local frag_lun=$(echo $line | cut -d: -f5 |
15498                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15499                 local ext_len=$(echo $line | cut -d: -f4)
15500                 if (( $frag_lun != $last_lun )); then
15501                         if (( tot_len != 1024 )); then
15502                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15503                                 return
15504                         else
15505                                 (( num_luns += 1 ))
15506                                 local tot_len=0
15507                         fi
15508                 fi
15509                 (( tot_len += ext_len ))
15510                 last_lun=$frag_lun
15511         done
15512         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
15513                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15514                 return
15515         fi
15516
15517         echo "FIEMAP on N-stripe file succeeded"
15518 }
15519 run_test 130d "FIEMAP (N-stripe file)"
15520
15521 test_130e() {
15522         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15523
15524         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15525         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15526         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15527                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15528
15529         trap cleanup_130 EXIT RETURN
15530
15531         local fm_file=$DIR/$tfile
15532         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
15533         stack_trap "rm -f $fm_file"
15534
15535         local num_blks=512
15536         local expected_len=$(( (num_blks / 2) * 64 ))
15537         for ((i = 0; i < $num_blks; i++)); do
15538                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
15539                         conv=notrunc > /dev/null 2>&1
15540         done
15541
15542         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15543         filefrag_op=$(filefrag -ve -k $fm_file |
15544                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15545
15546         local last_lun=$(echo $filefrag_op | cut -d: -f5)
15547
15548         IFS=$'\n'
15549         local tot_len=0
15550         local num_luns=1
15551         for line in $filefrag_op; do
15552                 local frag_lun=$(echo $line | cut -d: -f5)
15553                 local ext_len=$(echo $line | cut -d: -f4)
15554                 if (( $frag_lun != $last_lun )); then
15555                         if (( tot_len != $expected_len )); then
15556                                 error "OST$last_lun $tot_len != $expected_len"
15557                         else
15558                                 (( num_luns += 1 ))
15559                                 tot_len=0
15560                         fi
15561                 fi
15562                 (( tot_len += ext_len ))
15563                 last_lun=$frag_lun
15564         done
15565         if (( num_luns != 2 || tot_len != $expected_len )); then
15566                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
15567         fi
15568
15569         echo "FIEMAP with continuation calls succeeded"
15570 }
15571 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
15572
15573 test_130f() {
15574         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15575         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15576         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15577                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15578
15579         local fm_file=$DIR/$tfile
15580         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
15581                 error "multiop create with lov_delay_create on $fm_file"
15582
15583         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15584         filefrag_extents=$(filefrag -vek $fm_file |
15585                            awk '/extents? found/ { print $2 }')
15586         if (( $filefrag_extents != 0 )); then
15587                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
15588         fi
15589
15590         rm -f $fm_file
15591 }
15592 run_test 130f "FIEMAP (unstriped file)"
15593
15594 test_130g() {
15595         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
15596                 skip "Need MDS version with at least 2.12.53 for overstriping"
15597         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15598         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15599         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15600                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15601
15602         local file=$DIR/$tfile
15603         local nr=$((OSTCOUNT * 100))
15604
15605         $LFS setstripe -C $nr -S1M $file ||
15606                 error "failed to setstripe -C $nr $file"
15607
15608         stack_trap "rm -f $file"
15609         dd if=/dev/zero of=$file count=$nr bs=1M
15610         sync
15611         nr=$($LFS getstripe -c $file)
15612
15613         local extents=$(filefrag -v $file |
15614                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
15615
15616         echo "filefrag list $extents extents in file with stripecount $nr"
15617         if (( extents < nr )); then
15618                 $LFS getstripe $file
15619                 filefrag -v $file
15620                 error "filefrag printed $extents < $nr extents"
15621         fi
15622 }
15623 run_test 130g "FIEMAP (overstripe file)"
15624
15625 # Test for writev/readv
15626 test_131a() {
15627         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
15628                 error "writev test failed"
15629         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
15630                 error "readv failed"
15631         rm -f $DIR/$tfile
15632 }
15633 run_test 131a "test iov's crossing stripe boundary for writev/readv"
15634
15635 test_131b() {
15636         local fsize=$((524288 + 1048576 + 1572864))
15637         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
15638                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15639                         error "append writev test failed"
15640
15641         ((fsize += 1572864 + 1048576))
15642         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
15643                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15644                         error "append writev test failed"
15645         rm -f $DIR/$tfile
15646 }
15647 run_test 131b "test append writev"
15648
15649 test_131c() {
15650         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
15651         error "NOT PASS"
15652 }
15653 run_test 131c "test read/write on file w/o objects"
15654
15655 test_131d() {
15656         rwv -f $DIR/$tfile -w -n 1 1572864
15657         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
15658         if [ "$NOB" != 1572864 ]; then
15659                 error "Short read filed: read $NOB bytes instead of 1572864"
15660         fi
15661         rm -f $DIR/$tfile
15662 }
15663 run_test 131d "test short read"
15664
15665 test_131e() {
15666         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
15667         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
15668         error "read hitting hole failed"
15669         rm -f $DIR/$tfile
15670 }
15671 run_test 131e "test read hitting hole"
15672
15673 check_stats() {
15674         local facet=$1
15675         local op=$2
15676         local want=${3:-0}
15677         local res
15678
15679         # open             11 samples [usecs] 468 4793 13658 35791898
15680         case $facet in
15681         mds*) res=($(do_facet $facet \
15682                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
15683                  ;;
15684         ost*) res=($(do_facet $facet \
15685                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
15686                  ;;
15687         *) error "Wrong facet '$facet'" ;;
15688         esac
15689         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
15690         # if $want is zero, it means any stat increment is ok.
15691         if (( $want > 0 )); then
15692                 local count=${res[1]}
15693
15694                 if (( $count != $want )); then
15695                         if [[ $facet =~ "mds" ]]; then
15696                                 do_nodes $(comma_list $(mdts_nodes)) \
15697                                         $LCTL get_param mdt.*.md_stats
15698                         else
15699                                 do_nodes $(comma_list $(osts-nodes)) \
15700                                         $LCTL get_param obdfilter.*.stats
15701                         fi
15702                         error "The $op counter on $facet is $count, not $want"
15703                 fi
15704         fi
15705 }
15706
15707 test_133a() {
15708         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15709         remote_ost_nodsh && skip "remote OST with nodsh"
15710         remote_mds_nodsh && skip "remote MDS with nodsh"
15711         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15712                 skip_env "MDS doesn't support rename stats"
15713
15714         local testdir=$DIR/${tdir}/stats_testdir
15715
15716         mkdir -p $DIR/${tdir}
15717
15718         # clear stats.
15719         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15720         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15721
15722         # verify mdt stats first.
15723         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15724         check_stats $SINGLEMDS "mkdir" 1
15725
15726         # clear "open" from "lfs mkdir" above
15727         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15728         touch ${testdir}/${tfile} || error "touch failed"
15729         check_stats $SINGLEMDS "open" 1
15730         check_stats $SINGLEMDS "close" 1
15731         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
15732                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
15733                 check_stats $SINGLEMDS "mknod" 2
15734         }
15735         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
15736         check_stats $SINGLEMDS "unlink" 1
15737         rm -f ${testdir}/${tfile} || error "file remove failed"
15738         check_stats $SINGLEMDS "unlink" 2
15739
15740         # remove working dir and check mdt stats again.
15741         rmdir ${testdir} || error "rmdir failed"
15742         check_stats $SINGLEMDS "rmdir" 1
15743
15744         local testdir1=$DIR/${tdir}/stats_testdir1
15745         mkdir_on_mdt0 -p ${testdir}
15746         mkdir_on_mdt0 -p ${testdir1}
15747         touch ${testdir1}/test1
15748         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
15749         check_stats $SINGLEMDS "crossdir_rename" 1
15750
15751         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
15752         check_stats $SINGLEMDS "samedir_rename" 1
15753
15754         rm -rf $DIR/${tdir}
15755 }
15756 run_test 133a "Verifying MDT stats ========================================"
15757
15758 test_133b() {
15759         local res
15760
15761         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15762         remote_ost_nodsh && skip "remote OST with nodsh"
15763         remote_mds_nodsh && skip "remote MDS with nodsh"
15764
15765         local testdir=$DIR/${tdir}/stats_testdir
15766
15767         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15768         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15769         touch ${testdir}/${tfile} || error "touch failed"
15770         cancel_lru_locks mdc
15771
15772         # clear stats.
15773         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15774         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15775
15776         # extra mdt stats verification.
15777         chmod 444 ${testdir}/${tfile} || error "chmod failed"
15778         check_stats $SINGLEMDS "setattr" 1
15779         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15780         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
15781         then            # LU-1740
15782                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
15783                 check_stats $SINGLEMDS "getattr" 1
15784         fi
15785         rm -rf $DIR/${tdir}
15786
15787         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
15788         # so the check below is not reliable
15789         [ $MDSCOUNT -eq 1 ] || return 0
15790
15791         # Sleep to avoid a cached response.
15792         #define OBD_STATFS_CACHE_SECONDS 1
15793         sleep 2
15794         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15795         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15796         $LFS df || error "lfs failed"
15797         check_stats $SINGLEMDS "statfs" 1
15798
15799         # check aggregated statfs (LU-10018)
15800         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
15801                 return 0
15802         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
15803                 return 0
15804         sleep 2
15805         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15806         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15807         df $DIR
15808         check_stats $SINGLEMDS "statfs" 1
15809
15810         # We want to check that the client didn't send OST_STATFS to
15811         # ost1 but the MDT also uses OST_STATFS for precreate. So some
15812         # extra care is needed here.
15813         if remote_mds; then
15814                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
15815                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
15816
15817                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
15818                 [ "$res" ] && error "OST got STATFS"
15819         fi
15820
15821         return 0
15822 }
15823 run_test 133b "Verifying extra MDT stats =================================="
15824
15825 test_133c() {
15826         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15827         remote_ost_nodsh && skip "remote OST with nodsh"
15828         remote_mds_nodsh && skip "remote MDS with nodsh"
15829
15830         local testdir=$DIR/$tdir/stats_testdir
15831
15832         test_mkdir -p $testdir
15833
15834         # verify obdfilter stats.
15835         $LFS setstripe -c 1 -i 0 $testdir/$tfile
15836         sync
15837         cancel_lru_locks osc
15838         wait_delete_completed
15839
15840         # clear stats.
15841         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15842         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15843
15844         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
15845                 error "dd failed"
15846         sync
15847         cancel_lru_locks osc
15848         check_stats ost1 "write" 1
15849
15850         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
15851         check_stats ost1 "read" 1
15852
15853         > $testdir/$tfile || error "truncate failed"
15854         check_stats ost1 "punch" 1
15855
15856         rm -f $testdir/$tfile || error "file remove failed"
15857         wait_delete_completed
15858         check_stats ost1 "destroy" 1
15859
15860         rm -rf $DIR/$tdir
15861 }
15862 run_test 133c "Verifying OST stats ========================================"
15863
15864 order_2() {
15865         local value=$1
15866         local orig=$value
15867         local order=1
15868
15869         while [ $value -ge 2 ]; do
15870                 order=$((order*2))
15871                 value=$((value/2))
15872         done
15873
15874         if [ $orig -gt $order ]; then
15875                 order=$((order*2))
15876         fi
15877         echo $order
15878 }
15879
15880 size_in_KMGT() {
15881     local value=$1
15882     local size=('K' 'M' 'G' 'T');
15883     local i=0
15884     local size_string=$value
15885
15886     while [ $value -ge 1024 ]; do
15887         if [ $i -gt 3 ]; then
15888             #T is the biggest unit we get here, if that is bigger,
15889             #just return XXXT
15890             size_string=${value}T
15891             break
15892         fi
15893         value=$((value >> 10))
15894         if [ $value -lt 1024 ]; then
15895             size_string=${value}${size[$i]}
15896             break
15897         fi
15898         i=$((i + 1))
15899     done
15900
15901     echo $size_string
15902 }
15903
15904 get_rename_size() {
15905         local size=$1
15906         local context=${2:-.}
15907         local sample=$(do_facet $SINGLEMDS $LCTL \
15908                 get_param mdt.$FSNAME-MDT0000.rename_stats |
15909                 grep -A1 $context |
15910                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
15911         echo $sample
15912 }
15913
15914 test_133d() {
15915         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15916         remote_ost_nodsh && skip "remote OST with nodsh"
15917         remote_mds_nodsh && skip "remote MDS with nodsh"
15918         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15919                 skip_env "MDS doesn't support rename stats"
15920
15921         local testdir1=$DIR/${tdir}/stats_testdir1
15922         local testdir2=$DIR/${tdir}/stats_testdir2
15923         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
15924
15925         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15926
15927         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
15928         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
15929
15930         createmany -o $testdir1/test 512 || error "createmany failed"
15931
15932         # check samedir rename size
15933         mv ${testdir1}/test0 ${testdir1}/test_0
15934
15935         local testdir1_size=$(ls -l $DIR/${tdir} |
15936                 awk '/stats_testdir1/ {print $5}')
15937         local testdir2_size=$(ls -l $DIR/${tdir} |
15938                 awk '/stats_testdir2/ {print $5}')
15939
15940         testdir1_size=$(order_2 $testdir1_size)
15941         testdir2_size=$(order_2 $testdir2_size)
15942
15943         testdir1_size=$(size_in_KMGT $testdir1_size)
15944         testdir2_size=$(size_in_KMGT $testdir2_size)
15945
15946         echo "source rename dir size: ${testdir1_size}"
15947         echo "target rename dir size: ${testdir2_size}"
15948
15949         local cmd="do_facet $SINGLEMDS $LCTL "
15950         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
15951
15952         eval $cmd || error "$cmd failed"
15953         local samedir=$($cmd | grep 'same_dir')
15954         local same_sample=$(get_rename_size $testdir1_size)
15955         [ -z "$samedir" ] && error "samedir_rename_size count error"
15956         [[ $same_sample -eq 1 ]] ||
15957                 error "samedir_rename_size error $same_sample"
15958         echo "Check same dir rename stats success"
15959
15960         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15961
15962         # check crossdir rename size
15963         mv ${testdir1}/test_0 ${testdir2}/test_0
15964
15965         testdir1_size=$(ls -l $DIR/${tdir} |
15966                 awk '/stats_testdir1/ {print $5}')
15967         testdir2_size=$(ls -l $DIR/${tdir} |
15968                 awk '/stats_testdir2/ {print $5}')
15969
15970         testdir1_size=$(order_2 $testdir1_size)
15971         testdir2_size=$(order_2 $testdir2_size)
15972
15973         testdir1_size=$(size_in_KMGT $testdir1_size)
15974         testdir2_size=$(size_in_KMGT $testdir2_size)
15975
15976         echo "source rename dir size: ${testdir1_size}"
15977         echo "target rename dir size: ${testdir2_size}"
15978
15979         eval $cmd || error "$cmd failed"
15980         local crossdir=$($cmd | grep 'crossdir')
15981         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
15982         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
15983         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
15984         [[ $src_sample -eq 1 ]] ||
15985                 error "crossdir_rename_size error $src_sample"
15986         [[ $tgt_sample -eq 1 ]] ||
15987                 error "crossdir_rename_size error $tgt_sample"
15988         echo "Check cross dir rename stats success"
15989         rm -rf $DIR/${tdir}
15990 }
15991 run_test 133d "Verifying rename_stats ========================================"
15992
15993 test_133e() {
15994         remote_mds_nodsh && skip "remote MDS with nodsh"
15995         remote_ost_nodsh && skip "remote OST with nodsh"
15996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15997
15998         local testdir=$DIR/${tdir}/stats_testdir
15999         local ctr f0 f1 bs=32768 count=42 sum
16000
16001         mkdir -p ${testdir} || error "mkdir failed"
16002
16003         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
16004
16005         for ctr in {write,read}_bytes; do
16006                 sync
16007                 cancel_lru_locks osc
16008
16009                 do_facet ost1 $LCTL set_param -n \
16010                         "obdfilter.*.exports.clear=clear"
16011
16012                 if [ $ctr = write_bytes ]; then
16013                         f0=/dev/zero
16014                         f1=${testdir}/${tfile}
16015                 else
16016                         f0=${testdir}/${tfile}
16017                         f1=/dev/null
16018                 fi
16019
16020                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
16021                         error "dd failed"
16022                 sync
16023                 cancel_lru_locks osc
16024
16025                 sum=$(do_facet ost1 $LCTL get_param \
16026                         "obdfilter.*.exports.*.stats" |
16027                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
16028                                 $1 == ctr { sum += $7 }
16029                                 END { printf("%0.0f", sum) }')
16030
16031                 if ((sum != bs * count)); then
16032                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
16033                 fi
16034         done
16035
16036         rm -rf $DIR/${tdir}
16037 }
16038 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
16039
16040 test_133f() {
16041         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
16042                 skip "too old lustre for get_param -R ($facet_ver)"
16043
16044         # verifying readability.
16045         $LCTL get_param -R '*' &> /dev/null
16046
16047         # Verifing writability with badarea_io.
16048         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
16049         local skipped_params='force_lbug|changelog_mask|daemon_file'
16050         $LCTL list_param -FR '*' | grep '=' | tr -d = |
16051                 egrep -v "$skipped_params" |
16052                 xargs -n 1 find $proc_dirs -name |
16053                 xargs -n 1 badarea_io ||
16054                 error "client badarea_io failed"
16055
16056         # remount the FS in case writes/reads /proc break the FS
16057         cleanup || error "failed to unmount"
16058         setup || error "failed to setup"
16059 }
16060 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
16061
16062 test_133g() {
16063         remote_mds_nodsh && skip "remote MDS with nodsh"
16064         remote_ost_nodsh && skip "remote OST with nodsh"
16065
16066         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
16067         local proc_dirs_str=$(eval echo $proc_dirs)
16068         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
16069         local facet
16070         for facet in mds1 ost1; do
16071                 local facet_ver=$(lustre_version_code $facet)
16072                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
16073                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
16074                 else
16075                         log "$facet: too old lustre for get_param -R"
16076                 fi
16077                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
16078                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
16079                                 tr -d = | egrep -v $skipped_params |
16080                                 xargs -n 1 find $proc_dirs_str -name |
16081                                 xargs -n 1 badarea_io" ||
16082                                         error "$facet badarea_io failed"
16083                 else
16084                         skip_noexit "$facet: too old lustre for get_param -R"
16085                 fi
16086         done
16087
16088         # remount the FS in case writes/reads /proc break the FS
16089         cleanup || error "failed to unmount"
16090         setup || error "failed to setup"
16091 }
16092 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
16093
16094 test_133h() {
16095         remote_mds_nodsh && skip "remote MDS with nodsh"
16096         remote_ost_nodsh && skip "remote OST with nodsh"
16097         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
16098                 skip "Need MDS version at least 2.9.54"
16099
16100         local facet
16101         for facet in client mds1 ost1; do
16102                 # Get the list of files that are missing the terminating newline
16103                 local plist=$(do_facet $facet
16104                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
16105                 local ent
16106                 for ent in $plist; do
16107                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
16108                                 awk -v FS='\v' -v RS='\v\v' \
16109                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
16110                                         print FILENAME}'" 2>/dev/null)
16111                         [ -z $missing ] || {
16112                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
16113                                 error "file does not end with newline: $facet-$ent"
16114                         }
16115                 done
16116         done
16117 }
16118 run_test 133h "Proc files should end with newlines"
16119
16120 test_134a() {
16121         remote_mds_nodsh && skip "remote MDS with nodsh"
16122         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
16123                 skip "Need MDS version at least 2.7.54"
16124
16125         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
16126         cancel_lru_locks mdc
16127
16128         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
16129         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
16130         [ $unused -eq 0 ] || error "$unused locks are not cleared"
16131
16132         local nr=1000
16133         createmany -o $DIR/$tdir/f $nr ||
16134                 error "failed to create $nr files in $DIR/$tdir"
16135         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
16136
16137         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
16138         do_facet mds1 $LCTL set_param fail_loc=0x327
16139         do_facet mds1 $LCTL set_param fail_val=500
16140         touch $DIR/$tdir/m
16141
16142         echo "sleep 10 seconds ..."
16143         sleep 10
16144         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
16145
16146         do_facet mds1 $LCTL set_param fail_loc=0
16147         do_facet mds1 $LCTL set_param fail_val=0
16148         [ $lck_cnt -lt $unused ] ||
16149                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
16150
16151         rm $DIR/$tdir/m
16152         unlinkmany $DIR/$tdir/f $nr
16153 }
16154 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
16155
16156 test_134b() {
16157         remote_mds_nodsh && skip "remote MDS with nodsh"
16158         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
16159                 skip "Need MDS version at least 2.7.54"
16160
16161         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
16162         cancel_lru_locks mdc
16163
16164         local low_wm=$(do_facet mds1 $LCTL get_param -n \
16165                         ldlm.lock_reclaim_threshold_mb)
16166         # disable reclaim temporarily
16167         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
16168
16169         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
16170         do_facet mds1 $LCTL set_param fail_loc=0x328
16171         do_facet mds1 $LCTL set_param fail_val=500
16172
16173         $LCTL set_param debug=+trace
16174
16175         local nr=600
16176         createmany -o $DIR/$tdir/f $nr &
16177         local create_pid=$!
16178
16179         echo "Sleep $TIMEOUT seconds ..."
16180         sleep $TIMEOUT
16181         if ! ps -p $create_pid  > /dev/null 2>&1; then
16182                 do_facet mds1 $LCTL set_param fail_loc=0
16183                 do_facet mds1 $LCTL set_param fail_val=0
16184                 do_facet mds1 $LCTL set_param \
16185                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
16186                 error "createmany finished incorrectly!"
16187         fi
16188         do_facet mds1 $LCTL set_param fail_loc=0
16189         do_facet mds1 $LCTL set_param fail_val=0
16190         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
16191         wait $create_pid || return 1
16192
16193         unlinkmany $DIR/$tdir/f $nr
16194 }
16195 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
16196
16197 test_135() {
16198         remote_mds_nodsh && skip "remote MDS with nodsh"
16199         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
16200                 skip "Need MDS version at least 2.13.50"
16201         local fname
16202
16203         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
16204
16205 #define OBD_FAIL_PLAIN_RECORDS 0x1319
16206         #set only one record at plain llog
16207         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
16208
16209         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
16210
16211         #fill already existed plain llog each 64767
16212         #wrapping whole catalog
16213         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
16214
16215         createmany -o $DIR/$tdir/$tfile_ 64700
16216         for (( i = 0; i < 64700; i = i + 2 ))
16217         do
16218                 rm $DIR/$tdir/$tfile_$i &
16219                 rm $DIR/$tdir/$tfile_$((i + 1)) &
16220                 local pid=$!
16221                 wait $pid
16222         done
16223
16224         #waiting osp synchronization
16225         wait_delete_completed
16226 }
16227 run_test 135 "Race catalog processing"
16228
16229 test_136() {
16230         remote_mds_nodsh && skip "remote MDS with nodsh"
16231         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
16232                 skip "Need MDS version at least 2.13.50"
16233         local fname
16234
16235         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
16236         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
16237         #set only one record at plain llog
16238 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
16239         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
16240
16241         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
16242
16243         #fill already existed 2 plain llogs each 64767
16244         #wrapping whole catalog
16245         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
16246         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
16247         wait_delete_completed
16248
16249         createmany -o $DIR/$tdir/$tfile_ 10
16250         sleep 25
16251
16252         do_facet $SINGLEMDS $LCTL set_param fail_val=3
16253         for (( i = 0; i < 10; i = i + 3 ))
16254         do
16255                 rm $DIR/$tdir/$tfile_$i &
16256                 rm $DIR/$tdir/$tfile_$((i + 1)) &
16257                 local pid=$!
16258                 wait $pid
16259                 sleep 7
16260                 rm $DIR/$tdir/$tfile_$((i + 2)) &
16261         done
16262
16263         #waiting osp synchronization
16264         wait_delete_completed
16265 }
16266 run_test 136 "Race catalog processing 2"
16267
16268 test_140() { #bug-17379
16269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16270
16271         test_mkdir $DIR/$tdir
16272         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
16273         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
16274
16275         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
16276         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
16277         local i=0
16278         while i=$((i + 1)); do
16279                 test_mkdir $i
16280                 cd $i || error "Changing to $i"
16281                 ln -s ../stat stat || error "Creating stat symlink"
16282                 # Read the symlink until ELOOP present,
16283                 # not LBUGing the system is considered success,
16284                 # we didn't overrun the stack.
16285                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
16286                 if [ $ret -ne 0 ]; then
16287                         if [ $ret -eq 40 ]; then
16288                                 break  # -ELOOP
16289                         else
16290                                 error "Open stat symlink"
16291                                         return
16292                         fi
16293                 fi
16294         done
16295         i=$((i - 1))
16296         echo "The symlink depth = $i"
16297         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
16298                 error "Invalid symlink depth"
16299
16300         # Test recursive symlink
16301         ln -s symlink_self symlink_self
16302         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
16303         echo "open symlink_self returns $ret"
16304         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
16305 }
16306 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
16307
16308 test_150a() {
16309         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16310
16311         local TF="$TMP/$tfile"
16312
16313         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16314         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16315         cp $TF $DIR/$tfile
16316         cancel_lru_locks $OSC
16317         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
16318         remount_client $MOUNT
16319         df -P $MOUNT
16320         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
16321
16322         $TRUNCATE $TF 6000
16323         $TRUNCATE $DIR/$tfile 6000
16324         cancel_lru_locks $OSC
16325         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
16326
16327         echo "12345" >>$TF
16328         echo "12345" >>$DIR/$tfile
16329         cancel_lru_locks $OSC
16330         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
16331
16332         echo "12345" >>$TF
16333         echo "12345" >>$DIR/$tfile
16334         cancel_lru_locks $OSC
16335         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
16336 }
16337 run_test 150a "truncate/append tests"
16338
16339 test_150b() {
16340         check_set_fallocate_or_skip
16341         local out
16342
16343         touch $DIR/$tfile
16344         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16345         out=$(check_fallocate $DIR/$tfile 2>&1) ||
16346                 skip_eopnotsupp "$out|check_fallocate failed"
16347 }
16348 run_test 150b "Verify fallocate (prealloc) functionality"
16349
16350 test_150bb() {
16351         check_set_fallocate_or_skip
16352
16353         touch $DIR/$tfile
16354         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16355         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
16356         > $DIR/$tfile
16357         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
16358         # precomputed md5sum for 20MB of zeroes
16359         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
16360         local sum=($(md5sum $DIR/$tfile))
16361
16362         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
16363
16364         check_set_fallocate 1
16365
16366         > $DIR/$tfile
16367         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
16368         sum=($(md5sum $DIR/$tfile))
16369
16370         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
16371 }
16372 run_test 150bb "Verify fallocate modes both zero space"
16373
16374 test_150c() {
16375         check_set_fallocate_or_skip
16376         local striping="-c2"
16377
16378         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16379         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
16380         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
16381         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
16382         local want=$((OSTCOUNT * 1048576))
16383
16384         # Must allocate all requested space, not more than 5% extra
16385         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16386                 error "bytes $bytes is not $want"
16387
16388         rm -f $DIR/$tfile
16389
16390         echo "verify fallocate on PFL file"
16391
16392         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
16393
16394         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
16395                 error "Create $DIR/$tfile failed"
16396         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
16397         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
16398         want=$((512 * 1048576))
16399
16400         # Must allocate all requested space, not more than 5% extra
16401         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16402                 error "bytes $bytes is not $want"
16403 }
16404 run_test 150c "Verify fallocate Size and Blocks"
16405
16406 test_150d() {
16407         check_set_fallocate_or_skip
16408         local striping="-c2"
16409
16410         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
16411
16412         stack_trap "rm -f $DIR/$tdir; wait_delete_completed"
16413         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
16414                 error "setstripe failed"
16415         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
16416         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
16417         local want=$((OSTCOUNT * 1048576))
16418
16419         # Must allocate all requested space, not more than 5% extra
16420         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16421                 error "bytes $bytes is not $want"
16422 }
16423 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
16424
16425 test_150e() {
16426         check_set_fallocate_or_skip
16427
16428         echo "df before:"
16429         $LFS df
16430         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16431         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16432                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16433
16434         # Find OST with Minimum Size
16435         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16436                        sort -un | head -1)
16437
16438         # Get 100MB per OST of the available space to reduce run time
16439         # else 60% of the available space if we are running SLOW tests
16440         if [ $SLOW == "no" ]; then
16441                 local space=$((1024 * 100 * OSTCOUNT))
16442         else
16443                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
16444         fi
16445
16446         fallocate -l${space}k $DIR/$tfile ||
16447                 error "fallocate ${space}k $DIR/$tfile failed"
16448         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
16449
16450         # get size immediately after fallocate. This should be correctly
16451         # updated
16452         local size=$(stat -c '%s' $DIR/$tfile)
16453         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
16454
16455         # Sleep for a while for statfs to get updated. And not pull from cache.
16456         sleep 2
16457
16458         echo "df after fallocate:"
16459         $LFS df
16460
16461         (( size / 1024 == space )) || error "size $size != requested $space"
16462         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
16463                 error "used $used < space $space"
16464
16465         rm $DIR/$tfile || error "rm failed"
16466         sync
16467         wait_delete_completed
16468
16469         echo "df after unlink:"
16470         $LFS df
16471 }
16472 run_test 150e "Verify 60% of available OST space consumed by fallocate"
16473
16474 test_150f() {
16475         local size
16476         local blocks
16477         local want_size_before=20480 # in bytes
16478         local want_blocks_before=40 # 512 sized blocks
16479         local want_blocks_after=24  # 512 sized blocks
16480         local length=$(((want_blocks_before - want_blocks_after) * 512))
16481
16482         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16483                 skip "need at least 2.14.0 for fallocate punch"
16484
16485         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16486                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16487         fi
16488
16489         check_set_fallocate_or_skip
16490         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16491
16492         [[ "x$DOM" == "xyes" ]] &&
16493                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
16494
16495         echo "Verify fallocate punch: Range within the file range"
16496         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16497                 error "dd failed for bs 4096 and count 5"
16498
16499         # Call fallocate with punch range which is within the file range
16500         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
16501                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
16502         # client must see changes immediately after fallocate
16503         size=$(stat -c '%s' $DIR/$tfile)
16504         blocks=$(stat -c '%b' $DIR/$tfile)
16505
16506         # Verify punch worked.
16507         (( blocks == want_blocks_after )) ||
16508                 error "punch failed: blocks $blocks != $want_blocks_after"
16509
16510         (( size == want_size_before )) ||
16511                 error "punch failed: size $size != $want_size_before"
16512
16513         # Verify there is hole in file
16514         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
16515         # precomputed md5sum
16516         local expect="4a9a834a2db02452929c0a348273b4aa"
16517
16518         cksum=($(md5sum $DIR/$tfile))
16519         [[ "${cksum[0]}" == "$expect" ]] ||
16520                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16521
16522         # Start second sub-case for fallocate punch.
16523         echo "Verify fallocate punch: Range overlapping and less than blocksize"
16524         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16525                 error "dd failed for bs 4096 and count 5"
16526
16527         # Punch range less than block size will have no change in block count
16528         want_blocks_after=40  # 512 sized blocks
16529
16530         # Punch overlaps two blocks and less than blocksize
16531         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
16532                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
16533         size=$(stat -c '%s' $DIR/$tfile)
16534         blocks=$(stat -c '%b' $DIR/$tfile)
16535
16536         # Verify punch worked.
16537         (( blocks == want_blocks_after )) ||
16538                 error "punch failed: blocks $blocks != $want_blocks_after"
16539
16540         (( size == want_size_before )) ||
16541                 error "punch failed: size $size != $want_size_before"
16542
16543         # Verify if range is really zero'ed out. We expect Zeros.
16544         # precomputed md5sum
16545         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
16546         cksum=($(md5sum $DIR/$tfile))
16547         [[ "${cksum[0]}" == "$expect" ]] ||
16548                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16549 }
16550 run_test 150f "Verify fallocate punch functionality"
16551
16552 test_150g() {
16553         local space
16554         local size
16555         local blocks
16556         local blocks_after
16557         local size_after
16558         local BS=4096 # Block size in bytes
16559
16560         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16561                 skip "need at least 2.14.0 for fallocate punch"
16562
16563         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16564                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16565         fi
16566
16567         check_set_fallocate_or_skip
16568         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16569
16570         if [[ "x$DOM" == "xyes" ]]; then
16571                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
16572                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
16573         else
16574                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16575                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16576         fi
16577
16578         # Get 100MB per OST of the available space to reduce run time
16579         # else 60% of the available space if we are running SLOW tests
16580         if [ $SLOW == "no" ]; then
16581                 space=$((1024 * 100 * OSTCOUNT))
16582         else
16583                 # Find OST with Minimum Size
16584                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16585                         sort -un | head -1)
16586                 echo "min size OST: $space"
16587                 space=$(((space * 60)/100 * OSTCOUNT))
16588         fi
16589         # space in 1k units, round to 4k blocks
16590         local blkcount=$((space * 1024 / $BS))
16591
16592         echo "Verify fallocate punch: Very large Range"
16593         fallocate -l${space}k $DIR/$tfile ||
16594                 error "fallocate ${space}k $DIR/$tfile failed"
16595         # write 1M at the end, start and in the middle
16596         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
16597                 error "dd failed: bs $BS count 256"
16598         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
16599                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
16600         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
16601                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
16602
16603         # Gather stats.
16604         size=$(stat -c '%s' $DIR/$tfile)
16605
16606         # gather punch length.
16607         local punch_size=$((size - (BS * 2)))
16608
16609         echo "punch_size = $punch_size"
16610         echo "size - punch_size: $((size - punch_size))"
16611         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
16612
16613         # Call fallocate to punch all except 2 blocks. We leave the
16614         # first and the last block
16615         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
16616         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
16617                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
16618
16619         size_after=$(stat -c '%s' $DIR/$tfile)
16620         blocks_after=$(stat -c '%b' $DIR/$tfile)
16621
16622         # Verify punch worked.
16623         # Size should be kept
16624         (( size == size_after )) ||
16625                 error "punch failed: size $size != $size_after"
16626
16627         # two 4k data blocks to remain plus possible 1 extra extent block
16628         (( blocks_after <= ((BS / 512) * 3) )) ||
16629                 error "too many blocks remains: $blocks_after"
16630
16631         # Verify that file has hole between the first and the last blocks
16632         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
16633         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
16634
16635         echo "Hole at [$hole_start, $hole_end)"
16636         (( hole_start == BS )) ||
16637                 error "no hole at offset $BS after punch"
16638
16639         (( hole_end == BS + punch_size )) ||
16640                 error "data at offset $hole_end < $((BS + punch_size))"
16641 }
16642 run_test 150g "Verify fallocate punch on large range"
16643
16644 test_150h() {
16645         local file=$DIR/$tfile
16646         local size
16647
16648         check_set_fallocate_or_skip
16649         statx_supported || skip_env "Test must be statx() syscall supported"
16650
16651         # fallocate() does not update the size information on the MDT
16652         fallocate -l 16K $file || error "failed to fallocate $file"
16653         cancel_lru_locks $OSC
16654         # STATX with cached-always mode will not send glimpse RPCs to OST,
16655         # it uses the caching attrs on the client side as much as possible.
16656         size=$($STATX --cached=always -c %s $file)
16657         [ $size == 16384 ] ||
16658                 error "size after fallocate() is $size, expected 16384"
16659 }
16660 run_test 150h "Verify extend fallocate updates the file size"
16661
16662 #LU-2902 roc_hit was not able to read all values from lproc
16663 function roc_hit_init() {
16664         local list=$(comma_list $(osts_nodes))
16665         local dir=$DIR/$tdir-check
16666         local file=$dir/$tfile
16667         local BEFORE
16668         local AFTER
16669         local idx
16670
16671         test_mkdir $dir
16672         #use setstripe to do a write to every ost
16673         for i in $(seq 0 $((OSTCOUNT-1))); do
16674                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
16675                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
16676                 idx=$(printf %04x $i)
16677                 BEFORE=$(get_osd_param $list *OST*$idx stats |
16678                         awk '$1 == "cache_access" {sum += $7}
16679                                 END { printf("%0.0f", sum) }')
16680
16681                 cancel_lru_locks osc
16682                 cat $file >/dev/null
16683
16684                 AFTER=$(get_osd_param $list *OST*$idx stats |
16685                         awk '$1 == "cache_access" {sum += $7}
16686                                 END { printf("%0.0f", sum) }')
16687
16688                 echo BEFORE:$BEFORE AFTER:$AFTER
16689                 if ! let "AFTER - BEFORE == 4"; then
16690                         rm -rf $dir
16691                         error "roc_hit is not safe to use"
16692                 fi
16693                 rm $file
16694         done
16695
16696         rm -rf $dir
16697 }
16698
16699 function roc_hit() {
16700         local list=$(comma_list $(osts_nodes))
16701         echo $(get_osd_param $list '' stats |
16702                 awk '$1 == "cache_hit" {sum += $7}
16703                         END { printf("%0.0f", sum) }')
16704 }
16705
16706 function set_cache() {
16707         local on=1
16708
16709         if [ "$2" == "off" ]; then
16710                 on=0;
16711         fi
16712         local list=$(comma_list $(osts_nodes))
16713         set_osd_param $list '' $1_cache_enable $on
16714
16715         cancel_lru_locks osc
16716 }
16717
16718 test_151() {
16719         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16720         remote_ost_nodsh && skip "remote OST with nodsh"
16721         (( CLIENT_VERSION == OST1_VERSION )) ||
16722                 skip "LU-13081: no interop testing for OSS cache"
16723
16724         local CPAGES=3
16725         local list=$(comma_list $(osts_nodes))
16726
16727         # check whether obdfilter is cache capable at all
16728         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
16729                 skip "not cache-capable obdfilter"
16730         fi
16731
16732         # check cache is enabled on all obdfilters
16733         if get_osd_param $list '' read_cache_enable | grep 0; then
16734                 skip "oss cache is disabled"
16735         fi
16736
16737         set_osd_param $list '' writethrough_cache_enable 1
16738
16739         # check write cache is enabled on all obdfilters
16740         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
16741                 skip "oss write cache is NOT enabled"
16742         fi
16743
16744         roc_hit_init
16745
16746         #define OBD_FAIL_OBD_NO_LRU  0x609
16747         do_nodes $list $LCTL set_param fail_loc=0x609
16748
16749         # pages should be in the case right after write
16750         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
16751                 error "dd failed"
16752
16753         local BEFORE=$(roc_hit)
16754         cancel_lru_locks osc
16755         cat $DIR/$tfile >/dev/null
16756         local AFTER=$(roc_hit)
16757
16758         do_nodes $list $LCTL set_param fail_loc=0
16759
16760         if ! let "AFTER - BEFORE == CPAGES"; then
16761                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
16762         fi
16763
16764         cancel_lru_locks osc
16765         # invalidates OST cache
16766         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
16767         set_osd_param $list '' read_cache_enable 0
16768         cat $DIR/$tfile >/dev/null
16769
16770         # now data shouldn't be found in the cache
16771         BEFORE=$(roc_hit)
16772         cancel_lru_locks osc
16773         cat $DIR/$tfile >/dev/null
16774         AFTER=$(roc_hit)
16775         if let "AFTER - BEFORE != 0"; then
16776                 error "IN CACHE: before: $BEFORE, after: $AFTER"
16777         fi
16778
16779         set_osd_param $list '' read_cache_enable 1
16780         rm -f $DIR/$tfile
16781 }
16782 run_test 151 "test cache on oss and controls ==============================="
16783
16784 test_152() {
16785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16786
16787         local TF="$TMP/$tfile"
16788
16789         # simulate ENOMEM during write
16790 #define OBD_FAIL_OST_NOMEM      0x226
16791         lctl set_param fail_loc=0x80000226
16792         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16793         cp $TF $DIR/$tfile
16794         sync || error "sync failed"
16795         lctl set_param fail_loc=0
16796
16797         # discard client's cache
16798         cancel_lru_locks osc
16799
16800         # simulate ENOMEM during read
16801         lctl set_param fail_loc=0x80000226
16802         cmp $TF $DIR/$tfile || error "cmp failed"
16803         lctl set_param fail_loc=0
16804
16805         rm -f $TF
16806 }
16807 run_test 152 "test read/write with enomem ============================"
16808
16809 test_153() {
16810         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
16811 }
16812 run_test 153 "test if fdatasync does not crash ======================="
16813
16814 dot_lustre_fid_permission_check() {
16815         local fid=$1
16816         local ffid=$MOUNT/.lustre/fid/$fid
16817         local test_dir=$2
16818
16819         echo "stat fid $fid"
16820         stat $ffid || error "stat $ffid failed."
16821         echo "touch fid $fid"
16822         touch $ffid || error "touch $ffid failed."
16823         echo "write to fid $fid"
16824         cat /etc/hosts > $ffid || error "write $ffid failed."
16825         echo "read fid $fid"
16826         diff /etc/hosts $ffid || error "read $ffid failed."
16827         echo "append write to fid $fid"
16828         cat /etc/hosts >> $ffid || error "append write $ffid failed."
16829         echo "rename fid $fid"
16830         mv $ffid $test_dir/$tfile.1 &&
16831                 error "rename $ffid to $tfile.1 should fail."
16832         touch $test_dir/$tfile.1
16833         mv $test_dir/$tfile.1 $ffid &&
16834                 error "rename $tfile.1 to $ffid should fail."
16835         rm -f $test_dir/$tfile.1
16836         echo "truncate fid $fid"
16837         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
16838         echo "link fid $fid"
16839         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
16840         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
16841                 id $USER0 || skip_env "missing user $USER0"
16842                 echo "setfacl fid $fid"
16843                 setfacl -R -m u:$USER0:rwx $ffid ||
16844                         error "setfacl $ffid failed"
16845                 echo "getfacl fid $fid"
16846                 getfacl $ffid || error "getfacl $ffid failed."
16847         fi
16848         echo "unlink fid $fid"
16849         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
16850         echo "mknod fid $fid"
16851         mknod $ffid c 1 3 && error "mknod $ffid should fail."
16852
16853         fid=[0xf00000400:0x1:0x0]
16854         ffid=$MOUNT/.lustre/fid/$fid
16855
16856         echo "stat non-exist fid $fid"
16857         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
16858         echo "write to non-exist fid $fid"
16859         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
16860         echo "link new fid $fid"
16861         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
16862
16863         mkdir -p $test_dir/$tdir
16864         touch $test_dir/$tdir/$tfile
16865         fid=$($LFS path2fid $test_dir/$tdir)
16866         rc=$?
16867         [ $rc -ne 0 ] &&
16868                 error "error: could not get fid for $test_dir/$dir/$tfile."
16869
16870         ffid=$MOUNT/.lustre/fid/$fid
16871
16872         echo "ls $fid"
16873         ls $ffid || error "ls $ffid failed."
16874         echo "touch $fid/$tfile.1"
16875         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
16876
16877         echo "touch $MOUNT/.lustre/fid/$tfile"
16878         touch $MOUNT/.lustre/fid/$tfile && \
16879                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
16880
16881         echo "setxattr to $MOUNT/.lustre/fid"
16882         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
16883
16884         echo "listxattr for $MOUNT/.lustre/fid"
16885         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
16886
16887         echo "delxattr from $MOUNT/.lustre/fid"
16888         setfattr -x trusted.name1 $MOUNT/.lustre/fid
16889
16890         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
16891         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
16892                 error "touch invalid fid should fail."
16893
16894         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
16895         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
16896                 error "touch non-normal fid should fail."
16897
16898         echo "rename $tdir to $MOUNT/.lustre/fid"
16899         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
16900                 error "rename to $MOUNT/.lustre/fid should fail."
16901
16902         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
16903         then            # LU-3547
16904                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
16905                 local new_obf_mode=777
16906
16907                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
16908                 chmod $new_obf_mode $DIR/.lustre/fid ||
16909                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
16910
16911                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
16912                 [ $obf_mode -eq $new_obf_mode ] ||
16913                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
16914
16915                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
16916                 chmod $old_obf_mode $DIR/.lustre/fid ||
16917                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
16918         fi
16919
16920         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
16921         fid=$($LFS path2fid $test_dir/$tfile-2)
16922
16923         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
16924         then # LU-5424
16925                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
16926                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
16927                         error "create lov data thru .lustre failed"
16928         fi
16929         echo "cp /etc/passwd $test_dir/$tfile-2"
16930         cp /etc/passwd $test_dir/$tfile-2 ||
16931                 error "copy to $test_dir/$tfile-2 failed."
16932         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
16933         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
16934                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
16935
16936         rm -rf $test_dir/tfile.lnk
16937         rm -rf $test_dir/$tfile-2
16938 }
16939
16940 test_154A() {
16941         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16942                 skip "Need MDS version at least 2.4.1"
16943
16944         local tf=$DIR/$tfile
16945         touch $tf
16946
16947         local fid=$($LFS path2fid $tf)
16948         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
16949
16950         # check that we get the same pathname back
16951         local rootpath
16952         local found
16953         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
16954                 echo "$rootpath $fid"
16955                 found=$($LFS fid2path $rootpath "$fid")
16956                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
16957                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
16958         done
16959
16960         # check wrong root path format
16961         rootpath=$MOUNT"_wrong"
16962         found=$($LFS fid2path $rootpath "$fid")
16963         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
16964 }
16965 run_test 154A "lfs path2fid and fid2path basic checks"
16966
16967 test_154B() {
16968         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16969                 skip "Need MDS version at least 2.4.1"
16970
16971         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
16972         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
16973         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
16974         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
16975
16976         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
16977         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
16978
16979         # check that we get the same pathname
16980         echo "PFID: $PFID, name: $name"
16981         local FOUND=$($LFS fid2path $MOUNT "$PFID")
16982         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
16983         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
16984                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
16985
16986         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
16987 }
16988 run_test 154B "verify the ll_decode_linkea tool"
16989
16990 test_154a() {
16991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16992         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16993         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
16994                 skip "Need MDS version at least 2.2.51"
16995         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
16996
16997         cp /etc/hosts $DIR/$tfile
16998
16999         fid=$($LFS path2fid $DIR/$tfile)
17000         rc=$?
17001         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
17002
17003         dot_lustre_fid_permission_check "$fid" $DIR ||
17004                 error "dot lustre permission check $fid failed"
17005
17006         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
17007
17008         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
17009
17010         touch $MOUNT/.lustre/file &&
17011                 error "creation is not allowed under .lustre"
17012
17013         mkdir $MOUNT/.lustre/dir &&
17014                 error "mkdir is not allowed under .lustre"
17015
17016         rm -rf $DIR/$tfile
17017 }
17018 run_test 154a "Open-by-FID"
17019
17020 test_154b() {
17021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17022         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17023         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17024         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
17025                 skip "Need MDS version at least 2.2.51"
17026
17027         local remote_dir=$DIR/$tdir/remote_dir
17028         local MDTIDX=1
17029         local rc=0
17030
17031         mkdir -p $DIR/$tdir
17032         $LFS mkdir -i $MDTIDX $remote_dir ||
17033                 error "create remote directory failed"
17034
17035         cp /etc/hosts $remote_dir/$tfile
17036
17037         fid=$($LFS path2fid $remote_dir/$tfile)
17038         rc=$?
17039         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
17040
17041         dot_lustre_fid_permission_check "$fid" $remote_dir ||
17042                 error "dot lustre permission check $fid failed"
17043         rm -rf $DIR/$tdir
17044 }
17045 run_test 154b "Open-by-FID for remote directory"
17046
17047 test_154c() {
17048         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
17049                 skip "Need MDS version at least 2.4.1"
17050
17051         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
17052         local FID1=$($LFS path2fid $DIR/$tfile.1)
17053         local FID2=$($LFS path2fid $DIR/$tfile.2)
17054         local FID3=$($LFS path2fid $DIR/$tfile.3)
17055
17056         local N=1
17057         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
17058                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
17059                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
17060                 local want=FID$N
17061                 [ "$FID" = "${!want}" ] ||
17062                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
17063                 N=$((N + 1))
17064         done
17065
17066         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
17067         do
17068                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
17069                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
17070                 N=$((N + 1))
17071         done
17072 }
17073 run_test 154c "lfs path2fid and fid2path multiple arguments"
17074
17075 test_154d() {
17076         remote_mds_nodsh && skip "remote MDS with nodsh"
17077         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
17078                 skip "Need MDS version at least 2.5.53"
17079
17080         if remote_mds; then
17081                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
17082         else
17083                 nid="0@lo"
17084         fi
17085         local proc_ofile="mdt.*.exports.'$nid'.open_files"
17086         local fd
17087         local cmd
17088
17089         rm -f $DIR/$tfile
17090         touch $DIR/$tfile
17091
17092         local fid=$($LFS path2fid $DIR/$tfile)
17093         # Open the file
17094         fd=$(free_fd)
17095         cmd="exec $fd<$DIR/$tfile"
17096         eval $cmd
17097         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
17098         echo "$fid_list" | grep "$fid"
17099         rc=$?
17100
17101         cmd="exec $fd>/dev/null"
17102         eval $cmd
17103         if [ $rc -ne 0 ]; then
17104                 error "FID $fid not found in open files list $fid_list"
17105         fi
17106 }
17107 run_test 154d "Verify open file fid"
17108
17109 test_154e()
17110 {
17111         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
17112                 skip "Need MDS version at least 2.6.50"
17113
17114         if ls -a $MOUNT | grep -q '^\.lustre$'; then
17115                 error ".lustre returned by readdir"
17116         fi
17117 }
17118 run_test 154e ".lustre is not returned by readdir"
17119
17120 test_154f() {
17121         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17122
17123         # create parent directory on a single MDT to avoid cross-MDT hardlinks
17124         mkdir_on_mdt0 $DIR/$tdir
17125         # test dirs inherit from its stripe
17126         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
17127         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
17128         cp /etc/hosts $DIR/$tdir/foo1/$tfile
17129         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
17130         touch $DIR/f
17131
17132         # get fid of parents
17133         local FID0=$($LFS path2fid $DIR/$tdir)
17134         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
17135         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
17136         local FID3=$($LFS path2fid $DIR)
17137
17138         # check that path2fid --parents returns expected <parent_fid>/name
17139         # 1) test for a directory (single parent)
17140         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
17141         [ "$parent" == "$FID0/foo1" ] ||
17142                 error "expected parent: $FID0/foo1, got: $parent"
17143
17144         # 2) test for a file with nlink > 1 (multiple parents)
17145         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
17146         echo "$parent" | grep -F "$FID1/$tfile" ||
17147                 error "$FID1/$tfile not returned in parent list"
17148         echo "$parent" | grep -F "$FID2/link" ||
17149                 error "$FID2/link not returned in parent list"
17150
17151         # 3) get parent by fid
17152         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
17153         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17154         echo "$parent" | grep -F "$FID1/$tfile" ||
17155                 error "$FID1/$tfile not returned in parent list (by fid)"
17156         echo "$parent" | grep -F "$FID2/link" ||
17157                 error "$FID2/link not returned in parent list (by fid)"
17158
17159         # 4) test for entry in root directory
17160         parent=$($LFS path2fid --parents $DIR/f)
17161         echo "$parent" | grep -F "$FID3/f" ||
17162                 error "$FID3/f not returned in parent list"
17163
17164         # 5) test it on root directory
17165         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
17166                 error "$MOUNT should not have parents"
17167
17168         # enable xattr caching and check that linkea is correctly updated
17169         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
17170         save_lustre_params client "llite.*.xattr_cache" > $save
17171         lctl set_param llite.*.xattr_cache 1
17172
17173         # 6.1) linkea update on rename
17174         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
17175
17176         # get parents by fid
17177         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17178         # foo1 should no longer be returned in parent list
17179         echo "$parent" | grep -F "$FID1" &&
17180                 error "$FID1 should no longer be in parent list"
17181         # the new path should appear
17182         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
17183                 error "$FID2/$tfile.moved is not in parent list"
17184
17185         # 6.2) linkea update on unlink
17186         rm -f $DIR/$tdir/foo2/link
17187         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17188         # foo2/link should no longer be returned in parent list
17189         echo "$parent" | grep -F "$FID2/link" &&
17190                 error "$FID2/link should no longer be in parent list"
17191         true
17192
17193         rm -f $DIR/f
17194         restore_lustre_params < $save
17195         rm -f $save
17196 }
17197 run_test 154f "get parent fids by reading link ea"
17198
17199 test_154g()
17200 {
17201         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
17202            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
17203                 skip "Need MDS version at least 2.6.92"
17204
17205         mkdir_on_mdt0 $DIR/$tdir
17206         llapi_fid_test -d $DIR/$tdir
17207 }
17208 run_test 154g "various llapi FID tests"
17209
17210 test_154h()
17211 {
17212         (( $CLIENT_VERSION >= $(version_code 2.15.55.1) )) ||
17213                 skip "Need client at least version 2.15.55.1"
17214
17215         # Create an empty file
17216         touch $DIR/$tfile
17217
17218         # Get FID (interactive mode) and save under $TMP/$tfile.log
17219         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
17220                 path2fid $DIR/$tfile
17221         EOF
17222
17223         fid=$(cat $TMP/$tfile.log)
17224         # $fid should not be empty
17225         [[ ! -z $fid ]] || error "FID is empty"
17226         $LFS rmfid $DIR "$fid" || error "rmfid failed for $fid"
17227 }
17228 run_test 154h "Verify interactive path2fid"
17229
17230 test_155_small_load() {
17231     local temp=$TMP/$tfile
17232     local file=$DIR/$tfile
17233
17234     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
17235         error "dd of=$temp bs=6096 count=1 failed"
17236     cp $temp $file
17237     cancel_lru_locks $OSC
17238     cmp $temp $file || error "$temp $file differ"
17239
17240     $TRUNCATE $temp 6000
17241     $TRUNCATE $file 6000
17242     cmp $temp $file || error "$temp $file differ (truncate1)"
17243
17244     echo "12345" >>$temp
17245     echo "12345" >>$file
17246     cmp $temp $file || error "$temp $file differ (append1)"
17247
17248     echo "12345" >>$temp
17249     echo "12345" >>$file
17250     cmp $temp $file || error "$temp $file differ (append2)"
17251
17252     rm -f $temp $file
17253     true
17254 }
17255
17256 test_155_big_load() {
17257         remote_ost_nodsh && skip "remote OST with nodsh"
17258
17259         local temp=$TMP/$tfile
17260         local file=$DIR/$tfile
17261
17262         free_min_max
17263         local cache_size=$(do_facet ost$((MAXI+1)) \
17264                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
17265
17266         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
17267         # pre-set value
17268         if [ -z "$cache_size" ]; then
17269                 cache_size=256
17270         fi
17271         local large_file_size=$((cache_size * 2))
17272
17273         echo "OSS cache size: $cache_size KB"
17274         echo "Large file size: $large_file_size KB"
17275
17276         [ $MAXV -le $large_file_size ] &&
17277                 skip_env "max available OST size needs > $large_file_size KB"
17278
17279         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
17280
17281         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
17282                 error "dd of=$temp bs=$large_file_size count=1k failed"
17283         cp $temp $file
17284         ls -lh $temp $file
17285         cancel_lru_locks osc
17286         cmp $temp $file || error "$temp $file differ"
17287
17288         rm -f $temp $file
17289         true
17290 }
17291
17292 save_writethrough() {
17293         local facets=$(get_facets OST)
17294
17295         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
17296 }
17297
17298 test_155a() {
17299         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17300
17301         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17302
17303         save_writethrough $p
17304
17305         set_cache read on
17306         set_cache writethrough on
17307         test_155_small_load
17308         restore_lustre_params < $p
17309         rm -f $p
17310 }
17311 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
17312
17313 test_155b() {
17314         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17315
17316         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17317
17318         save_writethrough $p
17319
17320         set_cache read on
17321         set_cache writethrough off
17322         test_155_small_load
17323         restore_lustre_params < $p
17324         rm -f $p
17325 }
17326 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
17327
17328 test_155c() {
17329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17330
17331         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17332
17333         save_writethrough $p
17334
17335         set_cache read off
17336         set_cache writethrough on
17337         test_155_small_load
17338         restore_lustre_params < $p
17339         rm -f $p
17340 }
17341 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
17342
17343 test_155d() {
17344         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17345
17346         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17347
17348         save_writethrough $p
17349
17350         set_cache read off
17351         set_cache writethrough off
17352         test_155_small_load
17353         restore_lustre_params < $p
17354         rm -f $p
17355 }
17356 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
17357
17358 test_155e() {
17359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17360
17361         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17362
17363         save_writethrough $p
17364
17365         set_cache read on
17366         set_cache writethrough on
17367         test_155_big_load
17368         restore_lustre_params < $p
17369         rm -f $p
17370 }
17371 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
17372
17373 test_155f() {
17374         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17375
17376         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17377
17378         save_writethrough $p
17379
17380         set_cache read on
17381         set_cache writethrough off
17382         test_155_big_load
17383         restore_lustre_params < $p
17384         rm -f $p
17385 }
17386 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
17387
17388 test_155g() {
17389         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17390
17391         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17392
17393         save_writethrough $p
17394
17395         set_cache read off
17396         set_cache writethrough on
17397         test_155_big_load
17398         restore_lustre_params < $p
17399         rm -f $p
17400 }
17401 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
17402
17403 test_155h() {
17404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17405
17406         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17407
17408         save_writethrough $p
17409
17410         set_cache read off
17411         set_cache writethrough off
17412         test_155_big_load
17413         restore_lustre_params < $p
17414         rm -f $p
17415 }
17416 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
17417
17418 test_156() {
17419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17420         remote_ost_nodsh && skip "remote OST with nodsh"
17421         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
17422                 skip "stats not implemented on old servers"
17423         [ "$ost1_FSTYPE" = "zfs" ] &&
17424                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
17425         (( CLIENT_VERSION == OST1_VERSION )) ||
17426                 skip "LU-13081: no interop testing for OSS cache"
17427
17428         local CPAGES=3
17429         local BEFORE
17430         local AFTER
17431         local file="$DIR/$tfile"
17432         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17433
17434         save_writethrough $p
17435         roc_hit_init
17436
17437         log "Turn on read and write cache"
17438         set_cache read on
17439         set_cache writethrough on
17440
17441         log "Write data and read it back."
17442         log "Read should be satisfied from the cache."
17443         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17444         BEFORE=$(roc_hit)
17445         cancel_lru_locks osc
17446         cat $file >/dev/null
17447         AFTER=$(roc_hit)
17448         if ! let "AFTER - BEFORE == CPAGES"; then
17449                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
17450         else
17451                 log "cache hits: before: $BEFORE, after: $AFTER"
17452         fi
17453
17454         log "Read again; it should be satisfied from the cache."
17455         BEFORE=$AFTER
17456         cancel_lru_locks osc
17457         cat $file >/dev/null
17458         AFTER=$(roc_hit)
17459         if ! let "AFTER - BEFORE == CPAGES"; then
17460                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
17461         else
17462                 log "cache hits:: before: $BEFORE, after: $AFTER"
17463         fi
17464
17465         log "Turn off the read cache and turn on the write cache"
17466         set_cache read off
17467         set_cache writethrough on
17468
17469         log "Read again; it should be satisfied from the cache."
17470         BEFORE=$(roc_hit)
17471         cancel_lru_locks osc
17472         cat $file >/dev/null
17473         AFTER=$(roc_hit)
17474         if ! let "AFTER - BEFORE == CPAGES"; then
17475                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
17476         else
17477                 log "cache hits:: before: $BEFORE, after: $AFTER"
17478         fi
17479
17480         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17481                 # > 2.12.56 uses pagecache if cached
17482                 log "Read again; it should not be satisfied from the cache."
17483                 BEFORE=$AFTER
17484                 cancel_lru_locks osc
17485                 cat $file >/dev/null
17486                 AFTER=$(roc_hit)
17487                 if ! let "AFTER - BEFORE == 0"; then
17488                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
17489                 else
17490                         log "cache hits:: before: $BEFORE, after: $AFTER"
17491                 fi
17492         fi
17493
17494         log "Write data and read it back."
17495         log "Read should be satisfied from the cache."
17496         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17497         BEFORE=$(roc_hit)
17498         cancel_lru_locks osc
17499         cat $file >/dev/null
17500         AFTER=$(roc_hit)
17501         if ! let "AFTER - BEFORE == CPAGES"; then
17502                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
17503         else
17504                 log "cache hits:: before: $BEFORE, after: $AFTER"
17505         fi
17506
17507         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17508                 # > 2.12.56 uses pagecache if cached
17509                 log "Read again; it should not be satisfied from the cache."
17510                 BEFORE=$AFTER
17511                 cancel_lru_locks osc
17512                 cat $file >/dev/null
17513                 AFTER=$(roc_hit)
17514                 if ! let "AFTER - BEFORE == 0"; then
17515                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
17516                 else
17517                         log "cache hits:: before: $BEFORE, after: $AFTER"
17518                 fi
17519         fi
17520
17521         log "Turn off read and write cache"
17522         set_cache read off
17523         set_cache writethrough off
17524
17525         log "Write data and read it back"
17526         log "It should not be satisfied from the cache."
17527         rm -f $file
17528         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17529         cancel_lru_locks osc
17530         BEFORE=$(roc_hit)
17531         cat $file >/dev/null
17532         AFTER=$(roc_hit)
17533         if ! let "AFTER - BEFORE == 0"; then
17534                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
17535         else
17536                 log "cache hits:: before: $BEFORE, after: $AFTER"
17537         fi
17538
17539         log "Turn on the read cache and turn off the write cache"
17540         set_cache read on
17541         set_cache writethrough off
17542
17543         log "Write data and read it back"
17544         log "It should not be satisfied from the cache."
17545         rm -f $file
17546         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17547         BEFORE=$(roc_hit)
17548         cancel_lru_locks osc
17549         cat $file >/dev/null
17550         AFTER=$(roc_hit)
17551         if ! let "AFTER - BEFORE == 0"; then
17552                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
17553         else
17554                 log "cache hits:: before: $BEFORE, after: $AFTER"
17555         fi
17556
17557         log "Read again; it should be satisfied from the cache."
17558         BEFORE=$(roc_hit)
17559         cancel_lru_locks osc
17560         cat $file >/dev/null
17561         AFTER=$(roc_hit)
17562         if ! let "AFTER - BEFORE == CPAGES"; then
17563                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
17564         else
17565                 log "cache hits:: before: $BEFORE, after: $AFTER"
17566         fi
17567
17568         restore_lustre_params < $p
17569         rm -f $p $file
17570 }
17571 run_test 156 "Verification of tunables"
17572
17573 test_160a() {
17574         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17575         remote_mds_nodsh && skip "remote MDS with nodsh"
17576         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17577                 skip "Need MDS version at least 2.2.0"
17578
17579         changelog_register || error "changelog_register failed"
17580         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17581         changelog_users $SINGLEMDS | grep -q $cl_user ||
17582                 error "User $cl_user not found in changelog_users"
17583
17584         mkdir_on_mdt0 $DIR/$tdir
17585
17586         # change something
17587         test_mkdir -p $DIR/$tdir/pics/2008/zachy
17588         changelog_clear 0 || error "changelog_clear failed"
17589         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
17590         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
17591         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17592         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17593         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17594         rm $DIR/$tdir/pics/desktop.jpg
17595
17596         echo "verifying changelog mask"
17597         changelog_chmask "-MKDIR"
17598         changelog_chmask "-CLOSE"
17599
17600         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
17601         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
17602
17603         changelog_chmask "+MKDIR"
17604         changelog_chmask "+CLOSE"
17605
17606         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
17607         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
17608
17609         MKDIRS=$(changelog_dump | grep -c "MKDIR")
17610         CLOSES=$(changelog_dump | grep -c "CLOSE")
17611         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
17612         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
17613
17614         # verify contents
17615         echo "verifying target fid"
17616         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
17617         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
17618         [ "$fidc" == "$fidf" ] ||
17619                 error "changelog '$tfile' fid $fidc != file fid $fidf"
17620         echo "verifying parent fid"
17621         # The FID returned from the Changelog may be the directory shard on
17622         # a different MDT, and not the FID returned by path2fid on the parent.
17623         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
17624         # since this is what will matter when recreating this file in the tree.
17625         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
17626         local pathp=$($LFS fid2path $MOUNT "$fidp")
17627         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
17628                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
17629
17630         echo "getting records for $cl_user"
17631         changelog_users $SINGLEMDS
17632         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
17633         local nclr=3
17634         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
17635                 error "changelog_clear failed"
17636         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
17637         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
17638         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
17639                 error "user index expect $user_rec1 + $nclr != $user_rec2"
17640
17641         local min0_rec=$(changelog_users $SINGLEMDS |
17642                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
17643         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
17644                           awk '{ print $1; exit; }')
17645
17646         changelog_dump | tail -n 5
17647         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
17648         [ $first_rec == $((min0_rec + 1)) ] ||
17649                 error "first index should be $min0_rec + 1 not $first_rec"
17650
17651         # LU-3446 changelog index reset on MDT restart
17652         local cur_rec1=$(changelog_users $SINGLEMDS |
17653                          awk '/^current.index:/ { print $NF }')
17654         changelog_clear 0 ||
17655                 error "clear all changelog records for $cl_user failed"
17656         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
17657         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
17658                 error "Fail to start $SINGLEMDS"
17659         local cur_rec2=$(changelog_users $SINGLEMDS |
17660                          awk '/^current.index:/ { print $NF }')
17661         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
17662         [ $cur_rec1 == $cur_rec2 ] ||
17663                 error "current index should be $cur_rec1 not $cur_rec2"
17664
17665         echo "verifying users from this test are deregistered"
17666         changelog_deregister || error "changelog_deregister failed"
17667         changelog_users $SINGLEMDS | grep -q $cl_user &&
17668                 error "User '$cl_user' still in changelog_users"
17669
17670         # lctl get_param -n mdd.*.changelog_users
17671         # current_index: 144
17672         # ID    index (idle seconds)
17673         # cl3   144   (2) mask=<list>
17674         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
17675                 # this is the normal case where all users were deregistered
17676                 # make sure no new records are added when no users are present
17677                 local last_rec1=$(changelog_users $SINGLEMDS |
17678                                   awk '/^current.index:/ { print $NF }')
17679                 touch $DIR/$tdir/chloe
17680                 local last_rec2=$(changelog_users $SINGLEMDS |
17681                                   awk '/^current.index:/ { print $NF }')
17682                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
17683                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
17684         else
17685                 # any changelog users must be leftovers from a previous test
17686                 changelog_users $SINGLEMDS
17687                 echo "other changelog users; can't verify off"
17688         fi
17689 }
17690 run_test 160a "changelog sanity"
17691
17692 test_160b() { # LU-3587
17693         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17694         remote_mds_nodsh && skip "remote MDS with nodsh"
17695         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17696                 skip "Need MDS version at least 2.2.0"
17697
17698         changelog_register || error "changelog_register failed"
17699         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17700         changelog_users $SINGLEMDS | grep -q $cl_user ||
17701                 error "User '$cl_user' not found in changelog_users"
17702
17703         local longname1=$(str_repeat a 255)
17704         local longname2=$(str_repeat b 255)
17705
17706         cd $DIR
17707         echo "creating very long named file"
17708         touch $longname1 || error "create of '$longname1' failed"
17709         echo "renaming very long named file"
17710         mv $longname1 $longname2
17711
17712         changelog_dump | grep RENME | tail -n 5
17713         rm -f $longname2
17714 }
17715 run_test 160b "Verify that very long rename doesn't crash in changelog"
17716
17717 test_160c() {
17718         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17719         remote_mds_nodsh && skip "remote MDS with nodsh"
17720
17721         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
17722                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
17723                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
17724                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
17725
17726         local rc=0
17727
17728         # Registration step
17729         changelog_register || error "changelog_register failed"
17730
17731         rm -rf $DIR/$tdir
17732         mkdir -p $DIR/$tdir
17733         $MCREATE $DIR/$tdir/foo_160c
17734         changelog_chmask "-TRUNC"
17735         $TRUNCATE $DIR/$tdir/foo_160c 200
17736         changelog_chmask "+TRUNC"
17737         $TRUNCATE $DIR/$tdir/foo_160c 199
17738         changelog_dump | tail -n 5
17739         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
17740         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
17741 }
17742 run_test 160c "verify that changelog log catch the truncate event"
17743
17744 test_160d() {
17745         remote_mds_nodsh && skip "remote MDS with nodsh"
17746         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17747         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17748         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
17749                 skip "Need MDS version at least 2.7.60"
17750
17751         # Registration step
17752         changelog_register || error "changelog_register failed"
17753
17754         mkdir -p $DIR/$tdir/migrate_dir
17755         changelog_clear 0 || error "changelog_clear failed"
17756
17757         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
17758         changelog_dump | tail -n 5
17759         local migrates=$(changelog_dump | grep -c "MIGRT")
17760         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
17761 }
17762 run_test 160d "verify that changelog log catch the migrate event"
17763
17764 test_160e() {
17765         remote_mds_nodsh && skip "remote MDS with nodsh"
17766
17767         # Create a user
17768         changelog_register || error "changelog_register failed"
17769
17770         local MDT0=$(facet_svc $SINGLEMDS)
17771         local rc
17772
17773         # No user (expect fail)
17774         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
17775         rc=$?
17776         if [ $rc -eq 0 ]; then
17777                 error "Should fail without user"
17778         elif [ $rc -ne 4 ]; then
17779                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
17780         fi
17781
17782         # Delete a future user (expect fail)
17783         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
17784         rc=$?
17785         if [ $rc -eq 0 ]; then
17786                 error "Deleted non-existant user cl77"
17787         elif [ $rc -ne 2 ]; then
17788                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
17789         fi
17790
17791         # Clear to a bad index (1 billion should be safe)
17792         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
17793         rc=$?
17794
17795         if [ $rc -eq 0 ]; then
17796                 error "Successfully cleared to invalid CL index"
17797         elif [ $rc -ne 22 ]; then
17798                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
17799         fi
17800 }
17801 run_test 160e "changelog negative testing (should return errors)"
17802
17803 test_160f() {
17804         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17805         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17806                 skip "Need MDS version at least 2.10.56"
17807
17808         local mdts=$(comma_list $(mdts_nodes))
17809
17810         # Create a user
17811         changelog_register || error "first changelog_register failed"
17812         changelog_register || error "second changelog_register failed"
17813         local cl_users
17814         declare -A cl_user1
17815         declare -A cl_user2
17816         local user_rec1
17817         local user_rec2
17818         local i
17819
17820         # generate some changelog records to accumulate on each MDT
17821         # use all_char because created files should be evenly distributed
17822         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17823                 error "test_mkdir $tdir failed"
17824         log "$(date +%s): creating first files"
17825         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17826                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
17827                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
17828         done
17829
17830         # check changelogs have been generated
17831         local start=$SECONDS
17832         local idle_time=$((MDSCOUNT * 5 + 5))
17833         local nbcl=$(changelog_dump | wc -l)
17834         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17835
17836         for param in "changelog_max_idle_time=$idle_time" \
17837                      "changelog_gc=1" \
17838                      "changelog_min_gc_interval=2" \
17839                      "changelog_min_free_cat_entries=3"; do
17840                 local MDT0=$(facet_svc $SINGLEMDS)
17841                 local var="${param%=*}"
17842                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17843
17844                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17845                 do_nodes $mdts $LCTL set_param mdd.*.$param
17846         done
17847
17848         # force cl_user2 to be idle (1st part), but also cancel the
17849         # cl_user1 records so that it is not evicted later in the test.
17850         local sleep1=$((idle_time / 2))
17851         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
17852         sleep $sleep1
17853
17854         # simulate changelog catalog almost full
17855         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
17856         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
17857
17858         for i in $(seq $MDSCOUNT); do
17859                 cl_users=(${CL_USERS[mds$i]})
17860                 cl_user1[mds$i]="${cl_users[0]}"
17861                 cl_user2[mds$i]="${cl_users[1]}"
17862
17863                 [ -n "${cl_user1[mds$i]}" ] ||
17864                         error "mds$i: no user registered"
17865                 [ -n "${cl_user2[mds$i]}" ] ||
17866                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17867
17868                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17869                 [ -n "$user_rec1" ] ||
17870                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17871                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17872                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17873                 [ -n "$user_rec2" ] ||
17874                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17875                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17876                      "$user_rec1 + 2 == $user_rec2"
17877                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17878                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17879                               "$user_rec1 + 2, but is $user_rec2"
17880                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17881                 [ -n "$user_rec2" ] ||
17882                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17883                 [ $user_rec1 == $user_rec2 ] ||
17884                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17885                               "$user_rec1, but is $user_rec2"
17886         done
17887
17888         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
17889         local sleep2=$((idle_time - (SECONDS - start) + 1))
17890         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
17891         sleep $sleep2
17892
17893         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17894         # cl_user1 should be OK because it recently processed records.
17895         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
17896         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17897                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
17898                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
17899         done
17900
17901         # ensure gc thread is done
17902         for i in $(mdts_nodes); do
17903                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17904                         error "$i: GC-thread not done"
17905         done
17906
17907         local first_rec
17908         for (( i = 1; i <= MDSCOUNT; i++ )); do
17909                 # check cl_user1 still registered
17910                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17911                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17912                 # check cl_user2 unregistered
17913                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17914                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17915
17916                 # check changelogs are present and starting at $user_rec1 + 1
17917                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17918                 [ -n "$user_rec1" ] ||
17919                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17920                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17921                             awk '{ print $1; exit; }')
17922
17923                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17924                 [ $((user_rec1 + 1)) == $first_rec ] ||
17925                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17926         done
17927 }
17928 run_test 160f "changelog garbage collect (timestamped users)"
17929
17930 test_160g() {
17931         remote_mds_nodsh && skip "remote MDS with nodsh"
17932         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
17933                 skip "Need MDS version at least 2.14.55"
17934
17935         local mdts=$(comma_list $(mdts_nodes))
17936
17937         # Create a user
17938         changelog_register || error "first changelog_register failed"
17939         changelog_register || error "second changelog_register failed"
17940         local cl_users
17941         declare -A cl_user1
17942         declare -A cl_user2
17943         local user_rec1
17944         local user_rec2
17945         local i
17946
17947         # generate some changelog records to accumulate on each MDT
17948         # use all_char because created files should be evenly distributed
17949         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17950                 error "test_mkdir $tdir failed"
17951         for ((i = 0; i < MDSCOUNT; i++)); do
17952                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17953                         error "create $DIR/$tdir/d$i.1 failed"
17954         done
17955
17956         # check changelogs have been generated
17957         local nbcl=$(changelog_dump | wc -l)
17958         (( $nbcl > 0 )) || error "no changelogs found"
17959
17960         # reduce the max_idle_indexes value to make sure we exceed it
17961         for param in "changelog_max_idle_indexes=2" \
17962                      "changelog_gc=1" \
17963                      "changelog_min_gc_interval=2"; do
17964                 local MDT0=$(facet_svc $SINGLEMDS)
17965                 local var="${param%=*}"
17966                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17967
17968                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17969                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17970                         error "unable to set mdd.*.$param"
17971         done
17972
17973         local start=$SECONDS
17974         for i in $(seq $MDSCOUNT); do
17975                 cl_users=(${CL_USERS[mds$i]})
17976                 cl_user1[mds$i]="${cl_users[0]}"
17977                 cl_user2[mds$i]="${cl_users[1]}"
17978
17979                 [ -n "${cl_user1[mds$i]}" ] ||
17980                         error "mds$i: user1 is not registered"
17981                 [ -n "${cl_user2[mds$i]}" ] ||
17982                         error "mds$i: only ${cl_user1[mds$i]} is registered"
17983
17984                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17985                 [ -n "$user_rec1" ] ||
17986                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
17987                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17988                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17989                 [ -n "$user_rec2" ] ||
17990                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
17991                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
17992                      "$user_rec1 + 2 == $user_rec2"
17993                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17994                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
17995                               "expected $user_rec1 + 2, but is $user_rec2"
17996                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17997                 [ -n "$user_rec2" ] ||
17998                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
17999                 [ $user_rec1 == $user_rec2 ] ||
18000                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
18001                               "expected $user_rec1, but is $user_rec2"
18002         done
18003
18004         # ensure we are past the previous changelog_min_gc_interval set above
18005         local sleep2=$((start + 2 - SECONDS))
18006         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18007         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
18008         # cl_user1 should be OK because it recently processed records.
18009         for ((i = 0; i < MDSCOUNT; i++)); do
18010                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
18011                         error "create $DIR/$tdir/d$i.3 failed"
18012         done
18013
18014         # ensure gc thread is done
18015         for i in $(mdts_nodes); do
18016                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
18017                         error "$i: GC-thread not done"
18018         done
18019
18020         local first_rec
18021         for (( i = 1; i <= MDSCOUNT; i++ )); do
18022                 # check cl_user1 still registered
18023                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
18024                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
18025                 # check cl_user2 unregistered
18026                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
18027                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
18028
18029                 # check changelogs are present and starting at $user_rec1 + 1
18030                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18031                 [ -n "$user_rec1" ] ||
18032                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
18033                 first_rec=$($LFS changelog $(facet_svc mds$i) |
18034                             awk '{ print $1; exit; }')
18035
18036                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
18037                 [ $((user_rec1 + 1)) == $first_rec ] ||
18038                         error "mds$i: rec $first_rec != $user_rec1 + 1"
18039         done
18040 }
18041 run_test 160g "changelog garbage collect on idle records"
18042
18043 test_160h() {
18044         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18045         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
18046                 skip "Need MDS version at least 2.10.56"
18047
18048         local mdts=$(comma_list $(mdts_nodes))
18049
18050         # Create a user
18051         changelog_register || error "first changelog_register failed"
18052         changelog_register || error "second changelog_register failed"
18053         local cl_users
18054         declare -A cl_user1
18055         declare -A cl_user2
18056         local user_rec1
18057         local user_rec2
18058         local i
18059
18060         # generate some changelog records to accumulate on each MDT
18061         # use all_char because created files should be evenly distributed
18062         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18063                 error "test_mkdir $tdir failed"
18064         for ((i = 0; i < MDSCOUNT; i++)); do
18065                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18066                         error "create $DIR/$tdir/d$i.1 failed"
18067         done
18068
18069         # check changelogs have been generated
18070         local nbcl=$(changelog_dump | wc -l)
18071         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18072
18073         for param in "changelog_max_idle_time=10" \
18074                      "changelog_gc=1" \
18075                      "changelog_min_gc_interval=2"; do
18076                 local MDT0=$(facet_svc $SINGLEMDS)
18077                 local var="${param%=*}"
18078                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18079
18080                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18081                 do_nodes $mdts $LCTL set_param mdd.*.$param
18082         done
18083
18084         # force cl_user2 to be idle (1st part)
18085         sleep 9
18086
18087         for i in $(seq $MDSCOUNT); do
18088                 cl_users=(${CL_USERS[mds$i]})
18089                 cl_user1[mds$i]="${cl_users[0]}"
18090                 cl_user2[mds$i]="${cl_users[1]}"
18091
18092                 [ -n "${cl_user1[mds$i]}" ] ||
18093                         error "mds$i: no user registered"
18094                 [ -n "${cl_user2[mds$i]}" ] ||
18095                         error "mds$i: only ${cl_user2[mds$i]} is registered"
18096
18097                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18098                 [ -n "$user_rec1" ] ||
18099                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18100                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
18101                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18102                 [ -n "$user_rec2" ] ||
18103                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18104                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
18105                      "$user_rec1 + 2 == $user_rec2"
18106                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
18107                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
18108                               "$user_rec1 + 2, but is $user_rec2"
18109                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
18110                 [ -n "$user_rec2" ] ||
18111                         error "mds$i: User ${cl_user2[mds$i]} not registered"
18112                 [ $user_rec1 == $user_rec2 ] ||
18113                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
18114                               "$user_rec1, but is $user_rec2"
18115         done
18116
18117         # force cl_user2 to be idle (2nd part) and to reach
18118         # changelog_max_idle_time
18119         sleep 2
18120
18121         # force each GC-thread start and block then
18122         # one per MDT/MDD, set fail_val accordingly
18123         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
18124         do_nodes $mdts $LCTL set_param fail_loc=0x1316
18125
18126         # generate more changelogs to trigger fail_loc
18127         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
18128                 error "create $DIR/$tdir/${tfile}bis failed"
18129
18130         # stop MDT to stop GC-thread, should be done in back-ground as it will
18131         # block waiting for the thread to be released and exit
18132         declare -A stop_pids
18133         for i in $(seq $MDSCOUNT); do
18134                 stop mds$i &
18135                 stop_pids[mds$i]=$!
18136         done
18137
18138         for i in $(mdts_nodes); do
18139                 local facet
18140                 local nb=0
18141                 local facets=$(facets_up_on_host $i)
18142
18143                 for facet in ${facets//,/ }; do
18144                         if [[ $facet == mds* ]]; then
18145                                 nb=$((nb + 1))
18146                         fi
18147                 done
18148                 # ensure each MDS's gc threads are still present and all in "R"
18149                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
18150                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
18151                         error "$i: expected $nb GC-thread"
18152                 wait_update $i \
18153                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
18154                         "R" 20 ||
18155                         error "$i: GC-thread not found in R-state"
18156                 # check umounts of each MDT on MDS have reached kthread_stop()
18157                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
18158                         error "$i: expected $nb umount"
18159                 wait_update $i \
18160                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
18161                         error "$i: umount not found in D-state"
18162         done
18163
18164         # release all GC-threads
18165         do_nodes $mdts $LCTL set_param fail_loc=0
18166
18167         # wait for MDT stop to complete
18168         for i in $(seq $MDSCOUNT); do
18169                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
18170         done
18171
18172         # XXX
18173         # may try to check if any orphan changelog records are present
18174         # via ldiskfs/zfs and llog_reader...
18175
18176         # re-start/mount MDTs
18177         for i in $(seq $MDSCOUNT); do
18178                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
18179                         error "Fail to start mds$i"
18180         done
18181
18182         local first_rec
18183         for i in $(seq $MDSCOUNT); do
18184                 # check cl_user1 still registered
18185                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
18186                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18187                 # check cl_user2 unregistered
18188                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
18189                         error "mds$i: User ${cl_user2[mds$i]} still registered"
18190
18191                 # check changelogs are present and starting at $user_rec1 + 1
18192                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18193                 [ -n "$user_rec1" ] ||
18194                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18195                 first_rec=$($LFS changelog $(facet_svc mds$i) |
18196                             awk '{ print $1; exit; }')
18197
18198                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
18199                 [ $((user_rec1 + 1)) == $first_rec ] ||
18200                         error "mds$i: first index should be $user_rec1 + 1, " \
18201                               "but is $first_rec"
18202         done
18203 }
18204 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
18205               "during mount"
18206
18207 test_160i() {
18208
18209         local mdts=$(comma_list $(mdts_nodes))
18210
18211         changelog_register || error "first changelog_register failed"
18212
18213         # generate some changelog records to accumulate on each MDT
18214         # use all_char because created files should be evenly distributed
18215         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18216                 error "test_mkdir $tdir failed"
18217         for ((i = 0; i < MDSCOUNT; i++)); do
18218                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18219                         error "create $DIR/$tdir/d$i.1 failed"
18220         done
18221
18222         # check changelogs have been generated
18223         local nbcl=$(changelog_dump | wc -l)
18224         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18225
18226         # simulate race between register and unregister
18227         # XXX as fail_loc is set per-MDS, with DNE configs the race
18228         # simulation will only occur for one MDT per MDS and for the
18229         # others the normal race scenario will take place
18230         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
18231         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
18232         do_nodes $mdts $LCTL set_param fail_val=1
18233
18234         # unregister 1st user
18235         changelog_deregister &
18236         local pid1=$!
18237         # wait some time for deregister work to reach race rdv
18238         sleep 2
18239         # register 2nd user
18240         changelog_register || error "2nd user register failed"
18241
18242         wait $pid1 || error "1st user deregister failed"
18243
18244         local i
18245         local last_rec
18246         declare -A LAST_REC
18247         for i in $(seq $MDSCOUNT); do
18248                 if changelog_users mds$i | grep "^cl"; then
18249                         # make sure new records are added with one user present
18250                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
18251                                           awk '/^current.index:/ { print $NF }')
18252                 else
18253                         error "mds$i has no user registered"
18254                 fi
18255         done
18256
18257         # generate more changelog records to accumulate on each MDT
18258         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
18259                 error "create $DIR/$tdir/${tfile}bis failed"
18260
18261         for i in $(seq $MDSCOUNT); do
18262                 last_rec=$(changelog_users $SINGLEMDS |
18263                            awk '/^current.index:/ { print $NF }')
18264                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
18265                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
18266                         error "changelogs are off on mds$i"
18267         done
18268 }
18269 run_test 160i "changelog user register/unregister race"
18270
18271 test_160j() {
18272         remote_mds_nodsh && skip "remote MDS with nodsh"
18273         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
18274                 skip "Need MDS version at least 2.12.56"
18275
18276         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
18277         stack_trap "umount $MOUNT2" EXIT
18278
18279         changelog_register || error "first changelog_register failed"
18280         stack_trap "changelog_deregister" EXIT
18281
18282         # generate some changelog
18283         # use all_char because created files should be evenly distributed
18284         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18285                 error "mkdir $tdir failed"
18286         for ((i = 0; i < MDSCOUNT; i++)); do
18287                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18288                         error "create $DIR/$tdir/d$i.1 failed"
18289         done
18290
18291         # open the changelog device
18292         exec 3>/dev/changelog-$FSNAME-MDT0000
18293         stack_trap "exec 3>&-" EXIT
18294         exec 4</dev/changelog-$FSNAME-MDT0000
18295         stack_trap "exec 4<&-" EXIT
18296
18297         # umount the first lustre mount
18298         umount $MOUNT
18299         stack_trap "mount_client $MOUNT" EXIT
18300
18301         # read changelog, which may or may not fail, but should not crash
18302         cat <&4 >/dev/null
18303
18304         # clear changelog
18305         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18306         changelog_users $SINGLEMDS | grep -q $cl_user ||
18307                 error "User $cl_user not found in changelog_users"
18308
18309         printf 'clear:'$cl_user':0' >&3
18310 }
18311 run_test 160j "client can be umounted while its chanangelog is being used"
18312
18313 test_160k() {
18314         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18315         remote_mds_nodsh && skip "remote MDS with nodsh"
18316
18317         mkdir -p $DIR/$tdir/1/1
18318
18319         changelog_register || error "changelog_register failed"
18320         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18321
18322         changelog_users $SINGLEMDS | grep -q $cl_user ||
18323                 error "User '$cl_user' not found in changelog_users"
18324 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
18325         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
18326         rmdir $DIR/$tdir/1/1 & sleep 1
18327         mkdir $DIR/$tdir/2
18328         touch $DIR/$tdir/2/2
18329         rm -rf $DIR/$tdir/2
18330
18331         wait
18332         sleep 4
18333
18334         changelog_dump | grep rmdir || error "rmdir not recorded"
18335 }
18336 run_test 160k "Verify that changelog records are not lost"
18337
18338 # Verifies that a file passed as a parameter has recently had an operation
18339 # performed on it that has generated an MTIME changelog which contains the
18340 # correct parent FID. As files might reside on a different MDT from the
18341 # parent directory in DNE configurations, the FIDs are translated to paths
18342 # before being compared, which should be identical
18343 compare_mtime_changelog() {
18344         local file="${1}"
18345         local mdtidx
18346         local mtime
18347         local cl_fid
18348         local pdir
18349         local dir
18350
18351         mdtidx=$($LFS getstripe --mdt-index $file)
18352         mdtidx=$(printf "%04x" $mdtidx)
18353
18354         # Obtain the parent FID from the MTIME changelog
18355         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
18356         [ -z "$mtime" ] && error "MTIME changelog not recorded"
18357
18358         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
18359         [ -z "$cl_fid" ] && error "parent FID not present"
18360
18361         # Verify that the path for the parent FID is the same as the path for
18362         # the test directory
18363         pdir=$($LFS fid2path $MOUNT "$cl_fid")
18364
18365         dir=$(dirname $1)
18366
18367         [[ "${pdir%/}" == "$dir" ]] ||
18368                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
18369 }
18370
18371 test_160l() {
18372         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18373
18374         remote_mds_nodsh && skip "remote MDS with nodsh"
18375         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
18376                 skip "Need MDS version at least 2.13.55"
18377
18378         local cl_user
18379
18380         changelog_register || error "changelog_register failed"
18381         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18382
18383         changelog_users $SINGLEMDS | grep -q $cl_user ||
18384                 error "User '$cl_user' not found in changelog_users"
18385
18386         # Clear some types so that MTIME changelogs are generated
18387         changelog_chmask "-CREAT"
18388         changelog_chmask "-CLOSE"
18389
18390         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
18391
18392         # Test CL_MTIME during setattr
18393         touch $DIR/$tdir/$tfile
18394         compare_mtime_changelog $DIR/$tdir/$tfile
18395
18396         # Test CL_MTIME during close
18397         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
18398         compare_mtime_changelog $DIR/$tdir/${tfile}_2
18399 }
18400 run_test 160l "Verify that MTIME changelog records contain the parent FID"
18401
18402 test_160m() {
18403         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18404         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18405                 skip "Need MDS version at least 2.14.51"
18406         local cl_users
18407         local cl_user1
18408         local cl_user2
18409         local pid1
18410
18411         # Create a user
18412         changelog_register || error "first changelog_register failed"
18413         changelog_register || error "second changelog_register failed"
18414
18415         cl_users=(${CL_USERS[mds1]})
18416         cl_user1="${cl_users[0]}"
18417         cl_user2="${cl_users[1]}"
18418         # generate some changelog records to accumulate on MDT0
18419         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18420         createmany -m $DIR/$tdir/$tfile 50 ||
18421                 error "create $DIR/$tdir/$tfile failed"
18422         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18423         rm -f $DIR/$tdir
18424
18425         # check changelogs have been generated
18426         local nbcl=$(changelog_dump | wc -l)
18427         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18428
18429 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
18430         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
18431
18432         __changelog_clear mds1 $cl_user1 +10
18433         __changelog_clear mds1 $cl_user2 0 &
18434         pid1=$!
18435         sleep 2
18436         __changelog_clear mds1 $cl_user1 0 ||
18437                 error "fail to cancel record for $cl_user1"
18438         wait $pid1
18439         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
18440 }
18441 run_test 160m "Changelog clear race"
18442
18443 test_160n() {
18444         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18445         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18446                 skip "Need MDS version at least 2.14.51"
18447         local cl_users
18448         local cl_user1
18449         local cl_user2
18450         local pid1
18451         local first_rec
18452         local last_rec=0
18453
18454         # Create a user
18455         changelog_register || error "first changelog_register failed"
18456
18457         cl_users=(${CL_USERS[mds1]})
18458         cl_user1="${cl_users[0]}"
18459
18460         # generate some changelog records to accumulate on MDT0
18461         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18462         first_rec=$(changelog_users $SINGLEMDS |
18463                         awk '/^current.index:/ { print $NF }')
18464         while (( last_rec < (( first_rec + 65000)) )); do
18465                 createmany -m $DIR/$tdir/$tfile 10000 ||
18466                         error "create $DIR/$tdir/$tfile failed"
18467
18468                 for i in $(seq 0 10000); do
18469                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
18470                                 > /dev/null
18471                 done
18472
18473                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
18474                         error "unlinkmany failed unlink"
18475                 last_rec=$(changelog_users $SINGLEMDS |
18476                         awk '/^current.index:/ { print $NF }')
18477                 echo last record $last_rec
18478                 (( last_rec == 0 )) && error "no changelog found"
18479         done
18480
18481 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
18482         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
18483
18484         __changelog_clear mds1 $cl_user1 0 &
18485         pid1=$!
18486         sleep 2
18487         __changelog_clear mds1 $cl_user1 0 ||
18488                 error "fail to cancel record for $cl_user1"
18489         wait $pid1
18490         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
18491 }
18492 run_test 160n "Changelog destroy race"
18493
18494 test_160o() {
18495         local mdt="$(facet_svc $SINGLEMDS)"
18496
18497         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18498         remote_mds_nodsh && skip "remote MDS with nodsh"
18499         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
18500                 skip "Need MDS version at least 2.14.52"
18501
18502         changelog_register --user test_160o -m unlnk+close+open ||
18503                 error "changelog_register failed"
18504
18505         do_facet $SINGLEMDS $LCTL --device $mdt \
18506                                 changelog_register -u "Tt3_-#" &&
18507                 error "bad symbols in name should fail"
18508
18509         do_facet $SINGLEMDS $LCTL --device $mdt \
18510                                 changelog_register -u test_160o &&
18511                 error "the same name registration should fail"
18512
18513         do_facet $SINGLEMDS $LCTL --device $mdt \
18514                         changelog_register -u test_160toolongname &&
18515                 error "too long name registration should fail"
18516
18517         changelog_chmask "MARK+HSM"
18518         lctl get_param mdd.*.changelog*mask
18519         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18520         changelog_users $SINGLEMDS | grep -q $cl_user ||
18521                 error "User $cl_user not found in changelog_users"
18522         #verify username
18523         echo $cl_user | grep -q test_160o ||
18524                 error "User $cl_user has no specific name 'test160o'"
18525
18526         # change something
18527         changelog_clear 0 || error "changelog_clear failed"
18528         # generate some changelog records to accumulate on MDT0
18529         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18530         touch $DIR/$tdir/$tfile                 # open 1
18531
18532         OPENS=$(changelog_dump | grep -c "OPEN")
18533         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
18534
18535         # must be no MKDIR it wasn't set as user mask
18536         MKDIR=$(changelog_dump | grep -c "MKDIR")
18537         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
18538
18539         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
18540                                 mdd.$mdt.changelog_current_mask -n)
18541         # register maskless user
18542         changelog_register || error "changelog_register failed"
18543         # effective mask should be not changed because it is not minimal
18544         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18545                                 mdd.$mdt.changelog_current_mask -n)
18546         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
18547         # set server mask to minimal value
18548         changelog_chmask "MARK"
18549         # check effective mask again, should be treated as DEFMASK now
18550         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18551                                 mdd.$mdt.changelog_current_mask -n)
18552         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18553
18554         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
18555                 # set server mask back to some value
18556                 changelog_chmask "CLOSE,UNLNK"
18557                 # check effective mask again, should not remain as DEFMASK
18558                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
18559                                 mdd.$mdt.changelog_current_mask -n)
18560                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
18561         fi
18562
18563         do_facet $SINGLEMDS $LCTL --device $mdt \
18564                                 changelog_deregister -u test_160o ||
18565                 error "cannot deregister by name"
18566 }
18567 run_test 160o "changelog user name and mask"
18568
18569 test_160p() {
18570         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18571         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18572                 skip "Need MDS version at least 2.14.51"
18573         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
18574         local cl_users
18575         local cl_user1
18576         local entry_count
18577
18578         # Create a user
18579         changelog_register || error "first changelog_register failed"
18580
18581         cl_users=(${CL_USERS[mds1]})
18582         cl_user1="${cl_users[0]}"
18583
18584         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18585         createmany -m $DIR/$tdir/$tfile 50 ||
18586                 error "create $DIR/$tdir/$tfile failed"
18587         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18588         rm -rf $DIR/$tdir
18589
18590         # check changelogs have been generated
18591         entry_count=$(changelog_dump | wc -l)
18592         ((entry_count != 0)) || error "no changelog entries found"
18593
18594         # remove changelog_users and check that orphan entries are removed
18595         stop mds1
18596         local dev=$(mdsdevname 1)
18597         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
18598         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
18599         entry_count=$(changelog_dump | wc -l)
18600         ((entry_count == 0)) ||
18601                 error "found $entry_count changelog entries, expected none"
18602 }
18603 run_test 160p "Changelog orphan cleanup with no users"
18604
18605 test_160q() {
18606         local mdt="$(facet_svc $SINGLEMDS)"
18607         local clu
18608
18609         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18610         remote_mds_nodsh && skip "remote MDS with nodsh"
18611         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
18612                 skip "Need MDS version at least 2.14.54"
18613
18614         # set server mask to minimal value like server init does
18615         changelog_chmask "MARK"
18616         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
18617                 error "changelog_register failed"
18618         # check effective mask again, should be treated as DEFMASK now
18619         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18620                                 mdd.$mdt.changelog_current_mask -n)
18621         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
18622                 error "changelog_deregister failed"
18623         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18624 }
18625 run_test 160q "changelog effective mask is DEFMASK if not set"
18626
18627 test_160s() {
18628         remote_mds_nodsh && skip "remote MDS with nodsh"
18629         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
18630                 skip "Need MDS version at least 2.14.55"
18631
18632         local mdts=$(comma_list $(mdts_nodes))
18633
18634         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
18635         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
18636                                        fail_val=$((24 * 3600 * 10))
18637
18638         # Create a user which is 10 days old
18639         changelog_register || error "first changelog_register failed"
18640         local cl_users
18641         declare -A cl_user1
18642         local i
18643
18644         # generate some changelog records to accumulate on each MDT
18645         # use all_char because created files should be evenly distributed
18646         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18647                 error "test_mkdir $tdir failed"
18648         for ((i = 0; i < MDSCOUNT; i++)); do
18649                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18650                         error "create $DIR/$tdir/d$i.1 failed"
18651         done
18652
18653         # check changelogs have been generated
18654         local nbcl=$(changelog_dump | wc -l)
18655         (( nbcl > 0 )) || error "no changelogs found"
18656
18657         # reduce the max_idle_indexes value to make sure we exceed it
18658         for param in "changelog_max_idle_indexes=2097446912" \
18659                      "changelog_max_idle_time=2592000" \
18660                      "changelog_gc=1" \
18661                      "changelog_min_gc_interval=2"; do
18662                 local MDT0=$(facet_svc $SINGLEMDS)
18663                 local var="${param%=*}"
18664                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18665
18666                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18667                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
18668                         error "unable to set mdd.*.$param"
18669         done
18670
18671         local start=$SECONDS
18672         for i in $(seq $MDSCOUNT); do
18673                 cl_users=(${CL_USERS[mds$i]})
18674                 cl_user1[mds$i]="${cl_users[0]}"
18675
18676                 [[ -n "${cl_user1[mds$i]}" ]] ||
18677                         error "mds$i: no user registered"
18678         done
18679
18680         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
18681         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
18682
18683         # ensure we are past the previous changelog_min_gc_interval set above
18684         local sleep2=$((start + 2 - SECONDS))
18685         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18686
18687         # Generate one more changelog to trigger GC
18688         for ((i = 0; i < MDSCOUNT; i++)); do
18689                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
18690                         error "create $DIR/$tdir/d$i.3 failed"
18691         done
18692
18693         # ensure gc thread is done
18694         for node in $(mdts_nodes); do
18695                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
18696                         error "$node: GC-thread not done"
18697         done
18698
18699         do_nodes $mdts $LCTL set_param fail_loc=0
18700
18701         for (( i = 1; i <= MDSCOUNT; i++ )); do
18702                 # check cl_user1 is purged
18703                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
18704                         error "mds$i: User ${cl_user1[mds$i]} is registered"
18705         done
18706         return 0
18707 }
18708 run_test 160s "changelog garbage collect on idle records * time"
18709
18710 test_160t() {
18711         remote_mds_nodsh && skip "remote MDS with nodsh"
18712         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
18713                 skip "Need MDS version at least 2.15.50"
18714
18715         local MDT0=$(facet_svc $SINGLEMDS)
18716         local cl_users
18717         local cl_user1
18718         local cl_user2
18719         local start
18720
18721         changelog_register --user user1 -m all ||
18722                 error "user1 failed to register"
18723
18724         mkdir_on_mdt0 $DIR/$tdir
18725         # create default overstripe to maximize changelog size
18726         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
18727         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
18728         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18729
18730         # user2 consumes less records so less space
18731         changelog_register --user user2 || error "user2 failed to register"
18732         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
18733         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18734
18735         # check changelogs have been generated
18736         local nbcl=$(changelog_dump | wc -l)
18737         (( nbcl > 0 )) || error "no changelogs found"
18738
18739         # reduce the changelog_min_gc_interval to force check
18740         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
18741                 local var="${param%=*}"
18742                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18743
18744                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
18745                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
18746                         error "unable to set mdd.*.$param"
18747         done
18748
18749         start=$SECONDS
18750         cl_users=(${CL_USERS[mds1]})
18751         cl_user1="${cl_users[0]}"
18752         cl_user2="${cl_users[1]}"
18753
18754         [[ -n $cl_user1 ]] ||
18755                 error "mds1: user #1 isn't registered"
18756         [[ -n $cl_user2 ]] ||
18757                 error "mds1: user #2 isn't registered"
18758
18759         # ensure we are past the previous changelog_min_gc_interval set above
18760         local sleep2=$((start + 2 - SECONDS))
18761         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18762
18763         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
18764         do_facet mds1 $LCTL set_param fail_loc=0x018c \
18765                         fail_val=$(((llog_size1 + llog_size2) / 2))
18766
18767         # Generate more changelog to trigger GC
18768         createmany -o $DIR/$tdir/u3_ 4 ||
18769                 error "create failed for more files"
18770
18771         # ensure gc thread is done
18772         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
18773                 error "mds1: GC-thread not done"
18774
18775         do_facet mds1 $LCTL set_param fail_loc=0
18776
18777         # check cl_user1 is purged
18778         changelog_users mds1 | grep -q "$cl_user1" &&
18779                 error "User $cl_user1 is registered"
18780         # check cl_user2 is not purged
18781         changelog_users mds1 | grep -q "$cl_user2" ||
18782                 error "User $cl_user2 is not registered"
18783 }
18784 run_test 160t "changelog garbage collect on lack of space"
18785
18786 test_160u() { # LU-17400
18787         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18788         remote_mds_nodsh && skip "remote MDS with nodsh"
18789         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
18790                 skip "Need MDS version at least 2.2.0"
18791
18792         cd $DIR || error "cd $DIR failed"
18793
18794         # ensure changelog has a clean view if tests are run multiple times
18795         [ -d rename ] && rm -rf rename
18796
18797         changelog_register || error "changelog_register failed"
18798         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18799
18800         changelog_users $SINGLEMDS | grep -q $cl_user ||
18801                 error "User '$cl_user' not found in changelog_users"
18802
18803         local longname1=$(str_repeat a 255)
18804
18805         echo "creating simple directory tree"
18806         mkdir -p rename/a || error "create of simple directory tree failed"
18807         echo "creating rename/hw file"
18808         echo "hello world" > rename/hw || error "create of rename/hw failed"
18809         echo "creating very long named file"
18810         touch rename/$longname1 || error "create of 'rename/$longname1' failed"
18811         echo "move rename/hw to rename/a/a.hw"
18812         mv rename/hw rename/a/a.hw || error "mv failed"
18813
18814         RENME=($(changelog_dump | grep "RENME"))
18815         #declare -p RENME # for debugging captured value with indexes
18816
18817         [[ "${RENME[11]}" == "a.hw" && "${RENME[14]}" == "hw" ]] ||
18818                 error "changelog rename record type name/sname error"
18819 }
18820 run_test 160u "changelog rename record type name and sname strings are correct"
18821
18822 test_161a() {
18823         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18824
18825         test_mkdir -c1 $DIR/$tdir
18826         cp /etc/hosts $DIR/$tdir/$tfile
18827         test_mkdir -c1 $DIR/$tdir/foo1
18828         test_mkdir -c1 $DIR/$tdir/foo2
18829         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
18830         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
18831         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
18832         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
18833         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
18834         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18835                 $LFS fid2path $DIR $FID
18836                 error "bad link ea"
18837         fi
18838         # middle
18839         rm $DIR/$tdir/foo2/zachary
18840         # last
18841         rm $DIR/$tdir/foo2/thor
18842         # first
18843         rm $DIR/$tdir/$tfile
18844         # rename
18845         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
18846         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
18847                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
18848         rm $DIR/$tdir/foo2/maggie
18849
18850         # overflow the EA
18851         local longname=$tfile.avg_len_is_thirty_two_
18852         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
18853                 error_noexit 'failed to unlink many hardlinks'" EXIT
18854         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
18855                 error "failed to hardlink many files"
18856         links=$($LFS fid2path $DIR $FID | wc -l)
18857         echo -n "${links}/1000 links in link EA"
18858         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
18859 }
18860 run_test 161a "link ea sanity"
18861
18862 test_161b() {
18863         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18864         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
18865
18866         local MDTIDX=1
18867         local remote_dir=$DIR/$tdir/remote_dir
18868
18869         mkdir -p $DIR/$tdir
18870         $LFS mkdir -i $MDTIDX $remote_dir ||
18871                 error "create remote directory failed"
18872
18873         cp /etc/hosts $remote_dir/$tfile
18874         mkdir -p $remote_dir/foo1
18875         mkdir -p $remote_dir/foo2
18876         ln $remote_dir/$tfile $remote_dir/foo1/sofia
18877         ln $remote_dir/$tfile $remote_dir/foo2/zachary
18878         ln $remote_dir/$tfile $remote_dir/foo1/luna
18879         ln $remote_dir/$tfile $remote_dir/foo2/thor
18880
18881         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
18882                      tr -d ']')
18883         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18884                 $LFS fid2path $DIR $FID
18885                 error "bad link ea"
18886         fi
18887         # middle
18888         rm $remote_dir/foo2/zachary
18889         # last
18890         rm $remote_dir/foo2/thor
18891         # first
18892         rm $remote_dir/$tfile
18893         # rename
18894         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
18895         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
18896         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
18897                 $LFS fid2path $DIR $FID
18898                 error "bad link rename"
18899         fi
18900         rm $remote_dir/foo2/maggie
18901
18902         # overflow the EA
18903         local longname=filename_avg_len_is_thirty_two_
18904         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
18905                 error "failed to hardlink many files"
18906         links=$($LFS fid2path $DIR $FID | wc -l)
18907         echo -n "${links}/1000 links in link EA"
18908         [[ ${links} -gt 60 ]] ||
18909                 error "expected at least 60 links in link EA"
18910         unlinkmany $remote_dir/foo2/$longname 1000 ||
18911         error "failed to unlink many hardlinks"
18912 }
18913 run_test 161b "link ea sanity under remote directory"
18914
18915 test_161c() {
18916         remote_mds_nodsh && skip "remote MDS with nodsh"
18917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18918         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
18919                 skip "Need MDS version at least 2.1.5"
18920
18921         # define CLF_RENAME_LAST 0x0001
18922         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
18923         changelog_register || error "changelog_register failed"
18924
18925         rm -rf $DIR/$tdir
18926         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
18927         touch $DIR/$tdir/foo_161c
18928         touch $DIR/$tdir/bar_161c
18929         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18930         changelog_dump | grep RENME | tail -n 5
18931         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18932         changelog_clear 0 || error "changelog_clear failed"
18933         if [ x$flags != "x0x1" ]; then
18934                 error "flag $flags is not 0x1"
18935         fi
18936
18937         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
18938         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
18939         touch $DIR/$tdir/foo_161c
18940         touch $DIR/$tdir/bar_161c
18941         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18942         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18943         changelog_dump | grep RENME | tail -n 5
18944         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18945         changelog_clear 0 || error "changelog_clear failed"
18946         if [ x$flags != "x0x0" ]; then
18947                 error "flag $flags is not 0x0"
18948         fi
18949         echo "rename overwrite a target having nlink > 1," \
18950                 "changelog record has flags of $flags"
18951
18952         # rename doesn't overwrite a target (changelog flag 0x0)
18953         touch $DIR/$tdir/foo_161c
18954         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
18955         changelog_dump | grep RENME | tail -n 5
18956         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
18957         changelog_clear 0 || error "changelog_clear failed"
18958         if [ x$flags != "x0x0" ]; then
18959                 error "flag $flags is not 0x0"
18960         fi
18961         echo "rename doesn't overwrite a target," \
18962                 "changelog record has flags of $flags"
18963
18964         # define CLF_UNLINK_LAST 0x0001
18965         # unlink a file having nlink = 1 (changelog flag 0x1)
18966         rm -f $DIR/$tdir/foo2_161c
18967         changelog_dump | grep UNLNK | tail -n 5
18968         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18969         changelog_clear 0 || error "changelog_clear failed"
18970         if [ x$flags != "x0x1" ]; then
18971                 error "flag $flags is not 0x1"
18972         fi
18973         echo "unlink a file having nlink = 1," \
18974                 "changelog record has flags of $flags"
18975
18976         # unlink a file having nlink > 1 (changelog flag 0x0)
18977         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18978         rm -f $DIR/$tdir/foobar_161c
18979         changelog_dump | grep UNLNK | tail -n 5
18980         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18981         changelog_clear 0 || error "changelog_clear failed"
18982         if [ x$flags != "x0x0" ]; then
18983                 error "flag $flags is not 0x0"
18984         fi
18985         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
18986 }
18987 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
18988
18989 test_161d() {
18990         remote_mds_nodsh && skip "remote MDS with nodsh"
18991         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
18992
18993         local pid
18994         local fid
18995
18996         changelog_register || error "changelog_register failed"
18997
18998         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
18999         # interfer with $MOUNT/.lustre/fid/ access
19000         mkdir $DIR/$tdir
19001         [[ $? -eq 0 ]] || error "mkdir failed"
19002
19003         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | CFS_FAIL_ONCE
19004         $LCTL set_param fail_loc=0x8000140c
19005         # 5s pause
19006         $LCTL set_param fail_val=5
19007
19008         # create file
19009         echo foofoo > $DIR/$tdir/$tfile &
19010         pid=$!
19011
19012         # wait for create to be delayed
19013         sleep 2
19014
19015         ps -p $pid
19016         [[ $? -eq 0 ]] || error "create should be blocked"
19017
19018         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
19019         stack_trap "rm -f $tempfile"
19020         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
19021         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
19022         # some delay may occur during ChangeLog publishing and file read just
19023         # above, that could allow file write to happen finally
19024         [[ -s $tempfile ]] && echo "file should be empty"
19025
19026         $LCTL set_param fail_loc=0
19027
19028         wait $pid
19029         [[ $? -eq 0 ]] || error "create failed"
19030 }
19031 run_test 161d "create with concurrent .lustre/fid access"
19032
19033 check_path() {
19034         local expected="$1"
19035         shift
19036         local fid="$2"
19037
19038         local path
19039         path=$($LFS fid2path "$@")
19040         local rc=$?
19041
19042         if [ $rc -ne 0 ]; then
19043                 error "path looked up of '$expected' failed: rc=$rc"
19044         elif [ "$path" != "$expected" ]; then
19045                 error "path looked up '$path' instead of '$expected'"
19046         else
19047                 echo "FID '$fid' resolves to path '$path' as expected"
19048         fi
19049 }
19050
19051 test_162a() { # was test_162
19052         test_mkdir -p -c1 $DIR/$tdir/d2
19053         touch $DIR/$tdir/d2/$tfile
19054         touch $DIR/$tdir/d2/x1
19055         touch $DIR/$tdir/d2/x2
19056         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
19057         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
19058         # regular file
19059         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
19060         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
19061
19062         # softlink
19063         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
19064         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
19065         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
19066
19067         # softlink to wrong file
19068         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
19069         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
19070         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
19071
19072         # hardlink
19073         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
19074         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
19075         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
19076         # fid2path dir/fsname should both work
19077         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
19078         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
19079
19080         # hardlink count: check that there are 2 links
19081         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
19082         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
19083
19084         # hardlink indexing: remove the first link
19085         rm $DIR/$tdir/d2/p/q/r/hlink
19086         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
19087 }
19088 run_test 162a "path lookup sanity"
19089
19090 test_162b() {
19091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19092         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19093
19094         mkdir $DIR/$tdir
19095         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19096                                 error "create striped dir failed"
19097
19098         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
19099                                         tail -n 1 | awk '{print $2}')
19100         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
19101
19102         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
19103         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
19104
19105         # regular file
19106         for ((i=0;i<5;i++)); do
19107                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
19108                         error "get fid for f$i failed"
19109                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
19110
19111                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
19112                         error "get fid for d$i failed"
19113                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
19114         done
19115
19116         return 0
19117 }
19118 run_test 162b "striped directory path lookup sanity"
19119
19120 # LU-4239: Verify fid2path works with paths 100 or more directories deep
19121 test_162c() {
19122         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
19123                 skip "Need MDS version at least 2.7.51"
19124
19125         local lpath=$tdir.local
19126         local rpath=$tdir.remote
19127
19128         test_mkdir $DIR/$lpath
19129         test_mkdir $DIR/$rpath
19130
19131         for ((i = 0; i <= 101; i++)); do
19132                 lpath="$lpath/$i"
19133                 mkdir $DIR/$lpath
19134                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
19135                         error "get fid for local directory $DIR/$lpath failed"
19136                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
19137
19138                 rpath="$rpath/$i"
19139                 test_mkdir $DIR/$rpath
19140                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
19141                         error "get fid for remote directory $DIR/$rpath failed"
19142                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
19143         done
19144
19145         return 0
19146 }
19147 run_test 162c "fid2path works with paths 100 or more directories deep"
19148
19149 oalr_event_count() {
19150         local event="${1}"
19151         local trace="${2}"
19152
19153         awk -v name="${FSNAME}-OST0000" \
19154             -v event="${event}" \
19155             '$1 == "TRACE" && $2 == event && $3 == name' \
19156             "${trace}" |
19157         wc -l
19158 }
19159
19160 oalr_expect_event_count() {
19161         local event="${1}"
19162         local trace="${2}"
19163         local expect="${3}"
19164         local count
19165
19166         count=$(oalr_event_count "${event}" "${trace}")
19167         if ((count == expect)); then
19168                 return 0
19169         fi
19170
19171         error_noexit "${event} event count was '${count}', expected ${expect}"
19172         cat "${trace}" >&2
19173         exit 1
19174 }
19175
19176 cleanup_165() {
19177         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
19178         stop ost1
19179         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
19180 }
19181
19182 setup_165() {
19183         sync # Flush previous IOs so we can count log entries.
19184         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
19185         stack_trap cleanup_165 EXIT
19186 }
19187
19188 test_165a() {
19189         local trace="/tmp/${tfile}.trace"
19190         local rc
19191         local count
19192
19193         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19194                 skip "OFD access log unsupported"
19195
19196         setup_165
19197         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19198         sleep 5
19199
19200         do_facet ost1 ofd_access_log_reader --list
19201         stop ost1
19202
19203         do_facet ost1 killall -TERM ofd_access_log_reader
19204         wait
19205         rc=$?
19206
19207         if ((rc != 0)); then
19208                 error "ofd_access_log_reader exited with rc = '${rc}'"
19209         fi
19210
19211         # Parse trace file for discovery events:
19212         oalr_expect_event_count alr_log_add "${trace}" 1
19213         oalr_expect_event_count alr_log_eof "${trace}" 1
19214         oalr_expect_event_count alr_log_free "${trace}" 1
19215 }
19216 run_test 165a "ofd access log discovery"
19217
19218 test_165b() {
19219         local trace="/tmp/${tfile}.trace"
19220         local file="${DIR}/${tfile}"
19221         local pfid1
19222         local pfid2
19223         local -a entry
19224         local rc
19225         local count
19226         local size
19227         local flags
19228
19229         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19230                 skip "OFD access log unsupported"
19231
19232         setup_165
19233         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19234         sleep 5
19235
19236         do_facet ost1 ofd_access_log_reader --list
19237
19238         lfs setstripe -c 1 -i 0 "${file}"
19239         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19240                 error "cannot create '${file}'"
19241
19242         sleep 5
19243         do_facet ost1 killall -TERM ofd_access_log_reader
19244         wait
19245         rc=$?
19246
19247         if ((rc != 0)); then
19248                 error "ofd_access_log_reader exited with rc = '${rc}'"
19249         fi
19250
19251         oalr_expect_event_count alr_log_entry "${trace}" 1
19252
19253         pfid1=$($LFS path2fid "${file}")
19254
19255         # 1     2             3   4    5     6   7    8    9     10
19256         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
19257         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
19258
19259         echo "entry = '${entry[*]}'" >&2
19260
19261         pfid2=${entry[4]}
19262         if [[ "${pfid1}" != "${pfid2}" ]]; then
19263                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
19264         fi
19265
19266         size=${entry[8]}
19267         if ((size != 1048576)); then
19268                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
19269         fi
19270
19271         flags=${entry[10]}
19272         if [[ "${flags}" != "w" ]]; then
19273                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
19274         fi
19275
19276         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19277         sleep 5
19278
19279         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
19280                 error "cannot read '${file}'"
19281         sleep 5
19282
19283         do_facet ost1 killall -TERM ofd_access_log_reader
19284         wait
19285         rc=$?
19286
19287         if ((rc != 0)); then
19288                 error "ofd_access_log_reader exited with rc = '${rc}'"
19289         fi
19290
19291         oalr_expect_event_count alr_log_entry "${trace}" 1
19292
19293         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
19294         echo "entry = '${entry[*]}'" >&2
19295
19296         pfid2=${entry[4]}
19297         if [[ "${pfid1}" != "${pfid2}" ]]; then
19298                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
19299         fi
19300
19301         size=${entry[8]}
19302         if ((size != 524288)); then
19303                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
19304         fi
19305
19306         flags=${entry[10]}
19307         if [[ "${flags}" != "r" ]]; then
19308                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
19309         fi
19310 }
19311 run_test 165b "ofd access log entries are produced and consumed"
19312
19313 test_165c() {
19314         local trace="/tmp/${tfile}.trace"
19315         local file="${DIR}/${tdir}/${tfile}"
19316
19317         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19318                 skip "OFD access log unsupported"
19319
19320         test_mkdir "${DIR}/${tdir}"
19321
19322         setup_165
19323         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19324         sleep 5
19325
19326         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
19327
19328         # 4096 / 64 = 64. Create twice as many entries.
19329         for ((i = 0; i < 128; i++)); do
19330                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
19331                         error "cannot create file"
19332         done
19333
19334         sync
19335
19336         do_facet ost1 killall -TERM ofd_access_log_reader
19337         wait
19338         rc=$?
19339         if ((rc != 0)); then
19340                 error "ofd_access_log_reader exited with rc = '${rc}'"
19341         fi
19342
19343         unlinkmany  "${file}-%d" 128
19344 }
19345 run_test 165c "full ofd access logs do not block IOs"
19346
19347 oal_get_read_count() {
19348         local stats="$1"
19349
19350         # STATS lustre-OST0001 alr_read_count 1
19351
19352         do_facet ost1 cat "${stats}" |
19353         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
19354              END { print count; }'
19355 }
19356
19357 oal_expect_read_count() {
19358         local stats="$1"
19359         local count
19360         local expect="$2"
19361
19362         # Ask ofd_access_log_reader to write stats.
19363         do_facet ost1 killall -USR1 ofd_access_log_reader
19364
19365         # Allow some time for things to happen.
19366         sleep 1
19367
19368         count=$(oal_get_read_count "${stats}")
19369         if ((count == expect)); then
19370                 return 0
19371         fi
19372
19373         error_noexit "bad read count, got ${count}, expected ${expect}"
19374         do_facet ost1 cat "${stats}" >&2
19375         exit 1
19376 }
19377
19378 test_165d() {
19379         local stats="/tmp/${tfile}.stats"
19380         local file="${DIR}/${tdir}/${tfile}"
19381         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
19382
19383         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19384                 skip "OFD access log unsupported"
19385
19386         test_mkdir "${DIR}/${tdir}"
19387
19388         setup_165
19389         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
19390         sleep 5
19391
19392         lfs setstripe -c 1 -i 0 "${file}"
19393
19394         do_facet ost1 lctl set_param "${param}=rw"
19395         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19396                 error "cannot create '${file}'"
19397         oal_expect_read_count "${stats}" 1
19398
19399         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19400                 error "cannot read '${file}'"
19401         oal_expect_read_count "${stats}" 2
19402
19403         do_facet ost1 lctl set_param "${param}=r"
19404         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19405                 error "cannot create '${file}'"
19406         oal_expect_read_count "${stats}" 2
19407
19408         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19409                 error "cannot read '${file}'"
19410         oal_expect_read_count "${stats}" 3
19411
19412         do_facet ost1 lctl set_param "${param}=w"
19413         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19414                 error "cannot create '${file}'"
19415         oal_expect_read_count "${stats}" 4
19416
19417         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19418                 error "cannot read '${file}'"
19419         oal_expect_read_count "${stats}" 4
19420
19421         do_facet ost1 lctl set_param "${param}=0"
19422         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19423                 error "cannot create '${file}'"
19424         oal_expect_read_count "${stats}" 4
19425
19426         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19427                 error "cannot read '${file}'"
19428         oal_expect_read_count "${stats}" 4
19429
19430         do_facet ost1 killall -TERM ofd_access_log_reader
19431         wait
19432         rc=$?
19433         if ((rc != 0)); then
19434                 error "ofd_access_log_reader exited with rc = '${rc}'"
19435         fi
19436 }
19437 run_test 165d "ofd_access_log mask works"
19438
19439 test_165e() {
19440         local stats="/tmp/${tfile}.stats"
19441         local file0="${DIR}/${tdir}-0/${tfile}"
19442         local file1="${DIR}/${tdir}-1/${tfile}"
19443
19444         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19445                 skip "OFD access log unsupported"
19446
19447         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
19448
19449         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
19450         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
19451
19452         lfs setstripe -c 1 -i 0 "${file0}"
19453         lfs setstripe -c 1 -i 0 "${file1}"
19454
19455         setup_165
19456         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
19457         sleep 5
19458
19459         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
19460                 error "cannot create '${file0}'"
19461         sync
19462         oal_expect_read_count "${stats}" 0
19463
19464         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
19465                 error "cannot create '${file1}'"
19466         sync
19467         oal_expect_read_count "${stats}" 1
19468
19469         do_facet ost1 killall -TERM ofd_access_log_reader
19470         wait
19471         rc=$?
19472         if ((rc != 0)); then
19473                 error "ofd_access_log_reader exited with rc = '${rc}'"
19474         fi
19475 }
19476 run_test 165e "ofd_access_log MDT index filter works"
19477
19478 test_165f() {
19479         local trace="/tmp/${tfile}.trace"
19480         local rc
19481         local count
19482
19483         setup_165
19484         do_facet ost1 timeout 60 ofd_access_log_reader \
19485                 --exit-on-close --debug=- --trace=- > "${trace}" &
19486         sleep 5
19487         stop ost1
19488
19489         wait
19490         rc=$?
19491
19492         if ((rc != 0)); then
19493                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
19494                 cat "${trace}"
19495                 exit 1
19496         fi
19497 }
19498 run_test 165f "ofd_access_log_reader --exit-on-close works"
19499
19500 test_169() {
19501         # do directio so as not to populate the page cache
19502         log "creating a 10 Mb file"
19503         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
19504                 error "multiop failed while creating a file"
19505         log "starting reads"
19506         dd if=$DIR/$tfile of=/dev/null bs=4096 &
19507         log "truncating the file"
19508         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
19509                 error "multiop failed while truncating the file"
19510         log "killing dd"
19511         kill %+ || true # reads might have finished
19512         echo "wait until dd is finished"
19513         wait
19514         log "removing the temporary file"
19515         rm -rf $DIR/$tfile || error "tmp file removal failed"
19516 }
19517 run_test 169 "parallel read and truncate should not deadlock"
19518
19519 test_170() {
19520         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19521
19522         $LCTL clear     # bug 18514
19523         $LCTL debug_daemon start $TMP/${tfile}_log_good
19524         touch $DIR/$tfile
19525         $LCTL debug_daemon stop
19526         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
19527                 error "sed failed to read log_good"
19528
19529         $LCTL debug_daemon start $TMP/${tfile}_log_good
19530         rm -rf $DIR/$tfile
19531         $LCTL debug_daemon stop
19532
19533         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
19534                error "lctl df log_bad failed"
19535
19536         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19537         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19538
19539         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
19540         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
19541
19542         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
19543                 error "bad_line good_line1 good_line2 are empty"
19544
19545         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19546         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
19547         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19548
19549         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
19550         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19551         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19552
19553         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
19554                 error "bad_line_new good_line_new are empty"
19555
19556         local expected_good=$((good_line1 + good_line2*2))
19557
19558         rm -f $TMP/${tfile}*
19559         # LU-231, short malformed line may not be counted into bad lines
19560         if [ $bad_line -ne $bad_line_new ] &&
19561                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
19562                 error "expected $bad_line bad lines, but got $bad_line_new"
19563                 return 1
19564         fi
19565
19566         if [ $expected_good -ne $good_line_new ]; then
19567                 error "expected $expected_good good lines, but got $good_line_new"
19568                 return 2
19569         fi
19570         true
19571 }
19572 run_test 170 "test lctl df to handle corrupted log ====================="
19573
19574 test_171() { # bug20592
19575         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19576
19577         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
19578         $LCTL set_param fail_loc=0x50e
19579         $LCTL set_param fail_val=3000
19580         multiop_bg_pause $DIR/$tfile O_s || true
19581         local MULTIPID=$!
19582         kill -USR1 $MULTIPID
19583         # cause log dump
19584         sleep 3
19585         wait $MULTIPID
19586         if dmesg | grep "recursive fault"; then
19587                 error "caught a recursive fault"
19588         fi
19589         $LCTL set_param fail_loc=0
19590         true
19591 }
19592 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
19593
19594 test_172() {
19595
19596         #define OBD_FAIL_OBD_CLEANUP  0x60e
19597         $LCTL set_param fail_loc=0x60e
19598         umount $MOUNT || error "umount $MOUNT failed"
19599         stack_trap "mount_client $MOUNT"
19600
19601         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
19602                 error "no client OBDs are remained"
19603
19604         $LCTL dl | while read devno state type name foo; do
19605                 case $type in
19606                 lov|osc|lmv|mdc)
19607                         $LCTL --device $name cleanup
19608                         $LCTL --device $name detach
19609                         ;;
19610                 *)
19611                         # skip server devices
19612                         ;;
19613                 esac
19614         done
19615
19616         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
19617                 $LCTL dl | egrep " osc | lov | lmv | mdc "
19618                 error "some client OBDs are still remained"
19619         fi
19620
19621 }
19622 run_test 172 "manual device removal with lctl cleanup/detach ======"
19623
19624 # it would be good to share it with obdfilter-survey/iokit-libecho code
19625 setup_obdecho_osc () {
19626         local rc=0
19627         local ost_nid=$1
19628         local obdfilter_name=$2
19629         echo "Creating new osc for $obdfilter_name on $ost_nid"
19630         # make sure we can find loopback nid
19631         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
19632
19633         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
19634                            ${obdfilter_name}_osc_UUID || rc=2; }
19635         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
19636                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
19637         return $rc
19638 }
19639
19640 cleanup_obdecho_osc () {
19641         local obdfilter_name=$1
19642         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
19643         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
19644         return 0
19645 }
19646
19647 obdecho_test() {
19648         local OBD=$1
19649         local node=$2
19650         local pages=${3:-64}
19651         local rc=0
19652         local id
19653
19654         local count=10
19655         local obd_size=$(get_obd_size $node $OBD)
19656         local page_size=$(get_page_size $node)
19657         if [[ -n "$obd_size" ]]; then
19658                 local new_count=$((obd_size / (pages * page_size / 1024)))
19659                 [[ $new_count -ge $count ]] || count=$new_count
19660         fi
19661
19662         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
19663         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
19664                            rc=2; }
19665         if [ $rc -eq 0 ]; then
19666             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
19667             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
19668         fi
19669         echo "New object id is $id"
19670         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
19671                            rc=4; }
19672         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
19673                            "test_brw $count w v $pages $id" || rc=4; }
19674         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
19675                            rc=4; }
19676         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
19677                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
19678         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
19679                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
19680         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
19681         return $rc
19682 }
19683
19684 test_180a() {
19685         skip "obdecho on osc is no longer supported"
19686 }
19687 run_test 180a "test obdecho on osc"
19688
19689 test_180b() {
19690         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19691         remote_ost_nodsh && skip "remote OST with nodsh"
19692
19693         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19694                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19695                 error "failed to load module obdecho"
19696
19697         local target=$(do_facet ost1 $LCTL dl |
19698                        awk '/obdfilter/ { print $4; exit; }')
19699
19700         if [ -n "$target" ]; then
19701                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
19702         else
19703                 do_facet ost1 $LCTL dl
19704                 error "there is no obdfilter target on ost1"
19705         fi
19706 }
19707 run_test 180b "test obdecho directly on obdfilter"
19708
19709 test_180c() { # LU-2598
19710         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19711         remote_ost_nodsh && skip "remote OST with nodsh"
19712         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
19713                 skip "Need MDS version at least 2.4.0"
19714
19715         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19716                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19717                 error "failed to load module obdecho"
19718
19719         local target=$(do_facet ost1 $LCTL dl |
19720                        awk '/obdfilter/ { print $4; exit; }')
19721
19722         if [ -n "$target" ]; then
19723                 local pages=16384 # 64MB bulk I/O RPC size
19724
19725                 obdecho_test "$target" ost1 "$pages" ||
19726                         error "obdecho_test with pages=$pages failed with $?"
19727         else
19728                 do_facet ost1 $LCTL dl
19729                 error "there is no obdfilter target on ost1"
19730         fi
19731 }
19732 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
19733
19734 test_181() { # bug 22177
19735         test_mkdir $DIR/$tdir
19736         # create enough files to index the directory
19737         createmany -o $DIR/$tdir/foobar 4000
19738         # print attributes for debug purpose
19739         lsattr -d .
19740         # open dir
19741         multiop_bg_pause $DIR/$tdir D_Sc || return 1
19742         MULTIPID=$!
19743         # remove the files & current working dir
19744         unlinkmany $DIR/$tdir/foobar 4000
19745         rmdir $DIR/$tdir
19746         kill -USR1 $MULTIPID
19747         wait $MULTIPID
19748         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
19749         return 0
19750 }
19751 run_test 181 "Test open-unlinked dir ========================"
19752
19753 test_182a() {
19754         local fcount=1000
19755         local tcount=10
19756
19757         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19758
19759         $LCTL set_param mdc.*.rpc_stats=clear
19760
19761         for (( i = 0; i < $tcount; i++ )) ; do
19762                 mkdir $DIR/$tdir/$i
19763         done
19764
19765         for (( i = 0; i < $tcount; i++ )) ; do
19766                 createmany -o $DIR/$tdir/$i/f- $fcount &
19767         done
19768         wait
19769
19770         for (( i = 0; i < $tcount; i++ )) ; do
19771                 unlinkmany $DIR/$tdir/$i/f- $fcount &
19772         done
19773         wait
19774
19775         $LCTL get_param mdc.*.rpc_stats
19776
19777         rm -rf $DIR/$tdir
19778 }
19779 run_test 182a "Test parallel modify metadata operations from mdc"
19780
19781 test_182b() {
19782         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19783         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19784         local dcount=1000
19785         local tcount=10
19786         local stime
19787         local etime
19788         local delta
19789
19790         do_facet mds1 $LCTL list_param \
19791                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
19792                 skip "MDS lacks parallel RPC handling"
19793
19794         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19795
19796         rpc_count=$(do_facet mds1 $LCTL get_param -n \
19797                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
19798
19799         stime=$(date +%s)
19800         createmany -i 0 -d $DIR/$tdir/t- $tcount
19801
19802         for (( i = 0; i < $tcount; i++ )) ; do
19803                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19804         done
19805         wait
19806         etime=$(date +%s)
19807         delta=$((etime - stime))
19808         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
19809
19810         stime=$(date +%s)
19811         for (( i = 0; i < $tcount; i++ )) ; do
19812                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
19813         done
19814         wait
19815         etime=$(date +%s)
19816         delta=$((etime - stime))
19817         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
19818
19819         rm -rf $DIR/$tdir
19820
19821         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19822
19823         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
19824
19825         stime=$(date +%s)
19826         createmany -i 0 -d $DIR/$tdir/t- $tcount
19827
19828         for (( i = 0; i < $tcount; i++ )) ; do
19829                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19830         done
19831         wait
19832         etime=$(date +%s)
19833         delta=$((etime - stime))
19834         echo "Time for file creation $delta sec for 1 RPC sent at a time"
19835
19836         stime=$(date +%s)
19837         for (( i = 0; i < $tcount; i++ )) ; do
19838                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
19839         done
19840         wait
19841         etime=$(date +%s)
19842         delta=$((etime - stime))
19843         echo "Time for file removal $delta sec for 1 RPC sent at a time"
19844
19845         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
19846 }
19847 run_test 182b "Test parallel modify metadata operations from osp"
19848
19849 test_183() { # LU-2275
19850         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19851         remote_mds_nodsh && skip "remote MDS with nodsh"
19852         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
19853                 skip "Need MDS version at least 2.3.56"
19854
19855         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19856         echo aaa > $DIR/$tdir/$tfile
19857
19858 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
19859         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
19860
19861         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
19862         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
19863
19864         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19865
19866         # Flush negative dentry cache
19867         touch $DIR/$tdir/$tfile
19868
19869         # We are not checking for any leaked references here, they'll
19870         # become evident next time we do cleanup with module unload.
19871         rm -rf $DIR/$tdir
19872 }
19873 run_test 183 "No crash or request leak in case of strange dispositions ========"
19874
19875 # test suite 184 is for LU-2016, LU-2017
19876 test_184a() {
19877         check_swap_layouts_support
19878
19879         dir0=$DIR/$tdir/$testnum
19880         test_mkdir -p -c1 $dir0
19881         ref1=/etc/passwd
19882         ref2=/etc/group
19883         file1=$dir0/f1
19884         file2=$dir0/f2
19885         $LFS setstripe -c1 $file1
19886         cp $ref1 $file1
19887         $LFS setstripe -c2 $file2
19888         cp $ref2 $file2
19889         gen1=$($LFS getstripe -g $file1)
19890         gen2=$($LFS getstripe -g $file2)
19891
19892         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
19893         gen=$($LFS getstripe -g $file1)
19894         [[ $gen1 != $gen ]] ||
19895                 error "Layout generation on $file1 does not change"
19896         gen=$($LFS getstripe -g $file2)
19897         [[ $gen2 != $gen ]] ||
19898                 error "Layout generation on $file2 does not change"
19899
19900         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
19901         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19902
19903         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
19904 }
19905 run_test 184a "Basic layout swap"
19906
19907 test_184b() {
19908         check_swap_layouts_support
19909
19910         dir0=$DIR/$tdir/$testnum
19911         mkdir -p $dir0 || error "creating dir $dir0"
19912         file1=$dir0/f1
19913         file2=$dir0/f2
19914         file3=$dir0/f3
19915         dir1=$dir0/d1
19916         dir2=$dir0/d2
19917         mkdir $dir1 $dir2
19918         $LFS setstripe -c1 $file1
19919         $LFS setstripe -c2 $file2
19920         $LFS setstripe -c1 $file3
19921         chown $RUNAS_ID $file3
19922         gen1=$($LFS getstripe -g $file1)
19923         gen2=$($LFS getstripe -g $file2)
19924
19925         $LFS swap_layouts $dir1 $dir2 &&
19926                 error "swap of directories layouts should fail"
19927         $LFS swap_layouts $dir1 $file1 &&
19928                 error "swap of directory and file layouts should fail"
19929         $RUNAS $LFS swap_layouts $file1 $file2 &&
19930                 error "swap of file we cannot write should fail"
19931         $LFS swap_layouts $file1 $file3 &&
19932                 error "swap of file with different owner should fail"
19933         /bin/true # to clear error code
19934 }
19935 run_test 184b "Forbidden layout swap (will generate errors)"
19936
19937 test_184c() {
19938         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
19939         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
19940         check_swap_layouts_support
19941         check_swap_layout_no_dom $DIR
19942
19943         local dir0=$DIR/$tdir/$testnum
19944         mkdir -p $dir0 || error "creating dir $dir0"
19945
19946         local ref1=$dir0/ref1
19947         local ref2=$dir0/ref2
19948         local file1=$dir0/file1
19949         local file2=$dir0/file2
19950         # create a file large enough for the concurrent test
19951         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
19952         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
19953         echo "ref file size: ref1($(stat -c %s $ref1))," \
19954              "ref2($(stat -c %s $ref2))"
19955
19956         cp $ref2 $file2
19957         dd if=$ref1 of=$file1 bs=16k &
19958         local DD_PID=$!
19959
19960         # Make sure dd starts to copy file, but wait at most 5 seconds
19961         local loops=0
19962         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
19963
19964         $LFS swap_layouts $file1 $file2
19965         local rc=$?
19966         wait $DD_PID
19967         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
19968         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
19969
19970         # how many bytes copied before swapping layout
19971         local copied=$(stat -c %s $file2)
19972         local remaining=$(stat -c %s $ref1)
19973         remaining=$((remaining - copied))
19974         echo "Copied $copied bytes before swapping layout..."
19975
19976         cmp -n $copied $file1 $ref2 | grep differ &&
19977                 error "Content mismatch [0, $copied) of ref2 and file1"
19978         cmp -n $copied $file2 $ref1 ||
19979                 error "Content mismatch [0, $copied) of ref1 and file2"
19980         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
19981                 error "Content mismatch [$copied, EOF) of ref1 and file1"
19982
19983         # clean up
19984         rm -f $ref1 $ref2 $file1 $file2
19985 }
19986 run_test 184c "Concurrent write and layout swap"
19987
19988 test_184d() {
19989         check_swap_layouts_support
19990         check_swap_layout_no_dom $DIR
19991         [ -z "$(which getfattr 2>/dev/null)" ] &&
19992                 skip_env "no getfattr command"
19993
19994         local file1=$DIR/$tdir/$tfile-1
19995         local file2=$DIR/$tdir/$tfile-2
19996         local file3=$DIR/$tdir/$tfile-3
19997         local lovea1
19998         local lovea2
19999
20000         mkdir -p $DIR/$tdir
20001         touch $file1 || error "create $file1 failed"
20002         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
20003                 error "create $file2 failed"
20004         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
20005                 error "create $file3 failed"
20006         lovea1=$(get_layout_param $file1)
20007
20008         $LFS swap_layouts $file2 $file3 ||
20009                 error "swap $file2 $file3 layouts failed"
20010         $LFS swap_layouts $file1 $file2 ||
20011                 error "swap $file1 $file2 layouts failed"
20012
20013         lovea2=$(get_layout_param $file2)
20014         echo "$lovea1"
20015         echo "$lovea2"
20016         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
20017
20018         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
20019         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
20020 }
20021 run_test 184d "allow stripeless layouts swap"
20022
20023 test_184e() {
20024         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
20025                 skip "Need MDS version at least 2.6.94"
20026         check_swap_layouts_support
20027         check_swap_layout_no_dom $DIR
20028         [ -z "$(which getfattr 2>/dev/null)" ] &&
20029                 skip_env "no getfattr command"
20030
20031         local file1=$DIR/$tdir/$tfile-1
20032         local file2=$DIR/$tdir/$tfile-2
20033         local file3=$DIR/$tdir/$tfile-3
20034         local lovea
20035
20036         mkdir -p $DIR/$tdir
20037         touch $file1 || error "create $file1 failed"
20038         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
20039                 error "create $file2 failed"
20040         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
20041                 error "create $file3 failed"
20042
20043         $LFS swap_layouts $file1 $file2 ||
20044                 error "swap $file1 $file2 layouts failed"
20045
20046         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
20047         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
20048
20049         echo 123 > $file1 || error "Should be able to write into $file1"
20050
20051         $LFS swap_layouts $file1 $file3 ||
20052                 error "swap $file1 $file3 layouts failed"
20053
20054         echo 123 > $file1 || error "Should be able to write into $file1"
20055
20056         rm -rf $file1 $file2 $file3
20057 }
20058 run_test 184e "Recreate layout after stripeless layout swaps"
20059
20060 test_184f() {
20061         # Create a file with name longer than sizeof(struct stat) ==
20062         # 144 to see if we can get chars from the file name to appear
20063         # in the returned striping. Note that 'f' == 0x66.
20064         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
20065
20066         mkdir -p $DIR/$tdir
20067         mcreate $DIR/$tdir/$file
20068         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
20069                 error "IOC_MDC_GETFILEINFO returned garbage striping"
20070         fi
20071 }
20072 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
20073
20074 test_185() { # LU-2441
20075         # LU-3553 - no volatile file support in old servers
20076         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
20077                 skip "Need MDS version at least 2.3.60"
20078
20079         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
20080         touch $DIR/$tdir/spoo
20081         local mtime1=$(stat -c "%Y" $DIR/$tdir)
20082         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
20083                 error "cannot create/write a volatile file"
20084         [ "$FILESET" == "" ] &&
20085         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
20086                 error "FID is still valid after close"
20087
20088         multiop_bg_pause $DIR/$tdir Vw4096_c
20089         local multi_pid=$!
20090
20091         local OLD_IFS=$IFS
20092         IFS=":"
20093         local fidv=($fid)
20094         IFS=$OLD_IFS
20095         # assume that the next FID for this client is sequential, since stdout
20096         # is unfortunately eaten by multiop_bg_pause
20097         local n=$((${fidv[1]} + 1))
20098         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
20099         if [ "$FILESET" == "" ]; then
20100                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
20101                         error "FID is missing before close"
20102         fi
20103         kill -USR1 $multi_pid
20104         # 1 second delay, so if mtime change we will see it
20105         sleep 1
20106         local mtime2=$(stat -c "%Y" $DIR/$tdir)
20107         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
20108 }
20109 run_test 185 "Volatile file support"
20110
20111 function create_check_volatile() {
20112         local idx=$1
20113         local tgt
20114
20115         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
20116         local PID=$!
20117         sleep 1
20118         local FID=$(cat /tmp/${tfile}.fid)
20119         [ "$FID" == "" ] && error "can't get FID for volatile"
20120         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
20121         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
20122         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
20123         kill -USR1 $PID
20124         wait
20125         sleep 1
20126         cancel_lru_locks mdc # flush opencache
20127         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
20128         return 0
20129 }
20130
20131 test_185a(){
20132         # LU-12516 - volatile creation via .lustre
20133         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
20134                 skip "Need MDS version at least 2.3.55"
20135
20136         create_check_volatile 0
20137         [ $MDSCOUNT -lt 2 ] && return 0
20138
20139         # DNE case
20140         create_check_volatile 1
20141
20142         return 0
20143 }
20144 run_test 185a "Volatile file creation in .lustre/fid/"
20145
20146 test_187a() {
20147         remote_mds_nodsh && skip "remote MDS with nodsh"
20148         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
20149                 skip "Need MDS version at least 2.3.0"
20150
20151         local dir0=$DIR/$tdir/$testnum
20152         mkdir -p $dir0 || error "creating dir $dir0"
20153
20154         local file=$dir0/file1
20155         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
20156         stack_trap "rm -f $file"
20157         local dv1=$($LFS data_version $file)
20158         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
20159         local dv2=$($LFS data_version $file)
20160         [[ $dv1 != $dv2 ]] ||
20161                 error "data version did not change on write $dv1 == $dv2"
20162 }
20163 run_test 187a "Test data version change"
20164
20165 test_187b() {
20166         remote_mds_nodsh && skip "remote MDS with nodsh"
20167         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
20168                 skip "Need MDS version at least 2.3.0"
20169
20170         local dir0=$DIR/$tdir/$testnum
20171         mkdir -p $dir0 || error "creating dir $dir0"
20172
20173         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
20174         [[ ${DV[0]} != ${DV[1]} ]] ||
20175                 error "data version did not change on write"\
20176                       " ${DV[0]} == ${DV[1]}"
20177
20178         # clean up
20179         rm -f $file1
20180 }
20181 run_test 187b "Test data version change on volatile file"
20182
20183 test_200() {
20184         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20185         remote_mgs_nodsh && skip "remote MGS with nodsh"
20186         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
20187
20188         local POOL=${POOL:-cea1}
20189         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
20190         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
20191         # Pool OST targets
20192         local first_ost=0
20193         local last_ost=$(($OSTCOUNT - 1))
20194         local ost_step=2
20195         local ost_list=$(seq $first_ost $ost_step $last_ost)
20196         local ost_range="$first_ost $last_ost $ost_step"
20197         local test_path=$POOL_ROOT/$POOL_DIR_NAME
20198         local file_dir=$POOL_ROOT/file_tst
20199         local subdir=$test_path/subdir
20200         local rc=0
20201
20202         while : ; do
20203                 # former test_200a test_200b
20204                 pool_add $POOL                          || { rc=$? ; break; }
20205                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
20206                 # former test_200c test_200d
20207                 mkdir -p $test_path
20208                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
20209                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
20210                 mkdir -p $subdir
20211                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
20212                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
20213                                                         || { rc=$? ; break; }
20214                 # former test_200e test_200f
20215                 local files=$((OSTCOUNT*3))
20216                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
20217                                                         || { rc=$? ; break; }
20218                 pool_create_files $POOL $file_dir $files "$ost_list" \
20219                                                         || { rc=$? ; break; }
20220                 # former test_200g test_200h
20221                 pool_lfs_df $POOL                       || { rc=$? ; break; }
20222                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
20223
20224                 # former test_201a test_201b test_201c
20225                 pool_remove_first_target $POOL          || { rc=$? ; break; }
20226
20227                 local f=$test_path/$tfile
20228                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
20229                 pool_remove $POOL $f                    || { rc=$? ; break; }
20230                 break
20231         done
20232
20233         destroy_test_pools
20234
20235         return $rc
20236 }
20237 run_test 200 "OST pools"
20238
20239 # usage: default_attr <count | size | offset>
20240 default_attr() {
20241         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
20242 }
20243
20244 # usage: check_default_stripe_attr
20245 check_default_stripe_attr() {
20246         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
20247         case $1 in
20248         --stripe-count|-c)
20249                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
20250         --stripe-size|-S)
20251                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
20252         --stripe-index|-i)
20253                 EXPECTED=-1;;
20254         *)
20255                 error "unknown getstripe attr '$1'"
20256         esac
20257
20258         [ $ACTUAL == $EXPECTED ] ||
20259                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
20260 }
20261
20262 test_204a() {
20263         test_mkdir $DIR/$tdir
20264         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
20265
20266         check_default_stripe_attr --stripe-count
20267         check_default_stripe_attr --stripe-size
20268         check_default_stripe_attr --stripe-index
20269 }
20270 run_test 204a "Print default stripe attributes"
20271
20272 test_204b() {
20273         test_mkdir $DIR/$tdir
20274         $LFS setstripe --stripe-count 1 $DIR/$tdir
20275
20276         check_default_stripe_attr --stripe-size
20277         check_default_stripe_attr --stripe-index
20278 }
20279 run_test 204b "Print default stripe size and offset"
20280
20281 test_204c() {
20282         test_mkdir $DIR/$tdir
20283         $LFS setstripe --stripe-size 65536 $DIR/$tdir
20284
20285         check_default_stripe_attr --stripe-count
20286         check_default_stripe_attr --stripe-index
20287 }
20288 run_test 204c "Print default stripe count and offset"
20289
20290 test_204d() {
20291         test_mkdir $DIR/$tdir
20292         $LFS setstripe --stripe-index 0 $DIR/$tdir
20293
20294         check_default_stripe_attr --stripe-count
20295         check_default_stripe_attr --stripe-size
20296 }
20297 run_test 204d "Print default stripe count and size"
20298
20299 test_204e() {
20300         test_mkdir $DIR/$tdir
20301         $LFS setstripe -d $DIR/$tdir
20302
20303         # LU-16904 check if root is set as PFL layout
20304         local numcomp=$($LFS getstripe --component-count $MOUNT)
20305
20306         if [[ $numcomp -gt 0 ]]; then
20307                 check_default_stripe_attr --stripe-count
20308         else
20309                 check_default_stripe_attr --stripe-count --raw
20310         fi
20311         check_default_stripe_attr --stripe-size --raw
20312         check_default_stripe_attr --stripe-index --raw
20313 }
20314 run_test 204e "Print raw stripe attributes"
20315
20316 test_204f() {
20317         test_mkdir $DIR/$tdir
20318         $LFS setstripe --stripe-count 1 $DIR/$tdir
20319
20320         check_default_stripe_attr --stripe-size --raw
20321         check_default_stripe_attr --stripe-index --raw
20322 }
20323 run_test 204f "Print raw stripe size and offset"
20324
20325 test_204g() {
20326         test_mkdir $DIR/$tdir
20327         $LFS setstripe --stripe-size 65536 $DIR/$tdir
20328
20329         check_default_stripe_attr --stripe-count --raw
20330         check_default_stripe_attr --stripe-index --raw
20331 }
20332 run_test 204g "Print raw stripe count and offset"
20333
20334 test_204h() {
20335         test_mkdir $DIR/$tdir
20336         $LFS setstripe --stripe-index 0 $DIR/$tdir
20337
20338         check_default_stripe_attr --stripe-count --raw
20339         check_default_stripe_attr --stripe-size --raw
20340 }
20341 run_test 204h "Print raw stripe count and size"
20342
20343 # Figure out which job scheduler is being used, if any,
20344 # or use a fake one
20345 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
20346         JOBENV=SLURM_JOB_ID
20347 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
20348         JOBENV=LSB_JOBID
20349 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
20350         JOBENV=PBS_JOBID
20351 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
20352         JOBENV=LOADL_STEP_ID
20353 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
20354         JOBENV=JOB_ID
20355 else
20356         $LCTL list_param jobid_name > /dev/null 2>&1
20357         if [ $? -eq 0 ]; then
20358                 JOBENV=nodelocal
20359         else
20360                 JOBENV=FAKE_JOBID
20361         fi
20362 fi
20363 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
20364
20365 verify_jobstats() {
20366         local cmd=($1)
20367         shift
20368         local facets="$@"
20369
20370 # we don't really need to clear the stats for this test to work, since each
20371 # command has a unique jobid, but it makes debugging easier if needed.
20372 #       for facet in $facets; do
20373 #               local dev=$(convert_facet2label $facet)
20374 #               # clear old jobstats
20375 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
20376 #       done
20377
20378         # use a new JobID for each test, or we might see an old one
20379         [ "$JOBENV" = "FAKE_JOBID" ] &&
20380                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
20381
20382         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
20383
20384         [ "$JOBENV" = "nodelocal" ] && {
20385                 FAKE_JOBID=id.$testnum.%e.$RANDOM
20386                 $LCTL set_param jobid_name=$FAKE_JOBID
20387                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
20388         }
20389
20390         log "Test: ${cmd[*]}"
20391         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
20392
20393         if [ $JOBENV = "FAKE_JOBID" ]; then
20394                 FAKE_JOBID=$JOBVAL ${cmd[*]}
20395         else
20396                 ${cmd[*]}
20397         fi
20398
20399         # all files are created on OST0000
20400         for facet in $facets; do
20401                 local stats="*.$(convert_facet2label $facet).job_stats"
20402
20403                 # strip out libtool wrappers for in-tree executables
20404                 if (( $(do_facet $facet lctl get_param $stats |
20405                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
20406                         do_facet $facet lctl get_param $stats
20407                         error "No jobstats for $JOBVAL found on $facet::$stats"
20408                 fi
20409         done
20410 }
20411
20412 jobstats_set() {
20413         local new_jobenv=$1
20414
20415         set_persistent_param_and_check client "jobid_var" \
20416                 "$FSNAME.sys.jobid_var" $new_jobenv
20417 }
20418
20419 test_205a() { # Job stats
20420         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20421         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
20422                 skip "Need MDS version with at least 2.7.1"
20423         remote_mgs_nodsh && skip "remote MGS with nodsh"
20424         remote_mds_nodsh && skip "remote MDS with nodsh"
20425         remote_ost_nodsh && skip "remote OST with nodsh"
20426         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
20427                 skip "Server doesn't support jobstats"
20428         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
20429
20430         local old_jobenv=$($LCTL get_param -n jobid_var)
20431         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
20432         stack_trap "jobstats_set $old_jobenv" EXIT
20433
20434         changelog_register
20435
20436         local old_jobid_name=$($LCTL get_param jobid_name)
20437         stack_trap "$LCTL set_param $old_jobid_name" EXIT
20438
20439         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
20440                                 mdt.*.job_cleanup_interval | head -n 1)
20441         local new_interval=5
20442         do_facet $SINGLEMDS \
20443                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
20444         stack_trap "do_facet $SINGLEMDS \
20445                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
20446         local start=$SECONDS
20447
20448         local cmd
20449         # mkdir
20450         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
20451         verify_jobstats "$cmd" "$SINGLEMDS"
20452         # rmdir
20453         cmd="rmdir $DIR/$tdir"
20454         verify_jobstats "$cmd" "$SINGLEMDS"
20455         # mkdir on secondary MDT
20456         if [ $MDSCOUNT -gt 1 ]; then
20457                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
20458                 verify_jobstats "$cmd" "mds2"
20459         fi
20460         # mknod
20461         cmd="mknod $DIR/$tfile c 1 3"
20462         verify_jobstats "$cmd" "$SINGLEMDS"
20463         # unlink
20464         cmd="rm -f $DIR/$tfile"
20465         verify_jobstats "$cmd" "$SINGLEMDS"
20466         # create all files on OST0000 so verify_jobstats can find OST stats
20467         # open & close
20468         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
20469         verify_jobstats "$cmd" "$SINGLEMDS"
20470         # setattr
20471         cmd="touch $DIR/$tfile"
20472         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20473         # write
20474         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
20475         verify_jobstats "$cmd" "ost1"
20476         # read
20477         cancel_lru_locks osc
20478         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
20479         verify_jobstats "$cmd" "ost1"
20480         # truncate
20481         cmd="$TRUNCATE $DIR/$tfile 0"
20482         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20483         # rename
20484         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
20485         verify_jobstats "$cmd" "$SINGLEMDS"
20486         # jobstats expiry - sleep until old stats should be expired
20487         local left=$((new_interval + 5 - (SECONDS - start)))
20488         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
20489                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
20490                         "0" $left
20491         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
20492         verify_jobstats "$cmd" "$SINGLEMDS"
20493         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
20494             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
20495
20496         # Ensure that jobid are present in changelog (if supported by MDS)
20497         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
20498                 changelog_dump | tail -10
20499                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
20500                 [ $jobids -eq 9 ] ||
20501                         error "Wrong changelog jobid count $jobids != 9"
20502
20503                 # LU-5862
20504                 JOBENV="disable"
20505                 jobstats_set $JOBENV
20506                 touch $DIR/$tfile
20507                 changelog_dump | grep $tfile
20508                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
20509                 [ $jobids -eq 0 ] ||
20510                         error "Unexpected jobids when jobid_var=$JOBENV"
20511         fi
20512
20513         # test '%j' access to environment variable - if supported
20514         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
20515                 JOBENV="JOBCOMPLEX"
20516                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20517
20518                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20519         fi
20520
20521         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
20522                 JOBENV="JOBCOMPLEX"
20523                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
20524
20525                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20526         fi
20527
20528         # test '%j' access to per-session jobid - if supported
20529         if lctl list_param jobid_this_session > /dev/null 2>&1
20530         then
20531                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
20532                 lctl set_param jobid_this_session=$USER
20533
20534                 JOBENV="JOBCOMPLEX"
20535                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20536
20537                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20538         fi
20539 }
20540 run_test 205a "Verify job stats"
20541
20542 # LU-13117, LU-13597, LU-16599
20543 test_205b() {
20544         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
20545                 skip "Need MDS version at least 2.13.54.91"
20546
20547         local job_stats="mdt.*.job_stats"
20548         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
20549
20550         do_facet mds1 $LCTL set_param $job_stats=clear
20551
20552         # Setting jobid_var to USER might not be supported
20553         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
20554         $LCTL set_param jobid_var=USER || true
20555         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
20556         $LCTL set_param jobid_name="%j.%e.%u"
20557
20558         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
20559         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
20560                 { do_facet mds1 $LCTL get_param $job_stats;
20561                   error "Unexpected jobid found"; }
20562         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
20563                 { do_facet mds1 $LCTL get_param $job_stats;
20564                   error "wrong job_stats format found"; }
20565
20566         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
20567                 echo "MDS does not yet escape jobid" && return 0
20568
20569         mkdir_on_mdt0 $DIR/$tdir
20570         $LCTL set_param jobid_var=TEST205b
20571         env -i TEST205b="has sp" touch $DIR/$tdir/$tfile.2
20572         local jobid=$(do_facet mds1 $LCTL get_param $job_stats |
20573                       awk '/has\\x20sp/ {print $3}')
20574         [[ -n "$jobid" ]] || { do_facet mds1 $LCTL get_param $job_stats;
20575                   error "jobid not escaped"; }
20576
20577         if (( $MDS1_VERSION >= $(version_code 2.15.53.139) )); then
20578                 # need to run such a command on mds1:
20579                 # lctl set_param mdt.$FSNAME-MDT0000.job_stats='"has\x20sp.touch.0"'
20580                 #
20581                 # there might be multiple MDTs on single mds server, so need to
20582                 # specifiy MDT0000. Or the command will fail due to other MDTs
20583                 do_facet_vp mds1 $LCTL set_param mdt.$FSNAME-MDT0000.job_stats=$jobid ||
20584                         error "cannot clear escaped jobid in job_stats";
20585         else
20586                 echo "MDS does not support clearing escaped jobid"
20587         fi
20588 }
20589 run_test 205b "Verify job stats jobid and output format"
20590
20591 # LU-13733
20592 test_205c() {
20593         $LCTL set_param llite.*.stats=0
20594         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
20595         $LCTL get_param llite.*.stats
20596         $LCTL get_param llite.*.stats | grep \
20597                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
20598                         error "wrong client stats format found"
20599 }
20600 run_test 205c "Verify client stats format"
20601
20602 test_205d() {
20603         local file=$DIR/$tdir/$tfile
20604
20605         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20606                 skip "need lustre >= 2.15.53 for lljobstat"
20607         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20608                 skip "need lustre >= 2.15.53 for lljobstat"
20609         verify_yaml_available || skip_env "YAML verification not installed"
20610
20611         test_mkdir -i 0 $DIR/$tdir
20612         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
20613         stack_trap "rm -rf $DIR/$tdir"
20614
20615         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
20616                 error "failed to write data to $file"
20617         mv $file $file.2
20618
20619         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
20620         echo -n 'verify rename_stats...'
20621         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
20622                 verify_yaml || error "rename_stats is not valid YAML"
20623         echo " OK"
20624
20625         echo -n 'verify mdt job_stats...'
20626         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
20627                 verify_yaml || error "job_stats on mds1 is not valid YAML"
20628         echo " OK"
20629
20630         echo -n 'verify ost job_stats...'
20631         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
20632                 verify_yaml || error "job_stats on ost1 is not valid YAML"
20633         echo " OK"
20634 }
20635 run_test 205d "verify the format of some stats files"
20636
20637 test_205e() {
20638         local ops_comma
20639         local file=$DIR/$tdir/$tfile
20640         local -a cli_params
20641
20642         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20643                 skip "need lustre >= 2.15.53 for lljobstat"
20644         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20645                 skip "need lustre >= 2.15.53 for lljobstat"
20646         verify_yaml_available || skip_env "YAML verification not installed"
20647
20648         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20649         $LCTL set_param jobid_var=nodelocal jobid_name=205e.%e.%u
20650         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20651
20652         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
20653         stack_trap "rm -rf $DIR/$tdir"
20654
20655         $LFS setstripe -E EOF -i 0 -c 1 $file ||
20656                 error "failed to create $file on ost1"
20657         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
20658                 error "failed to write data to $file"
20659
20660         do_facet mds1 "$LCTL get_param *.*.job_stats"
20661         do_facet ost1 "$LCTL get_param *.*.job_stats"
20662
20663         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
20664         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
20665                 error "The output of lljobstat is not an valid YAML"
20666
20667         # verify that job dd.0 does exist and has some ops on ost1
20668         # typically this line is like:
20669         # - 205e.dd.0:            {ops: 20, ...}
20670         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
20671                     awk '$2=="205e.dd.0:" {print $4}')
20672
20673         (( ${ops_comma%,} >= 10 )) ||
20674                 error "cannot find job 205e.dd.0 with ops >= 10"
20675 }
20676 run_test 205e "verify the output of lljobstat"
20677
20678 test_205f() {
20679         verify_yaml_available || skip_env "YAML verification not installed"
20680
20681         # check both qos_ost_weights and qos_mdt_weights
20682         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
20683         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
20684                 error "qos_ost_weights is not valid YAML"
20685 }
20686 run_test 205f "verify qos_ost_weights YAML format "
20687
20688 __test_205_jobstats_dump() {
20689         local -a pids
20690         local nbr_instance=$1
20691
20692         while true; do
20693                 if (( ${#pids[@]} >= nbr_instance )); then
20694                         wait ${pids[@]}
20695                         pids=()
20696                 fi
20697
20698                 do_facet mds1 "$LCTL get_param mdt.*.job_stats > /dev/null" &
20699                 pids+=( $! )
20700         done
20701 }
20702
20703 __test_205_cleanup() {
20704         kill $@
20705         # Clear all job entries
20706         do_facet mds1 "$LCTL set_param mdt.*.job_stats=clear"
20707 }
20708
20709 test_205g() {
20710         local -a mds1_params
20711         local -a cli_params
20712         local pids
20713         local interval=5
20714
20715         mds1_params=( $(do_facet mds1 $LCTL get_param mdt.*.job_cleanup_interval) )
20716         do_facet mds1 $LCTL set_param mdt.*.job_cleanup_interval=$interval
20717         stack_trap "do_facet mds1 $LCTL set_param ${mds1_params[*]}" EXIT
20718
20719         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20720         $LCTL set_param jobid_var=TEST205G_ID jobid_name=%j.%p
20721         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20722
20723         # start jobs loop
20724         export TEST205G_ID=205g
20725         stack_trap "unset TEST205G_ID" EXIT
20726         while true; do
20727                 printf $DIR/$tfile.{0001..1000} | xargs -P10 -n1 touch
20728         done & pids="$! "
20729
20730         __test_205_jobstats_dump 4 & pids+="$! "
20731         stack_trap "__test_205_cleanup $pids" EXIT INT
20732
20733         [[ $SLOW == "no" ]] && sleep 90 || sleep 240
20734 }
20735 run_test 205g "stress test for job_stats procfile"
20736
20737 test_205h() {
20738         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
20739                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
20740         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
20741
20742         local dir=$DIR/$tdir
20743         local f=$dir/$tfile
20744         local f2=$dir/$tfile-2
20745         local f3=$dir/$tfile-3
20746         local subdir=$DIR/dir
20747         local val
20748
20749         local mdts=$(comma_list $(mdts_nodes))
20750         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20751         local client_saved=$($LCTL get_param -n jobid_var)
20752
20753         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20754         stack_trap "$LCTL set_param jobid_var=$client_saved" EXIT
20755
20756         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job ||
20757                 error "failed to set job_xattr parameter to user.job"
20758         $LCTL set_param jobid_var=procname.uid ||
20759                 error "failed to set jobid_var parameter"
20760
20761         test_mkdir $dir
20762
20763         touch $f
20764         val=$(getfattr -n user.job $f | grep user.job)
20765         [[ $val = user.job=\"touch.0\" ]] ||
20766                 error "expected user.job=\"touch.0\", got '$val'"
20767
20768         mkdir $subdir
20769         val=$(getfattr -n user.job $subdir | grep user.job)
20770         [[ $val = user.job=\"mkdir.0\" ]] ||
20771                 error "expected user.job=\"mkdir.0\", got '$val'"
20772
20773         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE ||
20774                 error "failed to set job_xattr parameter to NONE"
20775
20776         touch $f2
20777         val=$(getfattr -d $f2)
20778         [[ -z $val ]] ||
20779                 error "expected no user xattr, got '$val'"
20780
20781         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=trusted.job ||
20782                 error "failed to set job_xattr parameter to trusted.job"
20783
20784         touch $f3
20785         val=$(getfattr -n trusted.job $f3 | grep trusted.job)
20786         [[ $val = trusted.job=\"touch.0\" ]] ||
20787                 error "expected trusted.job=\"touch.0\", got '$val'"
20788 }
20789 run_test 205h "check jobid xattr is stored correctly"
20790
20791 test_205i() {
20792         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
20793                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
20794
20795         local mdts=$(comma_list $(mdts_nodes))
20796         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20797
20798         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20799
20800         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.1234567 ||
20801                 error "failed to set mdt.*.job_xattr to user.1234567"
20802
20803         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.12345678 &&
20804                 error "failed to reject too long job_xattr name"
20805
20806         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=userjob &&
20807                 error "failed to reject job_xattr name in bad format"
20808
20809         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job/ &&
20810                 error "failed to reject job_xattr name with invalid character"
20811
20812         do_nodes $mdts "printf 'mdt.*.job_xattr=user.job\x80' |
20813                         xargs $LCTL set_param" &&
20814                 error "failed to reject job_xattr name with non-ascii character"
20815
20816         return 0
20817 }
20818 run_test 205i "check job_xattr parameter accepts and rejects values correctly"
20819
20820 # LU-1480, LU-1773 and LU-1657
20821 test_206() {
20822         mkdir -p $DIR/$tdir
20823         $LFS setstripe -c -1 $DIR/$tdir
20824 #define OBD_FAIL_LOV_INIT 0x1403
20825         $LCTL set_param fail_loc=0xa0001403
20826         $LCTL set_param fail_val=1
20827         touch $DIR/$tdir/$tfile || true
20828 }
20829 run_test 206 "fail lov_init_raid0() doesn't lbug"
20830
20831 test_207a() {
20832         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20833         local fsz=`stat -c %s $DIR/$tfile`
20834         cancel_lru_locks mdc
20835
20836         # do not return layout in getattr intent
20837 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
20838         $LCTL set_param fail_loc=0x170
20839         local sz=`stat -c %s $DIR/$tfile`
20840
20841         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
20842
20843         rm -rf $DIR/$tfile
20844 }
20845 run_test 207a "can refresh layout at glimpse"
20846
20847 test_207b() {
20848         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20849         local cksum=`md5sum $DIR/$tfile`
20850         local fsz=`stat -c %s $DIR/$tfile`
20851         cancel_lru_locks mdc
20852         cancel_lru_locks osc
20853
20854         # do not return layout in getattr intent
20855 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
20856         $LCTL set_param fail_loc=0x171
20857
20858         # it will refresh layout after the file is opened but before read issues
20859         echo checksum is "$cksum"
20860         echo "$cksum" |md5sum -c --quiet || error "file differs"
20861
20862         rm -rf $DIR/$tfile
20863 }
20864 run_test 207b "can refresh layout at open"
20865
20866 test_208() {
20867         # FIXME: in this test suite, only RD lease is used. This is okay
20868         # for now as only exclusive open is supported. After generic lease
20869         # is done, this test suite should be revised. - Jinshan
20870
20871         remote_mds_nodsh && skip "remote MDS with nodsh"
20872         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
20873                 skip "Need MDS version at least 2.4.52"
20874
20875         echo "==== test 1: verify get lease work"
20876         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
20877
20878         echo "==== test 2: verify lease can be broken by upcoming open"
20879         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20880         local PID=$!
20881         sleep 2
20882
20883         $MULTIOP $DIR/$tfile oO_RDWR:c
20884         kill -USR1 $PID && wait $PID || error "break lease error"
20885
20886         echo "==== test 3: verify lease can't be granted if an open already exists"
20887         $MULTIOP $DIR/$tfile oO_RDWR:_c &
20888         local PID=$!
20889         sleep 2
20890
20891         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
20892         kill -USR1 $PID && wait $PID || error "open file error"
20893
20894         echo "==== test 4: lease can sustain over recovery"
20895         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
20896         PID=$!
20897         sleep 2
20898
20899         fail mds1
20900
20901         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
20902
20903         echo "==== test 5: lease broken can't be regained by replay"
20904         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20905         PID=$!
20906         sleep 2
20907
20908         # open file to break lease and then recovery
20909         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
20910         fail mds1
20911
20912         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
20913
20914         rm -f $DIR/$tfile
20915 }
20916 run_test 208 "Exclusive open"
20917
20918 test_209() {
20919         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
20920                 skip_env "must have disp_stripe"
20921
20922         touch $DIR/$tfile
20923         sync; sleep 5; sync;
20924
20925         echo 3 > /proc/sys/vm/drop_caches
20926         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20927                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20928         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20929
20930         # open/close 500 times
20931         for i in $(seq 500); do
20932                 cat $DIR/$tfile
20933         done
20934
20935         echo 3 > /proc/sys/vm/drop_caches
20936         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20937                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20938         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20939
20940         echo "before: $req_before, after: $req_after"
20941         [ $((req_after - req_before)) -ge 300 ] &&
20942                 error "open/close requests are not freed"
20943         return 0
20944 }
20945 run_test 209 "read-only open/close requests should be freed promptly"
20946
20947 test_210() {
20948         local pid
20949
20950         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
20951         pid=$!
20952         sleep 1
20953
20954         $LFS getstripe $DIR/$tfile
20955         kill -USR1 $pid
20956         wait $pid || error "multiop failed"
20957
20958         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
20959         pid=$!
20960         sleep 1
20961
20962         $LFS getstripe $DIR/$tfile
20963         kill -USR1 $pid
20964         wait $pid || error "multiop failed"
20965 }
20966 run_test 210 "lfs getstripe does not break leases"
20967
20968 function test_211() {
20969         local PID
20970         local id
20971         local rc
20972
20973         stack_trap "rm -f $DIR/$tfile" EXIT
20974         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=10 oflag=direct ||
20975                 error "can't create file"
20976         $LFS mirror extend -N $DIR/$tfile ||
20977                 error "can't create a replica"
20978         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
20979         $LFS getstripe $DIR/$tfile
20980         stale=$($LFS getstripe $DIR/$tfile | grep stale | wc -l)
20981         (( $stale != 1 )) && error "expected 1 stale, found $stale"
20982
20983         $MULTIOP $DIR/$tfile OeW_E+eUc &
20984         PID=$!
20985         sleep 0.3
20986
20987         id=$($LFS getstripe $DIR/$tfile |
20988                 awk '/lcme_mirror_id:/{id=$2}/lcme_flags.*init$/{print id}')
20989         $LFS mirror split -d --mirror-id $id $DIR/$tfile &&
20990                 error "removed last in-sync replica?"
20991
20992         kill -USR1 $PID
20993         wait $PID
20994         (( $? == 0 )) || error "failed split broke the lease"
20995 }
20996 run_test 211 "failed mirror split doesn't break write lease"
20997
20998 test_212() {
20999         size=`date +%s`
21000         size=$((size % 8192 + 1))
21001         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
21002         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
21003         rm -f $DIR/f212 $DIR/f212.xyz
21004 }
21005 run_test 212 "Sendfile test ============================================"
21006
21007 test_213() {
21008         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
21009         cancel_lru_locks osc
21010         lctl set_param fail_loc=0x8000040f
21011         # generate a read lock
21012         cat $DIR/$tfile > /dev/null
21013         # write to the file, it will try to cancel the above read lock.
21014         cat /etc/hosts >> $DIR/$tfile
21015 }
21016 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
21017
21018 test_214() { # for bug 20133
21019         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
21020         for (( i=0; i < 340; i++ )) ; do
21021                 touch $DIR/$tdir/d214c/a$i
21022         done
21023
21024         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
21025         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
21026         ls $DIR/d214c || error "ls $DIR/d214c failed"
21027         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
21028         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
21029 }
21030 run_test 214 "hash-indexed directory test - bug 20133"
21031
21032 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
21033 create_lnet_proc_files() {
21034         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
21035 }
21036
21037 # counterpart of create_lnet_proc_files
21038 remove_lnet_proc_files() {
21039         rm -f $TMP/lnet_$1.sys
21040 }
21041
21042 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
21043 # 3rd arg as regexp for body
21044 check_lnet_proc_stats() {
21045         local l=$(cat "$TMP/lnet_$1" |wc -l)
21046         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
21047
21048         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
21049 }
21050
21051 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
21052 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
21053 # optional and can be regexp for 2nd line (lnet.routes case)
21054 check_lnet_proc_entry() {
21055         local blp=2          # blp stands for 'position of 1st line of body'
21056         [ -z "$5" ] || blp=3 # lnet.routes case
21057
21058         local l=$(cat "$TMP/lnet_$1" |wc -l)
21059         # subtracting one from $blp because the body can be empty
21060         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
21061
21062         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
21063                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
21064
21065         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
21066                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
21067
21068         # bail out if any unexpected line happened
21069         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
21070         [ "$?" != 0 ] || error "$2 misformatted"
21071 }
21072
21073 test_215() { # for bugs 18102, 21079, 21517
21074         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21075
21076         local N='(0|[1-9][0-9]*)'       # non-negative numeric
21077         local P='[1-9][0-9]*'           # positive numeric
21078         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
21079         local NET='[a-z][a-z0-9]*'      # LNet net like o2ib2
21080         local ADDR='[0-9.]+'            # LNet addr like 10.0.0.1
21081         local ADDR6='([0-9a-f]{0,4}:){2,7}[0-9a-f]{0,4}' # IPv6 LNet addr
21082         local NID="$ADDR@$NET"          # LNet nid like 10.0.0.1@o2ib2
21083         local NID6="$ADDR6@$NET"        # LNet nid like 2601:8c1:c180::cbdd@tcp
21084
21085         local L1 # regexp for 1st line
21086         local L2 # regexp for 2nd line (optional)
21087         local BR # regexp for the rest (body)
21088
21089         # lnet.stats should look as 11 space-separated non-negative numerics
21090         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
21091         create_lnet_proc_files "stats"
21092         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
21093         remove_lnet_proc_files "stats"
21094
21095         # lnet.routes should look like this:
21096         # Routing disabled/enabled
21097         # net hops priority state router
21098         # where net is a string like tcp0, hops > 0, priority >= 0,
21099         # state is up/down,
21100         # router is a string like 192.168.1.1@tcp2
21101         L1="^Routing (disabled|enabled)$"
21102         L2="^net +hops +priority +state +router$"
21103         BR="^$NET +$N +(0|1) +(up|down) +($NID|$NID6)$"
21104         create_lnet_proc_files "routes"
21105         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
21106         remove_lnet_proc_files "routes"
21107
21108         # lnet.routers should look like this:
21109         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
21110         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
21111         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
21112         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
21113         L1="^ref +rtr_ref +alive +router$"
21114         BR="^$P +$P +(up|down) +($NID|$NID6)$"
21115         create_lnet_proc_files "routers"
21116         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
21117         remove_lnet_proc_files "routers"
21118
21119         # lnet.peers should look like this:
21120         # nid refs state last max rtr min tx min queue
21121         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
21122         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
21123         # numeric (0 or >0 or <0), queue >= 0.
21124         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
21125         BR="^($NID|$NID6) +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
21126         create_lnet_proc_files "peers"
21127         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
21128         remove_lnet_proc_files "peers"
21129
21130         # lnet.buffers  should look like this:
21131         # pages count credits min
21132         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
21133         L1="^pages +count +credits +min$"
21134         BR="^ +$N +$N +$I +$I$"
21135         create_lnet_proc_files "buffers"
21136         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
21137         remove_lnet_proc_files "buffers"
21138
21139         # lnet.nis should look like this:
21140         # nid status alive refs peer rtr max tx min
21141         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
21142         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
21143         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
21144         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
21145         BR="^($NID|$NID6) +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
21146         create_lnet_proc_files "nis"
21147         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
21148         remove_lnet_proc_files "nis"
21149
21150         # can we successfully write to lnet.stats?
21151         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
21152 }
21153 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
21154
21155 test_216() { # bug 20317
21156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21157         remote_ost_nodsh && skip "remote OST with nodsh"
21158
21159         local node
21160         local facets=$(get_facets OST)
21161         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
21162
21163         save_lustre_params client "osc.*.contention_seconds" > $p
21164         save_lustre_params $facets \
21165                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
21166         save_lustre_params $facets \
21167                 "ldlm.namespaces.filter-*.contended_locks" >> $p
21168         save_lustre_params $facets \
21169                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
21170         clear_stats osc.*.osc_stats
21171
21172         # agressive lockless i/o settings
21173         do_nodes $(comma_list $(osts_nodes)) \
21174                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
21175                         ldlm.namespaces.filter-*.contended_locks=0 \
21176                         ldlm.namespaces.filter-*.contention_seconds=60"
21177         lctl set_param -n osc.*.contention_seconds=60
21178
21179         $DIRECTIO write $DIR/$tfile 0 10 4096
21180         $CHECKSTAT -s 40960 $DIR/$tfile
21181
21182         # disable lockless i/o
21183         do_nodes $(comma_list $(osts_nodes)) \
21184                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
21185                         ldlm.namespaces.filter-*.contended_locks=32 \
21186                         ldlm.namespaces.filter-*.contention_seconds=0"
21187         lctl set_param -n osc.*.contention_seconds=0
21188         clear_stats osc.*.osc_stats
21189
21190         dd if=/dev/zero of=$DIR/$tfile count=0
21191         $CHECKSTAT -s 0 $DIR/$tfile
21192
21193         restore_lustre_params <$p
21194         rm -f $p
21195         rm $DIR/$tfile
21196 }
21197 run_test 216 "check lockless direct write updates file size and kms correctly"
21198
21199 test_217() { # bug 22430
21200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21201
21202         local node
21203
21204         for node in $(nodes_list); do
21205                 local nid=$(host_nids_address $node $NETTYPE)
21206                 local node_ip=$(do_node $node getent ahostsv4 $node |
21207                                 awk '{ print $1; exit; }')
21208
21209                 echo "node: '$node', nid: '$nid', node_ip='$node_ip'"
21210                 # if hostname matches any NID, use hostname for better testing
21211                 if [[ -z "$nid" || "$nid" =~ "$node_ip" ]]; then
21212                         echo "lctl ping node $node@$NETTYPE"
21213                         lctl ping $node@$NETTYPE ||
21214                                 error "ping $node@$NETTYPE failed rc=$?"
21215                 else # otherwise, at least test 'lctl ping' is working
21216                         echo "lctl ping nid $(h2nettype $nid)"
21217                         lctl ping $(h2nettype $nid) ||
21218                                 error "ping $(h2nettype $nid) failed rc=$?"
21219                         echo "skipping $node (no hyphen detected)"
21220                 fi
21221         done
21222
21223         return 0
21224 }
21225 run_test 217 "check lctl ping for hostnames with embedded hyphen ('-')"
21226
21227 test_218() {
21228         # do directio so as not to populate the page cache
21229         log "creating a 10 Mb file"
21230         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
21231                 error "multiop failed while creating a file"
21232         log "starting reads"
21233         dd if=$DIR/$tfile of=/dev/null bs=4096 &
21234         log "truncating the file"
21235         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
21236                 error "multiop failed while truncating the file"
21237         log "killing dd"
21238         kill %+ || true # reads might have finished
21239         echo "wait until dd is finished"
21240         wait
21241         log "removing the temporary file"
21242         rm -rf $DIR/$tfile || error "tmp file removal failed"
21243 }
21244 run_test 218 "parallel read and truncate should not deadlock"
21245
21246 test_219() {
21247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21248
21249         # write one partial page
21250         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
21251         # set no grant so vvp_io_commit_write will do sync write
21252         $LCTL set_param fail_loc=0x411
21253         # write a full page at the end of file
21254         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
21255
21256         $LCTL set_param fail_loc=0
21257         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
21258         $LCTL set_param fail_loc=0x411
21259         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
21260
21261         # LU-4201
21262         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
21263         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
21264 }
21265 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
21266
21267 test_220() { #LU-325
21268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21269         remote_ost_nodsh && skip "remote OST with nodsh"
21270         remote_mds_nodsh && skip "remote MDS with nodsh"
21271         remote_mgs_nodsh && skip "remote MGS with nodsh"
21272
21273         local OSTIDX=0
21274
21275         # create on MDT0000 so the last_id and next_id are correct
21276         mkdir_on_mdt0 $DIR/$tdir
21277         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
21278         OST=${OST%_UUID}
21279
21280         # on the mdt's osc
21281         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
21282         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
21283                         osp.$mdtosc_proc1.prealloc_last_id)
21284         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
21285                         osp.$mdtosc_proc1.prealloc_next_id)
21286
21287         $LFS df -i
21288
21289         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
21290         #define OBD_FAIL_OST_ENOINO              0x229
21291         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
21292         create_pool $FSNAME.$TESTNAME || return 1
21293         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
21294
21295         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
21296
21297         MDSOBJS=$((last_id - next_id))
21298         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
21299
21300         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
21301         echo "OST still has $count kbytes free"
21302
21303         echo "create $MDSOBJS files @next_id..."
21304         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
21305
21306         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
21307                         osp.$mdtosc_proc1.prealloc_last_id)
21308         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
21309                         osp.$mdtosc_proc1.prealloc_next_id)
21310
21311         echo "after creation, last_id=$last_id2, next_id=$next_id2"
21312         $LFS df -i
21313
21314         echo "cleanup..."
21315
21316         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
21317         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
21318
21319         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
21320                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
21321         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
21322                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
21323         echo "unlink $MDSOBJS files @$next_id..."
21324         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
21325 }
21326 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
21327
21328 test_221() {
21329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21330
21331         dd if=`which date` of=$MOUNT/date oflag=sync
21332         chmod +x $MOUNT/date
21333
21334         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
21335         $LCTL set_param fail_loc=0x80001401
21336
21337         $MOUNT/date > /dev/null
21338         rm -f $MOUNT/date
21339 }
21340 run_test 221 "make sure fault and truncate race to not cause OOM"
21341
21342 test_222a () {
21343         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21344
21345         rm -rf $DIR/$tdir
21346         test_mkdir $DIR/$tdir
21347         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21348         createmany -o $DIR/$tdir/$tfile 10
21349         cancel_lru_locks mdc
21350         cancel_lru_locks osc
21351         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21352         $LCTL set_param fail_loc=0x31a
21353         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
21354         $LCTL set_param fail_loc=0
21355         rm -r $DIR/$tdir
21356 }
21357 run_test 222a "AGL for ls should not trigger CLIO lock failure"
21358
21359 test_222b () {
21360         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21361
21362         rm -rf $DIR/$tdir
21363         test_mkdir $DIR/$tdir
21364         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21365         createmany -o $DIR/$tdir/$tfile 10
21366         cancel_lru_locks mdc
21367         cancel_lru_locks osc
21368         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21369         $LCTL set_param fail_loc=0x31a
21370         rm -r $DIR/$tdir || error "AGL for rmdir failed"
21371         $LCTL set_param fail_loc=0
21372 }
21373 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
21374
21375 test_223 () {
21376         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21377
21378         rm -rf $DIR/$tdir
21379         test_mkdir $DIR/$tdir
21380         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21381         createmany -o $DIR/$tdir/$tfile 10
21382         cancel_lru_locks mdc
21383         cancel_lru_locks osc
21384         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
21385         $LCTL set_param fail_loc=0x31b
21386         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
21387         $LCTL set_param fail_loc=0
21388         rm -r $DIR/$tdir
21389 }
21390 run_test 223 "osc reenqueue if without AGL lock granted ======================="
21391
21392 test_224a() { # LU-1039, MRP-303
21393         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21394         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
21395         $LCTL set_param fail_loc=0x508
21396         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
21397         $LCTL set_param fail_loc=0
21398         df $DIR
21399 }
21400 run_test 224a "Don't panic on bulk IO failure"
21401
21402 test_224bd_sub() { # LU-1039, MRP-303
21403         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21404         local timeout=$1
21405
21406         shift
21407         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
21408
21409         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21410
21411         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
21412         cancel_lru_locks osc
21413         set_checksums 0
21414         stack_trap "set_checksums $ORIG_CSUM" EXIT
21415         local at_max_saved=0
21416
21417         # adaptive timeouts may prevent seeing the issue
21418         if at_is_enabled; then
21419                 at_max_saved=$(at_max_get mds)
21420                 at_max_set 0 mds client
21421                 stack_trap "at_max_set $at_max_saved mds client" EXIT
21422         fi
21423
21424         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
21425         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
21426         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
21427
21428         do_facet ost1 $LCTL set_param fail_loc=0
21429         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
21430         df $DIR
21431 }
21432
21433 test_224b() {
21434         test_224bd_sub 3 error "dd failed"
21435 }
21436 run_test 224b "Don't panic on bulk IO failure"
21437
21438 test_224c() { # LU-6441
21439         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21440         remote_mds_nodsh && skip "remote MDS with nodsh"
21441
21442         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
21443         save_writethrough $p
21444         set_cache writethrough on
21445
21446         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
21447         local at_max=$($LCTL get_param -n at_max)
21448         local timeout=$($LCTL get_param -n timeout)
21449         local test_at="at_max"
21450         local param_at="$FSNAME.sys.at_max"
21451         local test_timeout="timeout"
21452         local param_timeout="$FSNAME.sys.timeout"
21453
21454         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
21455
21456         set_persistent_param_and_check client "$test_at" "$param_at" 0
21457         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
21458
21459         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
21460         do_facet ost1 "$LCTL set_param fail_loc=0x520"
21461         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21462         stack_trap "rm -f $DIR/$tfile"
21463         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
21464         sync
21465         do_facet ost1 "$LCTL set_param fail_loc=0"
21466
21467         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
21468         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
21469                 $timeout
21470
21471         $LCTL set_param -n $pages_per_rpc
21472         restore_lustre_params < $p
21473         rm -f $p
21474 }
21475 run_test 224c "Don't hang if one of md lost during large bulk RPC"
21476
21477 test_224d() { # LU-11169
21478         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
21479 }
21480 run_test 224d "Don't corrupt data on bulk IO timeout"
21481
21482 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
21483 test_225a () {
21484         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21485         if [ -z ${MDSSURVEY} ]; then
21486                 skip_env "mds-survey not found"
21487         fi
21488         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21489                 skip "Need MDS version at least 2.2.51"
21490
21491         local mds=$(facet_host $SINGLEMDS)
21492         local target=$(do_nodes $mds 'lctl dl' |
21493                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21494
21495         local cmd1="file_count=1000 thrhi=4"
21496         local cmd2="dir_count=2 layer=mdd stripe_count=0"
21497         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21498         local cmd="$cmd1 $cmd2 $cmd3"
21499
21500         rm -f ${TMP}/mds_survey*
21501         echo + $cmd
21502         eval $cmd || error "mds-survey with zero-stripe failed"
21503         cat ${TMP}/mds_survey*
21504         rm -f ${TMP}/mds_survey*
21505 }
21506 run_test 225a "Metadata survey sanity with zero-stripe"
21507
21508 test_225b () {
21509         if [ -z ${MDSSURVEY} ]; then
21510                 skip_env "mds-survey not found"
21511         fi
21512         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21513                 skip "Need MDS version at least 2.2.51"
21514         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21515         remote_mds_nodsh && skip "remote MDS with nodsh"
21516         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
21517                 skip_env "Need to mount OST to test"
21518         fi
21519
21520         local mds=$(facet_host $SINGLEMDS)
21521         local target=$(do_nodes $mds 'lctl dl' |
21522                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21523
21524         local cmd1="file_count=1000 thrhi=4"
21525         local cmd2="dir_count=2 layer=mdd stripe_count=1"
21526         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21527         local cmd="$cmd1 $cmd2 $cmd3"
21528
21529         rm -f ${TMP}/mds_survey*
21530         echo + $cmd
21531         eval $cmd || error "mds-survey with stripe_count failed"
21532         cat ${TMP}/mds_survey*
21533         rm -f ${TMP}/mds_survey*
21534 }
21535 run_test 225b "Metadata survey sanity with stripe_count = 1"
21536
21537 mcreate_path2fid () {
21538         local mode=$1
21539         local major=$2
21540         local minor=$3
21541         local name=$4
21542         local desc=$5
21543         local path=$DIR/$tdir/$name
21544         local fid
21545         local rc
21546         local fid_path
21547
21548         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
21549                 error "cannot create $desc"
21550
21551         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
21552         rc=$?
21553         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
21554
21555         fid_path=$($LFS fid2path $MOUNT $fid)
21556         rc=$?
21557         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
21558
21559         [ "$path" == "$fid_path" ] ||
21560                 error "fid2path returned $fid_path, expected $path"
21561
21562         echo "pass with $path and $fid"
21563 }
21564
21565 test_226a () {
21566         rm -rf $DIR/$tdir
21567         mkdir -p $DIR/$tdir
21568
21569         mcreate_path2fid 0010666 0 0 fifo "FIFO"
21570         mcreate_path2fid 0020666 1 3 null "character special file (null)"
21571         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
21572         mcreate_path2fid 0040666 0 0 dir "directory"
21573         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
21574         mcreate_path2fid 0100666 0 0 file "regular file"
21575         mcreate_path2fid 0120666 0 0 link "symbolic link"
21576         mcreate_path2fid 0140666 0 0 sock "socket"
21577 }
21578 run_test 226a "call path2fid and fid2path on files of all type"
21579
21580 test_226b () {
21581         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21582
21583         local MDTIDX=1
21584
21585         rm -rf $DIR/$tdir
21586         mkdir -p $DIR/$tdir
21587         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
21588                 error "create remote directory failed"
21589         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
21590         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
21591                                 "character special file (null)"
21592         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
21593                                 "character special file (no device)"
21594         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
21595         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
21596                                 "block special file (loop)"
21597         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
21598         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
21599         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
21600 }
21601 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
21602
21603 test_226c () {
21604         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21605         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
21606                 skip "Need MDS version at least 2.13.55"
21607
21608         local submnt=/mnt/submnt
21609         local srcfile=/etc/passwd
21610         local dstfile=$submnt/passwd
21611         local path
21612         local fid
21613
21614         rm -rf $DIR/$tdir
21615         rm -rf $submnt
21616         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
21617                 error "create remote directory failed"
21618         mkdir -p $submnt || error "create $submnt failed"
21619         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
21620                 error "mount $submnt failed"
21621         stack_trap "umount $submnt" EXIT
21622
21623         cp $srcfile $dstfile
21624         fid=$($LFS path2fid $dstfile)
21625         path=$($LFS fid2path $submnt "$fid")
21626         [ "$path" = "$dstfile" ] ||
21627                 error "fid2path $submnt $fid failed ($path != $dstfile)"
21628 }
21629 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
21630
21631 test_226d () {
21632         (( $CLIENT_VERSION >= $(version_code 2.15.57) )) ||
21633                 skip "Need client at least version 2.15.57"
21634
21635         # Define First test dataset
21636         local testdirs_01=$DIR/$tdir
21637         local testdata_01=$testdirs_01/${tdir}_01
21638         local testresult_01=${tdir}_01
21639         # Define Second test dataset
21640         local testdirs_02=$DIR/$tdir/$tdir
21641         local testdata_02=$testdirs_02/${tdir}_02
21642         local testresult_02=${tdir}_02
21643         # Define third test dataset (top level)
21644         local testdata_03=$DIR/${tdir}_03
21645         local testresult_03=${tdir}_03
21646
21647         # Create first test dataset
21648         mkdir -p $testdirs_01 || error "cannot create dir $testdirs_01"
21649         touch $testdata_01 || error "cannot create file $testdata_01"
21650
21651         # Create second test dataset
21652         mkdir -p $testdirs_02 || error "cannot create dir $testdirs_02"
21653         touch $testdata_02 || error "cannot create file $testdata_02"
21654
21655         # Create third test dataset
21656         touch $testdata_03 || error "cannot create file $testdata_03"
21657
21658         local fid01=$($LFS getstripe -F "$testdata_01") ||
21659                 error "getstripe failed on $testdata_01"
21660         local fid02=$($LFS getstripe -F "$testdata_02") ||
21661                 error "getstripe failed on $testdata_01"
21662         local fid03=$($LFS getstripe -F "$testdata_03") ||
21663                 error "getstripe failed on $testdata_03"
21664
21665         # Verify only -n option
21666         local out1=$($LFS fid2path -n $DIR $fid01) ||
21667                 error "fid2path failed on $fid01"
21668         local out2=$($LFS fid2path -n $DIR $fid02) ||
21669                 error "fid2path failed on $fid02"
21670         local out3=$($LFS fid2path -n $DIR $fid03) ||
21671                 error "fid2path failed on $fid03"
21672
21673         [[ "$out1" == "$testresult_01" ]] ||
21674                 error "fid2path failed: Expected $testresult_01 got $out1"
21675         [[ "$out2" == "$testresult_02" ]] ||
21676                 error "fid2path failed: Expected $testresult_02 got $out2"
21677         [[ "$out3" == "$testresult_03" ]] ||
21678                 error "fid2path failed: Expected $testresult_03 got $out3"
21679
21680         # Verify with option -fn together
21681         out1=$($LFS fid2path -fn $DIR $fid01) ||
21682                 error "fid2path -fn failed on $fid01"
21683         out2=$($LFS fid2path -fn $DIR $fid02) ||
21684                 error "fid2path -fn failed on $fid02"
21685         out3=$($LFS fid2path -fn $DIR $fid03) ||
21686                 error "fid2path -fn failed on $fid03"
21687
21688         local tmpout=$(echo $out1 | cut -d" " -f2)
21689         [[ "$tmpout" == "$testresult_01" ]] ||
21690                 error "fid2path -fn failed: Expected $testresult_01 got $out1"
21691
21692         tmpout=$(echo $out2 | cut -d" " -f2)
21693         [[ "$tmpout" == "$testresult_02" ]] ||
21694                 error "fid2path -fn failed: Expected $testresult_02 got $out2"
21695
21696         tmpout=$(echo $out3 | cut -d" " -f2)
21697         [[ "$tmpout" == "$testresult_03" ]] ||
21698                 error "fid2path -fn failed: Expected $testresult_03 got $out3"
21699 }
21700 run_test 226d "verify fid2path with -n and -fn option"
21701
21702 test_226e () {
21703         (( $CLIENT_VERSION >= $(version_code 2.15.56) )) ||
21704                 skip "Need client at least version 2.15.56"
21705
21706         # Define filename with 'newline' and a space
21707         local testfile="Test"$'\n'"file 01"
21708         # Define link name with multiple 'newline' and a space
21709         local linkfile="Link"$'\n'"file "$'\n'"01"
21710         # Remove prior hard link
21711         rm -f $DIR/"$linkfile"
21712
21713         # Create file
21714         touch $DIR/"$testfile"
21715         # Create link
21716         ln $DIR/"$testfile" $DIR/"$linkfile"
21717
21718         local fid=$($LFS getstripe -F "$DIR/$testfile") ||
21719                 error "getstripe failed on $DIR/$testfile"
21720
21721         # Call with -0 option
21722         local out1=$($LFS fid2path -0 $DIR $fid | xargs --null -n1 \
21723                 echo "FILE:" | grep -c "FILE:")
21724
21725         # With -0 option the output should be exactly 2 lines.
21726         (( $out1 == 2 )) || error "fid2path -0 failed on $fid, $out1"
21727 }
21728 run_test 226e "Verify path2fid -0 option with newline and space"
21729
21730 # LU-1299 Executing or running ldd on a truncated executable does not
21731 # cause an out-of-memory condition.
21732 test_227() {
21733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21734         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
21735
21736         dd if=$(which date) of=$MOUNT/date bs=1k count=1
21737         chmod +x $MOUNT/date
21738
21739         $MOUNT/date > /dev/null
21740         ldd $MOUNT/date > /dev/null
21741         rm -f $MOUNT/date
21742 }
21743 run_test 227 "running truncated executable does not cause OOM"
21744
21745 # LU-1512 try to reuse idle OI blocks
21746 test_228a() {
21747         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21748         remote_mds_nodsh && skip "remote MDS with nodsh"
21749         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21750
21751         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21752         local myDIR=$DIR/$tdir
21753
21754         mkdir -p $myDIR
21755         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21756         $LCTL set_param fail_loc=0x80001002
21757         createmany -o $myDIR/t- 10000
21758         $LCTL set_param fail_loc=0
21759         # The guard is current the largest FID holder
21760         touch $myDIR/guard
21761         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21762                     tr -d '[')
21763         local IDX=$(($SEQ % 64))
21764
21765         do_facet $SINGLEMDS sync
21766         # Make sure journal flushed.
21767         sleep 6
21768         local blk1=$(do_facet $SINGLEMDS \
21769                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21770                      grep Blockcount | awk '{print $4}')
21771
21772         # Remove old files, some OI blocks will become idle.
21773         unlinkmany $myDIR/t- 10000
21774         # Create new files, idle OI blocks should be reused.
21775         createmany -o $myDIR/t- 2000
21776         do_facet $SINGLEMDS sync
21777         # Make sure journal flushed.
21778         sleep 6
21779         local blk2=$(do_facet $SINGLEMDS \
21780                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21781                      grep Blockcount | awk '{print $4}')
21782
21783         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21784 }
21785 run_test 228a "try to reuse idle OI blocks"
21786
21787 test_228b() {
21788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21789         remote_mds_nodsh && skip "remote MDS with nodsh"
21790         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21791
21792         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21793         local myDIR=$DIR/$tdir
21794
21795         mkdir -p $myDIR
21796         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21797         $LCTL set_param fail_loc=0x80001002
21798         createmany -o $myDIR/t- 10000
21799         $LCTL set_param fail_loc=0
21800         # The guard is current the largest FID holder
21801         touch $myDIR/guard
21802         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21803                     tr -d '[')
21804         local IDX=$(($SEQ % 64))
21805
21806         do_facet $SINGLEMDS sync
21807         # Make sure journal flushed.
21808         sleep 6
21809         local blk1=$(do_facet $SINGLEMDS \
21810                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21811                      grep Blockcount | awk '{print $4}')
21812
21813         # Remove old files, some OI blocks will become idle.
21814         unlinkmany $myDIR/t- 10000
21815
21816         # stop the MDT
21817         stop $SINGLEMDS || error "Fail to stop MDT."
21818         # remount the MDT
21819         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
21820                 error "Fail to start MDT."
21821
21822         client_up || error "Fail to df."
21823         # Create new files, idle OI blocks should be reused.
21824         createmany -o $myDIR/t- 2000
21825         do_facet $SINGLEMDS sync
21826         # Make sure journal flushed.
21827         sleep 6
21828         local blk2=$(do_facet $SINGLEMDS \
21829                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21830                      grep Blockcount | awk '{print $4}')
21831
21832         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21833 }
21834 run_test 228b "idle OI blocks can be reused after MDT restart"
21835
21836 #LU-1881
21837 test_228c() {
21838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21839         remote_mds_nodsh && skip "remote MDS with nodsh"
21840         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21841
21842         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21843         local myDIR=$DIR/$tdir
21844
21845         mkdir -p $myDIR
21846         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21847         $LCTL set_param fail_loc=0x80001002
21848         # 20000 files can guarantee there are index nodes in the OI file
21849         createmany -o $myDIR/t- 20000
21850         $LCTL set_param fail_loc=0
21851         # The guard is current the largest FID holder
21852         touch $myDIR/guard
21853         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21854                     tr -d '[')
21855         local IDX=$(($SEQ % 64))
21856
21857         do_facet $SINGLEMDS sync
21858         # Make sure journal flushed.
21859         sleep 6
21860         local blk1=$(do_facet $SINGLEMDS \
21861                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21862                      grep Blockcount | awk '{print $4}')
21863
21864         # Remove old files, some OI blocks will become idle.
21865         unlinkmany $myDIR/t- 20000
21866         rm -f $myDIR/guard
21867         # The OI file should become empty now
21868
21869         # Create new files, idle OI blocks should be reused.
21870         createmany -o $myDIR/t- 2000
21871         do_facet $SINGLEMDS sync
21872         # Make sure journal flushed.
21873         sleep 6
21874         local blk2=$(do_facet $SINGLEMDS \
21875                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21876                      grep Blockcount | awk '{print $4}')
21877
21878         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21879 }
21880 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
21881
21882 test_229() { # LU-2482, LU-3448
21883         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21884         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
21885         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
21886                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
21887
21888         rm -f $DIR/$tfile
21889
21890         # Create a file with a released layout and stripe count 2.
21891         $MULTIOP $DIR/$tfile H2c ||
21892                 error "failed to create file with released layout"
21893
21894         $LFS getstripe -v $DIR/$tfile
21895
21896         local pattern=$($LFS getstripe -L $DIR/$tfile)
21897         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
21898
21899         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
21900                 error "getstripe"
21901         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
21902         stat $DIR/$tfile || error "failed to stat released file"
21903
21904         chown $RUNAS_ID $DIR/$tfile ||
21905                 error "chown $RUNAS_ID $DIR/$tfile failed"
21906
21907         chgrp $RUNAS_ID $DIR/$tfile ||
21908                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
21909
21910         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
21911         rm $DIR/$tfile || error "failed to remove released file"
21912 }
21913 run_test 229 "getstripe/stat/rm/attr changes work on released files"
21914
21915 test_230a() {
21916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21917         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21918         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21919                 skip "Need MDS version at least 2.11.52"
21920
21921         local MDTIDX=1
21922
21923         test_mkdir $DIR/$tdir
21924         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
21925         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
21926         [ $mdt_idx -ne 0 ] &&
21927                 error "create local directory on wrong MDT $mdt_idx"
21928
21929         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
21930                         error "create remote directory failed"
21931         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
21932         [ $mdt_idx -ne $MDTIDX ] &&
21933                 error "create remote directory on wrong MDT $mdt_idx"
21934
21935         createmany -o $DIR/$tdir/test_230/t- 10 ||
21936                 error "create files on remote directory failed"
21937         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
21938         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
21939         rm -r $DIR/$tdir || error "unlink remote directory failed"
21940 }
21941 run_test 230a "Create remote directory and files under the remote directory"
21942
21943 test_230b() {
21944         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21945         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21946         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21947                 skip "Need MDS version at least 2.11.52"
21948
21949         local MDTIDX=1
21950         local mdt_index
21951         local i
21952         local file
21953         local pid
21954         local stripe_count
21955         local migrate_dir=$DIR/$tdir/migrate_dir
21956         local other_dir=$DIR/$tdir/other_dir
21957
21958         test_mkdir $DIR/$tdir
21959         test_mkdir -i0 -c1 $migrate_dir
21960         test_mkdir -i0 -c1 $other_dir
21961         for ((i=0; i<10; i++)); do
21962                 mkdir -p $migrate_dir/dir_${i}
21963                 createmany -o $migrate_dir/dir_${i}/f 10 ||
21964                         error "create files under remote dir failed $i"
21965         done
21966
21967         cp /etc/passwd $migrate_dir/$tfile
21968         cp /etc/passwd $other_dir/$tfile
21969         chattr +SAD $migrate_dir
21970         chattr +SAD $migrate_dir/$tfile
21971
21972         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21973         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21974         local old_dir_mode=$(stat -c%f $migrate_dir)
21975         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
21976
21977         mkdir -p $migrate_dir/dir_default_stripe2
21978         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
21979         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
21980
21981         mkdir -p $other_dir
21982         ln $migrate_dir/$tfile $other_dir/luna
21983         ln $migrate_dir/$tfile $migrate_dir/sofia
21984         ln $other_dir/$tfile $migrate_dir/david
21985         ln -s $migrate_dir/$tfile $other_dir/zachary
21986         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
21987         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
21988
21989         local len
21990         local lnktgt
21991
21992         # inline symlink
21993         for len in 58 59 60; do
21994                 lnktgt=$(str_repeat 'l' $len)
21995                 touch $migrate_dir/$lnktgt
21996                 ln -s $lnktgt $migrate_dir/${len}char_ln
21997         done
21998
21999         # PATH_MAX
22000         for len in 4094 4095; do
22001                 lnktgt=$(str_repeat 'l' $len)
22002                 ln -s $lnktgt $migrate_dir/${len}char_ln
22003         done
22004
22005         # NAME_MAX
22006         for len in 254 255; do
22007                 touch $migrate_dir/$(str_repeat 'l' $len)
22008         done
22009
22010         $LFS migrate -m $MDTIDX $migrate_dir ||
22011                 error "fails on migrating remote dir to MDT1"
22012
22013         echo "migratate to MDT1, then checking.."
22014         for ((i = 0; i < 10; i++)); do
22015                 for file in $(find $migrate_dir/dir_${i}); do
22016                         mdt_index=$($LFS getstripe -m $file)
22017                         # broken symlink getstripe will fail
22018                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
22019                                 error "$file is not on MDT${MDTIDX}"
22020                 done
22021         done
22022
22023         # the multiple link file should still in MDT0
22024         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
22025         [ $mdt_index == 0 ] ||
22026                 error "$file is not on MDT${MDTIDX}"
22027
22028         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
22029         [ "$old_dir_flag" = "$new_dir_flag" ] ||
22030                 error " expect $old_dir_flag get $new_dir_flag"
22031
22032         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
22033         [ "$old_file_flag" = "$new_file_flag" ] ||
22034                 error " expect $old_file_flag get $new_file_flag"
22035
22036         local new_dir_mode=$(stat -c%f $migrate_dir)
22037         [ "$old_dir_mode" = "$new_dir_mode" ] ||
22038                 error "expect mode $old_dir_mode get $new_dir_mode"
22039
22040         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
22041         [ "$old_file_mode" = "$new_file_mode" ] ||
22042                 error "expect mode $old_file_mode get $new_file_mode"
22043
22044         diff /etc/passwd $migrate_dir/$tfile ||
22045                 error "$tfile different after migration"
22046
22047         diff /etc/passwd $other_dir/luna ||
22048                 error "luna different after migration"
22049
22050         diff /etc/passwd $migrate_dir/sofia ||
22051                 error "sofia different after migration"
22052
22053         diff /etc/passwd $migrate_dir/david ||
22054                 error "david different after migration"
22055
22056         diff /etc/passwd $other_dir/zachary ||
22057                 error "zachary different after migration"
22058
22059         diff /etc/passwd $migrate_dir/${tfile}_ln ||
22060                 error "${tfile}_ln different after migration"
22061
22062         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
22063                 error "${tfile}_ln_other different after migration"
22064
22065         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
22066         [ $stripe_count = 2 ] ||
22067                 error "dir strpe_count $d != 2 after migration."
22068
22069         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
22070         [ $stripe_count = 2 ] ||
22071                 error "file strpe_count $d != 2 after migration."
22072
22073         #migrate back to MDT0
22074         MDTIDX=0
22075
22076         $LFS migrate -m $MDTIDX $migrate_dir ||
22077                 error "fails on migrating remote dir to MDT0"
22078
22079         echo "migrate back to MDT0, checking.."
22080         for file in $(find $migrate_dir); do
22081                 mdt_index=$($LFS getstripe -m $file)
22082                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
22083                         error "$file is not on MDT${MDTIDX}"
22084         done
22085
22086         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
22087         [ "$old_dir_flag" = "$new_dir_flag" ] ||
22088                 error " expect $old_dir_flag get $new_dir_flag"
22089
22090         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
22091         [ "$old_file_flag" = "$new_file_flag" ] ||
22092                 error " expect $old_file_flag get $new_file_flag"
22093
22094         local new_dir_mode=$(stat -c%f $migrate_dir)
22095         [ "$old_dir_mode" = "$new_dir_mode" ] ||
22096                 error "expect mode $old_dir_mode get $new_dir_mode"
22097
22098         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
22099         [ "$old_file_mode" = "$new_file_mode" ] ||
22100                 error "expect mode $old_file_mode get $new_file_mode"
22101
22102         diff /etc/passwd ${migrate_dir}/$tfile ||
22103                 error "$tfile different after migration"
22104
22105         diff /etc/passwd ${other_dir}/luna ||
22106                 error "luna different after migration"
22107
22108         diff /etc/passwd ${migrate_dir}/sofia ||
22109                 error "sofia different after migration"
22110
22111         diff /etc/passwd ${other_dir}/zachary ||
22112                 error "zachary different after migration"
22113
22114         diff /etc/passwd $migrate_dir/${tfile}_ln ||
22115                 error "${tfile}_ln different after migration"
22116
22117         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
22118                 error "${tfile}_ln_other different after migration"
22119
22120         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
22121         [ $stripe_count = 2 ] ||
22122                 error "dir strpe_count $d != 2 after migration."
22123
22124         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
22125         [ $stripe_count = 2 ] ||
22126                 error "file strpe_count $d != 2 after migration."
22127
22128         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22129 }
22130 run_test 230b "migrate directory"
22131
22132 test_230c() {
22133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22134         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22135         remote_mds_nodsh && skip "remote MDS with nodsh"
22136         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22137                 skip "Need MDS version at least 2.11.52"
22138
22139         local MDTIDX=1
22140         local total=3
22141         local mdt_index
22142         local file
22143         local migrate_dir=$DIR/$tdir/migrate_dir
22144
22145         #If migrating directory fails in the middle, all entries of
22146         #the directory is still accessiable.
22147         test_mkdir $DIR/$tdir
22148         test_mkdir -i0 -c1 $migrate_dir
22149         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
22150         stat $migrate_dir
22151         createmany -o $migrate_dir/f $total ||
22152                 error "create files under ${migrate_dir} failed"
22153
22154         # fail after migrating top dir, and this will fail only once, so the
22155         # first sub file migration will fail (currently f3), others succeed.
22156         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
22157         do_facet mds1 lctl set_param fail_loc=0x1801
22158         local t=$(ls $migrate_dir | wc -l)
22159         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
22160                 error "migrate should fail"
22161         local u=$(ls $migrate_dir | wc -l)
22162         [ "$u" == "$t" ] || error "$u != $t during migration"
22163
22164         # add new dir/file should succeed
22165         mkdir $migrate_dir/dir ||
22166                 error "mkdir failed under migrating directory"
22167         touch $migrate_dir/file ||
22168                 error "create file failed under migrating directory"
22169
22170         # add file with existing name should fail
22171         for file in $migrate_dir/f*; do
22172                 stat $file > /dev/null || error "stat $file failed"
22173                 $OPENFILE -f O_CREAT:O_EXCL $file &&
22174                         error "open(O_CREAT|O_EXCL) $file should fail"
22175                 $MULTIOP $file m && error "create $file should fail"
22176                 touch $DIR/$tdir/remote_dir/$tfile ||
22177                         error "touch $tfile failed"
22178                 ln $DIR/$tdir/remote_dir/$tfile $file &&
22179                         error "link $file should fail"
22180                 mdt_index=$($LFS getstripe -m $file)
22181                 if [ $mdt_index == 0 ]; then
22182                         # file failed to migrate is not allowed to rename to
22183                         mv $DIR/$tdir/remote_dir/$tfile $file &&
22184                                 error "rename to $file should fail"
22185                 else
22186                         mv $DIR/$tdir/remote_dir/$tfile $file ||
22187                                 error "rename to $file failed"
22188                 fi
22189                 echo hello >> $file || error "write $file failed"
22190         done
22191
22192         # resume migration with different options should fail
22193         $LFS migrate -m 0 $migrate_dir &&
22194                 error "migrate -m 0 $migrate_dir should fail"
22195
22196         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
22197                 error "migrate -c 2 $migrate_dir should fail"
22198
22199         # resume migration should succeed
22200         $LFS migrate -m $MDTIDX $migrate_dir ||
22201                 error "migrate $migrate_dir failed"
22202
22203         echo "Finish migration, then checking.."
22204         for file in $(find $migrate_dir); do
22205                 mdt_index=$($LFS getstripe -m $file)
22206                 [ $mdt_index == $MDTIDX ] ||
22207                         error "$file is not on MDT${MDTIDX}"
22208         done
22209
22210         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22211 }
22212 run_test 230c "check directory accessiblity if migration failed"
22213
22214 test_230d() {
22215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22216         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22217         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22218                 skip "Need MDS version at least 2.11.52"
22219         # LU-11235
22220         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
22221
22222         local migrate_dir=$DIR/$tdir/migrate_dir
22223         local old_index
22224         local new_index
22225         local old_count
22226         local new_count
22227         local new_hash
22228         local mdt_index
22229         local i
22230         local j
22231
22232         old_index=$((RANDOM % MDSCOUNT))
22233         old_count=$((MDSCOUNT - old_index))
22234         new_index=$((RANDOM % MDSCOUNT))
22235         new_count=$((MDSCOUNT - new_index))
22236         new_hash=1 # for all_char
22237
22238         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
22239         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
22240
22241         test_mkdir $DIR/$tdir
22242         test_mkdir -i $old_index -c $old_count $migrate_dir
22243
22244         for ((i=0; i<100; i++)); do
22245                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
22246                 createmany -o $migrate_dir/dir_${i}/f 100 ||
22247                         error "create files under remote dir failed $i"
22248         done
22249
22250         echo -n "Migrate from MDT$old_index "
22251         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
22252         echo -n "to MDT$new_index"
22253         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
22254         echo
22255
22256         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
22257         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
22258                 error "migrate remote dir error"
22259
22260         echo "Finish migration, then checking.."
22261         for file in $(find $migrate_dir -maxdepth 1); do
22262                 mdt_index=$($LFS getstripe -m $file)
22263                 if [ $mdt_index -lt $new_index ] ||
22264                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
22265                         error "$file is on MDT$mdt_index"
22266                 fi
22267         done
22268
22269         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22270 }
22271 run_test 230d "check migrate big directory"
22272
22273 test_230e() {
22274         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22275         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22276         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22277                 skip "Need MDS version at least 2.11.52"
22278
22279         local i
22280         local j
22281         local a_fid
22282         local b_fid
22283
22284         mkdir_on_mdt0 $DIR/$tdir
22285         mkdir $DIR/$tdir/migrate_dir
22286         mkdir $DIR/$tdir/other_dir
22287         touch $DIR/$tdir/migrate_dir/a
22288         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
22289         ls $DIR/$tdir/other_dir
22290
22291         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22292                 error "migrate dir fails"
22293
22294         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
22295         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
22296
22297         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22298         [ $mdt_index == 0 ] || error "a is not on MDT0"
22299
22300         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
22301                 error "migrate dir fails"
22302
22303         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
22304         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
22305
22306         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22307         [ $mdt_index == 1 ] || error "a is not on MDT1"
22308
22309         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
22310         [ $mdt_index == 1 ] || error "b is not on MDT1"
22311
22312         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
22313         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
22314
22315         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
22316
22317         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22318 }
22319 run_test 230e "migrate mulitple local link files"
22320
22321 test_230f() {
22322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22323         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22324         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22325                 skip "Need MDS version at least 2.11.52"
22326
22327         local a_fid
22328         local ln_fid
22329
22330         mkdir -p $DIR/$tdir
22331         mkdir $DIR/$tdir/migrate_dir
22332         $LFS mkdir -i1 $DIR/$tdir/other_dir
22333         touch $DIR/$tdir/migrate_dir/a
22334         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
22335         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
22336         ls $DIR/$tdir/other_dir
22337
22338         # a should be migrated to MDT1, since no other links on MDT0
22339         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22340                 error "#1 migrate dir fails"
22341         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
22342         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
22343         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22344         [ $mdt_index == 1 ] || error "a is not on MDT1"
22345
22346         # a should stay on MDT1, because it is a mulitple link file
22347         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22348                 error "#2 migrate dir fails"
22349         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22350         [ $mdt_index == 1 ] || error "a is not on MDT1"
22351
22352         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22353                 error "#3 migrate dir fails"
22354
22355         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
22356         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
22357         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
22358
22359         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
22360         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
22361
22362         # a should be migrated to MDT0, since no other links on MDT1
22363         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22364                 error "#4 migrate dir fails"
22365         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22366         [ $mdt_index == 0 ] || error "a is not on MDT0"
22367
22368         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22369 }
22370 run_test 230f "migrate mulitple remote link files"
22371
22372 test_230g() {
22373         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22374         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22375         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22376                 skip "Need MDS version at least 2.11.52"
22377
22378         mkdir -p $DIR/$tdir/migrate_dir
22379
22380         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
22381                 error "migrating dir to non-exist MDT succeeds"
22382         true
22383 }
22384 run_test 230g "migrate dir to non-exist MDT"
22385
22386 test_230h() {
22387         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22388         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22389         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22390                 skip "Need MDS version at least 2.11.52"
22391
22392         local mdt_index
22393
22394         mkdir -p $DIR/$tdir/migrate_dir
22395
22396         $LFS migrate -m1 $DIR &&
22397                 error "migrating mountpoint1 should fail"
22398
22399         $LFS migrate -m1 $DIR/$tdir/.. &&
22400                 error "migrating mountpoint2 should fail"
22401
22402         # same as mv
22403         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
22404                 error "migrating $tdir/migrate_dir/.. should fail"
22405
22406         true
22407 }
22408 run_test 230h "migrate .. and root"
22409
22410 test_230i() {
22411         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22412         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22413         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22414                 skip "Need MDS version at least 2.11.52"
22415
22416         mkdir -p $DIR/$tdir/migrate_dir
22417
22418         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
22419                 error "migration fails with a tailing slash"
22420
22421         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
22422                 error "migration fails with two tailing slashes"
22423 }
22424 run_test 230i "lfs migrate -m tolerates trailing slashes"
22425
22426 test_230j() {
22427         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22428         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
22429                 skip "Need MDS version at least 2.11.52"
22430
22431         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22432         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
22433                 error "create $tfile failed"
22434         cat /etc/passwd > $DIR/$tdir/$tfile
22435
22436         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22437
22438         cmp /etc/passwd $DIR/$tdir/$tfile ||
22439                 error "DoM file mismatch after migration"
22440 }
22441 run_test 230j "DoM file data not changed after dir migration"
22442
22443 test_230k() {
22444         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
22445         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22446                 skip "Need MDS version at least 2.11.56"
22447
22448         local total=20
22449         local files_on_starting_mdt=0
22450
22451         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
22452         $LFS getdirstripe $DIR/$tdir
22453         for i in $(seq $total); do
22454                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
22455                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22456                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22457         done
22458
22459         echo "$files_on_starting_mdt files on MDT0"
22460
22461         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
22462         $LFS getdirstripe $DIR/$tdir
22463
22464         files_on_starting_mdt=0
22465         for i in $(seq $total); do
22466                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22467                         error "file $tfile.$i mismatch after migration"
22468                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
22469                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22470         done
22471
22472         echo "$files_on_starting_mdt files on MDT1 after migration"
22473         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
22474
22475         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
22476         $LFS getdirstripe $DIR/$tdir
22477
22478         files_on_starting_mdt=0
22479         for i in $(seq $total); do
22480                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22481                         error "file $tfile.$i mismatch after 2nd migration"
22482                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22483                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22484         done
22485
22486         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
22487         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
22488
22489         true
22490 }
22491 run_test 230k "file data not changed after dir migration"
22492
22493 test_230l() {
22494         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22495         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22496                 skip "Need MDS version at least 2.11.56"
22497
22498         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
22499         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
22500                 error "create files under remote dir failed $i"
22501         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22502 }
22503 run_test 230l "readdir between MDTs won't crash"
22504
22505 test_230m() {
22506         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22507         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22508                 skip "Need MDS version at least 2.11.56"
22509
22510         local MDTIDX=1
22511         local mig_dir=$DIR/$tdir/migrate_dir
22512         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
22513         local shortstr="b"
22514         local val
22515
22516         echo "Creating files and dirs with xattrs"
22517         test_mkdir $DIR/$tdir
22518         test_mkdir -i0 -c1 $mig_dir
22519         mkdir $mig_dir/dir
22520         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
22521                 error "cannot set xattr attr1 on dir"
22522         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
22523                 error "cannot set xattr attr2 on dir"
22524         touch $mig_dir/dir/f0
22525         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
22526                 error "cannot set xattr attr1 on file"
22527         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
22528                 error "cannot set xattr attr2 on file"
22529         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22530         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22531         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
22532         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22533         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
22534         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22535         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
22536         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22537         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
22538
22539         echo "Migrating to MDT1"
22540         $LFS migrate -m $MDTIDX $mig_dir ||
22541                 error "fails on migrating dir to MDT1"
22542
22543         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22544         echo "Checking xattrs"
22545         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22546         [ "$val" = $longstr ] ||
22547                 error "expecting xattr1 $longstr on dir, found $val"
22548         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22549         [ "$val" = $shortstr ] ||
22550                 error "expecting xattr2 $shortstr on dir, found $val"
22551         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22552         [ "$val" = $longstr ] ||
22553                 error "expecting xattr1 $longstr on file, found $val"
22554         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22555         [ "$val" = $shortstr ] ||
22556                 error "expecting xattr2 $shortstr on file, found $val"
22557 }
22558 run_test 230m "xattrs not changed after dir migration"
22559
22560 test_230n() {
22561         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22562         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22563                 skip "Need MDS version at least 2.13.53"
22564
22565         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
22566         cat /etc/hosts > $DIR/$tdir/$tfile
22567         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
22568         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
22569
22570         cmp /etc/hosts $DIR/$tdir/$tfile ||
22571                 error "File data mismatch after migration"
22572 }
22573 run_test 230n "Dir migration with mirrored file"
22574
22575 test_230o() {
22576         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
22577         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22578                 skip "Need MDS version at least 2.13.52"
22579
22580         local mdts=$(comma_list $(mdts_nodes))
22581         local timeout=100
22582         local restripe_status
22583         local delta
22584         local i
22585
22586         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22587
22588         # in case "crush" hash type is not set
22589         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22590
22591         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22592                            mdt.*MDT0000.enable_dir_restripe)
22593         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22594         stack_trap "do_nodes $mdts $LCTL set_param \
22595                     mdt.*.enable_dir_restripe=$restripe_status"
22596
22597         mkdir $DIR/$tdir
22598         createmany -m $DIR/$tdir/f 100 ||
22599                 error "create files under remote dir failed $i"
22600         createmany -d $DIR/$tdir/d 100 ||
22601                 error "create dirs under remote dir failed $i"
22602
22603         for i in $(seq 2 $MDSCOUNT); do
22604                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22605                 $LFS setdirstripe -c $i $DIR/$tdir ||
22606                         error "split -c $i $tdir failed"
22607                 wait_update $HOSTNAME \
22608                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
22609                         error "dir split not finished"
22610                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22611                         awk '/migrate/ {sum += $2} END { print sum }')
22612                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
22613                 # delta is around total_files/stripe_count
22614                 (( $delta < 200 / (i - 1) + 4 )) ||
22615                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
22616         done
22617 }
22618 run_test 230o "dir split"
22619
22620 test_230p() {
22621         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22622         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22623                 skip "Need MDS version at least 2.13.52"
22624
22625         local mdts=$(comma_list $(mdts_nodes))
22626         local timeout=100
22627         local restripe_status
22628         local delta
22629         local c
22630
22631         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22632
22633         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22634
22635         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22636                            mdt.*MDT0000.enable_dir_restripe)
22637         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22638         stack_trap "do_nodes $mdts $LCTL set_param \
22639                     mdt.*.enable_dir_restripe=$restripe_status"
22640
22641         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
22642         createmany -m $DIR/$tdir/f 100 ||
22643                 error "create files under remote dir failed"
22644         createmany -d $DIR/$tdir/d 100 ||
22645                 error "create dirs under remote dir failed"
22646
22647         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
22648                 local mdt_hash="crush"
22649
22650                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22651                 $LFS setdirstripe -c $c $DIR/$tdir ||
22652                         error "split -c $c $tdir failed"
22653                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
22654                         mdt_hash="$mdt_hash,fixed"
22655                 elif [ $c -eq 1 ]; then
22656                         mdt_hash="none"
22657                 fi
22658                 wait_update $HOSTNAME \
22659                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
22660                         error "dir merge not finished"
22661                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22662                         awk '/migrate/ {sum += $2} END { print sum }')
22663                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
22664                 # delta is around total_files/stripe_count
22665                 (( delta < 200 / c + 4 )) ||
22666                         error "$delta files migrated >= $((200 / c + 4))"
22667         done
22668 }
22669 run_test 230p "dir merge"
22670
22671 test_230q() {
22672         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
22673         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22674                 skip "Need MDS version at least 2.13.52"
22675
22676         local mdts=$(comma_list $(mdts_nodes))
22677         local saved_threshold=$(do_facet mds1 \
22678                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
22679         local saved_delta=$(do_facet mds1 \
22680                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
22681         local threshold=100
22682         local delta=2
22683         local total=0
22684         local stripe_count=0
22685         local stripe_index
22686         local nr_files
22687         local create
22688
22689         # test with fewer files on ZFS
22690         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
22691
22692         stack_trap "do_nodes $mdts $LCTL set_param \
22693                     mdt.*.dir_split_count=$saved_threshold"
22694         stack_trap "do_nodes $mdts $LCTL set_param \
22695                     mdt.*.dir_split_delta=$saved_delta"
22696         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
22697         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
22698         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
22699         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
22700         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
22701         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22702
22703         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22704         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22705
22706         create=$((threshold * 3 / 2))
22707         while [ $stripe_count -lt $MDSCOUNT ]; do
22708                 createmany -m $DIR/$tdir/f $total $create ||
22709                         error "create sub files failed"
22710                 stat $DIR/$tdir > /dev/null
22711                 total=$((total + create))
22712                 stripe_count=$((stripe_count + delta))
22713                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
22714
22715                 wait_update $HOSTNAME \
22716                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
22717                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
22718
22719                 wait_update $HOSTNAME \
22720                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
22721                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
22722
22723                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
22724                 echo "$nr_files/$total files on MDT$stripe_index after split"
22725                 # allow 10% margin of imbalance with crush hash
22726                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
22727                         error "$nr_files files on MDT$stripe_index after split"
22728
22729                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
22730                 [ $nr_files -eq $total ] ||
22731                         error "total sub files $nr_files != $total"
22732         done
22733
22734         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
22735
22736         echo "fixed layout directory won't auto split"
22737         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
22738         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
22739                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
22740         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
22741                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
22742 }
22743 run_test 230q "dir auto split"
22744
22745 test_230r() {
22746         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
22747         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
22748         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
22749                 skip "Need MDS version at least 2.13.54"
22750
22751         # maximum amount of local locks:
22752         # parent striped dir - 2 locks
22753         # new stripe in parent to migrate to - 1 lock
22754         # source and target - 2 locks
22755         # Total 5 locks for regular file
22756         mkdir -p $DIR/$tdir
22757         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
22758         touch $DIR/$tdir/dir1/eee
22759
22760         # create 4 hardlink for 4 more locks
22761         # Total: 9 locks > RS_MAX_LOCKS (8)
22762         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
22763         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
22764         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
22765         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
22766         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
22767         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
22768         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
22769         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
22770
22771         cancel_lru_locks mdc
22772
22773         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
22774                 error "migrate dir fails"
22775
22776         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22777 }
22778 run_test 230r "migrate with too many local locks"
22779
22780 test_230s() {
22781         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
22782                 skip "Need MDS version at least 2.14.52"
22783
22784         local mdts=$(comma_list $(mdts_nodes))
22785         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
22786                                 mdt.*MDT0000.enable_dir_restripe)
22787
22788         stack_trap "do_nodes $mdts $LCTL set_param \
22789                     mdt.*.enable_dir_restripe=$restripe_status"
22790
22791         local st
22792         for st in 0 1; do
22793                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
22794                 test_mkdir $DIR/$tdir
22795                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
22796                         error "$LFS mkdir should return EEXIST if target exists"
22797                 rmdir $DIR/$tdir
22798         done
22799 }
22800 run_test 230s "lfs mkdir should return -EEXIST if target exists"
22801
22802 test_230t()
22803 {
22804         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
22805         (( $MDS1_VERSION >= $(version_code 2.14.50) )) ||
22806                 skip "Need MDS version at least 2.14.50"
22807
22808         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
22809         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
22810         $LFS project -p 1 -s $DIR/$tdir ||
22811                 error "set $tdir project id failed"
22812         $LFS project -p 2 -s $DIR/$tdir/subdir ||
22813                 error "set subdir project id failed"
22814         local pbefore="$($LFS project -d $DIR/$tdir)"
22815         local sbefore="$($LFS project -d $DIR/$tdir/subdir)"
22816         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
22817
22818         local pafter="$($LFS project -d $DIR/$tdir)"
22819         local safter="$($LFS project -d $DIR/$tdir/subdir)"
22820         [[ "$pbefore" == "$pafter" ]] || error "projid '$pbefore' != '$pafter'"
22821         [[ "$sbefore" == "$safter" ]] || error "projid '$sbefore' != '$safter'"
22822
22823         (( $MDS1_VERSION >= $(version_code 2.15.59.107) )) ||
22824                 { echo "Need MDS >= 2.15.59.107 for projid rename"; return 0; }
22825
22826         # check rename works, even if source parent projid differs (LU-17016)
22827         test_mkdir $DIR/$tdir.2 || error "mkdir $tdir.2 failed"
22828         local fid_before=$($LFS path2fid $DIR/$tdir/subdir)
22829
22830         $LFS project -p 2 -s $DIR/$tdir.2 || error "set $tdir.2 projid failed"
22831         mrename $DIR/$tdir/subdir $DIR/$tdir.2/subdir ||
22832                 error "subdir failed rename for different source parent projid"
22833         local fid_after=$($LFS path2fid $DIR/$tdir.2/subdir)
22834
22835         [[ "$fid_before" == "$fid_after" ]] ||
22836                 error "fid before '$fid_before' != after '$fid_after'"
22837 }
22838 run_test 230t "migrate directory with project ID set"
22839
22840 test_230u()
22841 {
22842         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22843         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22844                 skip "Need MDS version at least 2.14.53"
22845
22846         local count
22847
22848         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22849         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22850         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
22851         for i in $(seq 0 $((MDSCOUNT - 1))); do
22852                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22853                 echo "$count dirs migrated to MDT$i"
22854         done
22855         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22856         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
22857 }
22858 run_test 230u "migrate directory by QOS"
22859
22860 test_230v()
22861 {
22862         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22863         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22864                 skip "Need MDS version at least 2.14.53"
22865
22866         local count
22867
22868         mkdir $DIR/$tdir || error "mkdir $tdir failed"
22869         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22870         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
22871         for i in $(seq 0 $((MDSCOUNT - 1))); do
22872                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22873                 echo "$count subdirs migrated to MDT$i"
22874                 (( i == 3 )) && (( count > 0 )) &&
22875                         error "subdir shouldn't be migrated to MDT3"
22876         done
22877         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22878         (( count == 3 )) || error "dirs migrated to $count MDTs"
22879 }
22880 run_test 230v "subdir migrated to the MDT where its parent is located"
22881
22882 test_230w() {
22883         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22884         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22885                 skip "Need MDS version at least 2.15.0"
22886
22887         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
22888         createmany -o $DIR/$tdir/f 10 || error "create files failed"
22889         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
22890
22891         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
22892                 error "migrate failed"
22893
22894         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
22895                 error "$tdir stripe count mismatch"
22896
22897         for i in $(seq 0 9); do
22898                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
22899                         error "d$i is striped"
22900         done
22901 }
22902 run_test 230w "non-recursive mode dir migration"
22903
22904 test_230x() {
22905         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22906         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22907                 skip "Need MDS version at least 2.15.0"
22908
22909         mkdir -p $DIR/$tdir || error "mkdir failed"
22910         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
22911
22912         local mdt_name=$(mdtname_from_index 0)
22913         local low=$(do_facet mds2 $LCTL get_param -n \
22914                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
22915         local high=$(do_facet mds2 $LCTL get_param -n \
22916                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
22917         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
22918         local maxage=$(do_facet mds2 $LCTL get_param -n \
22919                 osp.*$mdt_name-osp-MDT0001.maxage)
22920
22921         stack_trap "do_facet mds2 $LCTL set_param -n \
22922                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
22923                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
22924         stack_trap "do_facet mds2 $LCTL set_param -n \
22925                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
22926
22927         do_facet mds2 $LCTL set_param -n \
22928                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
22929         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
22930         sleep 4
22931         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
22932                 error "migrate $tdir should fail"
22933
22934         do_facet mds2 $LCTL set_param -n \
22935                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
22936         do_facet mds2 $LCTL set_param -n \
22937                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
22938         sleep 4
22939         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
22940                 error "migrate failed"
22941         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
22942                 error "$tdir stripe count mismatch"
22943 }
22944 run_test 230x "dir migration check space"
22945
22946 test_230y() {
22947         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22948         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
22949                 skip "Need MDS version at least 2.15.55.45"
22950
22951         local pid
22952
22953         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
22954         $LFS getdirstripe $DIR/$tdir
22955         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
22956         $LFS migrate -m 1 -c 2 $DIR/$tdir &
22957         pid=$!
22958         sleep 1
22959
22960         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
22961         do_facet mds2 lctl set_param fail_loc=0x1802
22962
22963         wait $pid
22964         do_facet mds2 lctl set_param fail_loc=0
22965         $LFS getdirstripe $DIR/$tdir
22966         unlinkmany -d $DIR/$tdir/d 100 || error "unlinkmany failed"
22967         rmdir $DIR/$tdir || error "rmdir $tdir failed"
22968 }
22969 run_test 230y "unlink dir with bad hash type"
22970
22971 test_230z() {
22972         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22973         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
22974                 skip "Need MDS version at least 2.15.55.45"
22975
22976         local pid
22977
22978         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
22979         $LFS getdirstripe $DIR/$tdir
22980         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
22981         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir &
22982         pid=$!
22983         sleep 1
22984
22985         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
22986         do_facet mds2 lctl set_param fail_loc=0x1802
22987
22988         wait $pid
22989         do_facet mds2 lctl set_param fail_loc=0
22990         $LFS getdirstripe $DIR/$tdir
22991
22992         # resume migration
22993         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir ||
22994                 error "resume migration failed"
22995         $LFS getdirstripe $DIR/$tdir
22996         [ $($LFS getdirstripe -H $DIR/$tdir) == "fnv_1a_64,fixed" ] ||
22997                 error "migration is not finished"
22998 }
22999 run_test 230z "resume dir migration with bad hash type"
23000
23001 test_231a()
23002 {
23003         # For simplicity this test assumes that max_pages_per_rpc
23004         # is the same across all OSCs
23005         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
23006         local bulk_size=$((max_pages * PAGE_SIZE))
23007         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
23008                                        head -n 1)
23009
23010         mkdir -p $DIR/$tdir
23011         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
23012                 error "failed to set stripe with -S ${brw_size}M option"
23013         stack_trap "rm -rf $DIR/$tdir"
23014
23015         # clear the OSC stats
23016         $LCTL set_param osc.*.stats=0 &>/dev/null
23017         stop_writeback
23018
23019         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
23020         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
23021                 oflag=direct &>/dev/null || error "dd failed"
23022
23023         sync; sleep 1; sync # just to be safe
23024         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
23025         if [ x$nrpcs != "x1" ]; then
23026                 $LCTL get_param osc.*.stats
23027                 error "found $nrpcs ost_write RPCs, not 1 as expected"
23028         fi
23029
23030         start_writeback
23031         # Drop the OSC cache, otherwise we will read from it
23032         cancel_lru_locks osc
23033
23034         # clear the OSC stats
23035         $LCTL set_param osc.*.stats=0 &>/dev/null
23036
23037         # Client reads $bulk_size.
23038         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
23039                 iflag=direct &>/dev/null || error "dd failed"
23040
23041         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
23042         if [ x$nrpcs != "x1" ]; then
23043                 $LCTL get_param osc.*.stats
23044                 error "found $nrpcs ost_read RPCs, not 1 as expected"
23045         fi
23046 }
23047 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
23048
23049 test_231b() {
23050         mkdir -p $DIR/$tdir
23051         stack_trap "rm -rf $DIR/$tdir"
23052         local i
23053         for i in {0..1023}; do
23054                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
23055                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
23056                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
23057         done
23058         sync
23059 }
23060 run_test 231b "must not assert on fully utilized OST request buffer"
23061
23062 test_232a() {
23063         mkdir -p $DIR/$tdir
23064         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
23065
23066         #define OBD_FAIL_LDLM_OST_LVB            0x31c
23067         do_facet ost1 $LCTL set_param fail_loc=0x31c
23068
23069         # ignore dd failure
23070         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
23071         stack_trap "rm -f $DIR/$tdir/$tfile"
23072
23073         do_facet ost1 $LCTL set_param fail_loc=0
23074         umount_client $MOUNT || error "umount failed"
23075         mount_client $MOUNT || error "mount failed"
23076         stop ost1 || error "cannot stop ost1"
23077         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23078 }
23079 run_test 232a "failed lock should not block umount"
23080
23081 test_232b() {
23082         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
23083                 skip "Need MDS version at least 2.10.58"
23084
23085         mkdir -p $DIR/$tdir
23086         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
23087         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
23088         stack_trap "rm -f $DIR/$tdir/$tfile"
23089         sync
23090         cancel_lru_locks osc
23091
23092         #define OBD_FAIL_LDLM_OST_LVB            0x31c
23093         do_facet ost1 $LCTL set_param fail_loc=0x31c
23094
23095         # ignore failure
23096         $LFS data_version $DIR/$tdir/$tfile || true
23097
23098         do_facet ost1 $LCTL set_param fail_loc=0
23099         umount_client $MOUNT || error "umount failed"
23100         mount_client $MOUNT || error "mount failed"
23101         stop ost1 || error "cannot stop ost1"
23102         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23103 }
23104 run_test 232b "failed data version lock should not block umount"
23105
23106 test_233a() {
23107         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
23108                 skip "Need MDS version at least 2.3.64"
23109         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
23110
23111         local fid=$($LFS path2fid $MOUNT)
23112
23113         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23114                 error "cannot access $MOUNT using its FID '$fid'"
23115 }
23116 run_test 233a "checking that OBF of the FS root succeeds"
23117
23118 test_233b() {
23119         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
23120                 skip "Need MDS version at least 2.5.90"
23121         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
23122
23123         local fid=$($LFS path2fid $MOUNT/.lustre)
23124
23125         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23126                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
23127
23128         fid=$($LFS path2fid $MOUNT/.lustre/fid)
23129         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23130                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
23131 }
23132 run_test 233b "checking that OBF of the FS .lustre succeeds"
23133
23134 test_234() {
23135         local p="$TMP/sanityN-$TESTNAME.parameters"
23136         save_lustre_params client "llite.*.xattr_cache" > $p
23137         lctl set_param llite.*.xattr_cache 1 ||
23138                 skip_env "xattr cache is not supported"
23139
23140         mkdir -p $DIR/$tdir || error "mkdir failed"
23141         touch $DIR/$tdir/$tfile || error "touch failed"
23142         # OBD_FAIL_LLITE_XATTR_ENOMEM
23143         $LCTL set_param fail_loc=0x1405
23144         getfattr -n user.attr $DIR/$tdir/$tfile &&
23145                 error "getfattr should have failed with ENOMEM"
23146         $LCTL set_param fail_loc=0x0
23147         rm -rf $DIR/$tdir
23148
23149         restore_lustre_params < $p
23150         rm -f $p
23151 }
23152 run_test 234 "xattr cache should not crash on ENOMEM"
23153
23154 test_235() {
23155         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
23156                 skip "Need MDS version at least 2.4.52"
23157
23158         flock_deadlock $DIR/$tfile
23159         local RC=$?
23160         case $RC in
23161                 0)
23162                 ;;
23163                 124) error "process hangs on a deadlock"
23164                 ;;
23165                 *) error "error executing flock_deadlock $DIR/$tfile"
23166                 ;;
23167         esac
23168 }
23169 run_test 235 "LU-1715: flock deadlock detection does not work properly"
23170
23171 #LU-2935
23172 test_236() {
23173         check_swap_layouts_support
23174
23175         local ref1=/etc/passwd
23176         local ref2=/etc/group
23177         local file1=$DIR/$tdir/f1
23178         local file2=$DIR/$tdir/f2
23179
23180         test_mkdir -c1 $DIR/$tdir
23181         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
23182         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
23183         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
23184         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
23185         local fd=$(free_fd)
23186         local cmd="exec $fd<>$file2"
23187         eval $cmd
23188         rm $file2
23189         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
23190                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
23191         cmd="exec $fd>&-"
23192         eval $cmd
23193         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
23194
23195         #cleanup
23196         rm -rf $DIR/$tdir
23197 }
23198 run_test 236 "Layout swap on open unlinked file"
23199
23200 # LU-4659 linkea consistency
23201 test_238() {
23202         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
23203                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
23204                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
23205                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
23206
23207         touch $DIR/$tfile
23208         ln $DIR/$tfile $DIR/$tfile.lnk
23209         touch $DIR/$tfile.new
23210         mv $DIR/$tfile.new $DIR/$tfile
23211         local fid1=$($LFS path2fid $DIR/$tfile)
23212         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
23213         local path1=$($LFS fid2path $FSNAME "$fid1")
23214         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
23215         local path2=$($LFS fid2path $FSNAME "$fid2")
23216         [ $tfile.lnk == $path2 ] ||
23217                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
23218         rm -f $DIR/$tfile*
23219 }
23220 run_test 238 "Verify linkea consistency"
23221
23222 test_239A() { # was test_239
23223         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
23224                 skip "Need MDS version at least 2.5.60"
23225
23226         local list=$(comma_list $(mdts_nodes))
23227
23228         mkdir -p $DIR/$tdir
23229         createmany -o $DIR/$tdir/f- 5000
23230         unlinkmany $DIR/$tdir/f- 5000
23231         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
23232                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
23233         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
23234                         osp.*MDT*.sync_in_flight" | calc_sum)
23235         [ "$changes" -eq 0 ] || error "$changes not synced"
23236 }
23237 run_test 239A "osp_sync test"
23238
23239 test_239a() { #LU-5297
23240         remote_mds_nodsh && skip "remote MDS with nodsh"
23241
23242         touch $DIR/$tfile
23243         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
23244         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
23245         chgrp $RUNAS_GID $DIR/$tfile
23246         wait_delete_completed
23247 }
23248 run_test 239a "process invalid osp sync record correctly"
23249
23250 test_239b() { #LU-5297
23251         remote_mds_nodsh && skip "remote MDS with nodsh"
23252
23253         touch $DIR/$tfile1
23254         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
23255         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
23256         chgrp $RUNAS_GID $DIR/$tfile1
23257         wait_delete_completed
23258         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
23259         touch $DIR/$tfile2
23260         chgrp $RUNAS_GID $DIR/$tfile2
23261         wait_delete_completed
23262 }
23263 run_test 239b "process osp sync record with ENOMEM error correctly"
23264
23265 test_240() {
23266         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23267         remote_mds_nodsh && skip "remote MDS with nodsh"
23268
23269         mkdir -p $DIR/$tdir
23270
23271         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
23272                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
23273         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
23274                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
23275
23276         umount_client $MOUNT || error "umount failed"
23277         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
23278         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
23279         mount_client $MOUNT || error "failed to mount client"
23280
23281         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
23282         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
23283 }
23284 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
23285
23286 test_241_bio() {
23287         local count=$1
23288         local bsize=$2
23289
23290         for LOOP in $(seq $count); do
23291                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
23292                 cancel_lru_locks $OSC || true
23293         done
23294 }
23295
23296 test_241_dio() {
23297         local count=$1
23298         local bsize=$2
23299
23300         for LOOP in $(seq $1); do
23301                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
23302                         2>/dev/null
23303         done
23304 }
23305
23306 test_241a() { # was test_241
23307         local bsize=$PAGE_SIZE
23308
23309         (( bsize < 40960 )) && bsize=40960
23310         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
23311         ls -la $DIR/$tfile
23312         cancel_lru_locks $OSC
23313         test_241_bio 1000 $bsize &
23314         PID=$!
23315         test_241_dio 1000 $bsize
23316         wait $PID
23317 }
23318 run_test 241a "bio vs dio"
23319
23320 test_241b() {
23321         local bsize=$PAGE_SIZE
23322
23323         (( bsize < 40960 )) && bsize=40960
23324         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
23325         ls -la $DIR/$tfile
23326         test_241_dio 1000 $bsize &
23327         PID=$!
23328         test_241_dio 1000 $bsize
23329         wait $PID
23330 }
23331 run_test 241b "dio vs dio"
23332
23333 test_242() {
23334         remote_mds_nodsh && skip "remote MDS with nodsh"
23335
23336         mkdir_on_mdt0 $DIR/$tdir
23337         touch $DIR/$tdir/$tfile
23338
23339         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
23340         do_facet mds1 lctl set_param fail_loc=0x105
23341         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
23342
23343         do_facet mds1 lctl set_param fail_loc=0
23344         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
23345 }
23346 run_test 242 "mdt_readpage failure should not cause directory unreadable"
23347
23348 test_243()
23349 {
23350         test_mkdir $DIR/$tdir
23351         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
23352 }
23353 run_test 243 "various group lock tests"
23354
23355 test_244a()
23356 {
23357         test_mkdir $DIR/$tdir
23358         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
23359         sendfile_grouplock $DIR/$tdir/$tfile || \
23360                 error "sendfile+grouplock failed"
23361         rm -rf $DIR/$tdir
23362 }
23363 run_test 244a "sendfile with group lock tests"
23364
23365 test_244b()
23366 {
23367         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23368
23369         local threads=50
23370         local size=$((1024*1024))
23371
23372         test_mkdir $DIR/$tdir
23373         for i in $(seq 1 $threads); do
23374                 local file=$DIR/$tdir/file_$((i / 10))
23375                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
23376                 local pids[$i]=$!
23377         done
23378         for i in $(seq 1 $threads); do
23379                 wait ${pids[$i]}
23380         done
23381 }
23382 run_test 244b "multi-threaded write with group lock"
23383
23384 test_245a() {
23385         local flagname="multi_mod_rpcs"
23386         local connect_data_name="max_mod_rpcs"
23387         local out
23388
23389         # check if multiple modify RPCs flag is set
23390         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
23391                 grep "connect_flags:")
23392         echo "$out"
23393
23394         echo "$out" | grep -qw $flagname
23395         if [ $? -ne 0 ]; then
23396                 echo "connect flag $flagname is not set"
23397                 return
23398         fi
23399
23400         # check if multiple modify RPCs data is set
23401         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
23402         echo "$out"
23403
23404         echo "$out" | grep -qw $connect_data_name ||
23405                 error "import should have connect data $connect_data_name"
23406 }
23407 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
23408
23409 test_245b() {
23410         local flagname="multi_mod_rpcs"
23411         local connect_data_name="max_mod_rpcs"
23412         local out
23413
23414         remote_mds_nodsh && skip "remote MDS with nodsh"
23415         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
23416
23417         # check if multiple modify RPCs flag is set
23418         out=$(do_facet mds1 \
23419               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
23420               grep "connect_flags:")
23421         echo "$out"
23422
23423         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
23424
23425         # check if multiple modify RPCs data is set
23426         out=$(do_facet mds1 \
23427               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
23428
23429         [[ "$out" =~ $connect_data_name ]] ||
23430                 {
23431                         echo "$out"
23432                         error "missing connect data $connect_data_name"
23433                 }
23434 }
23435 run_test 245b "check osp connection flag/data: multiple modify RPCs"
23436
23437 cleanup_247() {
23438         local submount=$1
23439
23440         trap 0
23441         umount_client $submount
23442         rmdir $submount
23443 }
23444
23445 test_247a() {
23446         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23447                 grep -q subtree ||
23448                 skip_env "Fileset feature is not supported"
23449
23450         local submount=${MOUNT}_$tdir
23451
23452         mkdir $MOUNT/$tdir
23453         mkdir -p $submount || error "mkdir $submount failed"
23454         FILESET="$FILESET/$tdir" mount_client $submount ||
23455                 error "mount $submount failed"
23456         trap "cleanup_247 $submount" EXIT
23457         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
23458         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
23459                 error "read $MOUNT/$tdir/$tfile failed"
23460         cleanup_247 $submount
23461 }
23462 run_test 247a "mount subdir as fileset"
23463
23464 test_247b() {
23465         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23466                 skip_env "Fileset feature is not supported"
23467
23468         local submount=${MOUNT}_$tdir
23469
23470         rm -rf $MOUNT/$tdir
23471         mkdir -p $submount || error "mkdir $submount failed"
23472         SKIP_FILESET=1
23473         FILESET="$FILESET/$tdir" mount_client $submount &&
23474                 error "mount $submount should fail"
23475         rmdir $submount
23476 }
23477 run_test 247b "mount subdir that dose not exist"
23478
23479 test_247c() {
23480         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23481                 skip_env "Fileset feature is not supported"
23482
23483         local submount=${MOUNT}_$tdir
23484
23485         mkdir -p $MOUNT/$tdir/dir1
23486         mkdir -p $submount || error "mkdir $submount failed"
23487         trap "cleanup_247 $submount" EXIT
23488         FILESET="$FILESET/$tdir" mount_client $submount ||
23489                 error "mount $submount failed"
23490         local fid=$($LFS path2fid $MOUNT/)
23491         $LFS fid2path $submount $fid && error "fid2path should fail"
23492         cleanup_247 $submount
23493 }
23494 run_test 247c "running fid2path outside subdirectory root"
23495
23496 test_247d() {
23497         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23498                 skip "Fileset feature is not supported"
23499
23500         local submount=${MOUNT}_$tdir
23501
23502         mkdir -p $MOUNT/$tdir/dir1
23503         mkdir -p $submount || error "mkdir $submount failed"
23504         FILESET="$FILESET/$tdir" mount_client $submount ||
23505                 error "mount $submount failed"
23506         trap "cleanup_247 $submount" EXIT
23507
23508         local td=$submount/dir1
23509         local fid=$($LFS path2fid $td)
23510         [ -z "$fid" ] && error "path2fid unable to get $td FID"
23511
23512         # check that we get the same pathname back
23513         local rootpath
23514         local found
23515         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
23516                 echo "$rootpath $fid"
23517                 found=$($LFS fid2path $rootpath "$fid")
23518                 [ -n "$found" ] || error "fid2path should succeed"
23519                 [ "$found" == "$td" ] || error "fid2path $found != $td"
23520         done
23521         # check wrong root path format
23522         rootpath=$submount"_wrong"
23523         found=$($LFS fid2path $rootpath "$fid")
23524         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
23525
23526         cleanup_247 $submount
23527 }
23528 run_test 247d "running fid2path inside subdirectory root"
23529
23530 # LU-8037
23531 test_247e() {
23532         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23533                 grep -q subtree ||
23534                 skip "Fileset feature is not supported"
23535
23536         local submount=${MOUNT}_$tdir
23537
23538         mkdir $MOUNT/$tdir
23539         mkdir -p $submount || error "mkdir $submount failed"
23540         FILESET="$FILESET/.." mount_client $submount &&
23541                 error "mount $submount should fail"
23542         rmdir $submount
23543 }
23544 run_test 247e "mount .. as fileset"
23545
23546 test_247f() {
23547         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
23548         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
23549                 skip "Need at least version 2.14.50.162"
23550         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23551                 skip "Fileset feature is not supported"
23552
23553         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
23554         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
23555                 error "mkdir remote failed"
23556         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
23557                 error "mkdir remote/subdir failed"
23558         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
23559                 error "mkdir striped failed"
23560         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
23561
23562         local submount=${MOUNT}_$tdir
23563
23564         mkdir -p $submount || error "mkdir $submount failed"
23565         stack_trap "rmdir $submount"
23566
23567         local dir
23568         local fileset=$FILESET
23569         local mdts=$(comma_list $(mdts_nodes))
23570
23571         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
23572         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
23573                 $tdir/striped/subdir $tdir/striped/.; do
23574                 FILESET="$fileset/$dir" mount_client $submount ||
23575                         error "mount $dir failed"
23576                 umount_client $submount
23577         done
23578 }
23579 run_test 247f "mount striped or remote directory as fileset"
23580
23581 test_subdir_mount_lock()
23582 {
23583         local testdir=$1
23584         local submount=${MOUNT}_$(basename $testdir)
23585
23586         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
23587
23588         mkdir -p $submount || error "mkdir $submount failed"
23589         stack_trap "rmdir $submount"
23590
23591         FILESET="$fileset/$testdir" mount_client $submount ||
23592                 error "mount $FILESET failed"
23593         stack_trap "umount $submount"
23594
23595         local mdts=$(comma_list $(mdts_nodes))
23596
23597         local nrpcs
23598
23599         stat $submount > /dev/null || error "stat $submount failed"
23600         cancel_lru_locks $MDC
23601         stat $submount > /dev/null || error "stat $submount failed"
23602         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23603         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
23604         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23605         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
23606                 awk '/getattr/ {sum += $2} END {print sum}')
23607
23608         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
23609 }
23610
23611 test_247g() {
23612         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23613
23614         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
23615                 error "mkdir $tdir failed"
23616         test_subdir_mount_lock $tdir
23617 }
23618 run_test 247g "striped directory submount revalidate ROOT from cache"
23619
23620 test_247h() {
23621         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23622         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
23623                 skip "Need MDS version at least 2.15.51"
23624
23625         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23626         test_subdir_mount_lock $tdir
23627         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
23628         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
23629                 error "mkdir $tdir.1 failed"
23630         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
23631 }
23632 run_test 247h "remote directory submount revalidate ROOT from cache"
23633
23634 test_248a() {
23635         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
23636         [ -z "$fast_read_sav" ] && skip "no fast read support"
23637
23638         # create a large file for fast read verification
23639         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
23640
23641         # make sure the file is created correctly
23642         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
23643                 { rm -f $DIR/$tfile; skip "file creation error"; }
23644
23645         echo "Test 1: verify that fast read is 4 times faster on cache read"
23646
23647         # small read with fast read enabled
23648         $LCTL set_param -n llite.*.fast_read=1
23649         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23650                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23651                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23652         # small read with fast read disabled
23653         $LCTL set_param -n llite.*.fast_read=0
23654         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23655                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23656                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23657
23658         # verify that fast read is 4 times faster for cache read
23659         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
23660                 error_not_in_vm "fast read was not 4 times faster: " \
23661                            "$t_fast vs $t_slow"
23662
23663         echo "Test 2: verify the performance between big and small read"
23664         $LCTL set_param -n llite.*.fast_read=1
23665
23666         # 1k non-cache read
23667         cancel_lru_locks osc
23668         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23669                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23670                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23671
23672         # 1M non-cache read
23673         cancel_lru_locks osc
23674         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23675                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23676                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23677
23678         # verify that big IO is not 4 times faster than small IO
23679         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
23680                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
23681
23682         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
23683         rm -f $DIR/$tfile
23684 }
23685 run_test 248a "fast read verification"
23686
23687 test_248b() {
23688         # Default short_io_bytes=16384, try both smaller and larger sizes.
23689         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
23690         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
23691         echo "bs=53248 count=113 normal buffered write"
23692         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
23693                 error "dd of initial data file failed"
23694         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
23695
23696         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
23697         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
23698                 error "dd with sync normal writes failed"
23699         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
23700
23701         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
23702         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
23703                 error "dd with sync small writes failed"
23704         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
23705
23706         cancel_lru_locks osc
23707
23708         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
23709         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
23710         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
23711         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
23712                 iflag=direct || error "dd with O_DIRECT small read failed"
23713         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
23714         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
23715                 error "compare $TMP/$tfile.1 failed"
23716
23717         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
23718         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
23719
23720         # just to see what the maximum tunable value is, and test parsing
23721         echo "test invalid parameter 2MB"
23722         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
23723                 error "too-large short_io_bytes allowed"
23724         echo "test maximum parameter 512KB"
23725         # if we can set a larger short_io_bytes, run test regardless of version
23726         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
23727                 # older clients may not allow setting it this large, that's OK
23728                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
23729                         skip "Need at least client version 2.13.50"
23730                 error "medium short_io_bytes failed"
23731         fi
23732         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23733         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
23734
23735         echo "test large parameter 64KB"
23736         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
23737         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23738
23739         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
23740         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
23741                 error "dd with sync large writes failed"
23742         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
23743
23744         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
23745         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
23746         num=$((113 * 4096 / PAGE_SIZE))
23747         echo "bs=$size count=$num oflag=direct large write $tfile.3"
23748         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
23749                 error "dd with O_DIRECT large writes failed"
23750         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
23751                 error "compare $DIR/$tfile.3 failed"
23752
23753         cancel_lru_locks osc
23754
23755         echo "bs=$size count=$num iflag=direct large read $tfile.2"
23756         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
23757                 error "dd with O_DIRECT large read failed"
23758         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
23759                 error "compare $TMP/$tfile.2 failed"
23760
23761         echo "bs=$size count=$num iflag=direct large read $tfile.3"
23762         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
23763                 error "dd with O_DIRECT large read failed"
23764         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
23765                 error "compare $TMP/$tfile.3 failed"
23766 }
23767 run_test 248b "test short_io read and write for both small and large sizes"
23768
23769 test_249() { # LU-7890
23770         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
23771                 skip "Need at least version 2.8.54"
23772
23773         rm -f $DIR/$tfile
23774         $LFS setstripe -c 1 $DIR/$tfile
23775         # Offset 2T == 4k * 512M
23776         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
23777                 error "dd to 2T offset failed"
23778 }
23779 run_test 249 "Write above 2T file size"
23780
23781 test_250() {
23782         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
23783          && skip "no 16TB file size limit on ZFS"
23784
23785         $LFS setstripe -c 1 $DIR/$tfile
23786         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
23787         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
23788         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
23789         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
23790                 conv=notrunc,fsync && error "append succeeded"
23791         return 0
23792 }
23793 run_test 250 "Write above 16T limit"
23794
23795 test_251() {
23796         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
23797
23798         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
23799         #Skip once - writing the first stripe will succeed
23800         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23801         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
23802                 error "short write happened"
23803
23804         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23805         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
23806                 error "short read happened"
23807
23808         rm -f $DIR/$tfile
23809 }
23810 run_test 251 "Handling short read and write correctly"
23811
23812 test_252() {
23813         remote_mds_nodsh && skip "remote MDS with nodsh"
23814         remote_ost_nodsh && skip "remote OST with nodsh"
23815         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
23816                 skip_env "ldiskfs only test"
23817         fi
23818
23819         local tgt
23820         local dev
23821         local out
23822         local uuid
23823         local num
23824         local gen
23825
23826         # check lr_reader on OST0000
23827         tgt=ost1
23828         dev=$(facet_device $tgt)
23829         out=$(do_facet $tgt $LR_READER $dev)
23830         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23831         echo "$out"
23832         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
23833         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
23834                 error "Invalid uuid returned by $LR_READER on target $tgt"
23835         echo -e "uuid returned by $LR_READER is '$uuid'\n"
23836
23837         # check lr_reader -c on MDT0000
23838         tgt=mds1
23839         dev=$(facet_device $tgt)
23840         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
23841                 skip "$LR_READER does not support additional options"
23842         fi
23843         out=$(do_facet $tgt $LR_READER -c $dev)
23844         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23845         echo "$out"
23846         num=$(echo "$out" | grep -c "mdtlov")
23847         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
23848                 error "Invalid number of mdtlov clients returned by $LR_READER"
23849         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
23850
23851         # check lr_reader -cr on MDT0000
23852         out=$(do_facet $tgt $LR_READER -cr $dev)
23853         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23854         echo "$out"
23855         echo "$out" | grep -q "^reply_data:$" ||
23856                 error "$LR_READER should have returned 'reply_data' section"
23857         num=$(echo "$out" | grep -c "client_generation")
23858         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
23859 }
23860 run_test 252 "check lr_reader tool"
23861
23862 test_253() {
23863         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23864         remote_mds_nodsh && skip "remote MDS with nodsh"
23865         remote_mgs_nodsh && skip "remote MGS with nodsh"
23866         check_set_fallocate_or_skip
23867
23868         local ostidx=0
23869         local rc=0
23870         local ost_name=$(ostname_from_index $ostidx)
23871
23872         # on the mdt's osc
23873         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
23874         do_facet $SINGLEMDS $LCTL get_param -n \
23875                 osp.$mdtosc_proc1.reserved_mb_high ||
23876                 skip  "remote MDS does not support reserved_mb_high"
23877
23878         rm -rf $DIR/$tdir
23879         wait_mds_ost_sync
23880         wait_delete_completed
23881         mkdir $DIR/$tdir
23882         stack_trap "rm -rf $DIR/$tdir"
23883
23884         pool_add $TESTNAME || error "Pool creation failed"
23885         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
23886
23887         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
23888                 error "Setstripe failed"
23889
23890         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
23891
23892         local wms=$(ost_watermarks_get $ostidx)
23893
23894         ost_watermarks_set $ostidx 60 50
23895         stack_trap "ost_watermarks_set $ostidx $wms"
23896
23897         local free_kb=$($LFS df $MOUNT | awk "/$ost_name/ { print \$4 }")
23898         local size=$((free_kb * 1024))
23899
23900         fallocate -l $size $DIR/$tdir/fill_ost$ostidx ||
23901                 error "fallocate failed"
23902         sleep_maxage
23903
23904         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
23905                         osp.$mdtosc_proc1.prealloc_status)
23906         echo "prealloc_status $oa_status"
23907
23908         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
23909                 error "File creation should fail"
23910
23911         #object allocation was stopped, but we still able to append files
23912         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
23913                 oflag=append || error "Append failed"
23914
23915         rm -f $DIR/$tdir/$tfile.0
23916         rm -f $DIR/$tdir/fill_ost$ostidx
23917
23918         wait_delete_completed
23919         sleep_maxage
23920
23921         for i in $(seq 10 12); do
23922                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
23923                         2>/dev/null || error "File creation failed after rm"
23924         done
23925
23926         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
23927                         osp.$mdtosc_proc1.prealloc_status)
23928         echo "prealloc_status $oa_status"
23929
23930         if (( oa_status != 0 )); then
23931                 error "Object allocation still disable after rm"
23932         fi
23933 }
23934 run_test 253 "Check object allocation limit"
23935
23936 test_254() {
23937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23938         remote_mds_nodsh && skip "remote MDS with nodsh"
23939
23940         local mdt=$(facet_svc $SINGLEMDS)
23941
23942         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
23943                 skip "MDS does not support changelog_size"
23944
23945         local cl_user
23946
23947         changelog_register || error "changelog_register failed"
23948
23949         changelog_clear 0 || error "changelog_clear failed"
23950
23951         local size1=$(do_facet $SINGLEMDS \
23952                       $LCTL get_param -n mdd.$mdt.changelog_size)
23953         echo "Changelog size $size1"
23954
23955         rm -rf $DIR/$tdir
23956         $LFS mkdir -i 0 $DIR/$tdir
23957         # change something
23958         mkdir -p $DIR/$tdir/pics/2008/zachy
23959         touch $DIR/$tdir/pics/2008/zachy/timestamp
23960         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
23961         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
23962         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
23963         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
23964         rm $DIR/$tdir/pics/desktop.jpg
23965
23966         local size2=$(do_facet $SINGLEMDS \
23967                       $LCTL get_param -n mdd.$mdt.changelog_size)
23968         echo "Changelog size after work $size2"
23969
23970         (( $size2 > $size1 )) ||
23971                 error "new Changelog size=$size2 less than old size=$size1"
23972 }
23973 run_test 254 "Check changelog size"
23974
23975 ladvise_no_type()
23976 {
23977         local type=$1
23978         local file=$2
23979
23980         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
23981                 awk -F: '{print $2}' | grep $type > /dev/null
23982         if [ $? -ne 0 ]; then
23983                 return 0
23984         fi
23985         return 1
23986 }
23987
23988 ladvise_no_ioctl()
23989 {
23990         local file=$1
23991
23992         lfs ladvise -a willread $file > /dev/null 2>&1
23993         if [ $? -eq 0 ]; then
23994                 return 1
23995         fi
23996
23997         lfs ladvise -a willread $file 2>&1 |
23998                 grep "Inappropriate ioctl for device" > /dev/null
23999         if [ $? -eq 0 ]; then
24000                 return 0
24001         fi
24002         return 1
24003 }
24004
24005 percent() {
24006         bc <<<"scale=2; ($1 - $2) * 100 / $2"
24007 }
24008
24009 # run a random read IO workload
24010 # usage: random_read_iops <filename> <filesize> <iosize>
24011 random_read_iops() {
24012         local file=$1
24013         local fsize=$2
24014         local iosize=${3:-4096}
24015
24016         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
24017                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
24018 }
24019
24020 drop_file_oss_cache() {
24021         local file="$1"
24022         local nodes="$2"
24023
24024         $LFS ladvise -a dontneed $file 2>/dev/null ||
24025                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
24026 }
24027
24028 ladvise_willread_performance()
24029 {
24030         local repeat=10
24031         local average_origin=0
24032         local average_cache=0
24033         local average_ladvise=0
24034
24035         for ((i = 1; i <= $repeat; i++)); do
24036                 echo "Iter $i/$repeat: reading without willread hint"
24037                 cancel_lru_locks osc
24038                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
24039                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
24040                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
24041                 average_origin=$(bc <<<"$average_origin + $speed_origin")
24042
24043                 cancel_lru_locks osc
24044                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
24045                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
24046                 average_cache=$(bc <<<"$average_cache + $speed_cache")
24047
24048                 cancel_lru_locks osc
24049                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
24050                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
24051                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
24052                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
24053                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
24054         done
24055         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
24056         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
24057         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
24058
24059         speedup_cache=$(percent $average_cache $average_origin)
24060         speedup_ladvise=$(percent $average_ladvise $average_origin)
24061
24062         echo "Average uncached read: $average_origin"
24063         echo "Average speedup with OSS cached read:" \
24064                 "$average_cache = +$speedup_cache%"
24065         echo "Average speedup with ladvise willread:" \
24066                 "$average_ladvise = +$speedup_ladvise%"
24067
24068         local lowest_speedup=20
24069         if (( ${speedup_cache%.*} < $lowest_speedup )); then
24070                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
24071                      "got $speedup_cache%. Skipping ladvise willread check."
24072                 return 0
24073         fi
24074
24075         # the test won't work on ZFS until it supports 'ladvise dontneed', but
24076         # it is still good to run until then to exercise 'ladvise willread'
24077         ! $LFS ladvise -a dontneed $DIR/$tfile &&
24078                 [ "$ost1_FSTYPE" = "zfs" ] &&
24079                 echo "osd-zfs does not support dontneed or drop_caches" &&
24080                 return 0
24081
24082         lowest_speedup=$(bc <<<"scale=2; $speedup_cache / 2")
24083         (( ${speedup_ladvise%.*} > ${lowest_speedup%.*} )) ||
24084                 error_not_in_vm "Speedup with willread is less than " \
24085                         "$lowest_speedup%, got $speedup_ladvise%"
24086 }
24087
24088 test_255a() {
24089         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
24090                 skip "lustre < 2.8.54 does not support ladvise "
24091         remote_ost_nodsh && skip "remote OST with nodsh"
24092
24093         stack_trap "rm -f $DIR/$tfile"
24094         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
24095
24096         ladvise_no_type willread $DIR/$tfile &&
24097                 skip "willread ladvise is not supported"
24098
24099         ladvise_no_ioctl $DIR/$tfile &&
24100                 skip "ladvise ioctl is not supported"
24101
24102         local size_mb=100
24103         local size=$((size_mb * 1048576))
24104         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
24105                 error "dd to $DIR/$tfile failed"
24106
24107         lfs ladvise -a willread $DIR/$tfile ||
24108                 error "Ladvise failed with no range argument"
24109
24110         lfs ladvise -a willread -s 0 $DIR/$tfile ||
24111                 error "Ladvise failed with no -l or -e argument"
24112
24113         lfs ladvise -a willread -e 1 $DIR/$tfile ||
24114                 error "Ladvise failed with only -e argument"
24115
24116         lfs ladvise -a willread -l 1 $DIR/$tfile ||
24117                 error "Ladvise failed with only -l argument"
24118
24119         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
24120                 error "End offset should not be smaller than start offset"
24121
24122         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
24123                 error "End offset should not be equal to start offset"
24124
24125         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
24126                 error "Ladvise failed with overflowing -s argument"
24127
24128         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
24129                 error "Ladvise failed with overflowing -e argument"
24130
24131         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
24132                 error "Ladvise failed with overflowing -l argument"
24133
24134         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
24135                 error "Ladvise succeeded with conflicting -l and -e arguments"
24136
24137         echo "Synchronous ladvise should wait"
24138         local delay=8
24139 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
24140         do_nodes $(comma_list $(osts_nodes)) \
24141                 $LCTL set_param fail_val=$delay fail_loc=0x237
24142         stack_trap "do_nodes $(comma_list $(osts_nodes)) \
24143                 $LCTL set_param fail_loc=0"
24144
24145         local start_ts=$SECONDS
24146         lfs ladvise -a willread $DIR/$tfile ||
24147                 error "Ladvise failed with no range argument"
24148         local end_ts=$SECONDS
24149         local inteval_ts=$((end_ts - start_ts))
24150
24151         if [ $inteval_ts -lt $(($delay - 1)) ]; then
24152                 error "Synchronous advice didn't wait reply"
24153         fi
24154
24155         echo "Asynchronous ladvise shouldn't wait"
24156         local start_ts=$SECONDS
24157         lfs ladvise -a willread -b $DIR/$tfile ||
24158                 error "Ladvise failed with no range argument"
24159         local end_ts=$SECONDS
24160         local inteval_ts=$((end_ts - start_ts))
24161
24162         if [ $inteval_ts -gt $(($delay / 2)) ]; then
24163                 error "Asynchronous advice blocked"
24164         fi
24165
24166         ladvise_willread_performance
24167 }
24168 run_test 255a "check 'lfs ladvise -a willread'"
24169
24170 facet_meminfo() {
24171         local facet=$1
24172         local info=$2
24173
24174         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
24175 }
24176
24177 test_255b() {
24178         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
24179                 skip "lustre < 2.8.54 does not support ladvise "
24180         remote_ost_nodsh && skip "remote OST with nodsh"
24181
24182         stack_trap "rm -f $DIR/$tfile"
24183         lfs setstripe -c 1 -i 0 $DIR/$tfile
24184
24185         ladvise_no_type dontneed $DIR/$tfile &&
24186                 skip "dontneed ladvise is not supported"
24187
24188         ladvise_no_ioctl $DIR/$tfile &&
24189                 skip "ladvise ioctl is not supported"
24190
24191         ! $LFS ladvise -a dontneed $DIR/$tfile &&
24192                 [ "$ost1_FSTYPE" = "zfs" ] &&
24193                 skip "zfs-osd does not support 'ladvise dontneed'"
24194
24195         local size_mb=100
24196         local size=$((size_mb * 1048576))
24197         # In order to prevent disturbance of other processes, only check 3/4
24198         # of the memory usage
24199         local kibibytes=$((size_mb * 1024 * 3 / 4))
24200
24201         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
24202                 error "dd to $DIR/$tfile failed"
24203
24204         #force write to complete before dropping OST cache & checking memory
24205         sync
24206
24207         local total=$(facet_meminfo ost1 MemTotal)
24208         echo "Total memory: $total KiB"
24209
24210         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
24211         local before_read=$(facet_meminfo ost1 Cached)
24212         echo "Cache used before read: $before_read KiB"
24213
24214         lfs ladvise -a willread $DIR/$tfile ||
24215                 error "Ladvise willread failed"
24216         local after_read=$(facet_meminfo ost1 Cached)
24217         echo "Cache used after read: $after_read KiB"
24218
24219         lfs ladvise -a dontneed $DIR/$tfile ||
24220                 error "Ladvise dontneed again failed"
24221         local no_read=$(facet_meminfo ost1 Cached)
24222         echo "Cache used after dontneed ladvise: $no_read KiB"
24223
24224         if [ $total -lt $((before_read + kibibytes)) ]; then
24225                 echo "Memory is too small, abort checking"
24226                 return 0
24227         fi
24228
24229         if [ $((before_read + kibibytes)) -gt $after_read ]; then
24230                 error "Ladvise willread should use more memory" \
24231                         "than $kibibytes KiB"
24232         fi
24233
24234         if [ $((no_read + kibibytes)) -gt $after_read ]; then
24235                 error "Ladvise dontneed should release more memory" \
24236                         "than $kibibytes KiB"
24237         fi
24238 }
24239 run_test 255b "check 'lfs ladvise -a dontneed'"
24240
24241 test_255c() {
24242         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
24243                 skip "lustre < 2.10.50 does not support lockahead"
24244
24245         local ost1_imp=$(get_osc_import_name client ost1)
24246         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24247                          cut -d'.' -f2)
24248         local count
24249         local new_count
24250         local difference
24251         local i
24252         local rc
24253
24254         test_mkdir -p $DIR/$tdir
24255         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24256
24257         #test 10 returns only success/failure
24258         i=10
24259         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24260         rc=$?
24261         if [ $rc -eq 255 ]; then
24262                 error "Ladvise test${i} failed, ${rc}"
24263         fi
24264
24265         #test 11 counts lock enqueue requests, all others count new locks
24266         i=11
24267         count=$(do_facet ost1 \
24268                 $LCTL get_param -n ost.OSS.ost.stats)
24269         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
24270
24271         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24272         rc=$?
24273         if [ $rc -eq 255 ]; then
24274                 error "Ladvise test${i} failed, ${rc}"
24275         fi
24276
24277         new_count=$(do_facet ost1 \
24278                 $LCTL get_param -n ost.OSS.ost.stats)
24279         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
24280                    awk '{ print $2 }')
24281
24282         difference="$((new_count - count))"
24283         if [ $difference -ne $rc ]; then
24284                 error "Ladvise test${i}, bad enqueue count, returned " \
24285                       "${rc}, actual ${difference}"
24286         fi
24287
24288         for i in $(seq 12 21); do
24289                 # If we do not do this, we run the risk of having too many
24290                 # locks and starting lock cancellation while we are checking
24291                 # lock counts.
24292                 cancel_lru_locks osc
24293
24294                 count=$($LCTL get_param -n \
24295                        ldlm.namespaces.$imp_name.lock_unused_count)
24296
24297                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
24298                 rc=$?
24299                 if [ $rc -eq 255 ]; then
24300                         error "Ladvise test ${i} failed, ${rc}"
24301                 fi
24302
24303                 new_count=$($LCTL get_param -n \
24304                        ldlm.namespaces.$imp_name.lock_unused_count)
24305                 difference="$((new_count - count))"
24306
24307                 # Test 15 output is divided by 100 to map down to valid return
24308                 if [ $i -eq 15 ]; then
24309                         rc="$((rc * 100))"
24310                 fi
24311
24312                 if [ $difference -ne $rc ]; then
24313                         error "Ladvise test ${i}, bad lock count, returned " \
24314                               "${rc}, actual ${difference}"
24315                 fi
24316         done
24317
24318         #test 22 returns only success/failure
24319         i=22
24320         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24321         rc=$?
24322         if [ $rc -eq 255 ]; then
24323                 error "Ladvise test${i} failed, ${rc}"
24324         fi
24325 }
24326 run_test 255c "suite of ladvise lockahead tests"
24327
24328 test_256() {
24329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24330         remote_mds_nodsh && skip "remote MDS with nodsh"
24331         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
24332         changelog_users $SINGLEMDS | grep "^cl" &&
24333                 skip "active changelog user"
24334
24335         local cl_user
24336         local cat_sl
24337         local mdt_dev
24338
24339         mdt_dev=$(facet_device $SINGLEMDS)
24340         echo $mdt_dev
24341
24342         changelog_register || error "changelog_register failed"
24343
24344         rm -rf $DIR/$tdir
24345         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
24346
24347         changelog_clear 0 || error "changelog_clear failed"
24348
24349         # change something
24350         touch $DIR/$tdir/{1..10}
24351
24352         # stop the MDT
24353         stop $SINGLEMDS || error "Fail to stop MDT"
24354
24355         # remount the MDT
24356         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
24357                 error "Fail to start MDT"
24358
24359         #after mount new plainllog is used
24360         touch $DIR/$tdir/{11..19}
24361         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
24362         stack_trap "rm -f $tmpfile"
24363         cat_sl=$(do_facet $SINGLEMDS "sync; \
24364                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24365                  llog_reader $tmpfile | grep -c type=1064553b")
24366         do_facet $SINGLEMDS llog_reader $tmpfile
24367
24368         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
24369
24370         changelog_clear 0 || error "changelog_clear failed"
24371
24372         cat_sl=$(do_facet $SINGLEMDS "sync; \
24373                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24374                  llog_reader $tmpfile | grep -c type=1064553b")
24375
24376         if (( cat_sl == 2 )); then
24377                 error "Empty plain llog was not deleted from changelog catalog"
24378         elif (( cat_sl != 1 )); then
24379                 error "Active plain llog shouldn't be deleted from catalog"
24380         fi
24381 }
24382 run_test 256 "Check llog delete for empty and not full state"
24383
24384 test_257() {
24385         remote_mds_nodsh && skip "remote MDS with nodsh"
24386         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
24387                 skip "Need MDS version at least 2.8.55"
24388
24389         test_mkdir $DIR/$tdir
24390
24391         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
24392                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
24393         stat $DIR/$tdir
24394
24395 #define OBD_FAIL_MDS_XATTR_REP                  0x161
24396         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
24397         local facet=mds$((mdtidx + 1))
24398         set_nodes_failloc $(facet_active_host $facet) 0x80000161
24399         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
24400
24401         stop $facet || error "stop MDS failed"
24402         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
24403                 error "start MDS fail"
24404         wait_recovery_complete $facet
24405 }
24406 run_test 257 "xattr locks are not lost"
24407
24408 # Verify we take the i_mutex when security requires it
24409 test_258a() {
24410 #define OBD_FAIL_IMUTEX_SEC 0x141c
24411         $LCTL set_param fail_loc=0x141c
24412         touch $DIR/$tfile
24413         chmod u+s $DIR/$tfile
24414         chmod a+rwx $DIR/$tfile
24415         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24416         RC=$?
24417         if [ $RC -ne 0 ]; then
24418                 error "error, failed to take i_mutex, rc=$?"
24419         fi
24420         rm -f $DIR/$tfile
24421 }
24422 run_test 258a "verify i_mutex security behavior when suid attributes is set"
24423
24424 # Verify we do NOT take the i_mutex in the normal case
24425 test_258b() {
24426 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
24427         $LCTL set_param fail_loc=0x141d
24428         touch $DIR/$tfile
24429         chmod a+rwx $DIR
24430         chmod a+rw $DIR/$tfile
24431         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24432         RC=$?
24433         if [ $RC -ne 0 ]; then
24434                 error "error, took i_mutex unnecessarily, rc=$?"
24435         fi
24436         rm -f $DIR/$tfile
24437
24438 }
24439 run_test 258b "verify i_mutex security behavior"
24440
24441 test_259() {
24442         local file=$DIR/$tfile
24443         local before
24444         local after
24445
24446         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
24447
24448         stack_trap "rm -f $file" EXIT
24449
24450         wait_delete_completed
24451         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24452         echo "before: $before"
24453
24454         $LFS setstripe -i 0 -c 1 $file
24455         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
24456         sync_all_data
24457         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24458         echo "after write: $after"
24459
24460 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
24461         do_facet ost1 $LCTL set_param fail_loc=0x2301
24462         $TRUNCATE $file 0
24463         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24464         echo "after truncate: $after"
24465
24466         stop ost1
24467         do_facet ost1 $LCTL set_param fail_loc=0
24468         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
24469         sleep 2
24470         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24471         echo "after restart: $after"
24472         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
24473                 error "missing truncate?"
24474
24475         return 0
24476 }
24477 run_test 259 "crash at delayed truncate"
24478
24479 test_260() {
24480 #define OBD_FAIL_MDC_CLOSE               0x806
24481         $LCTL set_param fail_loc=0x80000806
24482         touch $DIR/$tfile
24483
24484 }
24485 run_test 260 "Check mdc_close fail"
24486
24487 ### Data-on-MDT sanity tests ###
24488 test_270a() {
24489         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24490                 skip "Need MDS version at least 2.10.55 for DoM"
24491
24492         # create DoM file
24493         local dom=$DIR/$tdir/dom_file
24494         local tmp=$DIR/$tdir/tmp_file
24495
24496         mkdir_on_mdt0 $DIR/$tdir
24497
24498         # basic checks for DoM component creation
24499         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
24500                 error "Can set MDT layout to non-first entry"
24501
24502         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
24503                 error "Can define multiple entries as MDT layout"
24504
24505         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
24506
24507         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
24508         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
24509         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
24510
24511         local mdtidx=$($LFS getstripe -m $dom)
24512         local mdtname=MDT$(printf %04x $mdtidx)
24513         local facet=mds$((mdtidx + 1))
24514         local space_check=1
24515
24516         # Skip free space checks with ZFS
24517         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
24518
24519         # write
24520         sync
24521         local size_tmp=$((65536 * 3))
24522         local mdtfree1=$(do_facet $facet \
24523                          lctl get_param -n osd*.*$mdtname.kbytesfree)
24524
24525         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24526         # check also direct IO along write
24527         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
24528         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24529         sync
24530         cmp $tmp $dom || error "file data is different"
24531         [ $(stat -c%s $dom) == $size_tmp ] ||
24532                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24533         if [ $space_check == 1 ]; then
24534                 local mdtfree2=$(do_facet $facet \
24535                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
24536
24537                 # increase in usage from by $size_tmp
24538                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24539                         error "MDT free space wrong after write: " \
24540                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24541         fi
24542
24543         # truncate
24544         local size_dom=10000
24545
24546         $TRUNCATE $dom $size_dom
24547         [ $(stat -c%s $dom) == $size_dom ] ||
24548                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
24549         if [ $space_check == 1 ]; then
24550                 mdtfree1=$(do_facet $facet \
24551                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24552                 # decrease in usage from $size_tmp to new $size_dom
24553                 [ $(($mdtfree1 - $mdtfree2)) -ge \
24554                   $(((size_tmp - size_dom) / 1024)) ] ||
24555                         error "MDT free space is wrong after truncate: " \
24556                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
24557         fi
24558
24559         # append
24560         cat $tmp >> $dom
24561         sync
24562         size_dom=$((size_dom + size_tmp))
24563         [ $(stat -c%s $dom) == $size_dom ] ||
24564                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
24565         if [ $space_check == 1 ]; then
24566                 mdtfree2=$(do_facet $facet \
24567                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24568                 # increase in usage by $size_tmp from previous
24569                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24570                         error "MDT free space is wrong after append: " \
24571                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24572         fi
24573
24574         # delete
24575         rm $dom
24576         if [ $space_check == 1 ]; then
24577                 mdtfree1=$(do_facet $facet \
24578                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24579                 # decrease in usage by $size_dom from previous
24580                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
24581                         error "MDT free space is wrong after removal: " \
24582                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
24583         fi
24584
24585         # combined striping
24586         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
24587                 error "Can't create DoM + OST striping"
24588
24589         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
24590         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24591         # check also direct IO along write
24592         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24593         sync
24594         cmp $tmp $dom || error "file data is different"
24595         [ $(stat -c%s $dom) == $size_tmp ] ||
24596                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24597         rm $dom $tmp
24598
24599         return 0
24600 }
24601 run_test 270a "DoM: basic functionality tests"
24602
24603 test_270b() {
24604         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24605                 skip "Need MDS version at least 2.10.55"
24606
24607         local dom=$DIR/$tdir/dom_file
24608         local max_size=1048576
24609
24610         mkdir -p $DIR/$tdir
24611         $LFS setstripe -E $max_size -L mdt $dom
24612
24613         # truncate over the limit
24614         $TRUNCATE $dom $(($max_size + 1)) &&
24615                 error "successful truncate over the maximum size"
24616         # write over the limit
24617         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
24618                 error "successful write over the maximum size"
24619         # append over the limit
24620         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
24621         echo "12345" >> $dom && error "successful append over the maximum size"
24622         rm $dom
24623
24624         return 0
24625 }
24626 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
24627
24628 test_270c() {
24629         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24630                 skip "Need MDS version at least 2.10.55"
24631
24632         mkdir -p $DIR/$tdir
24633         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24634
24635         # check files inherit DoM EA
24636         touch $DIR/$tdir/first
24637         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
24638                 error "bad pattern"
24639         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
24640                 error "bad stripe count"
24641         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
24642                 error "bad stripe size"
24643
24644         # check directory inherits DoM EA and uses it as default
24645         mkdir $DIR/$tdir/subdir
24646         touch $DIR/$tdir/subdir/second
24647         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
24648                 error "bad pattern in sub-directory"
24649         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
24650                 error "bad stripe count in sub-directory"
24651         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
24652                 error "bad stripe size in sub-directory"
24653         return 0
24654 }
24655 run_test 270c "DoM: DoM EA inheritance tests"
24656
24657 test_270d() {
24658         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24659                 skip "Need MDS version at least 2.10.55"
24660
24661         mkdir -p $DIR/$tdir
24662         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24663
24664         # inherit default DoM striping
24665         mkdir $DIR/$tdir/subdir
24666         touch $DIR/$tdir/subdir/f1
24667
24668         # change default directory striping
24669         $LFS setstripe -c 1 $DIR/$tdir/subdir
24670         touch $DIR/$tdir/subdir/f2
24671         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
24672                 error "wrong default striping in file 2"
24673         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
24674                 error "bad pattern in file 2"
24675         return 0
24676 }
24677 run_test 270d "DoM: change striping from DoM to RAID0"
24678
24679 test_270e() {
24680         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24681                 skip "Need MDS version at least 2.10.55"
24682
24683         mkdir -p $DIR/$tdir/dom
24684         mkdir -p $DIR/$tdir/norm
24685         DOMFILES=20
24686         NORMFILES=10
24687         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
24688         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
24689
24690         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
24691         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
24692
24693         # find DoM files by layout
24694         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
24695         [ $NUM -eq  $DOMFILES ] ||
24696                 error "lfs find -L: found $NUM, expected $DOMFILES"
24697         echo "Test 1: lfs find 20 DOM files by layout: OK"
24698
24699         # there should be 1 dir with default DOM striping
24700         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
24701         [ $NUM -eq  1 ] ||
24702                 error "lfs find -L: found $NUM, expected 1 dir"
24703         echo "Test 2: lfs find 1 DOM dir by layout: OK"
24704
24705         # find DoM files by stripe size
24706         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
24707         [ $NUM -eq  $DOMFILES ] ||
24708                 error "lfs find -S: found $NUM, expected $DOMFILES"
24709         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
24710
24711         # find files by stripe offset except DoM files
24712         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
24713         [ $NUM -eq  $NORMFILES ] ||
24714                 error "lfs find -i: found $NUM, expected $NORMFILES"
24715         echo "Test 5: lfs find no DOM files by stripe index: OK"
24716         return 0
24717 }
24718 run_test 270e "DoM: lfs find with DoM files test"
24719
24720 test_270f() {
24721         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24722                 skip "Need MDS version at least 2.10.55"
24723
24724         local mdtname=${FSNAME}-MDT0000-mdtlov
24725         local dom=$DIR/$tdir/dom_file
24726         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
24727                                                 lod.$mdtname.dom_stripesize)
24728         local dom_limit=131072
24729
24730         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
24731         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24732                                                 lod.$mdtname.dom_stripesize)
24733         [ ${dom_limit} -eq ${dom_current} ] ||
24734                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
24735
24736         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24737         $LFS setstripe -d $DIR/$tdir
24738         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
24739                 error "Can't set directory default striping"
24740
24741         # exceed maximum stripe size
24742         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24743                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
24744         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
24745                 error "Able to create DoM component size more than LOD limit"
24746
24747         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24748         dom_current=$(do_facet mds1 $LCTL get_param -n \
24749                                                 lod.$mdtname.dom_stripesize)
24750         [ 0 -eq ${dom_current} ] ||
24751                 error "Can't set zero DoM stripe limit"
24752         rm $dom
24753
24754         # attempt to create DoM file on server with disabled DoM should
24755         # remove DoM entry from layout and be succeed
24756         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
24757                 error "Can't create DoM file (DoM is disabled)"
24758         [ $($LFS getstripe -L $dom) == "mdt" ] &&
24759                 error "File has DoM component while DoM is disabled"
24760         rm $dom
24761
24762         # attempt to create DoM file with only DoM stripe should return error
24763         $LFS setstripe -E $dom_limit -L mdt $dom &&
24764                 error "Able to create DoM-only file while DoM is disabled"
24765
24766         # too low values to be aligned with smallest stripe size 64K
24767         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
24768         dom_current=$(do_facet mds1 $LCTL get_param -n \
24769                                                 lod.$mdtname.dom_stripesize)
24770         [ 30000 -eq ${dom_current} ] &&
24771                 error "Can set too small DoM stripe limit"
24772
24773         # 64K is a minimal stripe size in Lustre, expect limit of that size
24774         [ 65536 -eq ${dom_current} ] ||
24775                 error "Limit is not set to 64K but ${dom_current}"
24776
24777         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
24778         dom_current=$(do_facet mds1 $LCTL get_param -n \
24779                                                 lod.$mdtname.dom_stripesize)
24780         echo $dom_current
24781         [ 2147483648 -eq ${dom_current} ] &&
24782                 error "Can set too large DoM stripe limit"
24783
24784         do_facet mds1 $LCTL set_param -n \
24785                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
24786         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24787                 error "Can't create DoM component size after limit change"
24788         do_facet mds1 $LCTL set_param -n \
24789                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
24790         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
24791                 error "Can't create DoM file after limit decrease"
24792         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
24793                 error "Can create big DoM component after limit decrease"
24794         touch ${dom}_def ||
24795                 error "Can't create file with old default layout"
24796
24797         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
24798         return 0
24799 }
24800 run_test 270f "DoM: maximum DoM stripe size checks"
24801
24802 test_270g() {
24803         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
24804                 skip "Need MDS version at least 2.13.52"
24805         local dom=$DIR/$tdir/$tfile
24806
24807         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24808         local lodname=${FSNAME}-MDT0000-mdtlov
24809
24810         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24811         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
24812         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
24813         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24814
24815         local dom_limit=1024
24816         local dom_threshold="50%"
24817
24818         $LFS setstripe -d $DIR/$tdir
24819         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
24820                 error "Can't set directory default striping"
24821
24822         do_facet mds1 $LCTL set_param -n \
24823                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
24824         # set 0 threshold and create DOM file to change tunable stripesize
24825         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
24826         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
24827                 error "Failed to create $dom file"
24828         # now tunable dom_cur_stripesize should reach maximum
24829         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24830                                         lod.${lodname}.dom_stripesize_cur_kb)
24831         [[ $dom_current == $dom_limit ]] ||
24832                 error "Current DOM stripesize is not maximum"
24833         rm $dom
24834
24835         # set threshold for further tests
24836         do_facet mds1 $LCTL set_param -n \
24837                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
24838         echo "DOM threshold is $dom_threshold free space"
24839         local dom_def
24840         local dom_set
24841         # Spoof bfree to exceed threshold
24842         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
24843         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
24844         for spfree in 40 20 0 15 30 55; do
24845                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
24846                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
24847                         error "Failed to create $dom file"
24848                 dom_def=$(do_facet mds1 $LCTL get_param -n \
24849                                         lod.${lodname}.dom_stripesize_cur_kb)
24850                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
24851                 [[ $dom_def != $dom_current ]] ||
24852                         error "Default stripe size was not changed"
24853                 if (( spfree > 0 )) ; then
24854                         dom_set=$($LFS getstripe -S $dom)
24855                         (( dom_set == dom_def * 1024 )) ||
24856                                 error "DOM component size is still old"
24857                 else
24858                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
24859                                 error "DoM component is set with no free space"
24860                 fi
24861                 rm $dom
24862                 dom_current=$dom_def
24863         done
24864 }
24865 run_test 270g "DoM: default DoM stripe size depends on free space"
24866
24867 test_270h() {
24868         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
24869                 skip "Need MDS version at least 2.13.53"
24870
24871         local mdtname=${FSNAME}-MDT0000-mdtlov
24872         local dom=$DIR/$tdir/$tfile
24873         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24874
24875         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
24876         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24877
24878         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24879         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
24880                 error "can't create OST file"
24881         # mirrored file with DOM entry in the second mirror
24882         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
24883                 error "can't create mirror with DoM component"
24884
24885         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24886
24887         # DOM component in the middle and has other enries in the same mirror,
24888         # should succeed but lost DoM component
24889         $LFS setstripe --copy=${dom}_1 $dom ||
24890                 error "Can't create file from OST|DOM mirror layout"
24891         # check new file has no DoM layout after all
24892         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
24893                 error "File has DoM component while DoM is disabled"
24894 }
24895 run_test 270h "DoM: DoM stripe removal when disabled on server"
24896
24897 test_270i() {
24898         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
24899                 skip "Need MDS version at least 2.14.54"
24900
24901         mkdir $DIR/$tdir
24902         # DoM with plain layout
24903         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
24904                 error "default plain layout with DoM must fail"
24905         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
24906                 error "setstripe plain file layout with DoM must fail"
24907         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
24908                 error "default DoM layout with bad striping must fail"
24909         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
24910                 error "setstripe to DoM layout with bad striping must fail"
24911         return 0
24912 }
24913 run_test 270i "DoM: setting invalid DoM striping should fail"
24914
24915 test_270j() {
24916         (( $MDS1_VERSION >= $(version_code 2.15.55.203) )) ||
24917                 skip "Need MDS version at least 2.15.55.203"
24918
24919         local dom=$DIR/$tdir/$tfile
24920         local odv
24921         local ndv
24922
24923         mkdir -p $DIR/$tdir
24924
24925         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24926
24927         odv=$($LFS data_version $dom)
24928         chmod 666 $dom
24929         mv $dom ${dom}_moved
24930         link ${dom}_moved $dom
24931         setfattr -n user.attrx -v "some_attr" $dom
24932         ndv=$($LFS data_version $dom)
24933         (( $ndv == $odv )) ||
24934                 error "data version was changed by metadata operations"
24935
24936         dd if=/dev/urandom of=$dom bs=1M count=1 ||
24937                 error "failed to write data into $dom"
24938         cancel_lru_locks mdc
24939         ndv=$($LFS data_version $dom)
24940         (( $ndv != $odv )) ||
24941                 error "data version wasn't changed on write"
24942
24943         odv=$ndv
24944         $TRUNCATE $dom 1000 || error "failed to truncate $dom"
24945         ndv=$($LFS data_version $dom)
24946         (( $ndv != $odv )) ||
24947                 error "data version wasn't changed on truncate down"
24948
24949         odv=$ndv
24950         $TRUNCATE $dom 25000
24951         ndv=$($LFS data_version $dom)
24952         (( $ndv != $odv )) ||
24953                 error "data version wasn't changed on truncate up"
24954
24955         # check also fallocate for ldiskfs
24956         if [[ "$mds1_FSTYPE" == ldiskfs ]]; then
24957                 odv=$ndv
24958                 fallocate -l 1048576 $dom
24959                 ndv=$($LFS data_version $dom)
24960                 (( $ndv != $odv )) ||
24961                         error "data version wasn't changed on fallocate"
24962
24963                 odv=$ndv
24964                 fallocate -p --offset 4096 -l 4096 $dom
24965                 ndv=$($LFS data_version $dom)
24966                 (( $ndv != $odv )) ||
24967                         error "data version wasn't changed on fallocate punch"
24968         fi
24969 }
24970 run_test 270j "DoM migration: DOM file to the OST-striped file (plain)"
24971
24972 test_271a() {
24973         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24974                 skip "Need MDS version at least 2.10.55"
24975
24976         local dom=$DIR/$tdir/dom
24977
24978         mkdir -p $DIR/$tdir
24979
24980         $LFS setstripe -E 1024K -L mdt $dom
24981
24982         lctl set_param -n mdc.*.stats=clear
24983         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
24984         cat $dom > /dev/null
24985         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
24986         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
24987         ls $dom
24988         rm -f $dom
24989 }
24990 run_test 271a "DoM: data is cached for read after write"
24991
24992 test_271b() {
24993         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24994                 skip "Need MDS version at least 2.10.55"
24995
24996         local dom=$DIR/$tdir/dom
24997
24998         mkdir -p $DIR/$tdir
24999
25000         $LFS setstripe -E 1024K -L mdt -E EOF $dom
25001
25002         lctl set_param -n mdc.*.stats=clear
25003         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
25004         cancel_lru_locks mdc
25005         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
25006         # second stat to check size is cached on client
25007         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
25008         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
25009         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
25010         rm -f $dom
25011 }
25012 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
25013
25014 test_271ba() {
25015         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25016                 skip "Need MDS version at least 2.10.55"
25017
25018         local dom=$DIR/$tdir/dom
25019
25020         mkdir -p $DIR/$tdir
25021
25022         $LFS setstripe -E 1024K -L mdt -E EOF $dom
25023
25024         lctl set_param -n mdc.*.stats=clear
25025         lctl set_param -n osc.*.stats=clear
25026         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
25027         cancel_lru_locks mdc
25028         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
25029         # second stat to check size is cached on client
25030         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
25031         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
25032         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
25033         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
25034         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
25035         rm -f $dom
25036 }
25037 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
25038
25039
25040 get_mdc_stats() {
25041         local mdtidx=$1
25042         local param=$2
25043         local mdt=MDT$(printf %04x $mdtidx)
25044
25045         if [ -z $param ]; then
25046                 lctl get_param -n mdc.*$mdt*.stats
25047         else
25048                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
25049         fi
25050 }
25051
25052 test_271c() {
25053         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25054                 skip "Need MDS version at least 2.10.55"
25055
25056         local dom=$DIR/$tdir/dom
25057
25058         mkdir -p $DIR/$tdir
25059
25060         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25061
25062         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
25063         local facet=mds$((mdtidx + 1))
25064
25065         cancel_lru_locks mdc
25066         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
25067         createmany -o $dom 1000
25068         lctl set_param -n mdc.*.stats=clear
25069         smalliomany -w $dom 1000 200
25070         get_mdc_stats $mdtidx
25071         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
25072         # Each file has 1 open, 1 IO enqueues, total 2000
25073         # but now we have also +1 getxattr for security.capability, total 3000
25074         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
25075         unlinkmany $dom 1000
25076
25077         cancel_lru_locks mdc
25078         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
25079         createmany -o $dom 1000
25080         lctl set_param -n mdc.*.stats=clear
25081         smalliomany -w $dom 1000 200
25082         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
25083         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
25084         # for OPEN and IO lock.
25085         [ $((enq - enq_2)) -ge 1000 ] ||
25086                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
25087         unlinkmany $dom 1000
25088         return 0
25089 }
25090 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
25091
25092 cleanup_271def_tests() {
25093         trap 0
25094         rm -f $1
25095 }
25096
25097 test_271d() {
25098         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
25099                 skip "Need MDS version at least 2.10.57"
25100
25101         local dom=$DIR/$tdir/dom
25102         local tmp=$TMP/$tfile
25103         trap "cleanup_271def_tests $tmp" EXIT
25104
25105         mkdir -p $DIR/$tdir
25106
25107         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25108
25109         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
25110
25111         cancel_lru_locks mdc
25112         dd if=/dev/urandom of=$tmp bs=1000 count=1
25113         dd if=$tmp of=$dom bs=1000 count=1
25114         cancel_lru_locks mdc
25115
25116         cat /etc/hosts >> $tmp
25117         lctl set_param -n mdc.*.stats=clear
25118
25119         # append data to the same file it should update local page
25120         echo "Append to the same page"
25121         cat /etc/hosts >> $dom
25122         local num=$(get_mdc_stats $mdtidx ost_read)
25123         local ra=$(get_mdc_stats $mdtidx req_active)
25124         local rw=$(get_mdc_stats $mdtidx req_waittime)
25125
25126         [ -z $num ] || error "$num READ RPC occured"
25127         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25128         echo "... DONE"
25129
25130         # compare content
25131         cmp $tmp $dom || error "file miscompare"
25132
25133         cancel_lru_locks mdc
25134         lctl set_param -n mdc.*.stats=clear
25135
25136         echo "Open and read file"
25137         cat $dom > /dev/null
25138         local num=$(get_mdc_stats $mdtidx ost_read)
25139         local ra=$(get_mdc_stats $mdtidx req_active)
25140         local rw=$(get_mdc_stats $mdtidx req_waittime)
25141
25142         [ -z $num ] || error "$num READ RPC occured"
25143         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25144         echo "... DONE"
25145
25146         # compare content
25147         cmp $tmp $dom || error "file miscompare"
25148
25149         return 0
25150 }
25151 run_test 271d "DoM: read on open (1K file in reply buffer)"
25152
25153 test_271f() {
25154         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
25155                 skip "Need MDS version at least 2.10.57"
25156
25157         local dom=$DIR/$tdir/dom
25158         local tmp=$TMP/$tfile
25159         trap "cleanup_271def_tests $tmp" EXIT
25160
25161         mkdir -p $DIR/$tdir
25162
25163         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25164
25165         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
25166
25167         cancel_lru_locks mdc
25168         dd if=/dev/urandom of=$tmp bs=265000 count=1
25169         dd if=$tmp of=$dom bs=265000 count=1
25170         cancel_lru_locks mdc
25171         cat /etc/hosts >> $tmp
25172         lctl set_param -n mdc.*.stats=clear
25173
25174         echo "Append to the same page"
25175         cat /etc/hosts >> $dom
25176         local num=$(get_mdc_stats $mdtidx ost_read)
25177         local ra=$(get_mdc_stats $mdtidx req_active)
25178         local rw=$(get_mdc_stats $mdtidx req_waittime)
25179
25180         [ -z $num ] || error "$num READ RPC occured"
25181         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25182         echo "... DONE"
25183
25184         # compare content
25185         cmp $tmp $dom || error "file miscompare"
25186
25187         cancel_lru_locks mdc
25188         lctl set_param -n mdc.*.stats=clear
25189
25190         echo "Open and read file"
25191         cat $dom > /dev/null
25192         local num=$(get_mdc_stats $mdtidx ost_read)
25193         local ra=$(get_mdc_stats $mdtidx req_active)
25194         local rw=$(get_mdc_stats $mdtidx req_waittime)
25195
25196         [ -z $num ] && num=0
25197         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
25198         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25199         echo "... DONE"
25200
25201         # compare content
25202         cmp $tmp $dom || error "file miscompare"
25203
25204         return 0
25205 }
25206 run_test 271f "DoM: read on open (200K file and read tail)"
25207
25208 test_271g() {
25209         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
25210                 skip "Skipping due to old client or server version"
25211
25212         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
25213         # to get layout
25214         $CHECKSTAT -t file $DIR1/$tfile
25215
25216         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
25217         MULTIOP_PID=$!
25218         sleep 1
25219         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
25220         $LCTL set_param fail_loc=0x80000314
25221         rm $DIR1/$tfile || error "Unlink fails"
25222         RC=$?
25223         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
25224         [ $RC -eq 0 ] || error "Failed write to stale object"
25225 }
25226 run_test 271g "Discard DoM data vs client flush race"
25227
25228 test_272a() {
25229         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25230                 skip "Need MDS version at least 2.11.50"
25231
25232         local dom=$DIR/$tdir/dom
25233         mkdir -p $DIR/$tdir
25234
25235         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
25236         dd if=/dev/urandom of=$dom bs=512K count=1 ||
25237                 error "failed to write data into $dom"
25238         local old_md5=$(md5sum $dom)
25239
25240         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
25241                 error "failed to migrate to the same DoM component"
25242
25243         local new_md5=$(md5sum $dom)
25244
25245         [ "$old_md5" == "$new_md5" ] ||
25246                 error "md5sum differ: $old_md5, $new_md5"
25247
25248         [ $($LFS getstripe -c $dom) -eq 2 ] ||
25249                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
25250 }
25251 run_test 272a "DoM migration: new layout with the same DOM component"
25252
25253 test_272b() {
25254         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25255                 skip "Need MDS version at least 2.11.50"
25256
25257         local dom=$DIR/$tdir/dom
25258         mkdir -p $DIR/$tdir
25259         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25260         stack_trap "rm -rf $DIR/$tdir"
25261
25262         local mdtidx=$($LFS getstripe -m $dom)
25263         local mdtname=MDT$(printf %04x $mdtidx)
25264         local facet=mds$((mdtidx + 1))
25265
25266         local mdtfree1=$(do_facet $facet \
25267                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25268         dd if=/dev/urandom of=$dom bs=2M count=1 ||
25269                 error "failed to write data into $dom"
25270         local old_md5=$(md5sum $dom)
25271         cancel_lru_locks mdc
25272         local mdtfree1=$(do_facet $facet \
25273                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25274
25275         $LFS migrate -c2 $dom ||
25276                 error "failed to migrate to the new composite layout"
25277         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
25278                 error "MDT stripe was not removed"
25279         ! getfattr -n trusted.dataver $dom &> /dev/null ||
25280                 error "$dir1 shouldn't have DATAVER EA"
25281
25282         cancel_lru_locks mdc
25283         local new_md5=$(md5sum $dom)
25284         [ "$old_md5" == "$new_md5" ] ||
25285                 error "$old_md5 != $new_md5"
25286
25287         # Skip free space checks with ZFS
25288         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25289                 local mdtfree2=$(do_facet $facet \
25290                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25291                 [ $mdtfree2 -gt $mdtfree1 ] ||
25292                         error "MDT space is not freed after migration"
25293         fi
25294         return 0
25295 }
25296 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
25297
25298 test_272c() {
25299         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25300                 skip "Need MDS version at least 2.11.50"
25301
25302         local dom=$DIR/$tdir/$tfile
25303         mkdir -p $DIR/$tdir
25304         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25305         stack_trap "rm -rf $DIR/$tdir"
25306
25307         local mdtidx=$($LFS getstripe -m $dom)
25308         local mdtname=MDT$(printf %04x $mdtidx)
25309         local facet=mds$((mdtidx + 1))
25310
25311         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25312                 error "failed to write data into $dom"
25313         local old_md5=$(md5sum $dom)
25314         cancel_lru_locks mdc
25315         local mdtfree1=$(do_facet $facet \
25316                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25317
25318         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
25319                 error "failed to migrate to the new composite layout"
25320         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
25321                 error "MDT stripe was not removed"
25322
25323         cancel_lru_locks mdc
25324         local new_md5=$(md5sum $dom)
25325         [ "$old_md5" == "$new_md5" ] ||
25326                 error "$old_md5 != $new_md5"
25327
25328         # Skip free space checks with ZFS
25329         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25330                 local mdtfree2=$(do_facet $facet \
25331                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25332                 [ $mdtfree2 -gt $mdtfree1 ] ||
25333                         error "MDS space is not freed after migration"
25334         fi
25335         return 0
25336 }
25337 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
25338
25339 test_272d() {
25340         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25341                 skip "Need MDS version at least 2.12.55"
25342
25343         local dom=$DIR/$tdir/$tfile
25344         mkdir -p $DIR/$tdir
25345         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25346
25347         local mdtidx=$($LFS getstripe -m $dom)
25348         local mdtname=MDT$(printf %04x $mdtidx)
25349         local facet=mds$((mdtidx + 1))
25350
25351         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25352                 error "failed to write data into $dom"
25353         local old_md5=$(md5sum $dom)
25354         cancel_lru_locks mdc
25355         local mdtfree1=$(do_facet $facet \
25356                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25357
25358         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
25359                 error "failed mirroring to the new composite layout"
25360         $LFS mirror resync $dom ||
25361                 error "failed mirror resync"
25362         $LFS mirror split --mirror-id 1 -d $dom ||
25363                 error "failed mirror split"
25364
25365         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
25366                 error "MDT stripe was not removed"
25367
25368         cancel_lru_locks mdc
25369         local new_md5=$(md5sum $dom)
25370         [ "$old_md5" == "$new_md5" ] ||
25371                 error "$old_md5 != $new_md5"
25372
25373         # Skip free space checks with ZFS
25374         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25375                 local mdtfree2=$(do_facet $facet \
25376                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25377                 [ $mdtfree2 -gt $mdtfree1 ] ||
25378                         error "MDS space is not freed after DOM mirror deletion"
25379         fi
25380         return 0
25381 }
25382 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
25383
25384 test_272e() {
25385         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25386                 skip "Need MDS version at least 2.12.55"
25387
25388         local dom=$DIR/$tdir/$tfile
25389         mkdir -p $DIR/$tdir
25390         $LFS setstripe -c 2 $dom
25391
25392         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25393                 error "failed to write data into $dom"
25394         local old_md5=$(md5sum $dom)
25395         cancel_lru_locks
25396
25397         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
25398                 error "failed mirroring to the DOM layout"
25399         $LFS mirror resync $dom ||
25400                 error "failed mirror resync"
25401         $LFS mirror split --mirror-id 1 -d $dom ||
25402                 error "failed mirror split"
25403
25404         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25405                 error "MDT stripe wasn't set"
25406
25407         cancel_lru_locks
25408         local new_md5=$(md5sum $dom)
25409         [ "$old_md5" == "$new_md5" ] ||
25410                 error "$old_md5 != $new_md5"
25411
25412         return 0
25413 }
25414 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
25415
25416 test_272f() {
25417         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25418                 skip "Need MDS version at least 2.12.55"
25419
25420         local dom=$DIR/$tdir/$tfile
25421         mkdir -p $DIR/$tdir
25422         $LFS setstripe -c 2 $dom
25423
25424         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25425                 error "failed to write data into $dom"
25426         local old_md5=$(md5sum $dom)
25427         cancel_lru_locks
25428
25429         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
25430                 error "failed migrating to the DOM file"
25431
25432         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25433                 error "MDT stripe wasn't set"
25434
25435         cancel_lru_locks
25436         local new_md5=$(md5sum $dom)
25437         [ "$old_md5" != "$new_md5" ] &&
25438                 error "$old_md5 != $new_md5"
25439
25440         return 0
25441 }
25442 run_test 272f "DoM migration: OST-striped file to DOM file"
25443
25444 test_273a() {
25445         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25446                 skip "Need MDS version at least 2.11.50"
25447
25448         # Layout swap cannot be done if either file has DOM component,
25449         # this will never be supported, migration should be used instead
25450
25451         local dom=$DIR/$tdir/$tfile
25452         mkdir -p $DIR/$tdir
25453
25454         $LFS setstripe -c2 ${dom}_plain
25455         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
25456         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
25457                 error "can swap layout with DoM component"
25458         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
25459                 error "can swap layout with DoM component"
25460
25461         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
25462         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
25463                 error "can swap layout with DoM component"
25464         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
25465                 error "can swap layout with DoM component"
25466         return 0
25467 }
25468 run_test 273a "DoM: layout swapping should fail with DOM"
25469
25470 test_273b() {
25471         mkdir -p $DIR/$tdir
25472         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
25473
25474 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
25475         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
25476
25477         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25478 }
25479 run_test 273b "DoM: race writeback and object destroy"
25480
25481 test_273c() {
25482         mkdir -p $DIR/$tdir
25483         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
25484
25485         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
25486         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
25487
25488         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25489 }
25490 run_test 273c "race writeback and object destroy"
25491
25492 test_275() {
25493         remote_ost_nodsh && skip "remote OST with nodsh"
25494         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
25495                 skip "Need OST version >= 2.10.57"
25496
25497         local file=$DIR/$tfile
25498         local oss
25499
25500         oss=$(comma_list $(osts_nodes))
25501
25502         dd if=/dev/urandom of=$file bs=1M count=2 ||
25503                 error "failed to create a file"
25504         stack_trap "rm -f $file"
25505         cancel_lru_locks osc
25506
25507         #lock 1
25508         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25509                 error "failed to read a file"
25510
25511 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
25512         $LCTL set_param fail_loc=0x8000031f
25513
25514         cancel_lru_locks osc &
25515         sleep 1
25516
25517 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
25518         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
25519         #IO takes another lock, but matches the PENDING one
25520         #and places it to the IO RPC
25521         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25522                 error "failed to read a file with PENDING lock"
25523 }
25524 run_test 275 "Read on a canceled duplicate lock"
25525
25526 test_276() {
25527         remote_ost_nodsh && skip "remote OST with nodsh"
25528         local pid
25529
25530         do_facet ost1 "(while true; do \
25531                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
25532                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
25533         pid=$!
25534
25535         for LOOP in $(seq 20); do
25536                 stop ost1
25537                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
25538         done
25539         kill -9 $pid
25540         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
25541                 rm $TMP/sanity_276_pid"
25542 }
25543 run_test 276 "Race between mount and obd_statfs"
25544
25545 test_277() {
25546         $LCTL set_param ldlm.namespaces.*.lru_size=0
25547         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25548         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25549                           awk '/^used_mb/ { print $2 }')
25550         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
25551         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
25552                 oflag=direct conv=notrunc
25553         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25554                     awk '/^used_mb/ { print $2 }')
25555         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
25556 }
25557 run_test 277 "Direct IO shall drop page cache"
25558
25559 test_278() {
25560         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
25561         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25562         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
25563                 skip "needs the same host for mdt1 mdt2" && return
25564
25565         local pid1
25566         local pid2
25567
25568 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
25569         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
25570         stop mds2 &
25571         pid2=$!
25572
25573         stop mds1
25574
25575         echo "Starting MDTs"
25576         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
25577         wait $pid2
25578 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
25579 #will return NULL
25580         do_facet mds2 $LCTL set_param fail_loc=0
25581
25582         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
25583         wait_recovery_complete mds2
25584 }
25585 run_test 278 "Race starting MDS between MDTs stop/start"
25586
25587 test_280() {
25588         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
25589                 skip "Need MGS version at least 2.13.52"
25590         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25591         combined_mgs_mds || skip "needs combined MGS/MDT"
25592
25593         umount_client $MOUNT
25594 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
25595         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
25596
25597         mount_client $MOUNT &
25598         sleep 1
25599         stop mgs || error "stop mgs failed"
25600         #for a race mgs would crash
25601         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
25602         # make sure we unmount client before remounting
25603         wait
25604         umount_client $MOUNT
25605         mount_client $MOUNT || error "mount client failed"
25606 }
25607 run_test 280 "Race between MGS umount and client llog processing"
25608
25609 cleanup_test_300() {
25610         trap 0
25611         umask $SAVE_UMASK
25612 }
25613
25614 test_striped_dir() {
25615         local mdt_index=$1
25616         local stripe_count=$2
25617         local overstriping=$3
25618         local stripe_index
25619         local getstripe_count
25620
25621         mkdir -p $DIR/$tdir
25622
25623         SAVE_UMASK=$(umask)
25624         trap cleanup_test_300 RETURN EXIT
25625
25626         if [ -z $overstriping ]; then
25627                 $LFS setdirstripe -i $mdt_index -c $stripe_count -H all_char \
25628                                         -o 755 $DIR/$tdir/striped_dir ||
25629                         error "set striped dir error"
25630         else
25631                 $LFS setdirstripe -i $mdt_index -C $stripe_count -H all_char \
25632                                         -o 755 $DIR/$tdir/striped_dir ||
25633                         error "set striped dir error"
25634         fi
25635
25636         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
25637         [ "$mode" = "755" ] || error "expect 755 got $mode"
25638
25639         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
25640                 error "getdirstripe failed"
25641         getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
25642         if [ "$getstripe_count" != "$stripe_count" ]; then
25643                 error "1:stripe_count is $getstripe_count, expect $stripe_count"
25644         fi
25645         getstripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
25646         if [ "$getstripe_count" != "$stripe_count" ]; then
25647                 error "2:stripe_count is $getstripe_count, expect $stripe_count"
25648         fi
25649
25650         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
25651         if [ "$stripe_index" != "$mdt_index" ]; then
25652                 error "stripe_index is $stripe_index, expect $mdt_index"
25653         fi
25654
25655         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25656                 error "nlink error after create striped dir"
25657
25658         mkdir $DIR/$tdir/striped_dir/a
25659         mkdir $DIR/$tdir/striped_dir/b
25660
25661         stat $DIR/$tdir/striped_dir/a ||
25662                 error "create dir under striped dir failed"
25663         stat $DIR/$tdir/striped_dir/b ||
25664                 error "create dir under striped dir failed"
25665
25666         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
25667                 error "nlink error after mkdir"
25668
25669         rmdir $DIR/$tdir/striped_dir/a
25670         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
25671                 error "nlink error after rmdir"
25672
25673         rmdir $DIR/$tdir/striped_dir/b
25674         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25675                 error "nlink error after rmdir"
25676
25677         chattr +i $DIR/$tdir/striped_dir
25678         createmany -o $DIR/$tdir/striped_dir/f 10 &&
25679                 error "immutable flags not working under striped dir!"
25680         chattr -i $DIR/$tdir/striped_dir
25681
25682         rmdir $DIR/$tdir/striped_dir ||
25683                 error "rmdir striped dir error"
25684
25685         cleanup_test_300
25686
25687         true
25688 }
25689
25690 test_300a() {
25691         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25692                 skip "skipped for lustre < 2.7.0"
25693         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25694         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25695
25696         test_striped_dir 0 2 || error "failed on striped dir on MDT0"
25697         test_striped_dir 1 2 || error "failed on striped dir on MDT0"
25698 }
25699 run_test 300a "basic striped dir sanity test"
25700
25701 test_300b() {
25702         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25703                 skip "skipped for lustre < 2.7.0"
25704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25705         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25706
25707         local i
25708         local mtime1
25709         local mtime2
25710         local mtime3
25711
25712         test_mkdir $DIR/$tdir || error "mkdir fail"
25713         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25714                 error "set striped dir error"
25715         for i in {0..9}; do
25716                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
25717                 sleep 1
25718                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
25719                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
25720                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
25721                 sleep 1
25722                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
25723                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
25724                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
25725         done
25726         true
25727 }
25728 run_test 300b "check ctime/mtime for striped dir"
25729
25730 test_300c() {
25731         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25732                 skip "skipped for lustre < 2.7.0"
25733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25734         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25735
25736         local file_count
25737
25738         mkdir_on_mdt0 $DIR/$tdir
25739         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
25740                 error "set striped dir error"
25741
25742         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
25743                 error "chown striped dir failed"
25744
25745         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
25746                 error "create 5k files failed"
25747
25748         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
25749
25750         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
25751
25752         rm -rf $DIR/$tdir
25753 }
25754 run_test 300c "chown && check ls under striped directory"
25755
25756 test_300d() {
25757         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25758                 skip "skipped for lustre < 2.7.0"
25759         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25760         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25761
25762         local stripe_count
25763         local file
25764
25765         mkdir -p $DIR/$tdir
25766         $LFS setstripe -c 2 $DIR/$tdir
25767
25768         #local striped directory
25769         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25770                 error "set striped dir error"
25771         #look at the directories for debug purposes
25772         ls -l $DIR/$tdir
25773         $LFS getdirstripe $DIR/$tdir
25774         ls -l $DIR/$tdir/striped_dir
25775         $LFS getdirstripe $DIR/$tdir/striped_dir
25776         createmany -o $DIR/$tdir/striped_dir/f 10 ||
25777                 error "create 10 files failed"
25778
25779         #remote striped directory
25780         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
25781                 error "set striped dir error"
25782         #look at the directories for debug purposes
25783         ls -l $DIR/$tdir
25784         $LFS getdirstripe $DIR/$tdir
25785         ls -l $DIR/$tdir/remote_striped_dir
25786         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
25787         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
25788                 error "create 10 files failed"
25789
25790         for file in $(find $DIR/$tdir); do
25791                 stripe_count=$($LFS getstripe -c $file)
25792                 [ $stripe_count -eq 2 ] ||
25793                         error "wrong stripe $stripe_count for $file"
25794         done
25795
25796         rm -rf $DIR/$tdir
25797 }
25798 run_test 300d "check default stripe under striped directory"
25799
25800 test_300e() {
25801         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25802                 skip "Need MDS version at least 2.7.55"
25803         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25804         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25805
25806         local stripe_count
25807         local file
25808
25809         mkdir -p $DIR/$tdir
25810
25811         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25812                 error "set striped dir error"
25813
25814         touch $DIR/$tdir/striped_dir/a
25815         touch $DIR/$tdir/striped_dir/b
25816         touch $DIR/$tdir/striped_dir/c
25817
25818         mkdir $DIR/$tdir/striped_dir/dir_a
25819         mkdir $DIR/$tdir/striped_dir/dir_b
25820         mkdir $DIR/$tdir/striped_dir/dir_c
25821
25822         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
25823                 error "set striped adir under striped dir error"
25824
25825         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
25826                 error "set striped bdir under striped dir error"
25827
25828         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
25829                 error "set striped cdir under striped dir error"
25830
25831         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
25832                 error "rename dir under striped dir fails"
25833
25834         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
25835                 error "rename dir under different stripes fails"
25836
25837         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
25838                 error "rename file under striped dir should succeed"
25839
25840         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
25841                 error "rename dir under striped dir should succeed"
25842
25843         rm -rf $DIR/$tdir
25844 }
25845 run_test 300e "check rename under striped directory"
25846
25847 test_300f() {
25848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25849         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25850         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25851                 skip "Need MDS version at least 2.7.55"
25852
25853         local stripe_count
25854         local file
25855
25856         rm -rf $DIR/$tdir
25857         mkdir -p $DIR/$tdir
25858
25859         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25860                 error "set striped dir error"
25861
25862         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
25863                 error "set striped dir error"
25864
25865         touch $DIR/$tdir/striped_dir/a
25866         mkdir $DIR/$tdir/striped_dir/dir_a
25867         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
25868                 error "create striped dir under striped dir fails"
25869
25870         touch $DIR/$tdir/striped_dir1/b
25871         mkdir $DIR/$tdir/striped_dir1/dir_b
25872         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
25873                 error "create striped dir under striped dir fails"
25874
25875         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
25876                 error "rename dir under different striped dir should fail"
25877
25878         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
25879                 error "rename striped dir under diff striped dir should fail"
25880
25881         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
25882                 error "rename file under diff striped dirs fails"
25883
25884         rm -rf $DIR/$tdir
25885 }
25886 run_test 300f "check rename cross striped directory"
25887
25888 test_300_check_default_striped_dir()
25889 {
25890         local dirname=$1
25891         local default_count=$2
25892         local default_index=$3
25893         local stripe_count
25894         local stripe_index
25895         local dir_stripe_index
25896         local dir
25897
25898         echo "checking $dirname $default_count $default_index"
25899         $LFS setdirstripe -D -c $default_count -i $default_index \
25900                                 -H all_char $DIR/$tdir/$dirname ||
25901                 error "set default stripe on striped dir error"
25902         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
25903         [ $stripe_count -eq $default_count ] ||
25904                 error "expect $default_count get $stripe_count for $dirname"
25905
25906         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
25907         [ $stripe_index -eq $default_index ] ||
25908                 error "expect $default_index get $stripe_index for $dirname"
25909
25910         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
25911                                                 error "create dirs failed"
25912
25913         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
25914         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
25915         for dir in $(find $DIR/$tdir/$dirname/*); do
25916                 stripe_count=$($LFS getdirstripe -c $dir)
25917                 (( $stripe_count == $default_count )) ||
25918                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
25919                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
25920                 error "stripe count $default_count != $stripe_count for $dir"
25921
25922                 stripe_index=$($LFS getdirstripe -i $dir)
25923                 [ $default_index -eq -1 ] ||
25924                         [ $stripe_index -eq $default_index ] ||
25925                         error "$stripe_index != $default_index for $dir"
25926
25927                 #check default stripe
25928                 stripe_count=$($LFS getdirstripe -D -c $dir)
25929                 [ $stripe_count -eq $default_count ] ||
25930                 error "default count $default_count != $stripe_count for $dir"
25931
25932                 stripe_index=$($LFS getdirstripe -D -i $dir)
25933                 [ $stripe_index -eq $default_index ] ||
25934                 error "default index $default_index != $stripe_index for $dir"
25935         done
25936         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
25937 }
25938
25939 test_300g() {
25940         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25941         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25942                 skip "Need MDS version at least 2.7.55"
25943
25944         local dir
25945         local stripe_count
25946         local stripe_index
25947
25948         mkdir_on_mdt0 $DIR/$tdir
25949         mkdir $DIR/$tdir/normal_dir
25950
25951         #Checking when client cache stripe index
25952         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25953         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
25954                 error "create striped_dir failed"
25955
25956         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
25957                 error "create dir0 fails"
25958         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
25959         [ $stripe_index -eq 0 ] ||
25960                 error "dir0 expect index 0 got $stripe_index"
25961
25962         mkdir $DIR/$tdir/striped_dir/dir1 ||
25963                 error "create dir1 fails"
25964         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
25965         [ $stripe_index -eq 1 ] ||
25966                 error "dir1 expect index 1 got $stripe_index"
25967
25968         #check default stripe count/stripe index
25969         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
25970         test_300_check_default_striped_dir normal_dir 1 0
25971         test_300_check_default_striped_dir normal_dir -1 1
25972         test_300_check_default_striped_dir normal_dir 2 -1
25973
25974         #delete default stripe information
25975         echo "delete default stripeEA"
25976         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
25977                 error "set default stripe on striped dir error"
25978
25979         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
25980         for dir in $(find $DIR/$tdir/normal_dir/*); do
25981                 stripe_count=$($LFS getdirstripe -c $dir)
25982                 [ $stripe_count -eq 0 ] ||
25983                         error "expect 1 get $stripe_count for $dir"
25984         done
25985 }
25986 run_test 300g "check default striped directory for normal directory"
25987
25988 test_300h() {
25989         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25990         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25991                 skip "Need MDS version at least 2.7.55"
25992
25993         local dir
25994         local stripe_count
25995
25996         mkdir $DIR/$tdir
25997         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25998                 error "set striped dir error"
25999
26000         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
26001         test_300_check_default_striped_dir striped_dir 1 0
26002         test_300_check_default_striped_dir striped_dir -1 1
26003         test_300_check_default_striped_dir striped_dir 2 -1
26004
26005         #delete default stripe information
26006         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
26007                 error "set default stripe on striped dir error"
26008
26009         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
26010         for dir in $(find $DIR/$tdir/striped_dir/*); do
26011                 stripe_count=$($LFS getdirstripe -c $dir)
26012                 [ $stripe_count -eq 0 ] ||
26013                         error "expect 1 get $stripe_count for $dir"
26014         done
26015 }
26016 run_test 300h "check default striped directory for striped directory"
26017
26018 test_300i() {
26019         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
26020         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
26021         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
26022                 skip "Need MDS version at least 2.7.55"
26023
26024         local stripe_count
26025         local file
26026
26027         mkdir $DIR/$tdir
26028
26029         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
26030                 error "set striped dir error"
26031
26032         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
26033                 error "create files under striped dir failed"
26034
26035         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
26036                 error "set striped hashdir error"
26037
26038         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
26039                 error "create dir0 under hash dir failed"
26040         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
26041                 error "create dir1 under hash dir failed"
26042         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
26043                 error "create dir2 under hash dir failed"
26044
26045         # unfortunately, we need to umount to clear dir layout cache for now
26046         # once we fully implement dir layout, we can drop this
26047         umount_client $MOUNT || error "umount failed"
26048         mount_client $MOUNT || error "mount failed"
26049
26050         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
26051         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
26052         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
26053
26054         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
26055                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
26056                         error "create crush2 dir $tdir/hashdir/d3 failed"
26057                 $LFS find -H crush2 $DIR/$tdir/hashdir
26058                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
26059                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
26060
26061                 # mkdir with an invalid hash type (hash=fail_val) from client
26062                 # should be replaced on MDS with a valid (default) hash type
26063                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
26064                 $LCTL set_param fail_loc=0x1901 fail_val=99
26065                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
26066
26067                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
26068                 local expect=$(do_facet mds1 \
26069                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
26070                 [[ $hash == $expect ]] ||
26071                         error "d99 hash '$hash' != expected hash '$expect'"
26072         fi
26073
26074         #set the stripe to be unknown hash type on read
26075         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
26076         $LCTL set_param fail_loc=0x1901 fail_val=99
26077         for ((i = 0; i < 10; i++)); do
26078                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
26079                         error "stat f-$i failed"
26080                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
26081         done
26082
26083         touch $DIR/$tdir/striped_dir/f0 &&
26084                 error "create under striped dir with unknown hash should fail"
26085
26086         $LCTL set_param fail_loc=0
26087
26088         umount_client $MOUNT || error "umount failed"
26089         mount_client $MOUNT || error "mount failed"
26090
26091         return 0
26092 }
26093 run_test 300i "client handle unknown hash type striped directory"
26094
26095 test_300j() {
26096         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26098         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26099                 skip "Need MDS version at least 2.7.55"
26100
26101         local stripe_count
26102         local file
26103
26104         mkdir $DIR/$tdir
26105
26106         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
26107         $LCTL set_param fail_loc=0x1702
26108         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
26109                 error "set striped dir error"
26110
26111         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
26112                 error "create files under striped dir failed"
26113
26114         $LCTL set_param fail_loc=0
26115
26116         rm -rf $DIR/$tdir || error "unlink striped dir fails"
26117
26118         return 0
26119 }
26120 run_test 300j "test large update record"
26121
26122 test_300k() {
26123         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26124         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26125         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26126                 skip "Need MDS version at least 2.7.55"
26127
26128         # this test needs a huge transaction
26129         local kb
26130         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
26131              osd*.$FSNAME-MDT0000.kbytestotal")
26132         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
26133
26134         local stripe_count
26135         local file
26136
26137         mkdir $DIR/$tdir
26138
26139         #define OBD_FAIL_LARGE_STRIPE   0x1703
26140         $LCTL set_param fail_loc=0x1703
26141         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
26142                 error "set striped dir error"
26143         $LCTL set_param fail_loc=0
26144
26145         $LFS getdirstripe $DIR/$tdir/striped_dir ||
26146                 error "getstripeddir fails"
26147         rm -rf $DIR/$tdir/striped_dir ||
26148                 error "unlink striped dir fails"
26149
26150         return 0
26151 }
26152 run_test 300k "test large striped directory"
26153
26154 test_300l() {
26155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26156         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26157         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26158                 skip "Need MDS version at least 2.7.55"
26159
26160         local stripe_index
26161
26162         test_mkdir -p $DIR/$tdir/striped_dir
26163         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
26164                         error "chown $RUNAS_ID failed"
26165         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
26166                 error "set default striped dir failed"
26167
26168         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
26169         $LCTL set_param fail_loc=0x80000158
26170         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
26171
26172         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
26173         [ $stripe_index -eq 1 ] ||
26174                 error "expect 1 get $stripe_index for $dir"
26175 }
26176 run_test 300l "non-root user to create dir under striped dir with stale layout"
26177
26178 test_300m() {
26179         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26180         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
26181         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26182                 skip "Need MDS version at least 2.7.55"
26183
26184         mkdir -p $DIR/$tdir/striped_dir
26185         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
26186                 error "set default stripes dir error"
26187
26188         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
26189
26190         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
26191         [ $stripe_count -eq 0 ] ||
26192                         error "expect 0 get $stripe_count for a"
26193
26194         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
26195                 error "set default stripes dir error"
26196
26197         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
26198
26199         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
26200         [ $stripe_count -eq 0 ] ||
26201                         error "expect 0 get $stripe_count for b"
26202
26203         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
26204                 error "set default stripes dir error"
26205
26206         mkdir $DIR/$tdir/striped_dir/c &&
26207                 error "default stripe_index is invalid, mkdir c should fails"
26208
26209         rm -rf $DIR/$tdir || error "rmdir fails"
26210 }
26211 run_test 300m "setstriped directory on single MDT FS"
26212
26213 cleanup_300n() {
26214         local list=$(comma_list $(mdts_nodes))
26215
26216         trap 0
26217         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26218 }
26219
26220 test_300n() {
26221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26222         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26223         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26224                 skip "Need MDS version at least 2.7.55"
26225         remote_mds_nodsh && skip "remote MDS with nodsh"
26226
26227         local stripe_index
26228         local list=$(comma_list $(mdts_nodes))
26229
26230         trap cleanup_300n RETURN EXIT
26231         mkdir -p $DIR/$tdir
26232         chmod 777 $DIR/$tdir
26233         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
26234                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
26235                 error "create striped dir succeeds with gid=0"
26236
26237         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
26238         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
26239                 error "create striped dir fails with gid=-1"
26240
26241         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26242         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
26243                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
26244                 error "set default striped dir succeeds with gid=0"
26245
26246
26247         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
26248         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
26249                 error "set default striped dir fails with gid=-1"
26250
26251
26252         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26253         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
26254                                         error "create test_dir fails"
26255         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
26256                                         error "create test_dir1 fails"
26257         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
26258                                         error "create test_dir2 fails"
26259         cleanup_300n
26260 }
26261 run_test 300n "non-root user to create dir under striped dir with default EA"
26262
26263 test_300o() {
26264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26265         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26266         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26267                 skip "Need MDS version at least 2.7.55"
26268
26269         local numfree1
26270         local numfree2
26271
26272         mkdir -p $DIR/$tdir
26273
26274         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
26275         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
26276         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
26277                 skip "not enough free inodes $numfree1 $numfree2"
26278         fi
26279
26280         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
26281         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
26282         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
26283                 skip "not enough free space $numfree1 $numfree2"
26284         fi
26285
26286         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
26287                 error "setdirstripe fails"
26288
26289         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
26290                 error "create dirs fails"
26291
26292         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
26293         ls $DIR/$tdir/striped_dir > /dev/null ||
26294                 error "ls striped dir fails"
26295         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
26296                 error "unlink big striped dir fails"
26297 }
26298 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
26299
26300 test_300p() {
26301         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26302         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26303         remote_mds_nodsh && skip "remote MDS with nodsh"
26304
26305         mkdir_on_mdt0 $DIR/$tdir
26306
26307         #define OBD_FAIL_OUT_ENOSPC     0x1704
26308         do_facet mds2 lctl set_param fail_loc=0x80001704
26309         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
26310                  && error "create striped directory should fail"
26311
26312         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
26313
26314         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
26315         true
26316 }
26317 run_test 300p "create striped directory without space"
26318
26319 test_300q() {
26320         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26321         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26322
26323         local fd=$(free_fd)
26324         local cmd="exec $fd<$tdir"
26325         cd $DIR
26326         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
26327         eval $cmd
26328         cmd="exec $fd<&-"
26329         trap "eval $cmd" EXIT
26330         cd $tdir || error "cd $tdir fails"
26331         rmdir  ../$tdir || error "rmdir $tdir fails"
26332         mkdir local_dir && error "create dir succeeds"
26333         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
26334         eval $cmd
26335         return 0
26336 }
26337 run_test 300q "create remote directory under orphan directory"
26338
26339 test_300r() {
26340         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26341                 skip "Need MDS version at least 2.7.55" && return
26342         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
26343
26344         mkdir $DIR/$tdir
26345
26346         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
26347                 error "set striped dir error"
26348
26349         $LFS getdirstripe $DIR/$tdir/striped_dir ||
26350                 error "getstripeddir fails"
26351
26352         local stripe_count
26353         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
26354                       awk '/lmv_stripe_count:/ { print $2 }')
26355
26356         [ $MDSCOUNT -ne $stripe_count ] &&
26357                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
26358
26359         rm -rf $DIR/$tdir/striped_dir ||
26360                 error "unlink striped dir fails"
26361 }
26362 run_test 300r "test -1 striped directory"
26363
26364 test_300s_helper() {
26365         local count=$1
26366
26367         local stripe_dir=$DIR/$tdir/striped_dir.$count
26368
26369         $LFS mkdir -c $count $stripe_dir ||
26370                 error "lfs mkdir -c error"
26371
26372         $LFS getdirstripe $stripe_dir ||
26373                 error "lfs getdirstripe fails"
26374
26375         local stripe_count
26376         stripe_count=$($LFS getdirstripe $stripe_dir |
26377                       awk '/lmv_stripe_count:/ { print $2 }')
26378
26379         [ $count -ne $stripe_count ] &&
26380                 error_noexit "bad stripe count $stripe_count expected $count"
26381
26382         local dupe_stripes
26383         dupe_stripes=$($LFS getdirstripe $stripe_dir |
26384                 awk '/0x/ {count[$1] += 1}; END {
26385                         for (idx in count) {
26386                                 if (count[idx]>1) {
26387                                         print "index " idx " count " count[idx]
26388                                 }
26389                         }
26390                 }')
26391
26392         if [[ -n "$dupe_stripes" ]] ; then
26393                 lfs getdirstripe $stripe_dir
26394                 error_noexit "Dupe MDT above: $dupe_stripes "
26395         fi
26396
26397         rm -rf $stripe_dir ||
26398                 error_noexit "unlink $stripe_dir fails"
26399 }
26400
26401 test_300s() {
26402         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26403                 skip "Need MDS version at least 2.7.55" && return
26404         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
26405
26406         mkdir $DIR/$tdir
26407         for count in $(seq 2 $MDSCOUNT); do
26408                 test_300s_helper $count
26409         done
26410 }
26411 run_test 300s "test lfs mkdir -c without -i"
26412
26413 test_300t() {
26414         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
26415                 skip "need MDS 2.14.55 or later"
26416         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
26417
26418         local testdir="$DIR/$tdir/striped_dir"
26419         local dir1=$testdir/dir1
26420         local dir2=$testdir/dir2
26421
26422         mkdir -p $testdir
26423
26424         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
26425                 error "failed to set default stripe count for $testdir"
26426
26427         mkdir $dir1
26428         local stripe_count=$($LFS getdirstripe -c $dir1)
26429
26430         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
26431
26432         local max_count=$((MDSCOUNT - 1))
26433         local mdts=$(comma_list $(mdts_nodes))
26434
26435         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
26436         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
26437
26438         mkdir $dir2
26439         stripe_count=$($LFS getdirstripe -c $dir2)
26440
26441         (( $stripe_count == $max_count )) || error "wrong stripe count"
26442 }
26443 run_test 300t "test max_mdt_stripecount"
26444
26445 MDT_OVSTRP_VER="2.15.60"
26446 # 300u family tests MDT overstriping
26447 test_300ua() {
26448         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26449
26450         local setcount=$((MDSCOUNT * 2))
26451
26452         local expected_count
26453
26454         mkdir $DIR/$tdir
26455         $LFS setdirstripe -C $setcount $DIR/$tdir/${tdir}.0 ||
26456                 error "(0) failed basic overstriped dir creation test"
26457         local getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.0)
26458
26459         # This does a basic interop test - if the MDS does not support mdt
26460         # overstriping, we should get stripes == number of MDTs
26461         if (( $MDS1_VERSION < $(version_code $MDT_OVSTRP_VER) )); then
26462                 expected_count=$MDSCOUNT
26463         else
26464                 expected_count=$setcount
26465         fi
26466         (( getstripe_count == expected_count )) ||
26467                 error "(1) incorrect stripe count for simple overstriped dir"
26468
26469         rm -rf $DIR/$tdir/${tdir}.0 ||
26470                 error "(2) unable to rm overstriped dir"
26471
26472         # Tests after this require overstriping support
26473         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26474                 { echo "skipped for MDS < $MDT_OVSTRP_VER"; return 0; }
26475
26476         test_striped_dir 0 $setcount true ||
26477                 error "(3)failed on overstriped dir"
26478         test_striped_dir 1 $setcount true ||
26479                 error "(4)failed on overstriped dir"
26480
26481         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26482
26483         test_striped_dir 0 $setcount true ||
26484                 error "(5)failed on overstriped dir"
26485 }
26486 run_test 300ua "basic overstriped dir sanity test"
26487
26488 test_300ub() {
26489         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26490                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26491         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26492
26493         mkdir $DIR/$tdir
26494
26495         echo "Testing invalid stripe count, failure expected"
26496         local setcount=$((MDSCOUNT * 2))
26497
26498         $LFS setdirstripe -c $setcount $DIR/$tdir/${tdir}.0
26499         local getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.0)
26500
26501         (( getstripe_count <= MDSCOUNT )) ||
26502                 error "(0)stripe count ($setcount) > MDT count ($MDSCOUNT) succeeded with -c"
26503
26504         # When a user requests > LMV_MAX_STRIPES_PER_MDT, we reduce to that
26505         setcount=$((MDSCOUNT * 2 * LMV_MAX_STRIPES_PER_MDT))
26506         $LFS setdirstripe -C $setcount $DIR/$tdir/${tdir}.1
26507
26508         local maxcount=$((MDSCOUNT * LMV_MAX_STRIPES_PER_MDT))
26509
26510         getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.1)
26511         (( getstripe_count == maxcount )) ||
26512                 error "(1)stripe_count is $getstripe_count, expect $maxcount"
26513
26514         # Test specific striping with -i
26515         $LFS setdirstripe -i 0,0,0,0 $DIR/$tdir/${tdir}.2
26516
26517         getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.2)
26518         (( getstripe_count == 4 )) ||
26519                 error "(2)stripe_count is $getstripe_count, expect 4"
26520
26521         local nonzeroindices=$($LFS getdirstripe $DIR/$tdir/${tdir}.2 | grep "\[" | \
26522                                grep -v mdtidx | awk '{print $1}' | grep -c -v 0)
26523
26524         [[ -n "$nonzeroindices" ]] ||
26525                 error "(3) stripes indices not all 0: $nonzeroindices"
26526
26527         # Test specific striping with too many stripes on one MDT
26528         echo "Testing invalid striping, failure expected"
26529         $LFS setdirstripe -i 0,1,0,1,0,1,0,1,0,1,0 $DIR/$tdir/${tdir}.3
26530         $LFS getdirstripe $DIR/$tdir/${tdir}.3
26531         getstripe_count=$($LFS getdirstripe $DIR/$tdir/${tdir}.3 | grep "\[" | \
26532                           grep -v mdtidx | awk '{print $1}' | grep -c '0')
26533         echo "stripes on MDT0: $getstripe_count"
26534         (( getstripe_count <= LMV_MAX_STRIPES_PER_MDT )) ||
26535                 error "(4) setstripe with too many stripes on MDT0 succeeded"
26536
26537         setcount=$((MDSCOUNT * 2))
26538         $LFS setdirstripe -C $setcount -H all_char $DIR/${tdir}.4 ||
26539                 error "(5) can't setdirstripe with manually set hash function"
26540
26541         getstripe_count=$($LFS getdirstripe -c $DIR/${tdir}.4)
26542         (( getstripe_count == setcount )) ||
26543                 error "(6)stripe_count is $getstripe_count, expect $setcount"
26544
26545         setcount=$((MDSCOUNT * 2))
26546         mkdir $DIR/${tdir}.5
26547         $LFS setdirstripe -C $setcount -D -H crush $DIR/${tdir}.5 ||
26548                 error "(7) can't setdirstripe with manually set hash function"
26549         mkdir $DIR/${tdir}.5/${tdir}.6
26550
26551         getstripe_count=$($LFS getdirstripe -c $DIR/${tdir}.5/${tdir}.6)
26552         (( getstripe_count == setcount )) ||
26553                 error "(8)stripe_count is $getstripe_count, expect $setcount"
26554 }
26555 run_test 300ub "test MDT overstriping interface & limits"
26556
26557 test_300uc() {
26558         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26559                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26560         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26561
26562         mkdir $DIR/$tdir
26563
26564         local setcount=$((MDSCOUNT * 2))
26565
26566         $LFS setdirstripe -D -C $setcount $DIR/$tdir
26567
26568         mkdir $DIR/$tdir/${tdir}.1
26569
26570         local getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.1)
26571
26572         (( getstripe_count == setcount )) ||
26573                 error "(0)stripe_count is $getstripe_count, expect $setcount"
26574
26575         mkdir $DIR/$tdir/${tdir}.1/${tdir}.2
26576
26577         local getstripe_count=$($LFS getdirstripe -c \
26578                                 $DIR/$tdir/${tdir}.1/${tdir}.2)
26579
26580         (( getstripe_count == setcount )) ||
26581                 error "(1)stripe_count is $getstripe_count, expect $setcount"
26582 }
26583 run_test 300uc "test MDT overstriping as default & inheritance"
26584
26585 test_300ud() {
26586         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26587                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26588         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26589
26590         local mdts=$(comma_list $(mdts_nodes))
26591         local timeout=100
26592
26593         local restripe_status
26594         local delta
26595         local i
26596
26597         [[ $mds1_FSTYPE == zfs ]] && timeout=300
26598
26599         # in case "crush" hash type is not set
26600         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
26601
26602         restripe_status=$(do_facet mds1 $LCTL get_param -n \
26603                            mdt.*MDT0000.enable_dir_restripe)
26604         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
26605         stack_trap "do_nodes $mdts $LCTL set_param \
26606                     mdt.*.enable_dir_restripe=$restripe_status"
26607
26608         mkdir $DIR/$tdir
26609         createmany -m $DIR/$tdir/f $((50 * MDSCOUNT)) ||
26610                 error "create files under remote dir failed $i"
26611         createmany -d $DIR/$tdir/d $((50 * MDSCOUNT)) ||
26612                 error "create dirs under remote dir failed $i"
26613
26614         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26615
26616         (( setcount < 13 )) || setcount=12
26617         for i in $(seq 2 $setcount); do
26618                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
26619                 $LFS setdirstripe -C $i $DIR/$tdir ||
26620                         error "split -C $i $tdir failed"
26621                 wait_update $HOSTNAME \
26622                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
26623                         error "dir split not finished"
26624                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
26625                         awk '/migrate/ {sum += $2} END { print sum }')
26626                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
26627                 # delta is around total_files/stripe_count, deviation 3%
26628                 (( delta < 100 * MDSCOUNT / i + 3 * MDSCOUNT )) ||
26629                         error "$delta files migrated >= $((100 * MDSCOUNT / i + 3 * MDSCOUNT))"
26630         done
26631 }
26632 run_test 300ud "dir split"
26633
26634 test_300ue() {
26635         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26636                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26637         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26638
26639         local mdts=$(comma_list $(mdts_nodes))
26640         local timeout=100
26641
26642         local restripe_status
26643         local delta
26644         local c
26645
26646         [[ $mds1_FSTYPE == zfs ]] && timeout=300
26647
26648         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
26649
26650         restripe_status=$(do_facet mds1 $LCTL get_param -n \
26651                            mdt.*MDT0000.enable_dir_restripe)
26652         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
26653         stack_trap "do_nodes $mdts $LCTL set_param \
26654                     mdt.*.enable_dir_restripe=$restripe_status"
26655
26656         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26657
26658         (( setcount < 13 )) || setcount=12
26659         test_mkdir -C $setcount -H crush $DIR/$tdir
26660         createmany -m $DIR/$tdir/f $((50 * MDSCOUNT)) ||
26661                 error "create files under remote dir failed"
26662         createmany -d $DIR/$tdir/d $((50 * MDSCOUNT)) ||
26663                 error "create dirs under remote dir failed"
26664
26665         for c in $(seq $((setcount - 1)) -1 1); do
26666                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
26667                 $LFS setdirstripe -C $c $DIR/$tdir ||
26668                         error "split -C $c $tdir failed"
26669                 wait_update $HOSTNAME \
26670                         "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" $timeout ||
26671                         error "dir merge not finished"
26672                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
26673                         awk '/migrate/ {sum += $2} END { print sum }')
26674                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
26675                 # delta is around total_files/stripe_count, deviation 3%
26676                 (( delta < 100 * MDSCOUNT / c + 3 * MDSCOUNT )) ||
26677                         error "$delta files migrated >= $((100 * MDSCOUNT / c + 3 * MDSCOUNT))"
26678         done
26679 }
26680 run_test 300ue "dir merge"
26681
26682 test_300uf() {
26683         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26684                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26685         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26686
26687         # maximum amount of local locks:
26688         # parent striped dir - 2 locks
26689         # new stripe in parent to migrate to - 1 lock
26690         # source and target - 2 locks
26691         # Total 5 locks for regular file
26692         #
26693         # NB: Overstriping should add several extra local locks
26694         # FIXME: Remove this once understood
26695         #lctl set_param *debug=-1 debug_mb=10000
26696         lctl clear
26697         lctl mark "touch/create"
26698         mkdir -p $DIR/$tdir
26699         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26700         local setcount=$((MDSCOUNT * 5))
26701
26702         $LFS mkdir -i1 -C $setcount $DIR/$tdir/dir1
26703         touch $DIR/$tdir/dir1/eee
26704
26705         lctl mark "hardlinks"
26706         # create 4 hardlink for 4 more locks
26707         # Total: 9 locks > RS_MAX_LOCKS (8)
26708         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
26709         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
26710         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
26711         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
26712         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
26713         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
26714         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
26715         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
26716
26717         lctl mark "cancel lru"
26718         cancel_lru_locks mdc
26719
26720         lctl mark "migrate"
26721         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
26722                 error "migrate dir fails"
26723
26724         rm -rf $DIR/$tdir || error "rm dir failed after migration"
26725 }
26726 run_test 300uf "migrate with too many local locks"
26727
26728 test_300ug() {
26729         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26730                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26731         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26732
26733         mkdir -p $DIR/$tdir
26734         local migrate_dir=$DIR/$tdir/migrate_dir
26735         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26736         local setcount2=$((setcount - 2))
26737
26738         $LFS setdirstripe -c 2 $migrate_dir ||
26739                 error "(0) failed to create striped directory"
26740
26741         $LFS migrate -m 0 -C $setcount $migrate_dir ||
26742                 error "(1)failed to migrate to overstriped directory"
26743         local getstripe_count=$($LFS getdirstripe -c $migrate_dir)
26744
26745         (( getstripe_count == setcount )) ||
26746                 error "(2)stripe_count is $getstripe_count, expect $setcount"
26747         touch $DIR/$tdir/migrate_dir/$tfile ||
26748                 error "(3)failed to create file in overstriped directory"
26749         $LFS migrate -m 0 -C $setcount2 $migrate_dir ||
26750                 error "(4)failed to migrate overstriped directory"
26751         # Check stripe count after migration
26752         $LFS getdirstripe $migrate_dir
26753         getstripe_count=$($LFS getdirstripe -c $migrate_dir)
26754         (( getstripe_count == setcount2 )) ||
26755                 error "(5)stripe_count is $getstripe_count, expect $setcount2"
26756
26757         rm -rf $migrate_dir || error "(6) unable to rm overstriped dir"
26758 }
26759 run_test 300ug "migrate overstriped dirs"
26760
26761 prepare_remote_file() {
26762         mkdir $DIR/$tdir/src_dir ||
26763                 error "create remote source failed"
26764
26765         cp /etc/hosts $DIR/$tdir/src_dir/a ||
26766                  error "cp to remote source failed"
26767         touch $DIR/$tdir/src_dir/a
26768
26769         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
26770                 error "create remote target dir failed"
26771
26772         touch $DIR/$tdir/tgt_dir/b
26773
26774         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
26775                 error "rename dir cross MDT failed!"
26776
26777         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
26778                 error "src_child still exists after rename"
26779
26780         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
26781                 error "missing file(a) after rename"
26782
26783         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
26784                 error "diff after rename"
26785 }
26786
26787 test_310a() {
26788         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
26789         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26790
26791         local remote_file=$DIR/$tdir/tgt_dir/b
26792
26793         mkdir -p $DIR/$tdir
26794
26795         prepare_remote_file || error "prepare remote file failed"
26796
26797         #open-unlink file
26798         $OPENUNLINK $remote_file $remote_file ||
26799                 error "openunlink $remote_file failed"
26800         $CHECKSTAT -a $remote_file || error "$remote_file exists"
26801 }
26802 run_test 310a "open unlink remote file"
26803
26804 test_310b() {
26805         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
26806         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26807
26808         local remote_file=$DIR/$tdir/tgt_dir/b
26809
26810         mkdir -p $DIR/$tdir
26811
26812         prepare_remote_file || error "prepare remote file failed"
26813
26814         ln $remote_file $DIR/$tfile || error "link failed for remote file"
26815         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
26816         $CHECKSTAT -t file $remote_file || error "check file failed"
26817 }
26818 run_test 310b "unlink remote file with multiple links while open"
26819
26820 test_310c() {
26821         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26822         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
26823
26824         local remote_file=$DIR/$tdir/tgt_dir/b
26825
26826         mkdir -p $DIR/$tdir
26827
26828         prepare_remote_file || error "prepare remote file failed"
26829
26830         ln $remote_file $DIR/$tfile || error "link failed for remote file"
26831         multiop_bg_pause $remote_file O_uc ||
26832                         error "mulitop failed for remote file"
26833         MULTIPID=$!
26834         $MULTIOP $DIR/$tfile Ouc
26835         kill -USR1 $MULTIPID
26836         wait $MULTIPID
26837 }
26838 run_test 310c "open-unlink remote file with multiple links"
26839
26840 #LU-4825
26841 test_311() {
26842         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26843         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
26844         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
26845                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
26846         remote_mds_nodsh && skip "remote MDS with nodsh"
26847
26848         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
26849         local mdts=$(comma_list $(mdts_nodes))
26850
26851         mkdir -p $DIR/$tdir
26852         $LFS setstripe -i 0 -c 1 $DIR/$tdir
26853         createmany -o $DIR/$tdir/$tfile. 1000
26854
26855         # statfs data is not real time, let's just calculate it
26856         old_iused=$((old_iused + 1000))
26857
26858         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
26859                         osp.*OST0000*MDT0000.create_count")
26860         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
26861                                 osp.*OST0000*MDT0000.max_create_count")
26862         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
26863
26864         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
26865         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
26866         [ $index -ne 0 ] || error "$tfile stripe index is 0"
26867
26868         unlinkmany $DIR/$tdir/$tfile. 1000
26869
26870         do_nodes $mdts "$LCTL set_param -n \
26871                         osp.*OST0000*.max_create_count=$max_count"
26872         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
26873                 do_nodes $mdts "$LCTL set_param -n \
26874                                 osp.*OST0000*.create_count=$count"
26875         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
26876                         grep "=0" && error "create_count is zero"
26877
26878         local new_iused
26879         for i in $(seq 120); do
26880                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
26881                 # system may be too busy to destroy all objs in time, use
26882                 # a somewhat small value to not fail autotest
26883                 [ $((old_iused - new_iused)) -gt 400 ] && break
26884                 sleep 1
26885         done
26886
26887         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
26888         [ $((old_iused - new_iused)) -gt 400 ] ||
26889                 error "objs not destroyed after unlink"
26890 }
26891 run_test 311 "disable OSP precreate, and unlink should destroy objs"
26892
26893 zfs_get_objid()
26894 {
26895         local ost=$1
26896         local tf=$2
26897         local fid=($($LFS getstripe $tf | grep 0x))
26898         local seq=${fid[3]#0x}
26899         local objid=${fid[1]}
26900
26901         local vdevdir=$(dirname $(facet_vdevice $ost))
26902         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
26903         local zfs_zapid=$(do_facet $ost $cmd |
26904                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
26905                           awk '/Object/{getline; print $1}')
26906         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
26907                           awk "/$objid = /"'{printf $3}')
26908
26909         echo $zfs_objid
26910 }
26911
26912 zfs_object_blksz() {
26913         local ost=$1
26914         local objid=$2
26915
26916         local vdevdir=$(dirname $(facet_vdevice $ost))
26917         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
26918         local blksz=$(do_facet $ost $cmd $objid |
26919                       awk '/dblk/{getline; printf $4}')
26920
26921         case "${blksz: -1}" in
26922                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
26923                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
26924                 *) ;;
26925         esac
26926
26927         echo $blksz
26928 }
26929
26930 test_312() { # LU-4856
26931         remote_ost_nodsh && skip "remote OST with nodsh"
26932         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
26933
26934         local max_blksz=$(do_facet ost1 \
26935                           $ZFS get -p recordsize $(facet_device ost1) |
26936                           awk '!/VALUE/{print $3}')
26937         local tf=$DIR/$tfile
26938
26939         $LFS setstripe -c1 $tf
26940         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
26941
26942         # Get ZFS object id
26943         local zfs_objid=$(zfs_get_objid $facet $tf)
26944         # block size change by sequential overwrite
26945         local bs
26946
26947         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
26948                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
26949
26950                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
26951                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
26952         done
26953         rm -f $tf
26954
26955         $LFS setstripe -c1 $tf
26956         facet="ost$(($($LFS getstripe -i $tf) + 1))"
26957
26958         # block size change by sequential append write
26959         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
26960         zfs_objid=$(zfs_get_objid $facet $tf)
26961         local count
26962
26963         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
26964                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
26965                         oflag=sync conv=notrunc
26966
26967                 blksz=$(zfs_object_blksz $facet $zfs_objid)
26968                 (( $blksz == 2 * count * PAGE_SIZE )) ||
26969                         error "blksz error, actual $blksz, " \
26970                                 "expected: 2 * $count * $PAGE_SIZE"
26971         done
26972         rm -f $tf
26973
26974         # random write
26975         $LFS setstripe -c1 $tf
26976         facet="ost$(($($LFS getstripe -i $tf) + 1))"
26977         zfs_objid=$(zfs_get_objid $facet $tf)
26978
26979         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
26980         blksz=$(zfs_object_blksz $facet $zfs_objid)
26981         (( blksz == PAGE_SIZE )) ||
26982                 error "blksz error: $blksz, expected: $PAGE_SIZE"
26983
26984         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
26985         blksz=$(zfs_object_blksz $facet $zfs_objid)
26986         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
26987
26988         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
26989         blksz=$(zfs_object_blksz $facet $zfs_objid)
26990         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
26991 }
26992 run_test 312 "make sure ZFS adjusts its block size by write pattern"
26993
26994 test_313() {
26995         remote_ost_nodsh && skip "remote OST with nodsh"
26996
26997         local file=$DIR/$tfile
26998
26999         rm -f $file
27000         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
27001
27002         # define OBD_FAIL_TGT_RCVD_EIO           0x720
27003         do_facet ost1 "$LCTL set_param fail_loc=0x720"
27004         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
27005                 error "write should failed"
27006         do_facet ost1 "$LCTL set_param fail_loc=0"
27007         rm -f $file
27008 }
27009 run_test 313 "io should fail after last_rcvd update fail"
27010
27011 test_314() {
27012         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
27013
27014         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
27015         do_facet ost1 "$LCTL set_param fail_loc=0x720"
27016         rm -f $DIR/$tfile
27017         wait_delete_completed
27018         do_facet ost1 "$LCTL set_param fail_loc=0"
27019 }
27020 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
27021
27022 test_315() { # LU-618
27023         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
27024
27025         local file=$DIR/$tfile
27026         rm -f $file
27027
27028         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
27029                 error "multiop file write failed"
27030         $MULTIOP $file oO_RDONLY:r4063232_c &
27031         PID=$!
27032
27033         sleep 2
27034
27035         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
27036         kill -USR1 $PID
27037
27038         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
27039         rm -f $file
27040 }
27041 run_test 315 "read should be accounted"
27042
27043 test_316() {
27044         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
27045         large_xattr_enabled || skip "ea_inode feature disabled"
27046
27047         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27048         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
27049         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
27050         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
27051
27052         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
27053 }
27054 run_test 316 "lfs migrate of file with large_xattr enabled"
27055
27056 test_317() {
27057         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
27058                 skip "Need MDS version at least 2.11.53"
27059         if [ "$ost1_FSTYPE" == "zfs" ]; then
27060                 skip "LU-10370: no implementation for ZFS"
27061         fi
27062
27063         local trunc_sz
27064         local grant_blk_size
27065
27066         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
27067                         awk '/grant_block_size:/ { print $2; exit; }')
27068         #
27069         # Create File of size 5M. Truncate it to below size's and verify
27070         # blocks count.
27071         #
27072         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
27073                 error "Create file $DIR/$tfile failed"
27074         stack_trap "rm -f $DIR/$tfile" EXIT
27075
27076         for trunc_sz in 2097152 4097 4000 509 0; do
27077                 $TRUNCATE $DIR/$tfile $trunc_sz ||
27078                         error "truncate $tfile to $trunc_sz failed"
27079                 local sz=$(stat --format=%s $DIR/$tfile)
27080                 local blk=$(stat --format=%b $DIR/$tfile)
27081                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
27082                                      grant_blk_size) * 8))
27083
27084                 if [[ $blk -ne $trunc_blk ]]; then
27085                         $(which stat) $DIR/$tfile
27086                         error "Expected Block $trunc_blk got $blk for $tfile"
27087                 fi
27088
27089                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
27090                         error "Expected Size $trunc_sz got $sz for $tfile"
27091         done
27092
27093         #
27094         # sparse file test
27095         # Create file with a hole and write actual 65536 bytes which aligned
27096         # with 4K and 64K PAGE_SIZE. Block count must be 128.
27097         #
27098         local bs=65536
27099         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
27100                 error "Create file : $DIR/$tfile"
27101
27102         #
27103         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
27104         # blocks. The block count must drop to 8.
27105         #
27106         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
27107                 ((bs - grant_blk_size) + 1)))
27108         $TRUNCATE $DIR/$tfile $trunc_sz ||
27109                 error "truncate $tfile to $trunc_sz failed"
27110
27111         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
27112         sz=$(stat --format=%s $DIR/$tfile)
27113         blk=$(stat --format=%b $DIR/$tfile)
27114
27115         if [[ $blk -ne $trunc_bsz ]]; then
27116                 $(which stat) $DIR/$tfile
27117                 error "Expected Block $trunc_bsz got $blk for $tfile"
27118         fi
27119
27120         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
27121                 error "Expected Size $trunc_sz got $sz for $tfile"
27122 }
27123 run_test 317 "Verify blocks get correctly update after truncate"
27124
27125 test_318() {
27126         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
27127         local old_max_active=$($LCTL get_param -n \
27128                             ${llite_name}.max_read_ahead_async_active \
27129                             2>/dev/null)
27130
27131         $LCTL set_param llite.*.max_read_ahead_async_active=256
27132         local max_active=$($LCTL get_param -n \
27133                            ${llite_name}.max_read_ahead_async_active \
27134                            2>/dev/null)
27135         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
27136
27137         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
27138                 error "set max_read_ahead_async_active should succeed"
27139
27140         $LCTL set_param llite.*.max_read_ahead_async_active=512
27141         max_active=$($LCTL get_param -n \
27142                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
27143         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
27144
27145         # restore @max_active
27146         [ $old_max_active -ne 0 ] && $LCTL set_param \
27147                 llite.*.max_read_ahead_async_active=$old_max_active
27148
27149         local old_threshold=$($LCTL get_param -n \
27150                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
27151         local max_per_file_mb=$($LCTL get_param -n \
27152                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
27153
27154         local invalid=$(($max_per_file_mb + 1))
27155         $LCTL set_param \
27156                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
27157                         && error "set $invalid should fail"
27158
27159         local valid=$(($invalid - 1))
27160         $LCTL set_param \
27161                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
27162                         error "set $valid should succeed"
27163         local threshold=$($LCTL get_param -n \
27164                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
27165         [ $threshold -eq $valid ] || error \
27166                 "expect threshold $valid got $threshold"
27167         $LCTL set_param \
27168                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
27169 }
27170 run_test 318 "Verify async readahead tunables"
27171
27172 test_319() {
27173         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
27174
27175         local before=$(date +%s)
27176         local evict
27177         local mdir=$DIR/$tdir
27178         local file=$mdir/xxx
27179
27180         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
27181         touch $file
27182
27183 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
27184         $LCTL set_param fail_val=5 fail_loc=0x8000032c
27185         $LFS migrate -m1 $mdir &
27186
27187         sleep 1
27188         dd if=$file of=/dev/null
27189         wait
27190         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
27191           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
27192
27193         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
27194 }
27195 run_test 319 "lost lease lock on migrate error"
27196
27197 test_360() {
27198         (( $OST1_VERSION >= $(version_code 2.15.58.96) )) ||
27199                 skip "Need OST version at least 2.15.58.96"
27200         [[ "$ost1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
27201
27202         check_set_fallocate_or_skip
27203         local param="osd-ldiskfs.delayed_unlink_mb"
27204         local old=($(do_facet ost1 "$LCTL get_param -n $param"))
27205
27206         do_facet ost1 "$LCTL set_param $param=1MiB"
27207         stack_trap "do_facet ost1 $LCTL set_param $param=${old[0]}"
27208
27209         mkdir $DIR/$tdir/
27210         do_facet ost1 $LCTL set_param debug=+inode
27211         do_facet ost1 $LCTL clear
27212         local files=100
27213
27214         for ((i = 0; i < $files; i++)); do
27215                 fallocate -l 1280k $DIR/$tdir/$tfile.$i ||
27216                         error "fallocate 1280k $DIR/$tdir/$tfile.$i failed"
27217         done
27218         local min=$(($($LFS find $DIR/$tdir --ost 0 | wc -l) / 2))
27219
27220         for ((i = 0; i < $files; i++)); do
27221                 unlink $DIR/$tdir/$tfile.$i ||
27222                         error "unlink $DIR/$tdir/$tfile.$i failed"
27223         done
27224
27225         local count=0
27226         local loop
27227
27228         for (( loop = 0; loop < 30 && count < min; loop++)); do
27229                 sleep 1
27230                 (( count += $(do_facet ost1 $LCTL dk | grep -c "delayed iput")))
27231                 echo "Count[$loop]: $count"
27232         done
27233         (( count >= min )) || error "$count < $min delayed iput after $loop s"
27234 }
27235 run_test 360 "ldiskfs unlink in a separate thread"
27236
27237 test_398a() { # LU-4198
27238         local ost1_imp=$(get_osc_import_name client ost1)
27239         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27240                          cut -d'.' -f2)
27241
27242         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27243         stack_trap "rm -f $DIR/$tfile"
27244         $LCTL set_param ldlm.namespaces.*.lru_size=clear
27245
27246         # request a new lock on client
27247         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27248
27249         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
27250         local lock_count=$($LCTL get_param -n \
27251                            ldlm.namespaces.$imp_name.lru_size)
27252         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
27253
27254         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
27255
27256         # no lock cached, should use lockless DIO and not enqueue new lock
27257         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
27258         lock_count=$($LCTL get_param -n \
27259                      ldlm.namespaces.$imp_name.lru_size)
27260         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
27261
27262         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
27263
27264         # no lock cached, should use locked DIO append
27265         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
27266                 conv=notrunc || error "DIO append failed"
27267         lock_count=$($LCTL get_param -n \
27268                      ldlm.namespaces.$imp_name.lru_size)
27269         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
27270 }
27271 run_test 398a "direct IO should cancel lock otherwise lockless"
27272
27273 test_398b() { # LU-4198
27274         local before=$(date +%s)
27275         local njobs=4
27276         local size=48
27277
27278         which fio || skip_env "no fio installed"
27279         $LFS setstripe -c -1 -S 1M $DIR/$tfile
27280         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
27281
27282         # Single page, multiple pages, stripe size, 4*stripe size
27283         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
27284                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
27285                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
27286                         --numjobs=$njobs --fallocate=none \
27287                         --iodepth=16 --allow_file_create=0 \
27288                         --size=$((size/njobs))M \
27289                         --filename=$DIR/$tfile &
27290                 bg_pid=$!
27291
27292                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
27293                 fio --name=rand-rw --rw=randrw --bs=$bsize \
27294                         --numjobs=$njobs --fallocate=none \
27295                         --iodepth=16 --allow_file_create=0 \
27296                         --size=$((size/njobs))M \
27297                         --filename=$DIR/$tfile || true
27298                 wait $bg_pid
27299         done
27300
27301         evict=$(do_facet client $LCTL get_param \
27302                 osc.$FSNAME-OST*-osc-*/state |
27303             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
27304
27305         [ -z "$evict" ] || [[ $evict -le $before ]] ||
27306                 (do_facet client $LCTL get_param \
27307                         osc.$FSNAME-OST*-osc-*/state;
27308                     error "eviction happened: $evict before:$before")
27309
27310         rm -f $DIR/$tfile
27311 }
27312 run_test 398b "DIO and buffer IO race"
27313
27314 test_398c() { # LU-4198
27315         local ost1_imp=$(get_osc_import_name client ost1)
27316         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27317                          cut -d'.' -f2)
27318
27319         which fio || skip_env "no fio installed"
27320
27321         saved_debug=$($LCTL get_param -n debug)
27322         $LCTL set_param debug=0
27323
27324         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
27325         ((size /= 1024)) # by megabytes
27326         ((size /= 2)) # write half of the OST at most
27327         [ $size -gt 40 ] && size=40 #reduce test time anyway
27328
27329         $LFS setstripe -c 1 $DIR/$tfile
27330
27331         # it seems like ldiskfs reserves more space than necessary if the
27332         # writing blocks are not mapped, so it extends the file firstly
27333         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
27334         cancel_lru_locks osc
27335
27336         # clear and verify rpc_stats later
27337         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
27338
27339         local njobs=4
27340         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
27341         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
27342                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
27343                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
27344                 --filename=$DIR/$tfile
27345         [ $? -eq 0 ] || error "fio write error"
27346
27347         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
27348                 error "Locks were requested while doing AIO"
27349
27350         # get the percentage of 1-page I/O
27351         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
27352                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
27353                 awk '{print $7}')
27354         (( $pct <= 50 )) || {
27355                 $LCTL get_param osc.${imp_name}.rpc_stats
27356                 error "$pct% of I/O are 1-page"
27357         }
27358
27359         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
27360         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
27361                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
27362                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
27363                 --filename=$DIR/$tfile
27364         [ $? -eq 0 ] || error "fio mixed read write error"
27365
27366         echo "AIO with large block size ${size}M"
27367         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
27368                 --numjobs=1 --fallocate=none --ioengine=libaio \
27369                 --iodepth=16 --allow_file_create=0 --size=${size}M \
27370                 --filename=$DIR/$tfile
27371         [ $? -eq 0 ] || error "fio large block size failed"
27372
27373         rm -f $DIR/$tfile
27374         $LCTL set_param debug="$saved_debug"
27375 }
27376 run_test 398c "run fio to test AIO"
27377
27378 test_398d() { #  LU-13846
27379         which aiocp || skip_env "no aiocp installed"
27380         local aio_file=$DIR/$tfile.aio
27381
27382         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
27383
27384         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
27385         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
27386         stack_trap "rm -f $DIR/$tfile $aio_file"
27387
27388         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
27389
27390         # test memory unaligned aio
27391         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file ||
27392                 error "unaligned aio failed"
27393         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
27394
27395         rm -f $DIR/$tfile $aio_file
27396 }
27397 run_test 398d "run aiocp to verify block size > stripe size"
27398
27399 test_398e() {
27400         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
27401         touch $DIR/$tfile.new
27402         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
27403 }
27404 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
27405
27406 test_398f() { #  LU-14687
27407         which aiocp || skip_env "no aiocp installed"
27408         local aio_file=$DIR/$tfile.aio
27409
27410         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
27411
27412         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
27413         stack_trap "rm -f $DIR/$tfile $aio_file"
27414
27415         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
27416         $LCTL set_param fail_loc=0x1418
27417         # make sure we don't crash and fail properly
27418         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
27419                 error "aio with page allocation failure succeeded"
27420         $LCTL set_param fail_loc=0
27421         diff $DIR/$tfile $aio_file
27422         [[ $? != 0 ]] || error "no diff after failed aiocp"
27423 }
27424 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
27425
27426 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
27427 # stripe and i/o size must be > stripe size
27428 # Old style synchronous DIO waits after submitting each chunk, resulting in a
27429 # single RPC in flight.  This test shows async DIO submission is working by
27430 # showing multiple RPCs in flight.
27431 test_398g() { #  LU-13798
27432         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
27433
27434         # We need to do some i/o first to acquire enough grant to put our RPCs
27435         # in flight; otherwise a new connection may not have enough grant
27436         # available
27437         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27438                 error "parallel dio failed"
27439         stack_trap "rm -f $DIR/$tfile"
27440
27441         # Reduce RPC size to 1M to avoid combination in to larger RPCs
27442         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
27443         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
27444         stack_trap "$LCTL set_param -n $pages_per_rpc"
27445
27446         # Recreate file so it's empty
27447         rm -f $DIR/$tfile
27448         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
27449         #Pause rpc completion to guarantee we see multiple rpcs in flight
27450         #define OBD_FAIL_OST_BRW_PAUSE_BULK
27451         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
27452         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
27453
27454         # Clear rpc stats
27455         $LCTL set_param osc.*.rpc_stats=c
27456
27457         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27458                 error "parallel dio failed"
27459         stack_trap "rm -f $DIR/$tfile"
27460
27461         $LCTL get_param osc.*-OST0000-*.rpc_stats
27462         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
27463                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
27464                 grep "8:" | awk '{print $8}')
27465         # We look at the "8 rpcs in flight" field, and verify A) it is present
27466         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
27467         # as expected for an 8M DIO to a file with 1M stripes.
27468         # NB: There is occasionally a mystery extra write RPC to a different
27469         # file.  I can't identify why that's happening, so we set up a margin
27470         # of 1 RPC here, ie, 8/9 RPCs at this size, or ~88%
27471         [ $pct -gt 87 ] || error "we should see 8 RPCs in flight"
27472
27473         # Verify turning off parallel dio works as expected
27474         # Clear rpc stats
27475         $LCTL set_param osc.*.rpc_stats=c
27476         $LCTL set_param llite.*.parallel_dio=0
27477         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
27478
27479         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27480                 error "dio with parallel dio disabled failed"
27481
27482         # Ideally, we would see only one RPC in flight here, but there is an
27483         # unavoidable race between i/o completion and RPC in flight counting,
27484         # so while only 1 i/o is in flight at a time, the RPC in flight counter
27485         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
27486         # So instead we just verify it's always < 8.
27487         $LCTL get_param osc.*-OST0000-*.rpc_stats
27488         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
27489                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
27490                 grep '^$' -B1 | grep . | awk '{print $1}')
27491         [ $ret != "8:" ] ||
27492                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
27493 }
27494 run_test 398g "verify parallel dio async RPC submission"
27495
27496 test_398h() { #  LU-13798
27497         local dio_file=$DIR/$tfile.dio
27498
27499         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
27500
27501         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27502         stack_trap "rm -f $DIR/$tfile $dio_file"
27503
27504         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
27505                 error "parallel dio failed"
27506         diff $DIR/$tfile $dio_file
27507         [[ $? == 0 ]] || error "file diff after aiocp"
27508 }
27509 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
27510
27511 test_398i() { #  LU-13798
27512         local dio_file=$DIR/$tfile.dio
27513
27514         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
27515
27516         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27517         stack_trap "rm -f $DIR/$tfile $dio_file"
27518
27519         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
27520         $LCTL set_param fail_loc=0x1418
27521         # make sure we don't crash and fail properly
27522         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
27523                 error "parallel dio page allocation failure succeeded"
27524         diff $DIR/$tfile $dio_file
27525         [[ $? != 0 ]] || error "no diff after failed aiocp"
27526 }
27527 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
27528
27529 test_398j() { #  LU-13798
27530         # Stripe size > RPC size but less than i/o size tests split across
27531         # stripes and RPCs for individual i/o op
27532         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
27533
27534         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
27535         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
27536         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
27537         stack_trap "$LCTL set_param -n $pages_per_rpc"
27538
27539         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27540                 error "parallel dio write failed"
27541         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
27542
27543         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
27544                 error "parallel dio read failed"
27545         diff $DIR/$tfile $DIR/$tfile.2
27546         [[ $? == 0 ]] || error "file diff after parallel dio read"
27547 }
27548 run_test 398j "test parallel dio where stripe size > rpc_size"
27549
27550 test_398k() { #  LU-13798
27551         wait_delete_completed
27552         wait_mds_ost_sync
27553
27554         # 4 stripe file; we will cause out of space on OST0
27555         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
27556
27557         # Fill OST0 (if it's not too large)
27558         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
27559                    head -n1)
27560         if [[ $ORIGFREE -gt $MAXFREE ]]; then
27561                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
27562         fi
27563         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
27564         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
27565                 error "dd should fill OST0"
27566         stack_trap "rm -f $DIR/$tfile.1"
27567
27568         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27569         err=$?
27570
27571         ls -la $DIR/$tfile
27572         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
27573                 error "file is not 0 bytes in size"
27574
27575         # dd above should not succeed, but don't error until here so we can
27576         # get debug info above
27577         [[ $err != 0 ]] ||
27578                 error "parallel dio write with enospc succeeded"
27579         stack_trap "rm -f $DIR/$tfile"
27580 }
27581 run_test 398k "test enospc on first stripe"
27582
27583 test_398l() { #  LU-13798
27584         wait_delete_completed
27585         wait_mds_ost_sync
27586
27587         # 4 stripe file; we will cause out of space on OST0
27588         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
27589         # happens on the second i/o chunk we issue
27590         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
27591
27592         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
27593         stack_trap "rm -f $DIR/$tfile"
27594
27595         # Fill OST0 (if it's not too large)
27596         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
27597                    head -n1)
27598         if [[ $ORIGFREE -gt $MAXFREE ]]; then
27599                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
27600         fi
27601         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
27602         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
27603                 error "dd should fill OST0"
27604         stack_trap "rm -f $DIR/$tfile.1"
27605
27606         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
27607         err=$?
27608         stack_trap "rm -f $DIR/$tfile.2"
27609
27610         # Check that short write completed as expected
27611         ls -la $DIR/$tfile.2
27612         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
27613                 error "file is not 1M in size"
27614
27615         # dd above should not succeed, but don't error until here so we can
27616         # get debug info above
27617         [[ $err != 0 ]] ||
27618                 error "parallel dio write with enospc succeeded"
27619
27620         # Truncate source file to same length as output file and diff them
27621         $TRUNCATE $DIR/$tfile 1048576
27622         diff $DIR/$tfile $DIR/$tfile.2
27623         [[ $? == 0 ]] || error "data incorrect after short write"
27624 }
27625 run_test 398l "test enospc on intermediate stripe/RPC"
27626
27627 test_398m() { #  LU-13798
27628         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
27629
27630         # Set up failure on OST0, the first stripe:
27631         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
27632         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
27633         # OST0 is on ost1, OST1 is on ost2.
27634         # So this fail_val specifies OST0
27635         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
27636         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
27637
27638         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
27639                 error "parallel dio write with failure on first stripe succeeded"
27640         stack_trap "rm -f $DIR/$tfile"
27641         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
27642
27643         # Place data in file for read
27644         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27645                 error "parallel dio write failed"
27646
27647         # Fail read on OST0, first stripe
27648         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
27649         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
27650         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
27651                 error "parallel dio read with error on first stripe succeeded"
27652         rm -f $DIR/$tfile.2
27653         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
27654
27655         # Switch to testing on OST1, second stripe
27656         # Clear file contents, maintain striping
27657         echo > $DIR/$tfile
27658         # Set up failure on OST1, second stripe:
27659         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
27660         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
27661
27662         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
27663                 error "parallel dio write with failure on second stripe succeeded"
27664         stack_trap "rm -f $DIR/$tfile"
27665         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
27666
27667         # Place data in file for read
27668         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27669                 error "parallel dio write failed"
27670
27671         # Fail read on OST1, second stripe
27672         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
27673         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
27674         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
27675                 error "parallel dio read with error on second stripe succeeded"
27676         rm -f $DIR/$tfile.2
27677         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
27678 }
27679 run_test 398m "test RPC failures with parallel dio"
27680
27681 # Parallel submission of DIO should not cause problems for append, but it's
27682 # important to verify.
27683 test_398n() { #  LU-13798
27684         $LFS setstripe -C 2 -S 1M $DIR/$tfile
27685
27686         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
27687                 error "dd to create source file failed"
27688         stack_trap "rm -f $DIR/$tfile"
27689
27690         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
27691                 error "parallel dio write with failure on second stripe succeeded"
27692         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
27693         diff $DIR/$tfile $DIR/$tfile.1
27694         [[ $? == 0 ]] || error "data incorrect after append"
27695
27696 }
27697 run_test 398n "test append with parallel DIO"
27698
27699 test_398o() {
27700         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
27701 }
27702 run_test 398o "right kms with DIO"
27703
27704 test_398p()
27705 {
27706         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
27707         which aiocp || skip_env "no aiocp installed"
27708
27709         local stripe_size=$((1024 * 1024)) #1 MiB
27710         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
27711         local file_size=$((25 * stripe_size))
27712
27713         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
27714         stack_trap "rm -f $DIR/$tfile*"
27715         # Just a bit bigger than the largest size in the test set below
27716         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
27717                 error "buffered i/o to create file failed"
27718
27719         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
27720                 $((stripe_size * 4)); do
27721
27722                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
27723
27724                 echo "bs: $bs, file_size $file_size"
27725                 aiocp -a $PAGE_SIZE -b $bs -s $file_size -f O_DIRECT \
27726                         $DIR/$tfile.1 $DIR/$tfile.2 &
27727                 pid_dio1=$!
27728                 # Buffered I/O with similar but not the same block size
27729                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
27730                         conv=notrunc &
27731                 pid_bio2=$!
27732                 wait $pid_dio1
27733                 rc1=$?
27734                 wait $pid_bio2
27735                 rc2=$?
27736                 if (( rc1 != 0 )); then
27737                         error "aio copy 1 w/bsize $bs failed: $rc1"
27738                 fi
27739                 if (( rc2 != 0 )); then
27740                         error "buffered copy 2 w/bsize $bs failed: $rc2"
27741                 fi
27742
27743                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
27744                         error "size incorrect"
27745                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
27746                         error "files differ, bsize $bs"
27747                 rm -f $DIR/$tfile.2
27748         done
27749 }
27750 run_test 398p "race aio with buffered i/o"
27751
27752 test_398q()
27753 {
27754         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
27755
27756         local stripe_size=$((1024 * 1024)) #1 MiB
27757         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
27758         local file_size=$((25 * stripe_size))
27759
27760         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
27761         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
27762
27763         # Just a bit bigger than the largest size in the test set below
27764         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
27765                 error "buffered i/o to create file failed"
27766
27767         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
27768                 $((stripe_size * 4)); do
27769
27770                 echo "bs: $bs, file_size $file_size"
27771                 dd if=$DIR/$tfile.1 bs=$((bs *2 )) of=$DIR/$tfile.2 \
27772                         conv=notrunc oflag=direct iflag=direct &
27773                 pid_dio1=$!
27774                 # Buffered I/O with similar but not the same block size
27775                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
27776                         conv=notrunc &
27777                 pid_bio2=$!
27778                 wait $pid_dio1
27779                 rc1=$?
27780                 wait $pid_bio2
27781                 rc2=$?
27782                 if (( rc1 != 0 )); then
27783                         error "dio copy 1 w/bsize $bs failed: $rc1"
27784                 fi
27785                 if (( rc2 != 0 )); then
27786                         error "buffered copy 2 w/bsize $bs failed: $rc2"
27787                 fi
27788
27789                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
27790                         error "size incorrect"
27791                 diff $DIR/$tfile.1 $DIR/$tfile.2 ||
27792                         error "files differ, bsize $bs"
27793         done
27794
27795         rm -f $DIR/$tfile*
27796 }
27797 run_test 398q "race dio with buffered i/o"
27798
27799 test_fake_rw() {
27800         local read_write=$1
27801         if [ "$read_write" = "write" ]; then
27802                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
27803         elif [ "$read_write" = "read" ]; then
27804                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
27805         else
27806                 error "argument error"
27807         fi
27808
27809         # turn off debug for performance testing
27810         local saved_debug=$($LCTL get_param -n debug)
27811         $LCTL set_param debug=0
27812
27813         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27814
27815         # get ost1 size - $FSNAME-OST0000
27816         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
27817         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
27818         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
27819
27820         if [ "$read_write" = "read" ]; then
27821                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
27822         fi
27823
27824         local start_time=$(date +%s.%N)
27825         $dd_cmd bs=1M count=$blocks oflag=sync ||
27826                 error "real dd $read_write error"
27827         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
27828
27829         if [ "$read_write" = "write" ]; then
27830                 rm -f $DIR/$tfile
27831         fi
27832
27833         # define OBD_FAIL_OST_FAKE_RW           0x238
27834         do_facet ost1 $LCTL set_param fail_loc=0x238
27835
27836         local start_time=$(date +%s.%N)
27837         $dd_cmd bs=1M count=$blocks oflag=sync ||
27838                 error "fake dd $read_write error"
27839         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
27840
27841         if [ "$read_write" = "write" ]; then
27842                 # verify file size
27843                 cancel_lru_locks osc
27844                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
27845                         error "$tfile size not $blocks MB"
27846         fi
27847         do_facet ost1 $LCTL set_param fail_loc=0
27848
27849         echo "fake $read_write $duration_fake vs. normal $read_write" \
27850                 "$duration in seconds"
27851         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
27852                 error_not_in_vm "fake write is slower"
27853
27854         $LCTL set_param -n debug="$saved_debug"
27855         rm -f $DIR/$tfile
27856 }
27857 test_399a() { # LU-7655 for OST fake write
27858         remote_ost_nodsh && skip "remote OST with nodsh"
27859
27860         test_fake_rw write
27861 }
27862 run_test 399a "fake write should not be slower than normal write"
27863
27864 test_399b() { # LU-8726 for OST fake read
27865         remote_ost_nodsh && skip "remote OST with nodsh"
27866         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
27867                 skip_env "ldiskfs only test"
27868         fi
27869
27870         test_fake_rw read
27871 }
27872 run_test 399b "fake read should not be slower than normal read"
27873
27874 test_400a() { # LU-1606, was conf-sanity test_74
27875         if ! which $CC > /dev/null 2>&1; then
27876                 skip_env "$CC is not installed"
27877         fi
27878
27879         local extra_flags=''
27880         local out=$TMP/$tfile
27881         local prefix=/usr/include/lustre
27882         local prog
27883
27884         # Oleg removes .c files in his test rig so test if any c files exist
27885         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
27886                 skip_env "Needed .c test files are missing"
27887
27888         if ! [[ -d $prefix ]]; then
27889                 # Assume we're running in tree and fixup the include path.
27890                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
27891                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
27892                 extra_flags+=" -L$LUSTRE/utils/.libs"
27893         fi
27894
27895         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
27896                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
27897                         error "client api broken"
27898         done
27899         rm -f $out
27900 }
27901 run_test 400a "Lustre client api program can compile and link"
27902
27903 test_400b() { # LU-1606, LU-5011
27904         local header
27905         local out=$TMP/$tfile
27906         local prefix=/usr/include/linux/lustre
27907
27908         # We use a hard coded prefix so that this test will not fail
27909         # when run in tree. There are headers in lustre/include/lustre/
27910         # that are not packaged (like lustre_idl.h) and have more
27911         # complicated include dependencies (like config.h and lnet/types.h).
27912         # Since this test about correct packaging we just skip them when
27913         # they don't exist (see below) rather than try to fixup cppflags.
27914
27915         if ! which $CC > /dev/null 2>&1; then
27916                 skip_env "$CC is not installed"
27917         fi
27918
27919         for header in $prefix/*.h; do
27920                 if ! [[ -f "$header" ]]; then
27921                         continue
27922                 fi
27923
27924                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
27925                         continue # lustre_ioctl.h is internal header
27926                 fi
27927
27928                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
27929                         error "cannot compile '$header'"
27930         done
27931         rm -f $out
27932 }
27933 run_test 400b "packaged headers can be compiled"
27934
27935 test_401a() { #LU-7437
27936         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
27937         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
27938
27939         #count the number of parameters by "list_param -R"
27940         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
27941         #count the number of parameters by listing proc files
27942         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
27943         echo "proc_dirs='$proc_dirs'"
27944         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
27945         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
27946                       sort -u | wc -l)
27947
27948         [ $params -eq $procs ] ||
27949                 error "found $params parameters vs. $procs proc files"
27950
27951         # test the list_param -D option only returns directories
27952         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
27953         #count the number of parameters by listing proc directories
27954         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
27955                 sort -u | wc -l)
27956
27957         [ $params -eq $procs ] ||
27958                 error "found $params parameters vs. $procs proc files"
27959 }
27960 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
27961
27962 test_401b() {
27963         # jobid_var may not allow arbitrary values, so use jobid_name
27964         # if available
27965         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27966                 local testname=jobid_name tmp='testing%p'
27967         else
27968                 local testname=jobid_var tmp=testing
27969         fi
27970
27971         local save=$($LCTL get_param -n $testname)
27972
27973         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
27974                 error "no error returned when setting bad parameters"
27975
27976         local jobid_new=$($LCTL get_param -n foe $testname baz)
27977         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
27978
27979         $LCTL set_param -n fog=bam $testname=$save bat=fog
27980         local jobid_old=$($LCTL get_param -n foe $testname bag)
27981         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
27982 }
27983 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
27984
27985 test_401c() {
27986         # jobid_var may not allow arbitrary values, so use jobid_name
27987         # if available
27988         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27989                 local testname=jobid_name
27990         else
27991                 local testname=jobid_var
27992         fi
27993
27994         local jobid_var_old=$($LCTL get_param -n $testname)
27995         local jobid_var_new
27996
27997         $LCTL set_param $testname= &&
27998                 error "no error returned for 'set_param a='"
27999
28000         jobid_var_new=$($LCTL get_param -n $testname)
28001         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
28002                 error "$testname was changed by setting without value"
28003
28004         $LCTL set_param $testname &&
28005                 error "no error returned for 'set_param a'"
28006
28007         jobid_var_new=$($LCTL get_param -n $testname)
28008         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
28009                 error "$testname was changed by setting without value"
28010 }
28011 run_test 401c "Verify 'lctl set_param' without value fails in either format."
28012
28013 test_401d() {
28014         # jobid_var may not allow arbitrary values, so use jobid_name
28015         # if available
28016         if $LCTL list_param jobid_name > /dev/null 2>&1; then
28017                 local testname=jobid_name new_value='foo=bar%p'
28018         else
28019                 local testname=jobid_var new_valuie=foo=bar
28020         fi
28021
28022         local jobid_var_old=$($LCTL get_param -n $testname)
28023         local jobid_var_new
28024
28025         $LCTL set_param $testname=$new_value ||
28026                 error "'set_param a=b' did not accept a value containing '='"
28027
28028         jobid_var_new=$($LCTL get_param -n $testname)
28029         [[ "$jobid_var_new" == "$new_value" ]] ||
28030                 error "'set_param a=b' failed on a value containing '='"
28031
28032         # Reset the $testname to test the other format
28033         $LCTL set_param $testname=$jobid_var_old
28034         jobid_var_new=$($LCTL get_param -n $testname)
28035         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
28036                 error "failed to reset $testname"
28037
28038         $LCTL set_param $testname $new_value ||
28039                 error "'set_param a b' did not accept a value containing '='"
28040
28041         jobid_var_new=$($LCTL get_param -n $testname)
28042         [[ "$jobid_var_new" == "$new_value" ]] ||
28043                 error "'set_param a b' failed on a value containing '='"
28044
28045         $LCTL set_param $testname $jobid_var_old
28046         jobid_var_new=$($LCTL get_param -n $testname)
28047         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
28048                 error "failed to reset $testname"
28049 }
28050 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
28051
28052 test_401e() { # LU-14779
28053         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
28054                 error "lctl list_param MGC* failed"
28055         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
28056         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
28057                 error "lctl get_param lru_size failed"
28058 }
28059 run_test 401e "verify 'lctl get_param' works with NID in parameter"
28060
28061 test_402() {
28062         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
28063         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
28064                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
28065         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
28066                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
28067                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
28068         remote_mds_nodsh && skip "remote MDS with nodsh"
28069
28070         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
28071 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
28072         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
28073         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
28074                 echo "Touch failed - OK"
28075 }
28076 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
28077
28078 test_403() {
28079         local file1=$DIR/$tfile.1
28080         local file2=$DIR/$tfile.2
28081         local tfile=$TMP/$tfile
28082
28083         rm -f $file1 $file2 $tfile
28084
28085         touch $file1
28086         ln $file1 $file2
28087
28088         # 30 sec OBD_TIMEOUT in ll_getattr()
28089         # right before populating st_nlink
28090         $LCTL set_param fail_loc=0x80001409
28091         stat -c %h $file1 > $tfile &
28092
28093         # create an alias, drop all locks and reclaim the dentry
28094         < $file2
28095         cancel_lru_locks mdc
28096         cancel_lru_locks osc
28097         sysctl -w vm.drop_caches=2
28098
28099         wait
28100
28101         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
28102
28103         rm -f $tfile $file1 $file2
28104 }
28105 run_test 403 "i_nlink should not drop to zero due to aliasing"
28106
28107 test_404() { # LU-6601
28108         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
28109                 skip "Need server version newer than 2.8.52"
28110         remote_mds_nodsh && skip "remote MDS with nodsh"
28111
28112         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
28113                 awk '/osp .*-osc-MDT/ { print $4}')
28114
28115         local osp
28116         for osp in $mosps; do
28117                 echo "Deactivate: " $osp
28118                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
28119                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
28120                         awk -vp=$osp '$4 == p { print $2 }')
28121                 [ $stat = IN ] || {
28122                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
28123                         error "deactivate error"
28124                 }
28125                 echo "Activate: " $osp
28126                 do_facet $SINGLEMDS $LCTL --device %$osp activate
28127                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
28128                         awk -vp=$osp '$4 == p { print $2 }')
28129                 [ $stat = UP ] || {
28130                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
28131                         error "activate error"
28132                 }
28133         done
28134 }
28135 run_test 404 "validate manual {de}activated works properly for OSPs"
28136
28137 test_405() {
28138         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
28139         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
28140                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
28141                         skip "Layout swap lock is not supported"
28142
28143         check_swap_layouts_support
28144         check_swap_layout_no_dom $DIR
28145
28146         test_mkdir $DIR/$tdir
28147         swap_lock_test -d $DIR/$tdir ||
28148                 error "One layout swap locked test failed"
28149 }
28150 run_test 405 "Various layout swap lock tests"
28151
28152 test_406() {
28153         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
28154         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
28155         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
28156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28157         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
28158                 skip "Need MDS version at least 2.8.50"
28159
28160         local def_stripe_size=$($LFS getstripe -S $MOUNT)
28161         local test_pool=$TESTNAME
28162
28163         pool_add $test_pool || error "pool_add failed"
28164         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
28165                 error "pool_add_targets failed"
28166
28167         save_layout_restore_at_exit $MOUNT
28168
28169         # parent set default stripe count only, child will stripe from both
28170         # parent and fs default
28171         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
28172                 error "setstripe $MOUNT failed"
28173         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
28174         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
28175         for i in $(seq 10); do
28176                 local f=$DIR/$tdir/$tfile.$i
28177                 touch $f || error "touch failed"
28178                 local count=$($LFS getstripe -c $f)
28179                 [ $count -eq $OSTCOUNT ] ||
28180                         error "$f stripe count $count != $OSTCOUNT"
28181                 local offset=$($LFS getstripe -i $f)
28182                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
28183                 local size=$($LFS getstripe -S $f)
28184                 [ $size -eq $((def_stripe_size * 2)) ] ||
28185                         error "$f stripe size $size != $((def_stripe_size * 2))"
28186                 local pool=$($LFS getstripe -p $f)
28187                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
28188         done
28189
28190         # change fs default striping, delete parent default striping, now child
28191         # will stripe from new fs default striping only
28192         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
28193                 error "change $MOUNT default stripe failed"
28194         $LFS setstripe -c 0 $DIR/$tdir ||
28195                 error "delete $tdir default stripe failed"
28196         for i in $(seq 11 20); do
28197                 local f=$DIR/$tdir/$tfile.$i
28198                 touch $f || error "touch $f failed"
28199                 local count=$($LFS getstripe -c $f)
28200                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
28201                 local offset=$($LFS getstripe -i $f)
28202                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
28203                 local size=$($LFS getstripe -S $f)
28204                 [ $size -eq $def_stripe_size ] ||
28205                         error "$f stripe size $size != $def_stripe_size"
28206                 local pool=$($LFS getstripe -p $f)
28207                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
28208         done
28209
28210         unlinkmany $DIR/$tdir/$tfile. 1 20
28211
28212         local f=$DIR/$tdir/$tfile
28213         pool_remove_all_targets $test_pool $f
28214         pool_remove $test_pool $f
28215 }
28216 run_test 406 "DNE support fs default striping"
28217
28218 test_407() {
28219         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
28220         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
28221                 skip "Need MDS version at least 2.8.55"
28222         remote_mds_nodsh && skip "remote MDS with nodsh"
28223
28224         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
28225                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
28226         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
28227                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
28228         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
28229
28230         #define OBD_FAIL_DT_TXN_STOP    0x2019
28231         for idx in $(seq $MDSCOUNT); do
28232                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
28233         done
28234         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
28235         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
28236                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
28237         true
28238 }
28239 run_test 407 "transaction fail should cause operation fail"
28240
28241 test_408() {
28242         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
28243
28244         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
28245         lctl set_param fail_loc=0x8000040a
28246         # let ll_prepare_partial_page() fail
28247         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
28248
28249         rm -f $DIR/$tfile
28250
28251         # create at least 100 unused inodes so that
28252         # shrink_icache_memory(0) should not return 0
28253         touch $DIR/$tfile-{0..100}
28254         rm -f $DIR/$tfile-{0..100}
28255         sync
28256
28257         echo 2 > /proc/sys/vm/drop_caches
28258 }
28259 run_test 408 "drop_caches should not hang due to page leaks"
28260
28261 test_409()
28262 {
28263         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28264
28265         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
28266         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
28267         touch $DIR/$tdir/guard || error "(2) Fail to create"
28268
28269         local PREFIX=$(str_repeat 'A' 128)
28270         echo "Create 1K hard links start at $(date)"
28271         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
28272                 error "(3) Fail to hard link"
28273
28274         echo "Links count should be right although linkEA overflow"
28275         stat $DIR/$tdir/guard || error "(4) Fail to stat"
28276         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
28277         [ $linkcount -eq 1001 ] ||
28278                 error "(5) Unexpected hard links count: $linkcount"
28279
28280         echo "List all links start at $(date)"
28281         ls -l $DIR/$tdir/foo > /dev/null ||
28282                 error "(6) Fail to list $DIR/$tdir/foo"
28283
28284         echo "Unlink hard links start at $(date)"
28285         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
28286                 error "(7) Fail to unlink"
28287         echo "Unlink hard links finished at $(date)"
28288 }
28289 run_test 409 "Large amount of cross-MDTs hard links on the same file"
28290
28291 test_410()
28292 {
28293         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
28294                 skip "Need client version at least 2.9.59"
28295         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
28296                 skip "Need MODULES build"
28297
28298         # Create a file, and stat it from the kernel
28299         local testfile=$DIR/$tfile
28300         touch $testfile
28301
28302         local run_id=$RANDOM
28303         local my_ino=$(stat --format "%i" $testfile)
28304
28305         # Try to insert the module. This will always fail as the
28306         # module is designed to not be inserted.
28307         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
28308             &> /dev/null
28309
28310         # Anything but success is a test failure
28311         dmesg | grep -q \
28312             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
28313             error "no inode match"
28314 }
28315 run_test 410 "Test inode number returned from kernel thread"
28316
28317 cleanup_test411_cgroup() {
28318         trap 0
28319         cat $1/memory.stat
28320         rmdir "$1"
28321 }
28322
28323 test_411a() {
28324         local cg_basedir=/sys/fs/cgroup/memory
28325         # LU-9966
28326         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
28327                 skip "no setup for cgroup"
28328
28329         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
28330                 error "test file creation failed"
28331         cancel_lru_locks osc
28332
28333         # Create a very small memory cgroup to force a slab allocation error
28334         local cgdir=$cg_basedir/osc_slab_alloc
28335         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
28336         trap "cleanup_test411_cgroup $cgdir" EXIT
28337         echo 2M > $cgdir/memory.kmem.limit_in_bytes
28338         echo 1M > $cgdir/memory.limit_in_bytes
28339
28340         # Should not LBUG, just be killed by oom-killer
28341         # dd will return 0 even allocation failure in some environment.
28342         # So don't check return value
28343         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
28344         cleanup_test411_cgroup $cgdir
28345
28346         return 0
28347 }
28348 run_test 411a "Slab allocation error with cgroup does not LBUG"
28349
28350 test_411b() {
28351         local cg_basedir=/sys/fs/cgroup/memory
28352         # LU-9966
28353         [ -e "$cg_basedir/memory.kmem.limit_in_bytes" ] ||
28354                 skip "no setup for cgroup"
28355         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
28356         # (x86) testing suggests we can't reliably avoid OOM with a 64M-256M
28357         # limit, so we have 384M in cgroup
28358         # (arm) this seems to hit OOM more often than x86, so 1024M
28359         if [[ $(uname -m) = aarch64 ]]; then
28360                 local memlimit_mb=1024
28361         else
28362                 local memlimit_mb=384
28363         fi
28364
28365         # Create a cgroup and set memory limit
28366         # (tfile is used as an easy way to get a recognizable cgroup name)
28367         local cgdir=$cg_basedir/$tfile
28368         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
28369         stack_trap "cleanup_test411_cgroup $cgdir" EXIT
28370         echo $((memlimit_mb * 1024 * 1024)) > $cgdir/memory.limit_in_bytes
28371
28372         echo "writing first file"
28373         # Write a file 4x the memory limit in size
28374         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=1M count=$((memlimit_mb * 4))" ||
28375                 error "(1) failed to write successfully"
28376
28377         sync
28378         cancel_lru_locks osc
28379
28380         rm -f $DIR/$tfile
28381         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
28382
28383         # Try writing at a larger block size
28384         # NB: if block size is >= 1/2 cgroup size, we sometimes get OOM killed
28385         # so test with 1/4 cgroup size (this seems reasonable to me - we do
28386         # need *some* memory to do IO in)
28387         echo "writing at larger block size"
28388         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=64M count=$((memlimit_mb * 4 / 128))" ||
28389                 error "(3) failed to write successfully"
28390
28391         sync
28392         cancel_lru_locks osc
28393         rm -f $DIR/$tfile
28394         $LFS setstripe -c 2 $DIR/$tfile.{1..4} || error "unable to setstripe"
28395
28396         # Try writing multiple files at once
28397         echo "writing multiple files"
28398         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.1 bs=32M count=$((memlimit_mb * 4 / 64))" &
28399         local pid1=$!
28400         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.2 bs=32M count=$((memlimit_mb * 4 / 64))" &
28401         local pid2=$!
28402         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.3 bs=32M count=$((memlimit_mb * 4 / 64))" &
28403         local pid3=$!
28404         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.4 bs=32M count=$((memlimit_mb * 4 / 64))" &
28405         local pid4=$!
28406
28407         wait $pid1
28408         local rc1=$?
28409         wait $pid2
28410         local rc2=$?
28411         wait $pid3
28412         local rc3=$?
28413         wait $pid4
28414         local rc4=$?
28415         if (( rc1 != 0)); then
28416                 error "error $rc1 writing to file from $pid1"
28417         fi
28418         if (( rc2 != 0)); then
28419                 error "error $rc2 writing to file from $pid2"
28420         fi
28421         if (( rc3 != 0)); then
28422                 error "error $rc3 writing to file from $pid3"
28423         fi
28424         if (( rc4 != 0)); then
28425                 error "error $rc4 writing to file from $pid4"
28426         fi
28427
28428         sync
28429         cancel_lru_locks osc
28430
28431         # These files can be large-ish (~1 GiB total), so delete them rather
28432         # than leave for later cleanup
28433         rm -f $DIR/$tfile.*
28434         return 0
28435 }
28436 run_test 411b "confirm Lustre can avoid OOM with reasonable cgroups limits"
28437
28438 test_412() {
28439         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
28440         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
28441                 skip "Need server version at least 2.10.55"
28442
28443         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
28444                 error "mkdir failed"
28445         $LFS getdirstripe $DIR/$tdir
28446         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
28447         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
28448                 error "expect $((MDSCOUT - 1)) get $stripe_index"
28449         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
28450         [ $stripe_count -eq 2 ] ||
28451                 error "expect 2 get $stripe_count"
28452
28453         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
28454
28455         local index
28456         local index2
28457
28458         # subdirs should be on the same MDT as parent
28459         for i in $(seq 0 $((MDSCOUNT - 1))); do
28460                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
28461                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
28462                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
28463                 (( index == i )) || error "mdt$i/sub on MDT$index"
28464         done
28465
28466         # stripe offset -1, ditto
28467         for i in {1..10}; do
28468                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
28469                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
28470                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
28471                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
28472                 (( index == index2 )) ||
28473                         error "qos$i on MDT$index, sub on MDT$index2"
28474         done
28475
28476         local testdir=$DIR/$tdir/inherit
28477
28478         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
28479         # inherit 2 levels
28480         for i in 1 2; do
28481                 testdir=$testdir/s$i
28482                 mkdir $testdir || error "mkdir $testdir failed"
28483                 index=$($LFS getstripe -m $testdir)
28484                 (( index == 1 )) ||
28485                         error "$testdir on MDT$index"
28486         done
28487
28488         # not inherit any more
28489         testdir=$testdir/s3
28490         mkdir $testdir || error "mkdir $testdir failed"
28491         getfattr -d -m dmv $testdir | grep dmv &&
28492                 error "default LMV set on $testdir" || true
28493 }
28494 run_test 412 "mkdir on specific MDTs"
28495
28496 TEST413_COUNT=${TEST413_COUNT:-200}
28497
28498 #
28499 # set_maxage() is used by test_413 only.
28500 # This is a helper function to set maxage. Does not return any value.
28501 # Input: maxage to set
28502 #
28503 set_maxage() {
28504         local lmv_qos_maxage
28505         local lod_qos_maxage
28506         local new_maxage=$1
28507
28508         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
28509         $LCTL set_param lmv.*.qos_maxage=$new_maxage
28510         stack_trap "$LCTL set_param \
28511                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
28512         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
28513                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
28514         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28515                 lod.*.mdt_qos_maxage=$new_maxage
28516         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28517                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
28518 }
28519
28520 generate_uneven_mdts() {
28521         local threshold=$1
28522         local ffree
28523         local bavail
28524         local max
28525         local min
28526         local max_index
28527         local min_index
28528         local tmp
28529         local i
28530
28531         echo
28532         echo "Check for uneven MDTs: "
28533
28534         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28535         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28536         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28537
28538         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28539         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28540         max_index=0
28541         min_index=0
28542         for ((i = 1; i < ${#ffree[@]}; i++)); do
28543                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28544                 if [ $tmp -gt $max ]; then
28545                         max=$tmp
28546                         max_index=$i
28547                 fi
28548                 if [ $tmp -lt $min ]; then
28549                         min=$tmp
28550                         min_index=$i
28551                 fi
28552         done
28553
28554         (( min > 0 )) || skip "low space on MDT$min_index"
28555         (( ${ffree[min_index]} > 0 )) ||
28556                 skip "no free files on MDT$min_index"
28557         (( ${ffree[min_index]} < 10000000 )) ||
28558                 skip "too many free files on MDT$min_index"
28559
28560         # Check if we need to generate uneven MDTs
28561         local diff=$(((max - min) * 100 / min))
28562         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
28563         local testdir # individual folder within $testdirp
28564         local start
28565         local cmd
28566
28567         # fallocate is faster to consume space on MDT, if available
28568         if check_fallocate_supported mds$((min_index + 1)); then
28569                 cmd="fallocate -l 128K "
28570         else
28571                 cmd="dd if=/dev/zero bs=128K count=1 of="
28572         fi
28573
28574         echo "using cmd $cmd"
28575         for (( i = 0; diff < threshold; i++ )); do
28576                 testdir=${testdirp}/$i
28577                 [ -d $testdir ] && continue
28578
28579                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
28580
28581                 mkdir -p $testdirp
28582                 # generate uneven MDTs, create till $threshold% diff
28583                 echo -n "weight diff=$diff% must be > $threshold% ..."
28584                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
28585                 $LFS mkdir -i $min_index $testdir ||
28586                         error "mkdir $testdir failed"
28587                 $LFS setstripe -E 1M -L mdt $testdir ||
28588                         error "setstripe $testdir failed"
28589                 start=$SECONDS
28590                 for (( f = 0; f < TEST413_COUNT; f++ )); do
28591                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
28592                 done
28593                 sync; sleep 1; sync
28594
28595                 # wait for QOS to update
28596                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
28597
28598                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
28599                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
28600                 max=$(((${ffree[max_index]} >> 8) *
28601                         (${bavail[max_index]} * bsize >> 16)))
28602                 min=$(((${ffree[min_index]} >> 8) *
28603                         (${bavail[min_index]} * bsize >> 16)))
28604                 (( min > 0 )) || skip "low space on MDT$min_index"
28605                 diff=$(((max - min) * 100 / min))
28606         done
28607
28608         echo "MDT filesfree available: ${ffree[*]}"
28609         echo "MDT blocks available: ${bavail[*]}"
28610         echo "weight diff=$diff%"
28611 }
28612
28613 test_qos_mkdir() {
28614         local mkdir_cmd=$1
28615         local stripe_count=$2
28616         local mdts=$(comma_list $(mdts_nodes))
28617
28618         local testdir
28619         local lmv_qos_prio_free
28620         local lmv_qos_threshold_rr
28621         local lod_qos_prio_free
28622         local lod_qos_threshold_rr
28623         local total
28624         local count
28625         local i
28626
28627         # @total is total directories created if it's testing plain
28628         # directories, otherwise it's total stripe object count for
28629         # striped directories test.
28630         # remote/striped directory unlinking is slow on zfs and may
28631         # timeout, test with fewer directories
28632         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
28633
28634         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
28635         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
28636         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
28637                 head -n1)
28638         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
28639         stack_trap "$LCTL set_param \
28640                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
28641         stack_trap "$LCTL set_param \
28642                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
28643
28644         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
28645                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
28646         lod_qos_prio_free=${lod_qos_prio_free%%%}
28647         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
28648                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
28649         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
28650         stack_trap "do_nodes $mdts $LCTL set_param \
28651                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
28652         stack_trap "do_nodes $mdts $LCTL set_param \
28653                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
28654
28655         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
28656         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
28657
28658         testdir=$DIR/$tdir-s$stripe_count/rr
28659
28660         local stripe_index=$($LFS getstripe -m $testdir)
28661         local test_mkdir_rr=true
28662
28663         getfattr -d -m dmv -e hex $testdir | grep dmv
28664         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
28665                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
28666                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
28667                         test_mkdir_rr=false
28668         fi
28669
28670         echo
28671         $test_mkdir_rr &&
28672                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
28673                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
28674
28675         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
28676         for (( i = 0; i < total / stripe_count; i++ )); do
28677                 eval $mkdir_cmd $testdir/subdir$i ||
28678                         error "$mkdir_cmd subdir$i failed"
28679         done
28680
28681         for (( i = 0; i < $MDSCOUNT; i++ )); do
28682                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
28683                 echo "$count directories created on MDT$i"
28684                 if $test_mkdir_rr; then
28685                         (( count == total / stripe_count / MDSCOUNT )) ||
28686                                 error "subdirs are not evenly distributed"
28687                 elif (( i == stripe_index )); then
28688                         (( count == total / stripe_count )) ||
28689                                 error "$count subdirs created on MDT$i"
28690                 else
28691                         (( count == 0 )) ||
28692                                 error "$count subdirs created on MDT$i"
28693                 fi
28694
28695                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
28696                         count=$($LFS getdirstripe $testdir/* |
28697                                 grep -c -P "^\s+$i\t")
28698                         echo "$count stripes created on MDT$i"
28699                         # deviation should < 5% of average
28700                         delta=$((count - total / MDSCOUNT))
28701                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
28702                                 error "stripes are not evenly distributed"
28703                 fi
28704         done
28705
28706         echo
28707         echo "Check for uneven MDTs: "
28708
28709         local ffree
28710         local bavail
28711         local max
28712         local min
28713         local max_index
28714         local min_index
28715         local tmp
28716
28717         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28718         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28719         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28720
28721         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28722         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28723         max_index=0
28724         min_index=0
28725         for ((i = 1; i < ${#ffree[@]}; i++)); do
28726                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28727                 if [ $tmp -gt $max ]; then
28728                         max=$tmp
28729                         max_index=$i
28730                 fi
28731                 if [ $tmp -lt $min ]; then
28732                         min=$tmp
28733                         min_index=$i
28734                 fi
28735         done
28736         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
28737
28738         (( min > 0 )) || skip "low space on MDT$min_index"
28739         (( ${ffree[min_index]} < 10000000 )) ||
28740                 skip "too many free files on MDT$min_index"
28741
28742         generate_uneven_mdts 120
28743
28744         echo "MDT filesfree available: ${ffree[*]}"
28745         echo "MDT blocks available: ${bavail[*]}"
28746         echo "weight diff=$(((max - min) * 100 / min))%"
28747         echo
28748         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
28749
28750         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
28751         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
28752         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
28753         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
28754         # decrease statfs age, so that it can be updated in time
28755         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
28756         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
28757
28758         sleep 1
28759
28760         testdir=$DIR/$tdir-s$stripe_count/qos
28761
28762         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
28763         for (( i = 0; i < total / stripe_count; i++ )); do
28764                 eval $mkdir_cmd $testdir/subdir$i ||
28765                         error "$mkdir_cmd subdir$i failed"
28766         done
28767
28768         max=0
28769         for (( i = 0; i < $MDSCOUNT; i++ )); do
28770                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
28771                 (( count > max )) && max=$count
28772                 echo "$count directories created on MDT$i : curmax=$max"
28773         done
28774
28775         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
28776
28777         # D-value should > 10% of average
28778         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
28779                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
28780
28781         # ditto for stripes
28782         if (( stripe_count > 1 )); then
28783                 max=0
28784                 for (( i = 0; i < $MDSCOUNT; i++ )); do
28785                         count=$($LFS getdirstripe $testdir/* |
28786                                 grep -c -P "^\s+$i\t")
28787                         (( count > max )) && max=$count
28788                         echo "$count stripes created on MDT$i"
28789                 done
28790
28791                 min=$($LFS getdirstripe $testdir/* |
28792                         grep -c -P "^\s+$min_index\t")
28793                 (( max - min > total / MDSCOUNT / 10 )) ||
28794                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
28795         fi
28796 }
28797
28798 most_full_mdt() {
28799         local ffree
28800         local bavail
28801         local bsize
28802         local min
28803         local min_index
28804         local tmp
28805
28806         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28807         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28808         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28809
28810         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28811         min_index=0
28812         for ((i = 1; i < ${#ffree[@]}; i++)); do
28813                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28814                 (( tmp < min )) && min=$tmp && min_index=$i
28815         done
28816
28817         echo -n $min_index
28818 }
28819
28820 test_413a() {
28821         [ $MDSCOUNT -lt 2 ] &&
28822                 skip "We need at least 2 MDTs for this test"
28823
28824         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
28825                 skip "Need server version at least 2.12.52"
28826
28827         local stripe_max=$((MDSCOUNT - 1))
28828         local stripe_count
28829
28830         # let caller set maxage for latest result
28831         set_maxage 1
28832
28833         # fill MDT unevenly
28834         generate_uneven_mdts 120
28835
28836         # test 4-stripe directory at most, otherwise it's too slow
28837         # We are being very defensive. Although Autotest uses 4 MDTs.
28838         # We make sure stripe_max does not go over 4.
28839         (( stripe_max > 4 )) && stripe_max=4
28840         # unlinking striped directory is slow on zfs, and may timeout, only test
28841         # plain directory
28842         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
28843         for stripe_count in $(seq 1 $stripe_max); do
28844                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
28845                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
28846                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
28847                         error "mkdir failed"
28848                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
28849         done
28850 }
28851 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
28852
28853 test_413b() {
28854         [ $MDSCOUNT -lt 2 ] &&
28855                 skip "We need at least 2 MDTs for this test"
28856
28857         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
28858                 skip "Need server version at least 2.12.52"
28859
28860         local stripe_max=$((MDSCOUNT - 1))
28861         local testdir
28862         local stripe_count
28863
28864         # let caller set maxage for latest result
28865         set_maxage 1
28866
28867         # fill MDT unevenly
28868         generate_uneven_mdts 120
28869
28870         # test 4-stripe directory at most, otherwise it's too slow
28871         # We are being very defensive. Although Autotest uses 4 MDTs.
28872         # We make sure stripe_max does not go over 4.
28873         (( stripe_max > 4 )) && stripe_max=4
28874         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
28875         for stripe_count in $(seq 1 $stripe_max); do
28876                 testdir=$DIR/$tdir-s$stripe_count
28877                 mkdir $testdir || error "mkdir $testdir failed"
28878                 mkdir $testdir/rr || error "mkdir rr failed"
28879                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
28880                         error "mkdir qos failed"
28881                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
28882                         $testdir/rr || error "setdirstripe rr failed"
28883                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
28884                         error "setdirstripe failed"
28885                 test_qos_mkdir "mkdir" $stripe_count
28886         done
28887 }
28888 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
28889
28890 test_413c() {
28891         (( $MDSCOUNT >= 2 )) ||
28892                 skip "We need at least 2 MDTs for this test"
28893
28894         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
28895                 skip "Need server version at least 2.14.51"
28896
28897         local testdir
28898         local inherit
28899         local inherit_rr
28900         local lmv_qos_maxage
28901         local lod_qos_maxage
28902
28903         # let caller set maxage for latest result
28904         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
28905         $LCTL set_param lmv.*.qos_maxage=1
28906         stack_trap "$LCTL set_param \
28907                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
28908         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
28909                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
28910         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28911                 lod.*.mdt_qos_maxage=1
28912         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28913                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
28914
28915         # fill MDT unevenly
28916         generate_uneven_mdts 120
28917
28918         testdir=$DIR/${tdir}-s1
28919         mkdir $testdir || error "mkdir $testdir failed"
28920         mkdir $testdir/rr || error "mkdir rr failed"
28921         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
28922         # default max_inherit is -1, default max_inherit_rr is 0
28923         $LFS setdirstripe -D -c 1 $testdir/rr ||
28924                 error "setdirstripe rr failed"
28925         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
28926                 error "setdirstripe qos failed"
28927         test_qos_mkdir "mkdir" 1
28928
28929         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
28930         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
28931         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
28932         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
28933         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
28934
28935         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
28936         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
28937         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
28938         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
28939         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
28940         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
28941         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
28942                 error "level2 shouldn't have default LMV" || true
28943 }
28944 run_test 413c "mkdir with default LMV max inherit rr"
28945
28946 test_413d() {
28947         (( MDSCOUNT >= 2 )) ||
28948                 skip "We need at least 2 MDTs for this test"
28949
28950         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
28951                 skip "Need server version at least 2.14.51"
28952
28953         local lmv_qos_threshold_rr
28954
28955         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
28956                 head -n1)
28957         stack_trap "$LCTL set_param \
28958                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
28959
28960         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
28961         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
28962         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
28963                 error "$tdir shouldn't have default LMV"
28964         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
28965                 error "mkdir sub failed"
28966
28967         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
28968
28969         (( count == 100 )) || error "$count subdirs on MDT0"
28970 }
28971 run_test 413d "inherit ROOT default LMV"
28972
28973 test_413e() {
28974         (( MDSCOUNT >= 2 )) ||
28975                 skip "We need at least 2 MDTs for this test"
28976         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
28977                 skip "Need server version at least 2.14.55"
28978
28979         local testdir=$DIR/$tdir
28980         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
28981         local max_inherit
28982         local sub_max_inherit
28983
28984         mkdir -p $testdir || error "failed to create $testdir"
28985
28986         # set default max-inherit to -1 if stripe count is 0 or 1
28987         $LFS setdirstripe -D -c 1 $testdir ||
28988                 error "failed to set default LMV"
28989         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
28990         (( max_inherit == -1 )) ||
28991                 error "wrong max_inherit value $max_inherit"
28992
28993         # set default max_inherit to a fixed value if stripe count is not 0 or 1
28994         $LFS setdirstripe -D -c -1 $testdir ||
28995                 error "failed to set default LMV"
28996         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
28997         (( max_inherit > 0 )) ||
28998                 error "wrong max_inherit value $max_inherit"
28999
29000         # and the subdir will decrease the max_inherit by 1
29001         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
29002         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
29003         (( sub_max_inherit == max_inherit - 1)) ||
29004                 error "wrong max-inherit of subdir $sub_max_inherit"
29005
29006         # check specified --max-inherit and warning message
29007         stack_trap "rm -f $tmpfile"
29008         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
29009                 error "failed to set default LMV"
29010         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
29011         (( max_inherit == -1 )) ||
29012                 error "wrong max_inherit value $max_inherit"
29013
29014         # check the warning messages
29015         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
29016                 error "failed to detect warning string"
29017         fi
29018 }
29019 run_test 413e "check default max-inherit value"
29020
29021 test_fs_dmv_inherit()
29022 {
29023         local testdir=$DIR/$tdir
29024
29025         local count
29026         local inherit
29027         local inherit_rr
29028
29029         for i in 1 2; do
29030                 mkdir $testdir || error "mkdir $testdir failed"
29031                 count=$($LFS getdirstripe -D -c $testdir)
29032                 (( count == 1 )) ||
29033                         error "$testdir default LMV count mismatch $count != 1"
29034                 inherit=$($LFS getdirstripe -D -X $testdir)
29035                 (( inherit == 3 - i )) ||
29036                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
29037                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
29038                 (( inherit_rr == 3 - i )) ||
29039                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
29040                 testdir=$testdir/sub
29041         done
29042
29043         mkdir $testdir || error "mkdir $testdir failed"
29044         count=$($LFS getdirstripe -D -c $testdir)
29045         (( count == 0 )) ||
29046                 error "$testdir default LMV count not zero: $count"
29047 }
29048
29049 test_413f() {
29050         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
29051
29052         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
29053                 skip "Need server version at least 2.14.55"
29054
29055         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
29056                 error "dump $DIR default LMV failed"
29057         stack_trap "setfattr --restore=$TMP/dmv.ea"
29058
29059         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
29060                 error "set $DIR default LMV failed"
29061
29062         test_fs_dmv_inherit
29063 }
29064 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
29065
29066 test_413g() {
29067         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
29068
29069         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
29070         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
29071                 error "dump $DIR default LMV failed"
29072         stack_trap "setfattr --restore=$TMP/dmv.ea"
29073
29074         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
29075                 error "set $DIR default LMV failed"
29076
29077         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
29078                 error "mount $MOUNT2 failed"
29079         stack_trap "umount_client $MOUNT2"
29080
29081         local saved_DIR=$DIR
29082
29083         export DIR=$MOUNT2
29084
29085         stack_trap "export DIR=$saved_DIR"
29086
29087         # first check filesystem-wide default LMV inheritance
29088         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
29089
29090         # then check subdirs are spread to all MDTs
29091         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
29092
29093         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
29094
29095         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
29096 }
29097 run_test 413g "enforce ROOT default LMV on subdir mount"
29098
29099 test_413h() {
29100         (( MDSCOUNT >= 2 )) ||
29101                 skip "We need at least 2 MDTs for this test"
29102
29103         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
29104                 skip "Need server version at least 2.15.50.6"
29105
29106         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
29107
29108         stack_trap "$LCTL set_param \
29109                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
29110         $LCTL set_param lmv.*.qos_maxage=1
29111
29112         local depth=5
29113         local rr_depth=4
29114         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
29115         local count=$((MDSCOUNT * 20))
29116
29117         generate_uneven_mdts 50
29118
29119         mkdir -p $dir || error "mkdir $dir failed"
29120         stack_trap "rm -rf $dir"
29121         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
29122                 --max-inherit-rr=$rr_depth $dir
29123
29124         for ((d=0; d < depth + 2; d++)); do
29125                 log "dir=$dir:"
29126                 for ((sub=0; sub < count; sub++)); do
29127                         mkdir $dir/d$sub
29128                 done
29129                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
29130                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
29131                 # subdirs within $rr_depth should be created round-robin
29132                 if (( d < rr_depth )); then
29133                         (( ${num[0]} != count )) ||
29134                                 error "all objects created on MDT ${num[1]}"
29135                 fi
29136
29137                 dir=$dir/d0
29138         done
29139 }
29140 run_test 413h "don't stick to parent for round-robin dirs"
29141
29142 test_413i() {
29143         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
29144
29145         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
29146                 skip "Need server version at least 2.14.55"
29147
29148         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
29149                 error "dump $DIR default LMV failed"
29150         stack_trap "setfattr --restore=$TMP/dmv.ea"
29151
29152         local testdir=$DIR/$tdir
29153         local def_max_rr=1
29154         local def_max=3
29155         local count
29156
29157         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
29158                 --max-inherit-rr=$def_max_rr $DIR ||
29159                 error "set $DIR default LMV failed"
29160
29161         for i in $(seq 2 3); do
29162                 def_max=$((def_max - 1))
29163                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
29164
29165                 mkdir $testdir
29166                 # RR is decremented and keeps zeroed once exhausted
29167                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
29168                 (( count == def_max_rr )) ||
29169                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
29170
29171                 # max-inherit is decremented
29172                 count=$($LFS getdirstripe -D --max-inherit $testdir)
29173                 (( count == def_max )) ||
29174                         error_noexit "$testdir: max-inherit $count != $def_max"
29175
29176                 testdir=$testdir/d$i
29177         done
29178
29179         # d3 is the last inherited from ROOT, no inheritance anymore
29180         # i.e. no the default layout anymore
29181         mkdir -p $testdir/d4/d5
29182         count=$($LFS getdirstripe -D --max-inherit $testdir)
29183         (( count == -1 )) ||
29184                 error_noexit "$testdir: max-inherit $count != -1"
29185
29186         local p_count=$($LFS getdirstripe -i $testdir)
29187
29188         for i in $(seq 4 5); do
29189                 testdir=$testdir/d$i
29190
29191                 # the root default layout is not applied once exhausted
29192                 count=$($LFS getdirstripe -i $testdir)
29193                 (( count == p_count )) ||
29194                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
29195         done
29196
29197         $LFS setdirstripe -i 0 $DIR/d2
29198         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
29199         (( count == -1 )) ||
29200                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
29201 }
29202 run_test 413i "check default layout inheritance"
29203
29204 test_413j()
29205 {
29206         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
29207
29208         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
29209         $LFS setdirstripe -D -c2 --max-inherit=2 $DIR/$tdir ||
29210                 error "setdirstripe $tdir failed"
29211
29212         local value=$(getfattr -n trusted.dmv $DIR/$tdir | \
29213                       grep "trusted.dmv" |sed -e 's/[^=]\+=//')
29214
29215         mkdir -p $DIR/$tdir/sub || error "mkdir sub failed"
29216         # setfattr dmv calls setdirstripe -D
29217         setfattr -n trusted.dmv -v $value $DIR/$tdir/sub ||
29218                 error "setfattr sub failed"
29219         local value2=$(getfattr -n trusted.dmv $DIR/$tdir/sub | \
29220                        grep "trusted.dmv" |sed -e 's/[^=]\+=//')
29221
29222         [ $value == $value2 ] || error "dmv mismatch"
29223
29224         (( MDS1_VERSION >= $(version_code 2.15.58) )) || return 0
29225
29226         # do not allow remove dmv by setfattr -x
29227         do_nodes $(comma_list $(mdts_nodes)) \
29228                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=0"
29229         setfattr -x trusted.dmv $DIR/$tdir/sub || error "setfattr sub failed"
29230         getfattr -n trusted.dmv $DIR/$tdir/sub || error "default LMV deleted"
29231
29232         # allow remove dmv by setfattr -x
29233         do_nodes $(comma_list $(mdts_nodes)) \
29234                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=1"
29235         setfattr -x trusted.dmv $DIR/$tdir/sub || error "setfattr sub failed"
29236         getfattr -n trusted.dmv $DIR/$tdir/sub && error "default LMV exists"
29237         do_nodes $(comma_list $(mdts_nodes)) \
29238                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=0"
29239 }
29240 run_test 413j "set default LMV by setxattr"
29241
29242 test_413z() {
29243         local pids=""
29244         local subdir
29245         local pid
29246
29247         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
29248                 unlinkmany $subdir/f. $TEST413_COUNT &
29249                 pids="$pids $!"
29250         done
29251
29252         for pid in $pids; do
29253                 wait $pid
29254         done
29255
29256         true
29257 }
29258 run_test 413z "413 test cleanup"
29259
29260 test_414() {
29261 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
29262         $LCTL set_param fail_loc=0x80000521
29263         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
29264         rm -f $DIR/$tfile
29265 }
29266 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
29267
29268 test_415() {
29269         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
29270         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
29271                 skip "Need server version at least 2.11.52"
29272
29273         # LU-11102
29274         local total=500
29275         local max=120
29276
29277         # this test may be slow on ZFS
29278         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
29279
29280         # though this test is designed for striped directory, let's test normal
29281         # directory too since lock is always saved as CoS lock.
29282         test_mkdir $DIR/$tdir || error "mkdir $tdir"
29283         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
29284         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
29285         # if looping with ONLY_REPEAT, wait for previous deletions to finish
29286         wait_delete_completed_mds
29287
29288         # run a loop without concurrent touch to measure rename duration.
29289         # only for test debug/robustness, NOT part of COS functional test.
29290         local start_time=$SECONDS
29291         for ((i = 0; i < total; i++)); do
29292                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
29293                         > /dev/null
29294         done
29295         local baseline=$((SECONDS - start_time))
29296         echo "rename $total files without 'touch' took $baseline sec"
29297
29298         (
29299                 while true; do
29300                         touch $DIR/$tdir
29301                 done
29302         ) &
29303         local setattr_pid=$!
29304
29305         # rename files back to original name so unlinkmany works
29306         start_time=$SECONDS
29307         for ((i = 0; i < total; i++)); do
29308                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
29309                         > /dev/null
29310         done
29311         local duration=$((SECONDS - start_time))
29312
29313         kill -9 $setattr_pid
29314
29315         echo "rename $total files with 'touch' took $duration sec"
29316         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
29317         (( duration <= max )) ||
29318                 error_not_in_vm "rename took $duration > $max sec"
29319 }
29320 run_test 415 "lock revoke is not missing"
29321
29322 test_416() {
29323         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
29324                 skip "Need server version at least 2.11.55"
29325
29326         # define OBD_FAIL_OSD_TXN_START    0x19a
29327         do_facet mds1 lctl set_param fail_loc=0x19a
29328
29329         lfs mkdir -c $MDSCOUNT $DIR/$tdir
29330
29331         true
29332 }
29333 run_test 416 "transaction start failure won't cause system hung"
29334
29335 cleanup_417() {
29336         trap 0
29337         do_nodes $(comma_list $(mdts_nodes)) \
29338                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
29339         do_nodes $(comma_list $(mdts_nodes)) \
29340                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
29341         do_nodes $(comma_list $(mdts_nodes)) \
29342                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
29343 }
29344
29345 test_417() {
29346         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
29347         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
29348                 skip "Need MDS version at least 2.11.56"
29349
29350         trap cleanup_417 RETURN EXIT
29351
29352         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
29353         do_nodes $(comma_list $(mdts_nodes)) \
29354                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
29355         $LFS migrate -m 0 $DIR/$tdir.1 &&
29356                 error "migrate dir $tdir.1 should fail"
29357
29358         do_nodes $(comma_list $(mdts_nodes)) \
29359                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
29360         $LFS mkdir -i 1 $DIR/$tdir.2 &&
29361                 error "create remote dir $tdir.2 should fail"
29362
29363         do_nodes $(comma_list $(mdts_nodes)) \
29364                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
29365         $LFS mkdir -c 2 $DIR/$tdir.3 &&
29366                 error "create striped dir $tdir.3 should fail"
29367         true
29368 }
29369 run_test 417 "disable remote dir, striped dir and dir migration"
29370
29371 # Checks that the outputs of df [-i] and lfs df [-i] match
29372 #
29373 # usage: check_lfs_df <blocks | inodes> <mountpoint>
29374 check_lfs_df() {
29375         local dir=$2
29376         local inodes
29377         local df_out
29378         local lfs_df_out
29379         local count
29380         local passed=false
29381
29382         # blocks or inodes
29383         [ "$1" == "blocks" ] && inodes= || inodes="-i"
29384
29385         for count in {1..100}; do
29386                 do_nodes "$CLIENTS" \
29387                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
29388                 sync; sleep 0.2
29389
29390                 # read the lines of interest
29391                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
29392                         error "df $inodes $dir | tail -n +2 failed"
29393                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
29394                         error "lfs df $inodes $dir | grep summary: failed"
29395
29396                 # skip first substrings of each output as they are different
29397                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
29398                 # compare the two outputs
29399                 passed=true
29400                 #  skip "available" on MDT until LU-13997 is fixed.
29401                 #for i in {1..5}; do
29402                 for i in 1 2 4 5; do
29403                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
29404                 done
29405                 $passed && break
29406         done
29407
29408         if ! $passed; then
29409                 df -P $inodes $dir
29410                 echo
29411                 lfs df $inodes $dir
29412                 error "df and lfs df $1 output mismatch: "      \
29413                       "df ${inodes}: ${df_out[*]}, "            \
29414                       "lfs df ${inodes}: ${lfs_df_out[*]}"
29415         fi
29416 }
29417
29418 test_418() {
29419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29420
29421         local dir=$DIR/$tdir
29422         local numfiles=$((RANDOM % 4096 + 2))
29423         local numblocks=$((RANDOM % 256 + 1))
29424
29425         wait_delete_completed
29426         test_mkdir $dir
29427
29428         # check block output
29429         check_lfs_df blocks $dir
29430         # check inode output
29431         check_lfs_df inodes $dir
29432
29433         # create a single file and retest
29434         echo "Creating a single file and testing"
29435         createmany -o $dir/$tfile- 1 &>/dev/null ||
29436                 error "creating 1 file in $dir failed"
29437         check_lfs_df blocks $dir
29438         check_lfs_df inodes $dir
29439
29440         # create a random number of files
29441         echo "Creating $((numfiles - 1)) files and testing"
29442         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
29443                 error "creating $((numfiles - 1)) files in $dir failed"
29444
29445         # write a random number of blocks to the first test file
29446         echo "Writing $numblocks 4K blocks and testing"
29447         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
29448                 count=$numblocks &>/dev/null ||
29449                 error "dd to $dir/${tfile}-0 failed"
29450
29451         # retest
29452         check_lfs_df blocks $dir
29453         check_lfs_df inodes $dir
29454
29455         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
29456                 error "unlinking $numfiles files in $dir failed"
29457 }
29458 run_test 418 "df and lfs df outputs match"
29459
29460 test_419()
29461 {
29462         local dir=$DIR/$tdir
29463
29464         mkdir -p $dir
29465         touch $dir/file
29466
29467         cancel_lru_locks mdc
29468
29469         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
29470         $LCTL set_param fail_loc=0x1410
29471         cat $dir/file
29472         $LCTL set_param fail_loc=0
29473         rm -rf $dir
29474 }
29475 run_test 419 "Verify open file by name doesn't crash kernel"
29476
29477 test_420()
29478 {
29479         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
29480                 skip "Need MDS version at least 2.12.53"
29481
29482         local SAVE_UMASK=$(umask)
29483         local dir=$DIR/$tdir
29484         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
29485
29486         mkdir -p $dir
29487         umask 0000
29488         mkdir -m03777 $dir/testdir
29489         ls -dn $dir/testdir
29490         # Need to remove trailing '.' when SELinux is enabled
29491         local dirperms=$(ls -dn $dir/testdir |
29492                          awk '{ sub(/\.$/, "", $1); print $1}')
29493         [ $dirperms == "drwxrwsrwt" ] ||
29494                 error "incorrect perms on $dir/testdir"
29495
29496         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
29497                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
29498         ls -n $dir/testdir/testfile
29499         local fileperms=$(ls -n $dir/testdir/testfile |
29500                           awk '{ sub(/\.$/, "", $1); print $1}')
29501         [ $fileperms == "-rwxr-xr-x" ] ||
29502                 error "incorrect perms on $dir/testdir/testfile"
29503
29504         umask $SAVE_UMASK
29505 }
29506 run_test 420 "clear SGID bit on non-directories for non-members"
29507
29508 test_421a() {
29509         local cnt
29510         local fid1
29511         local fid2
29512
29513         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29514                 skip "Need MDS version at least 2.12.54"
29515
29516         test_mkdir $DIR/$tdir
29517         createmany -o $DIR/$tdir/f 3
29518         cnt=$(ls -1 $DIR/$tdir | wc -l)
29519         [ $cnt != 3 ] && error "unexpected #files: $cnt"
29520
29521         fid1=$(lfs path2fid $DIR/$tdir/f1)
29522         fid2=$(lfs path2fid $DIR/$tdir/f2)
29523         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
29524
29525         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
29526         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
29527
29528         cnt=$(ls -1 $DIR/$tdir | wc -l)
29529         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
29530
29531         rm -f $DIR/$tdir/f3 || error "can't remove f3"
29532         createmany -o $DIR/$tdir/f 3
29533         cnt=$(ls -1 $DIR/$tdir | wc -l)
29534         [ $cnt != 3 ] && error "unexpected #files: $cnt"
29535
29536         fid1=$(lfs path2fid $DIR/$tdir/f1)
29537         fid2=$(lfs path2fid $DIR/$tdir/f2)
29538         echo "remove using fsname $FSNAME"
29539         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
29540
29541         cnt=$(ls -1 $DIR/$tdir | wc -l)
29542         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
29543 }
29544 run_test 421a "simple rm by fid"
29545
29546 test_421b() {
29547         local cnt
29548         local FID1
29549         local FID2
29550
29551         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29552                 skip "Need MDS version at least 2.12.54"
29553
29554         test_mkdir $DIR/$tdir
29555         createmany -o $DIR/$tdir/f 3
29556         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
29557         MULTIPID=$!
29558
29559         FID1=$(lfs path2fid $DIR/$tdir/f1)
29560         FID2=$(lfs path2fid $DIR/$tdir/f2)
29561         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
29562
29563         kill -USR1 $MULTIPID
29564         wait
29565
29566         cnt=$(ls $DIR/$tdir | wc -l)
29567         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
29568 }
29569 run_test 421b "rm by fid on open file"
29570
29571 test_421c() {
29572         local cnt
29573         local FIDS
29574
29575         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29576                 skip "Need MDS version at least 2.12.54"
29577
29578         test_mkdir $DIR/$tdir
29579         createmany -o $DIR/$tdir/f 3
29580         touch $DIR/$tdir/$tfile
29581         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
29582         cnt=$(ls -1 $DIR/$tdir | wc -l)
29583         [ $cnt != 184 ] && error "unexpected #files: $cnt"
29584
29585         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
29586         $LFS rmfid $DIR $FID1 || error "rmfid failed"
29587
29588         cnt=$(ls $DIR/$tdir | wc -l)
29589         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
29590 }
29591 run_test 421c "rm by fid against hardlinked files"
29592
29593 test_421d() {
29594         local cnt
29595         local FIDS
29596
29597         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29598                 skip "Need MDS version at least 2.12.54"
29599
29600         test_mkdir $DIR/$tdir
29601         createmany -o $DIR/$tdir/f 4097
29602         cnt=$(ls -1 $DIR/$tdir | wc -l)
29603         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
29604
29605         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
29606         $LFS rmfid $DIR $FIDS || error "rmfid failed"
29607
29608         cnt=$(ls $DIR/$tdir | wc -l)
29609         rm -rf $DIR/$tdir
29610         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
29611 }
29612 run_test 421d "rmfid en masse"
29613
29614 test_421e() {
29615         local cnt
29616         local FID
29617
29618         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
29619         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29620                 skip "Need MDS version at least 2.12.54"
29621
29622         mkdir -p $DIR/$tdir
29623         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
29624         createmany -o $DIR/$tdir/striped_dir/f 512
29625         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
29626         [ $cnt != 512 ] && error "unexpected #files: $cnt"
29627
29628         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
29629                 sed "s/[/][^:]*://g")
29630         $LFS rmfid $DIR $FIDS || error "rmfid failed"
29631
29632         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
29633         rm -rf $DIR/$tdir
29634         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
29635 }
29636 run_test 421e "rmfid in DNE"
29637
29638 test_421f() {
29639         local cnt
29640         local FID
29641
29642         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29643                 skip "Need MDS version at least 2.12.54"
29644
29645         test_mkdir $DIR/$tdir
29646         touch $DIR/$tdir/f
29647         cnt=$(ls -1 $DIR/$tdir | wc -l)
29648         [ $cnt != 1 ] && error "unexpected #files: $cnt"
29649
29650         FID=$(lfs path2fid $DIR/$tdir/f)
29651         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
29652         # rmfid should fail
29653         cnt=$(ls -1 $DIR/$tdir | wc -l)
29654         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
29655
29656         chmod a+rw $DIR/$tdir
29657         ls -la $DIR/$tdir
29658         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
29659         # rmfid should fail
29660         cnt=$(ls -1 $DIR/$tdir | wc -l)
29661         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
29662
29663         rm -f $DIR/$tdir/f
29664         $RUNAS touch $DIR/$tdir/f
29665         FID=$(lfs path2fid $DIR/$tdir/f)
29666         echo "rmfid as root"
29667         $LFS rmfid $DIR $FID || error "rmfid as root failed"
29668         cnt=$(ls -1 $DIR/$tdir | wc -l)
29669         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
29670
29671         rm -f $DIR/$tdir/f
29672         $RUNAS touch $DIR/$tdir/f
29673         cnt=$(ls -1 $DIR/$tdir | wc -l)
29674         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
29675         FID=$(lfs path2fid $DIR/$tdir/f)
29676         # rmfid w/o user_fid2path mount option should fail
29677         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
29678         cnt=$(ls -1 $DIR/$tdir | wc -l)
29679         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
29680
29681         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
29682         stack_trap "rmdir $tmpdir"
29683         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
29684                 error "failed to mount client'"
29685         stack_trap "umount_client $tmpdir"
29686
29687         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
29688         # rmfid should succeed
29689         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
29690         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
29691
29692         # rmfid shouldn't allow to remove files due to dir's permission
29693         chmod a+rwx $tmpdir/$tdir
29694         touch $tmpdir/$tdir/f
29695         ls -la $tmpdir/$tdir
29696         FID=$(lfs path2fid $tmpdir/$tdir/f)
29697         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
29698         return 0
29699 }
29700 run_test 421f "rmfid checks permissions"
29701
29702 test_421g() {
29703         local cnt
29704         local FIDS
29705
29706         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
29707         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29708                 skip "Need MDS version at least 2.12.54"
29709
29710         mkdir -p $DIR/$tdir
29711         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
29712         createmany -o $DIR/$tdir/striped_dir/f 512
29713         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
29714         [ $cnt != 512 ] && error "unexpected #files: $cnt"
29715
29716         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
29717                 sed "s/[/][^:]*://g")
29718
29719         rm -f $DIR/$tdir/striped_dir/f1*
29720         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
29721         removed=$((512 - cnt))
29722
29723         # few files have been just removed, so we expect
29724         # rmfid to fail on their fids
29725         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
29726         [ $removed != $errors ] && error "$errors != $removed"
29727
29728         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
29729         rm -rf $DIR/$tdir
29730         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
29731 }
29732 run_test 421g "rmfid to return errors properly"
29733
29734 test_421h() {
29735         local mount_other
29736         local mount_ret
29737         local rmfid_ret
29738         local old_fid
29739         local fidA
29740         local fidB
29741         local fidC
29742         local fidD
29743
29744         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
29745                 skip "Need MDS version at least 2.15.53"
29746
29747         test_mkdir $DIR/$tdir
29748         test_mkdir $DIR/$tdir/subdir
29749         touch $DIR/$tdir/subdir/file0
29750         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
29751         echo File $DIR/$tdir/subdir/file0 FID $old_fid
29752         rm -f $DIR/$tdir/subdir/file0
29753         touch $DIR/$tdir/subdir/fileA
29754         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
29755         echo File $DIR/$tdir/subdir/fileA FID $fidA
29756         touch $DIR/$tdir/subdir/fileB
29757         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
29758         echo File $DIR/$tdir/subdir/fileB FID $fidB
29759         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
29760         touch $DIR/$tdir/subdir/fileC
29761         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
29762         echo File $DIR/$tdir/subdir/fileC FID $fidC
29763         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
29764         touch $DIR/$tdir/fileD
29765         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
29766         echo File $DIR/$tdir/fileD FID $fidD
29767
29768         # mount another client mount point with subdirectory mount
29769         export FILESET=/$tdir/subdir
29770         mount_other=${MOUNT}_other
29771         mount_client $mount_other ${MOUNT_OPTS}
29772         mount_ret=$?
29773         export FILESET=""
29774         (( mount_ret == 0 )) || error "mount $mount_other failed"
29775
29776         echo Removing FIDs:
29777         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
29778         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
29779         rmfid_ret=$?
29780
29781         umount_client $mount_other || error "umount $mount_other failed"
29782
29783         (( rmfid_ret != 0 )) || error "rmfid should have failed"
29784
29785         # fileA should have been deleted
29786         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
29787
29788         # fileB should have been deleted
29789         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
29790
29791         # fileC should not have been deleted, fid also exists outside of fileset
29792         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
29793
29794         # fileD should not have been deleted, it exists outside of fileset
29795         stat $DIR/$tdir/fileD || error "fileD deleted"
29796 }
29797 run_test 421h "rmfid with fileset mount"
29798
29799 test_422() {
29800         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
29801         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
29802         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
29803         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
29804         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
29805
29806         local amc=$(at_max_get client)
29807         local amo=$(at_max_get mds1)
29808         local timeout=`lctl get_param -n timeout`
29809
29810         at_max_set 0 client
29811         at_max_set 0 mds1
29812
29813 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
29814         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
29815                         fail_val=$(((2*timeout + 10)*1000))
29816         touch $DIR/$tdir/d3/file &
29817         sleep 2
29818 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
29819         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
29820                         fail_val=$((2*timeout + 5))
29821         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
29822         local pid=$!
29823         sleep 1
29824         kill -9 $pid
29825         sleep $((2 * timeout))
29826         echo kill $pid
29827         kill -9 $pid
29828         lctl mark touch
29829         touch $DIR/$tdir/d2/file3
29830         touch $DIR/$tdir/d2/file4
29831         touch $DIR/$tdir/d2/file5
29832
29833         wait
29834         at_max_set $amc client
29835         at_max_set $amo mds1
29836
29837         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
29838         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
29839                 error "Watchdog is always throttled"
29840 }
29841 run_test 422 "kill a process with RPC in progress"
29842
29843 stat_test() {
29844     df -h $MOUNT &
29845     df -h $MOUNT &
29846     df -h $MOUNT &
29847     df -h $MOUNT &
29848     df -h $MOUNT &
29849     df -h $MOUNT &
29850 }
29851
29852 test_423() {
29853     local _stats
29854     # ensure statfs cache is expired
29855     sleep 2;
29856
29857     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
29858     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
29859
29860     return 0
29861 }
29862 run_test 423 "statfs should return a right data"
29863
29864 test_424() {
29865 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | CFS_FAIL_ONCE
29866         $LCTL set_param fail_loc=0x80000522
29867         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
29868         rm -f $DIR/$tfile
29869 }
29870 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
29871
29872 test_425() {
29873         test_mkdir -c -1 $DIR/$tdir
29874         $LFS setstripe -c -1 $DIR/$tdir
29875
29876         lru_resize_disable "" 100
29877         stack_trap "lru_resize_enable" EXIT
29878
29879         sleep 5
29880
29881         for i in $(seq $((MDSCOUNT * 125))); do
29882                 local t=$DIR/$tdir/$tfile_$i
29883
29884                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
29885                         error_noexit "Create file $t"
29886         done
29887         stack_trap "rm -rf $DIR/$tdir" EXIT
29888
29889         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
29890                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
29891                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
29892
29893                 [ $lock_count -le $lru_size ] ||
29894                         error "osc lock count $lock_count > lru size $lru_size"
29895         done
29896
29897         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
29898                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
29899                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
29900
29901                 [ $lock_count -le $lru_size ] ||
29902                         error "mdc lock count $lock_count > lru size $lru_size"
29903         done
29904 }
29905 run_test 425 "lock count should not exceed lru size"
29906
29907 test_426() {
29908         splice-test -r $DIR/$tfile
29909         splice-test -rd $DIR/$tfile
29910         splice-test $DIR/$tfile
29911         splice-test -d $DIR/$tfile
29912 }
29913 run_test 426 "splice test on Lustre"
29914
29915 test_427() {
29916         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
29917         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
29918                 skip "Need MDS version at least 2.12.4"
29919         local log
29920
29921         mkdir $DIR/$tdir
29922         mkdir $DIR/$tdir/1
29923         mkdir $DIR/$tdir/2
29924         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
29925         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
29926
29927         $LFS getdirstripe $DIR/$tdir/1/dir
29928
29929         #first setfattr for creating updatelog
29930         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
29931
29932 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
29933         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
29934         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
29935         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
29936
29937         sleep 2
29938         fail mds2
29939         wait_recovery_complete mds2 $((2*TIMEOUT))
29940
29941         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
29942         echo $log | grep "get update log failed" &&
29943                 error "update log corruption is detected" || true
29944 }
29945 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
29946
29947 test_428() {
29948         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29949         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
29950                               awk '/^max_cached_mb/ { print $2 }')
29951         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
29952
29953         $LCTL set_param -n llite.*.max_cached_mb=64
29954
29955         mkdir $DIR/$tdir
29956         $LFS setstripe -c 1 $DIR/$tdir
29957         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
29958         stack_trap "rm -f $DIR/$tdir/$tfile.*"
29959         #test write
29960         for f in $(seq 4); do
29961                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
29962         done
29963         wait
29964
29965         cancel_lru_locks osc
29966         # Test read
29967         for f in $(seq 4); do
29968                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
29969         done
29970         wait
29971 }
29972 run_test 428 "large block size IO should not hang"
29973
29974 test_429() { # LU-7915 / LU-10948
29975         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
29976         local testfile=$DIR/$tfile
29977         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
29978         local new_flag=1
29979         local first_rpc
29980         local second_rpc
29981         local third_rpc
29982
29983         $LCTL get_param $ll_opencache_threshold_count ||
29984                 skip "client does not have opencache parameter"
29985
29986         set_opencache $new_flag
29987         stack_trap "restore_opencache"
29988         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
29989                 error "enable opencache failed"
29990         touch $testfile
29991         # drop MDC DLM locks
29992         cancel_lru_locks mdc
29993         # clear MDC RPC stats counters
29994         $LCTL set_param $mdc_rpcstats=clear
29995
29996         # According to the current implementation, we need to run 3 times
29997         # open & close file to verify if opencache is enabled correctly.
29998         # 1st, RPCs are sent for lookup/open and open handle is released on
29999         #      close finally.
30000         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
30001         #      so open handle won't be released thereafter.
30002         # 3rd, No RPC is sent out.
30003         $MULTIOP $testfile oc || error "multiop failed"
30004         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
30005         echo "1st: $first_rpc RPCs in flight"
30006
30007         $MULTIOP $testfile oc || error "multiop failed"
30008         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
30009         echo "2nd: $second_rpc RPCs in flight"
30010
30011         $MULTIOP $testfile oc || error "multiop failed"
30012         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
30013         echo "3rd: $third_rpc RPCs in flight"
30014
30015         #verify no MDC RPC is sent
30016         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
30017 }
30018 run_test 429 "verify if opencache flag on client side does work"
30019
30020 lseek_test_430() {
30021         local offset
30022         local file=$1
30023
30024         # data at [200K, 400K)
30025         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
30026                 error "256K->512K dd fails"
30027         # data at [2M, 3M)
30028         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
30029                 error "2M->3M dd fails"
30030         # data at [4M, 5M)
30031         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
30032                 error "4M->5M dd fails"
30033         echo "Data at 256K...512K, 2M...3M and 4M...5M"
30034         # start at first component hole #1
30035         printf "Seeking hole from 1000 ... "
30036         offset=$(lseek_test -l 1000 $file)
30037         echo $offset
30038         [[ $offset == 1000 ]] || error "offset $offset != 1000"
30039         printf "Seeking data from 1000 ... "
30040         offset=$(lseek_test -d 1000 $file)
30041         echo $offset
30042         [[ $offset == 262144 ]] || error "offset $offset != 262144"
30043
30044         # start at first component data block
30045         printf "Seeking hole from 300000 ... "
30046         offset=$(lseek_test -l 300000 $file)
30047         echo $offset
30048         [[ $offset == 524288 ]] || error "offset $offset != 524288"
30049         printf "Seeking data from 300000 ... "
30050         offset=$(lseek_test -d 300000 $file)
30051         echo $offset
30052         [[ $offset == 300000 ]] || error "offset $offset != 300000"
30053
30054         # start at the first component but beyond end of object size
30055         printf "Seeking hole from 1000000 ... "
30056         offset=$(lseek_test -l 1000000 $file)
30057         echo $offset
30058         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
30059         printf "Seeking data from 1000000 ... "
30060         offset=$(lseek_test -d 1000000 $file)
30061         echo $offset
30062         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
30063
30064         # start at second component stripe 2 (empty file)
30065         printf "Seeking hole from 1500000 ... "
30066         offset=$(lseek_test -l 1500000 $file)
30067         echo $offset
30068         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
30069         printf "Seeking data from 1500000 ... "
30070         offset=$(lseek_test -d 1500000 $file)
30071         echo $offset
30072         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
30073
30074         # start at second component stripe 1 (all data)
30075         printf "Seeking hole from 3000000 ... "
30076         offset=$(lseek_test -l 3000000 $file)
30077         echo $offset
30078         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
30079         printf "Seeking data from 3000000 ... "
30080         offset=$(lseek_test -d 3000000 $file)
30081         echo $offset
30082         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
30083
30084         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
30085                 error "2nd dd fails"
30086         echo "Add data block at 640K...1280K"
30087
30088         # start at before new data block, in hole
30089         printf "Seeking hole from 600000 ... "
30090         offset=$(lseek_test -l 600000 $file)
30091         echo $offset
30092         [[ $offset == 600000 ]] || error "offset $offset != 600000"
30093         printf "Seeking data from 600000 ... "
30094         offset=$(lseek_test -d 600000 $file)
30095         echo $offset
30096         [[ $offset == 655360 ]] || error "offset $offset != 655360"
30097
30098         # start at the first component new data block
30099         printf "Seeking hole from 1000000 ... "
30100         offset=$(lseek_test -l 1000000 $file)
30101         echo $offset
30102         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
30103         printf "Seeking data from 1000000 ... "
30104         offset=$(lseek_test -d 1000000 $file)
30105         echo $offset
30106         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
30107
30108         # start at second component stripe 2, new data
30109         printf "Seeking hole from 1200000 ... "
30110         offset=$(lseek_test -l 1200000 $file)
30111         echo $offset
30112         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
30113         printf "Seeking data from 1200000 ... "
30114         offset=$(lseek_test -d 1200000 $file)
30115         echo $offset
30116         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
30117
30118         # start beyond file end
30119         printf "Using offset > filesize ... "
30120         lseek_test -l 4000000 $file && error "lseek should fail"
30121         printf "Using offset > filesize ... "
30122         lseek_test -d 4000000 $file && error "lseek should fail"
30123
30124         printf "Done\n\n"
30125 }
30126
30127 test_430a() {
30128         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
30129                 skip "MDT does not support SEEK_HOLE"
30130
30131         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
30132                 skip "OST does not support SEEK_HOLE"
30133
30134         local file=$DIR/$tdir/$tfile
30135
30136         mkdir -p $DIR/$tdir
30137
30138         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
30139         # OST stripe #1 will have continuous data at [1M, 3M)
30140         # OST stripe #2 is empty
30141         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
30142         lseek_test_430 $file
30143         rm $file
30144         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
30145         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
30146         lseek_test_430 $file
30147         rm $file
30148         $LFS setstripe -c2 -S 512K $file
30149         echo "Two stripes, stripe size 512K"
30150         lseek_test_430 $file
30151         rm $file
30152         # FLR with stale mirror
30153         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
30154                        -N -c2 -S 1M $file
30155         echo "Mirrored file:"
30156         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
30157         echo "Plain 2 stripes 1M"
30158         lseek_test_430 $file
30159         rm $file
30160 }
30161 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
30162
30163 test_430b() {
30164         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
30165                 skip "OST does not support SEEK_HOLE"
30166
30167         local offset
30168         local file=$DIR/$tdir/$tfile
30169
30170         mkdir -p $DIR/$tdir
30171         # Empty layout lseek should fail
30172         $MCREATE $file
30173         # seek from 0
30174         printf "Seeking hole from 0 ... "
30175         lseek_test -l 0 $file && error "lseek should fail"
30176         printf "Seeking data from 0 ... "
30177         lseek_test -d 0 $file && error "lseek should fail"
30178         rm $file
30179
30180         # 1M-hole file
30181         $LFS setstripe -E 1M -c2 -E eof $file
30182         $TRUNCATE $file 1048576
30183         printf "Seeking hole from 1000000 ... "
30184         offset=$(lseek_test -l 1000000 $file)
30185         echo $offset
30186         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
30187         printf "Seeking data from 1000000 ... "
30188         lseek_test -d 1000000 $file && error "lseek should fail"
30189         rm $file
30190
30191         # full component followed by non-inited one
30192         $LFS setstripe -E 1M -c2 -E eof $file
30193         dd if=/dev/urandom of=$file bs=1M count=1
30194         printf "Seeking hole from 1000000 ... "
30195         offset=$(lseek_test -l 1000000 $file)
30196         echo $offset
30197         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
30198         printf "Seeking hole from 1048576 ... "
30199         lseek_test -l 1048576 $file && error "lseek should fail"
30200         # init second component and truncate back
30201         echo "123" >> $file
30202         $TRUNCATE $file 1048576
30203         printf "Seeking hole from 1000000 ... "
30204         offset=$(lseek_test -l 1000000 $file)
30205         echo $offset
30206         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
30207         printf "Seeking hole from 1048576 ... "
30208         lseek_test -l 1048576 $file && error "lseek should fail"
30209         # boundary checks for big values
30210         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
30211         offset=$(lseek_test -d 0 $file.10g)
30212         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
30213         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
30214         offset=$(lseek_test -d 0 $file.100g)
30215         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
30216         return 0
30217 }
30218 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
30219
30220 test_430c() {
30221         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
30222                 skip "OST does not support SEEK_HOLE"
30223
30224         local file=$DIR/$tdir/$tfile
30225         local start
30226
30227         mkdir -p $DIR/$tdir
30228         stack_trap "rm -f $file $file.tmp"
30229         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M || error "dd failed"
30230
30231         # cp version 8.33+ prefers lseek over fiemap
30232         local ver=$(cp --version | awk '{ print $4; exit; }')
30233
30234         echo "cp $ver installed"
30235         if (( $(version_code $ver) >= $(version_code 8.33) )); then
30236                 start=$SECONDS
30237                 time cp -v $file $file.tmp || error "cp $file failed"
30238                 (( SECONDS - start < 5 )) || {
30239                         strace cp $file $file.tmp |&
30240                                 grep -E "open|read|seek|FIEMAP" |
30241                                 grep -A 100 $file
30242                         error "cp: too long runtime $((SECONDS - start))"
30243                 }
30244         else
30245                 echo "cp test skipped due to $ver < 8.33"
30246         fi
30247
30248         # tar version 1.29+ supports SEEK_HOLE/DATA
30249         ver=$(tar --version | awk '{ print $4; exit; }')
30250         echo "tar $ver installed"
30251         if (( $(version_code $ver) >= $(version_code 1.29) )); then
30252                 start=$SECONDS
30253                 time tar cvf $file.tmp --sparse $file || error "tar $file error"
30254                 (( SECONDS - start < 5 )) || {
30255                         strace tar cf $file.tmp --sparse $file |&
30256                                 grep -E "open|read|seek|FIEMAP" |
30257                                 grep -A 100 $file
30258                         error "tar: too long runtime $((SECONDS - start))"
30259                 }
30260         else
30261                 echo "tar test skipped due to $ver < 1.29"
30262         fi
30263 }
30264 run_test 430c "lseek: external tools check"
30265
30266 test_431() { # LU-14187
30267         local file=$DIR/$tdir/$tfile
30268
30269         mkdir -p $DIR/$tdir
30270         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
30271         dd if=/dev/urandom of=$file bs=4k count=1
30272         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
30273         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
30274         #define OBD_FAIL_OST_RESTART_IO 0x251
30275         do_facet ost1 "$LCTL set_param fail_loc=0x251"
30276         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
30277         cp $file $file.0
30278         cancel_lru_locks
30279         sync_all_data
30280         echo 3 > /proc/sys/vm/drop_caches
30281         diff  $file $file.0 || error "data diff"
30282 }
30283 run_test 431 "Restart transaction for IO"
30284
30285 cleanup_test_432() {
30286         do_facet mgs $LCTL nodemap_activate 0
30287         wait_nm_sync active
30288 }
30289
30290 test_432() {
30291         local tmpdir=$TMP/dir432
30292
30293         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
30294                 skip "Need MDS version at least 2.14.52"
30295
30296         stack_trap cleanup_test_432 EXIT
30297         mkdir $DIR/$tdir
30298         mkdir $tmpdir
30299
30300         do_facet mgs $LCTL nodemap_activate 1
30301         wait_nm_sync active
30302         do_facet mgs $LCTL nodemap_modify --name default \
30303                 --property admin --value 1
30304         do_facet mgs $LCTL nodemap_modify --name default \
30305                 --property trusted --value 1
30306         cancel_lru_locks mdc
30307         wait_nm_sync default admin_nodemap
30308         wait_nm_sync default trusted_nodemap
30309
30310         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
30311                grep -ci "Operation not permitted") -ne 0 ]; then
30312                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
30313         fi
30314 }
30315 run_test 432 "mv dir from outside Lustre"
30316
30317 test_433() {
30318         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30319
30320         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
30321                 skip "inode cache not supported"
30322
30323         $LCTL set_param llite.*.inode_cache=0
30324         stack_trap "$LCTL set_param llite.*.inode_cache=1"
30325
30326         local count=256
30327         local before
30328         local after
30329
30330         cancel_lru_locks mdc
30331         test_mkdir $DIR/$tdir || error "mkdir $tdir"
30332         createmany -m $DIR/$tdir/f $count
30333         createmany -d $DIR/$tdir/d $count
30334         ls -l $DIR/$tdir > /dev/null
30335         stack_trap "rm -rf $DIR/$tdir"
30336
30337         before=$(num_objects)
30338         cancel_lru_locks mdc
30339         after=$(num_objects)
30340
30341         # sometimes even @before is less than 2 * count
30342         while (( before - after < count )); do
30343                 sleep 1
30344                 after=$(num_objects)
30345                 wait=$((wait + 1))
30346                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
30347                 if (( wait > 60 )); then
30348                         error "inode slab grew from $before to $after"
30349                 fi
30350         done
30351
30352         echo "lustre_inode_cache $before objs before lock cancel, $after after"
30353 }
30354 run_test 433 "ldlm lock cancel releases dentries and inodes"
30355
30356 test_434() {
30357         local file
30358         local getxattr_count
30359         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
30360         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30361
30362         [[ $(getenforce) == "Disabled" ]] ||
30363                 skip "lsm selinux module have to be disabled for this test"
30364
30365         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
30366                 error "fail to create $DIR/$tdir/ on MDT0000"
30367
30368         touch $DIR/$tdir/$tfile-{001..100}
30369
30370         # disable the xattr cache
30371         save_lustre_params client "llite.*.xattr_cache" > $p
30372         lctl set_param llite.*.xattr_cache=0
30373         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
30374
30375         # clear clients mdc stats
30376         clear_stats $mdc_stat_param ||
30377                 error "fail to clear stats on mdc MDT0000"
30378
30379         for file in $DIR/$tdir/$tfile-{001..100}; do
30380                 getfattr -n security.selinux $file |&
30381                         grep -q "Operation not supported" ||
30382                         error "getxattr on security.selinux should return EOPNOTSUPP"
30383         done
30384
30385         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
30386         (( getxattr_count < 100 )) ||
30387                 error "client sent $getxattr_count getxattr RPCs to the MDS"
30388 }
30389 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
30390
30391 test_440() {
30392         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
30393                 source $LUSTRE/scripts/bash-completion/lustre
30394         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
30395                 source /usr/share/bash-completion/completions/lustre
30396         else
30397                 skip "bash completion scripts not found"
30398         fi
30399
30400         local lctl_completions
30401         local lfs_completions
30402
30403         lctl_completions=$(_lustre_cmds lctl)
30404         if [[ ! $lctl_completions =~ "get_param" ]]; then
30405                 error "lctl bash completion failed"
30406         fi
30407
30408         lfs_completions=$(_lustre_cmds lfs)
30409         if [[ ! $lfs_completions =~ "setstripe" ]]; then
30410                 error "lfs bash completion failed"
30411         fi
30412 }
30413 run_test 440 "bash completion for lfs, lctl"
30414
30415 test_442() {
30416         local pid1
30417         local pid2
30418         mkdir -p $DIR/$tdir
30419         multiop $DIR/$tdir/$tfile.1 O_w1 & pid1=$!
30420         multiop $DIR/$tdir/$tfile.1 O_w1 & pid2=$!
30421         sleep 1
30422         touch $DIR/$tdir/$tfile.2
30423         $LFS swap_layouts -n $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
30424         $LCTL set_param fail_loc=0x1430
30425         kill -USR1 $pid1
30426         sleep 1
30427         kill -USR1 $pid2
30428         wait
30429 }
30430 run_test 442 "truncate vs read/write should not panic"
30431
30432 prep_801() {
30433         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
30434         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
30435                 skip "Need server version at least 2.9.55"
30436
30437         start_full_debug_logging
30438 }
30439
30440 post_801() {
30441         stop_full_debug_logging
30442 }
30443
30444 barrier_stat() {
30445         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
30446                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
30447                            awk '/The barrier for/ { print $7 }')
30448                 echo $st
30449         else
30450                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
30451                 echo \'$st\'
30452         fi
30453 }
30454
30455 barrier_expired() {
30456         local expired
30457
30458         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
30459                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
30460                           awk '/will be expired/ { print $7 }')
30461         else
30462                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
30463         fi
30464
30465         echo $expired
30466 }
30467
30468 test_801a() {
30469         prep_801
30470
30471         echo "Start barrier_freeze at: $(date)"
30472         #define OBD_FAIL_BARRIER_DELAY          0x2202
30473         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
30474         # Do not reduce barrier time - See LU-11873
30475         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
30476
30477         sleep 2
30478         local b_status=$(barrier_stat)
30479         echo "Got barrier status at: $(date)"
30480         [ "$b_status" = "'freezing_p1'" ] ||
30481                 error "(1) unexpected barrier status $b_status"
30482
30483         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
30484         wait
30485         b_status=$(barrier_stat)
30486         [ "$b_status" = "'frozen'" ] ||
30487                 error "(2) unexpected barrier status $b_status"
30488
30489         local expired=$(barrier_expired)
30490         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
30491         sleep $((expired + 3))
30492
30493         b_status=$(barrier_stat)
30494         [ "$b_status" = "'expired'" ] ||
30495                 error "(3) unexpected barrier status $b_status"
30496
30497         # Do not reduce barrier time - See LU-11873
30498         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
30499                 error "(4) fail to freeze barrier"
30500
30501         b_status=$(barrier_stat)
30502         [ "$b_status" = "'frozen'" ] ||
30503                 error "(5) unexpected barrier status $b_status"
30504
30505         echo "Start barrier_thaw at: $(date)"
30506         #define OBD_FAIL_BARRIER_DELAY          0x2202
30507         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
30508         do_facet mgs $LCTL barrier_thaw $FSNAME &
30509
30510         sleep 2
30511         b_status=$(barrier_stat)
30512         echo "Got barrier status at: $(date)"
30513         [ "$b_status" = "'thawing'" ] ||
30514                 error "(6) unexpected barrier status $b_status"
30515
30516         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
30517         wait
30518         b_status=$(barrier_stat)
30519         [ "$b_status" = "'thawed'" ] ||
30520                 error "(7) unexpected barrier status $b_status"
30521
30522         #define OBD_FAIL_BARRIER_FAILURE        0x2203
30523         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
30524         do_facet mgs $LCTL barrier_freeze $FSNAME
30525
30526         b_status=$(barrier_stat)
30527         [ "$b_status" = "'failed'" ] ||
30528                 error "(8) unexpected barrier status $b_status"
30529
30530         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
30531         do_facet mgs $LCTL barrier_thaw $FSNAME
30532
30533         post_801
30534 }
30535 run_test 801a "write barrier user interfaces and stat machine"
30536
30537 test_801b() {
30538         prep_801
30539
30540         mkdir $DIR/$tdir || error "(1) fail to mkdir"
30541         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
30542         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
30543         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
30544         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
30545
30546         cancel_lru_locks mdc
30547
30548         # 180 seconds should be long enough
30549         do_facet mgs $LCTL barrier_freeze $FSNAME 180
30550
30551         local b_status=$(barrier_stat)
30552         [ "$b_status" = "'frozen'" ] ||
30553                 error "(6) unexpected barrier status $b_status"
30554
30555         mkdir $DIR/$tdir/d0/d10 &
30556         mkdir_pid=$!
30557
30558         touch $DIR/$tdir/d1/f13 &
30559         touch_pid=$!
30560
30561         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
30562         ln_pid=$!
30563
30564         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
30565         mv_pid=$!
30566
30567         rm -f $DIR/$tdir/d4/f12 &
30568         rm_pid=$!
30569
30570         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
30571
30572         # To guarantee taht the 'stat' is not blocked
30573         b_status=$(barrier_stat)
30574         [ "$b_status" = "'frozen'" ] ||
30575                 error "(8) unexpected barrier status $b_status"
30576
30577         # let above commands to run at background
30578         sleep 5
30579
30580         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
30581         ps -p $touch_pid || error "(10) touch should be blocked"
30582         ps -p $ln_pid || error "(11) link should be blocked"
30583         ps -p $mv_pid || error "(12) rename should be blocked"
30584         ps -p $rm_pid || error "(13) unlink should be blocked"
30585
30586         b_status=$(barrier_stat)
30587         [ "$b_status" = "'frozen'" ] ||
30588                 error "(14) unexpected barrier status $b_status"
30589
30590         do_facet mgs $LCTL barrier_thaw $FSNAME
30591         b_status=$(barrier_stat)
30592         [ "$b_status" = "'thawed'" ] ||
30593                 error "(15) unexpected barrier status $b_status"
30594
30595         wait $mkdir_pid || error "(16) mkdir should succeed"
30596         wait $touch_pid || error "(17) touch should succeed"
30597         wait $ln_pid || error "(18) link should succeed"
30598         wait $mv_pid || error "(19) rename should succeed"
30599         wait $rm_pid || error "(20) unlink should succeed"
30600
30601         post_801
30602 }
30603 run_test 801b "modification will be blocked by write barrier"
30604
30605 test_801c() {
30606         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30607
30608         prep_801
30609
30610         stop mds2 || error "(1) Fail to stop mds2"
30611
30612         do_facet mgs $LCTL barrier_freeze $FSNAME 30
30613
30614         local b_status=$(barrier_stat)
30615         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
30616                 do_facet mgs $LCTL barrier_thaw $FSNAME
30617                 error "(2) unexpected barrier status $b_status"
30618         }
30619
30620         do_facet mgs $LCTL barrier_rescan $FSNAME ||
30621                 error "(3) Fail to rescan barrier bitmap"
30622
30623         # Do not reduce barrier time - See LU-11873
30624         do_facet mgs $LCTL barrier_freeze $FSNAME 20
30625
30626         b_status=$(barrier_stat)
30627         [ "$b_status" = "'frozen'" ] ||
30628                 error "(4) unexpected barrier status $b_status"
30629
30630         do_facet mgs $LCTL barrier_thaw $FSNAME
30631         b_status=$(barrier_stat)
30632         [ "$b_status" = "'thawed'" ] ||
30633                 error "(5) unexpected barrier status $b_status"
30634
30635         local devname=$(mdsdevname 2)
30636
30637         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
30638
30639         do_facet mgs $LCTL barrier_rescan $FSNAME ||
30640                 error "(7) Fail to rescan barrier bitmap"
30641
30642         post_801
30643 }
30644 run_test 801c "rescan barrier bitmap"
30645
30646 test_802b() {
30647         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30648         remote_mds_nodsh && skip "remote MDS with nodsh"
30649
30650         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
30651                 skip "readonly option not available"
30652
30653         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
30654
30655         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
30656                 error "(2) Fail to copy"
30657
30658         # write back all cached data before setting MDT to readonly
30659         cancel_lru_locks
30660         sync_all_data
30661
30662         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
30663         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
30664
30665         echo "Modify should be refused"
30666         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
30667
30668         echo "Read should be allowed"
30669         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
30670                 error "(7) Read should succeed under ro mode"
30671
30672         # disable readonly
30673         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
30674 }
30675 run_test 802b "be able to set MDTs to readonly"
30676
30677 test_803a() {
30678         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30679         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
30680                 skip "MDS needs to be newer than 2.10.54"
30681
30682         mkdir_on_mdt0 $DIR/$tdir
30683         # Create some objects on all MDTs to trigger related logs objects
30684         for idx in $(seq $MDSCOUNT); do
30685                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
30686                         $DIR/$tdir/dir${idx} ||
30687                         error "Fail to create $DIR/$tdir/dir${idx}"
30688         done
30689
30690         wait_delete_completed # ensure old test cleanups are finished
30691         sleep 3
30692         echo "before create:"
30693         $LFS df -i $MOUNT
30694         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
30695
30696         for i in {1..10}; do
30697                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
30698                         error "Fail to create $DIR/$tdir/foo$i"
30699         done
30700
30701         # sync ZFS-on-MDS to refresh statfs data
30702         wait_zfs_commit mds1
30703         sleep 3
30704         echo "after create:"
30705         $LFS df -i $MOUNT
30706         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
30707
30708         # allow for an llog to be cleaned up during the test
30709         [ $after_used -ge $((before_used + 10 - 1)) ] ||
30710                 error "before ($before_used) + 10 > after ($after_used)"
30711
30712         for i in {1..10}; do
30713                 rm -rf $DIR/$tdir/foo$i ||
30714                         error "Fail to remove $DIR/$tdir/foo$i"
30715         done
30716
30717         # sync ZFS-on-MDS to refresh statfs data
30718         wait_zfs_commit mds1
30719         wait_delete_completed
30720         sleep 3 # avoid MDT return cached statfs
30721         echo "after unlink:"
30722         $LFS df -i $MOUNT
30723         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
30724
30725         # allow for an llog to be created during the test
30726         [ $after_used -le $((before_used + 1)) ] ||
30727                 error "after ($after_used) > before ($before_used) + 1"
30728 }
30729 run_test 803a "verify agent object for remote object"
30730
30731 test_803b() {
30732         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30733         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
30734                 skip "MDS needs to be newer than 2.13.56"
30735         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30736
30737         for i in $(seq 0 $((MDSCOUNT - 1))); do
30738                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
30739         done
30740
30741         local before=0
30742         local after=0
30743
30744         local tmp
30745
30746         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
30747         for i in $(seq 0 $((MDSCOUNT - 1))); do
30748                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
30749                         awk '/getattr/ { print $2 }')
30750                 before=$((before + tmp))
30751         done
30752         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
30753         for i in $(seq 0 $((MDSCOUNT - 1))); do
30754                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
30755                         awk '/getattr/ { print $2 }')
30756                 after=$((after + tmp))
30757         done
30758
30759         [ $before -eq $after ] || error "getattr count $before != $after"
30760 }
30761 run_test 803b "remote object can getattr from cache"
30762
30763 test_804() {
30764         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30765         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
30766                 skip "MDS needs to be newer than 2.10.54"
30767         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
30768
30769         mkdir -p $DIR/$tdir
30770         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
30771                 error "Fail to create $DIR/$tdir/dir0"
30772
30773         local fid=$($LFS path2fid $DIR/$tdir/dir0)
30774         local dev=$(mdsdevname 2)
30775
30776         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30777                 grep ${fid} || error "NOT found agent entry for dir0"
30778
30779         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
30780                 error "Fail to create $DIR/$tdir/dir1"
30781
30782         touch $DIR/$tdir/dir1/foo0 ||
30783                 error "Fail to create $DIR/$tdir/dir1/foo0"
30784         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
30785         local rc=0
30786
30787         for idx in $(seq $MDSCOUNT); do
30788                 dev=$(mdsdevname $idx)
30789                 do_facet mds${idx} \
30790                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30791                         grep ${fid} && rc=$idx
30792         done
30793
30794         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
30795                 error "Fail to rename foo0 to foo1"
30796         if [ $rc -eq 0 ]; then
30797                 for idx in $(seq $MDSCOUNT); do
30798                         dev=$(mdsdevname $idx)
30799                         do_facet mds${idx} \
30800                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30801                         grep ${fid} && rc=$idx
30802                 done
30803         fi
30804
30805         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
30806                 error "Fail to rename foo1 to foo2"
30807         if [ $rc -eq 0 ]; then
30808                 for idx in $(seq $MDSCOUNT); do
30809                         dev=$(mdsdevname $idx)
30810                         do_facet mds${idx} \
30811                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30812                         grep ${fid} && rc=$idx
30813                 done
30814         fi
30815
30816         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
30817
30818         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
30819                 error "Fail to link to $DIR/$tdir/dir1/foo2"
30820         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
30821                 error "Fail to rename foo2 to foo0"
30822         unlink $DIR/$tdir/dir1/foo0 ||
30823                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
30824         rm -rf $DIR/$tdir/dir0 ||
30825                 error "Fail to rm $DIR/$tdir/dir0"
30826
30827         for idx in $(seq $MDSCOUNT); do
30828                 rc=0
30829
30830                 stop mds${idx}
30831                 dev=$(mdsdevname $idx)
30832                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
30833                         rc=$?
30834                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
30835                         error "mount mds$idx failed"
30836                 df $MOUNT > /dev/null 2>&1
30837
30838                 # e2fsck should not return error
30839                 [ $rc -eq 0 ] ||
30840                         error "e2fsck detected error on MDT${idx}: rc=$rc"
30841         done
30842 }
30843 run_test 804 "verify agent entry for remote entry"
30844
30845 cleanup_805() {
30846         do_facet $SINGLEMDS zfs set quota=$old $fsset
30847         unlinkmany $DIR/$tdir/f- 1000000
30848         trap 0
30849 }
30850
30851 test_805() {
30852         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
30853         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
30854         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
30855                 skip "netfree not implemented before 0.7"
30856         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
30857                 skip "Need MDS version at least 2.10.57"
30858
30859         local fsset
30860         local freekb
30861         local usedkb
30862         local old
30863         local quota
30864         local pref="osd-zfs.$FSNAME-MDT0000."
30865
30866         # limit available space on MDS dataset to meet nospace issue
30867         # quickly. then ZFS 0.7.2 can use reserved space if asked
30868         # properly (using netfree flag in osd_declare_destroy()
30869         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
30870         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
30871                 gawk '{print $3}')
30872         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
30873         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
30874         let "usedkb=usedkb-freekb"
30875         let "freekb=freekb/2"
30876         if let "freekb > 5000"; then
30877                 let "freekb=5000"
30878         fi
30879         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
30880         trap cleanup_805 EXIT
30881         mkdir_on_mdt0 $DIR/$tdir
30882         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
30883                 error "Can't set PFL layout"
30884         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
30885         rm -rf $DIR/$tdir || error "not able to remove"
30886         do_facet $SINGLEMDS zfs set quota=$old $fsset
30887         trap 0
30888 }
30889 run_test 805 "ZFS can remove from full fs"
30890
30891 # Size-on-MDS test
30892 check_lsom_data()
30893 {
30894         local file=$1
30895         local expect=$(stat -c %s $file)
30896
30897         check_lsom_size $1 $expect
30898
30899         local blocks=$($LFS getsom -b $file)
30900         expect=$(stat -c %b $file)
30901         [[ $blocks == $expect ]] ||
30902                 error "$file expected blocks: $expect, got: $blocks"
30903 }
30904
30905 check_lsom_size()
30906 {
30907         local size
30908         local expect=$2
30909
30910         cancel_lru_locks mdc
30911
30912         size=$($LFS getsom -s $1)
30913         [[ $size == $expect ]] ||
30914                 error "$file expected size: $expect, got: $size"
30915 }
30916
30917 test_806() {
30918         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
30919                 skip "Need MDS version at least 2.11.52"
30920
30921         local bs=1048576
30922
30923         $LFS setstripe -c-1 $DIR/$tfile || error "setstripe $tfile failed"
30924
30925         disable_opencache
30926         stack_trap "restore_opencache"
30927
30928         # single-threaded write
30929         echo "Test SOM for single-threaded write"
30930         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
30931                 error "write $tfile failed"
30932         check_lsom_size $DIR/$tfile $bs
30933
30934         local num=32
30935         local size=$(($num * $bs))
30936         local offset=0
30937         local i
30938
30939         echo "Test SOM for single client multi-threaded($num) write"
30940         $TRUNCATE $DIR/$tfile 0
30941         for ((i = 0; i < $num; i++)); do
30942                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30943                 local pids[$i]=$!
30944                 offset=$((offset + $bs))
30945         done
30946         for (( i=0; i < $num; i++ )); do
30947                 wait ${pids[$i]}
30948         done
30949         check_lsom_size $DIR/$tfile $size
30950
30951         $TRUNCATE $DIR/$tfile 0
30952         for ((i = 0; i < $num; i++)); do
30953                 offset=$((offset - $bs))
30954                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30955                 local pids[$i]=$!
30956         done
30957         for (( i=0; i < $num; i++ )); do
30958                 wait ${pids[$i]}
30959         done
30960         check_lsom_size $DIR/$tfile $size
30961
30962         # multi-client writes
30963         num=$(get_node_count ${CLIENTS//,/ })
30964         size=$(($num * $bs))
30965         offset=0
30966         i=0
30967
30968         echo "Test SOM for multi-client ($num) writes"
30969         $TRUNCATE $DIR/$tfile 0
30970         for client in ${CLIENTS//,/ }; do
30971                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30972                 local pids[$i]=$!
30973                 i=$((i + 1))
30974                 offset=$((offset + $bs))
30975         done
30976         for (( i=0; i < $num; i++ )); do
30977                 wait ${pids[$i]}
30978         done
30979         check_lsom_size $DIR/$tfile $offset
30980
30981         i=0
30982         $TRUNCATE $DIR/$tfile 0
30983         for client in ${CLIENTS//,/ }; do
30984                 offset=$((offset - $bs))
30985                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30986                 local pids[$i]=$!
30987                 i=$((i + 1))
30988         done
30989         for (( i=0; i < $num; i++ )); do
30990                 wait ${pids[$i]}
30991         done
30992         check_lsom_size $DIR/$tfile $size
30993
30994         # verify SOM blocks count
30995         echo "Verify SOM block count"
30996         $TRUNCATE $DIR/$tfile 0
30997         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs))YSc ||
30998                 error "failed to write file $tfile with fdatasync and fstat"
30999         check_lsom_data $DIR/$tfile
31000
31001         $TRUNCATE $DIR/$tfile 0
31002         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs * 2))Yc ||
31003                 error "failed to write file $tfile with fdatasync"
31004         check_lsom_data $DIR/$tfile
31005
31006         $TRUNCATE $DIR/$tfile 0
31007         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:O_SYNC:w$((bs * 3))c ||
31008                 error "failed to write file $tfile with sync IO"
31009         check_lsom_data $DIR/$tfile
31010
31011         # verify truncate
31012         echo "Test SOM for truncate"
31013         # use ftruncate to sync blocks on close request
31014         $MULTIOP $DIR/$tfile oO_WRONLY:T16384c
31015         check_lsom_size $DIR/$tfile 16384
31016         check_lsom_data $DIR/$tfile
31017
31018         $TRUNCATE $DIR/$tfile 1234
31019         check_lsom_size $DIR/$tfile 1234
31020         # sync blocks on the MDT
31021         $MULTIOP $DIR/$tfile oc
31022         check_lsom_data $DIR/$tfile
31023 }
31024 run_test 806 "Verify Lazy Size on MDS"
31025
31026 test_807() {
31027         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
31028         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
31029                 skip "Need MDS version at least 2.11.52"
31030
31031         # Registration step
31032         changelog_register || error "changelog_register failed"
31033         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
31034         changelog_users $SINGLEMDS | grep -q $cl_user ||
31035                 error "User $cl_user not found in changelog_users"
31036
31037         rm -rf $DIR/$tdir || error "rm $tdir failed"
31038         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
31039         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
31040         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
31041         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
31042                 error "truncate $tdir/trunc failed"
31043
31044         local bs=1048576
31045         echo "Test SOM for single-threaded write with fsync"
31046         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
31047                 error "write $tfile failed"
31048         sync;sync;sync
31049
31050         # multi-client wirtes
31051         local num=$(get_node_count ${CLIENTS//,/ })
31052         local offset=0
31053         local i=0
31054
31055         echo "Test SOM for multi-client ($num) writes"
31056         touch $DIR/$tfile || error "touch $tfile failed"
31057         $TRUNCATE $DIR/$tfile 0
31058         for client in ${CLIENTS//,/ }; do
31059                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31060                 local pids[$i]=$!
31061                 i=$((i + 1))
31062                 offset=$((offset + $bs))
31063         done
31064         for (( i=0; i < $num; i++ )); do
31065                 wait ${pids[$i]}
31066         done
31067
31068         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
31069         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
31070         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
31071         check_lsom_data $DIR/$tdir/trunc
31072         check_lsom_data $DIR/$tdir/single_dd
31073         check_lsom_data $DIR/$tfile
31074
31075         rm -rf $DIR/$tdir
31076         # Deregistration step
31077         changelog_deregister || error "changelog_deregister failed"
31078 }
31079 run_test 807 "verify LSOM syncing tool"
31080
31081 check_som_nologged()
31082 {
31083         local lines=$($LFS changelog $FSNAME-MDT0000 |
31084                 grep 'x=trusted.som' | wc -l)
31085         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
31086 }
31087
31088 test_808() {
31089         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
31090                 skip "Need MDS version at least 2.11.55"
31091
31092         # Registration step
31093         changelog_register || error "changelog_register failed"
31094
31095         touch $DIR/$tfile || error "touch $tfile failed"
31096         check_som_nologged
31097
31098         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
31099                 error "write $tfile failed"
31100         check_som_nologged
31101
31102         $TRUNCATE $DIR/$tfile 1234
31103         check_som_nologged
31104
31105         $TRUNCATE $DIR/$tfile 1048576
31106         check_som_nologged
31107
31108         # Deregistration step
31109         changelog_deregister || error "changelog_deregister failed"
31110 }
31111 run_test 808 "Check trusted.som xattr not logged in Changelogs"
31112
31113 check_som_nodata()
31114 {
31115         $LFS getsom $1
31116         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
31117 }
31118
31119 test_809() {
31120         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
31121                 skip "Need MDS version at least 2.11.56"
31122
31123         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
31124                 error "failed to create DoM-only file $DIR/$tfile"
31125         touch $DIR/$tfile || error "touch $tfile failed"
31126         check_som_nodata $DIR/$tfile
31127
31128         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
31129                 error "write $tfile failed"
31130         check_som_nodata $DIR/$tfile
31131
31132         $TRUNCATE $DIR/$tfile 1234
31133         check_som_nodata $DIR/$tfile
31134
31135         $TRUNCATE $DIR/$tfile 4097
31136         check_som_nodata $DIR/$file
31137 }
31138 run_test 809 "Verify no SOM xattr store for DoM-only files"
31139
31140 test_810() {
31141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31142         $GSS && skip_env "could not run with gss"
31143         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
31144                 skip "OST < 2.12.58 doesn't align checksum"
31145
31146         set_checksums 1
31147         stack_trap "set_checksums $ORIG_CSUM" EXIT
31148         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
31149
31150         local csum
31151         local before
31152         local after
31153         for csum in $CKSUM_TYPES; do
31154                 #define OBD_FAIL_OSC_NO_GRANT   0x411
31155                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
31156                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
31157                         eval set -- $i
31158                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
31159                         before=$(md5sum $DIR/$tfile)
31160                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
31161                         after=$(md5sum $DIR/$tfile)
31162                         [ "$before" == "$after" ] ||
31163                                 error "$csum: $before != $after bs=$1 seek=$2"
31164                 done
31165         done
31166 }
31167 run_test 810 "partial page writes on ZFS (LU-11663)"
31168
31169 test_812a() {
31170         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
31171                 skip "OST < 2.12.51 doesn't support this fail_loc"
31172
31173         $LFS setstripe -c 1 -i 0 $DIR/$tfile
31174         # ensure ost1 is connected
31175         stat $DIR/$tfile >/dev/null || error "can't stat"
31176         wait_osc_import_state client ost1 FULL
31177         # no locks, no reqs to let the connection idle
31178         cancel_lru_locks osc
31179
31180         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
31181 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
31182         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
31183         wait_osc_import_state client ost1 CONNECTING
31184         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
31185
31186         stat $DIR/$tfile >/dev/null || error "can't stat file"
31187 }
31188 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
31189
31190 test_812b() { # LU-12378
31191         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
31192                 skip "OST < 2.12.51 doesn't support this fail_loc"
31193
31194         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
31195         # ensure ost1 is connected
31196         stat $DIR/$tfile >/dev/null || error "can't stat"
31197         wait_osc_import_state client ost1 FULL
31198         # no locks, no reqs to let the connection idle
31199         cancel_lru_locks osc
31200
31201         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
31202 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
31203         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
31204         wait_osc_import_state client ost1 CONNECTING
31205         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
31206
31207         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
31208         wait_osc_import_state client ost1 IDLE
31209 }
31210 run_test 812b "do not drop no resend request for idle connect"
31211
31212 test_812c() {
31213         local old
31214
31215         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
31216
31217         $LFS setstripe -c 1 -o 0 $DIR/$tfile
31218         $LFS getstripe $DIR/$tfile
31219         $LCTL set_param osc.*.idle_timeout=10
31220         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
31221         # ensure ost1 is connected
31222         stat $DIR/$tfile >/dev/null || error "can't stat"
31223         wait_osc_import_state client ost1 FULL
31224         # no locks, no reqs to let the connection idle
31225         cancel_lru_locks osc
31226
31227 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
31228         $LCTL set_param fail_loc=0x80000533
31229         sleep 15
31230         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
31231 }
31232 run_test 812c "idle import vs lock enqueue race"
31233
31234 test_813() {
31235         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
31236         [ -z "$file_heat_sav" ] && skip "no file heat support"
31237
31238         local readsample
31239         local writesample
31240         local readbyte
31241         local writebyte
31242         local readsample1
31243         local writesample1
31244         local readbyte1
31245         local writebyte1
31246
31247         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
31248         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
31249
31250         $LCTL set_param -n llite.*.file_heat=1
31251         echo "Turn on file heat"
31252         echo "Period second: $period_second, Decay percentage: $decay_pct"
31253
31254         echo "QQQQ" > $DIR/$tfile
31255         echo "QQQQ" > $DIR/$tfile
31256         echo "QQQQ" > $DIR/$tfile
31257         cat $DIR/$tfile > /dev/null
31258         cat $DIR/$tfile > /dev/null
31259         cat $DIR/$tfile > /dev/null
31260         cat $DIR/$tfile > /dev/null
31261
31262         local out=$($LFS heat_get $DIR/$tfile)
31263
31264         $LFS heat_get $DIR/$tfile
31265         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31266         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31267         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31268         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31269
31270         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
31271         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
31272         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
31273         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
31274
31275         sleep $((period_second + 3))
31276         echo "Sleep $((period_second + 3)) seconds..."
31277         # The recursion formula to calculate the heat of the file f is as
31278         # follow:
31279         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
31280         # Where Hi is the heat value in the period between time points i*I and
31281         # (i+1)*I; Ci is the access count in the period; the symbol P refers
31282         # to the weight of Ci.
31283         out=$($LFS heat_get $DIR/$tfile)
31284         $LFS heat_get $DIR/$tfile
31285         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31286         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31287         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31288         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31289
31290         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
31291                 error "read sample ($readsample) is wrong"
31292         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
31293                 error "write sample ($writesample) is wrong"
31294         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
31295                 error "read bytes ($readbyte) is wrong"
31296         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
31297                 error "write bytes ($writebyte) is wrong"
31298
31299         echo "QQQQ" > $DIR/$tfile
31300         echo "QQQQ" > $DIR/$tfile
31301         echo "QQQQ" > $DIR/$tfile
31302         cat $DIR/$tfile > /dev/null
31303         cat $DIR/$tfile > /dev/null
31304         cat $DIR/$tfile > /dev/null
31305         cat $DIR/$tfile > /dev/null
31306
31307         sleep $((period_second + 3))
31308         echo "Sleep $((period_second + 3)) seconds..."
31309
31310         out=$($LFS heat_get $DIR/$tfile)
31311         $LFS heat_get $DIR/$tfile
31312         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31313         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31314         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31315         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31316
31317         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
31318                 4 * $decay_pct) / 100") -eq 1 ] ||
31319                 error "read sample ($readsample1) is wrong"
31320         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
31321                 3 * $decay_pct) / 100") -eq 1 ] ||
31322                 error "write sample ($writesample1) is wrong"
31323         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
31324                 20 * $decay_pct) / 100") -eq 1 ] ||
31325                 error "read bytes ($readbyte1) is wrong"
31326         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
31327                 15 * $decay_pct) / 100") -eq 1 ] ||
31328                 error "write bytes ($writebyte1) is wrong"
31329
31330         echo "Turn off file heat for the file $DIR/$tfile"
31331         $LFS heat_set -o $DIR/$tfile
31332
31333         echo "QQQQ" > $DIR/$tfile
31334         echo "QQQQ" > $DIR/$tfile
31335         echo "QQQQ" > $DIR/$tfile
31336         cat $DIR/$tfile > /dev/null
31337         cat $DIR/$tfile > /dev/null
31338         cat $DIR/$tfile > /dev/null
31339         cat $DIR/$tfile > /dev/null
31340
31341         out=$($LFS heat_get $DIR/$tfile)
31342         $LFS heat_get $DIR/$tfile
31343         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31344         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31345         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31346         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31347
31348         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
31349         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
31350         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
31351         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
31352
31353         echo "Trun on file heat for the file $DIR/$tfile"
31354         $LFS heat_set -O $DIR/$tfile
31355
31356         echo "QQQQ" > $DIR/$tfile
31357         echo "QQQQ" > $DIR/$tfile
31358         echo "QQQQ" > $DIR/$tfile
31359         cat $DIR/$tfile > /dev/null
31360         cat $DIR/$tfile > /dev/null
31361         cat $DIR/$tfile > /dev/null
31362         cat $DIR/$tfile > /dev/null
31363
31364         out=$($LFS heat_get $DIR/$tfile)
31365         $LFS heat_get $DIR/$tfile
31366         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31367         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31368         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31369         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31370
31371         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
31372         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
31373         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
31374         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
31375
31376         $LFS heat_set -c $DIR/$tfile
31377         $LCTL set_param -n llite.*.file_heat=0
31378         echo "Turn off file heat support for the Lustre filesystem"
31379
31380         echo "QQQQ" > $DIR/$tfile
31381         echo "QQQQ" > $DIR/$tfile
31382         echo "QQQQ" > $DIR/$tfile
31383         cat $DIR/$tfile > /dev/null
31384         cat $DIR/$tfile > /dev/null
31385         cat $DIR/$tfile > /dev/null
31386         cat $DIR/$tfile > /dev/null
31387
31388         out=$($LFS heat_get $DIR/$tfile)
31389         $LFS heat_get $DIR/$tfile
31390         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31391         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31392         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31393         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31394
31395         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
31396         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
31397         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
31398         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
31399
31400         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
31401         rm -f $DIR/$tfile
31402 }
31403 run_test 813 "File heat verfication"
31404
31405 test_814()
31406 {
31407         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
31408         echo -n y >> $DIR/$tfile
31409         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
31410         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
31411 }
31412 run_test 814 "sparse cp works as expected (LU-12361)"
31413
31414 test_815()
31415 {
31416         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
31417         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
31418 }
31419 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
31420
31421 test_816() {
31422         local ost1_imp=$(get_osc_import_name client ost1)
31423         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
31424                          cut -d'.' -f2)
31425
31426         $LFS setstripe -c 1 -i 0 $DIR/$tfile
31427         # ensure ost1 is connected
31428
31429         stat $DIR/$tfile >/dev/null || error "can't stat"
31430         wait_osc_import_state client ost1 FULL
31431         # no locks, no reqs to let the connection idle
31432         cancel_lru_locks osc
31433         lru_resize_disable osc
31434         local before
31435         local now
31436         before=$($LCTL get_param -n \
31437                  ldlm.namespaces.$imp_name.lru_size)
31438
31439         wait_osc_import_state client ost1 IDLE
31440         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
31441         now=$($LCTL get_param -n \
31442               ldlm.namespaces.$imp_name.lru_size)
31443         [ $before == $now ] || error "lru_size changed $before != $now"
31444 }
31445 run_test 816 "do not reset lru_resize on idle reconnect"
31446
31447 cleanup_817() {
31448         umount $tmpdir
31449         exportfs -u localhost:$DIR/nfsexp
31450         rm -rf $DIR/nfsexp
31451 }
31452
31453 test_817() {
31454         systemctl restart nfs-server.service || skip "failed to restart nfsd"
31455
31456         mkdir -p $DIR/nfsexp
31457         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
31458                 error "failed to export nfs"
31459
31460         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
31461         stack_trap cleanup_817 EXIT
31462
31463         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
31464                 error "failed to mount nfs to $tmpdir"
31465
31466         cp /bin/true $tmpdir
31467         $DIR/nfsexp/true || error "failed to execute 'true' command"
31468 }
31469 run_test 817 "nfsd won't cache write lock for exec file"
31470
31471 test_818() {
31472         test_mkdir -i0 -c1 $DIR/$tdir
31473         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
31474         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
31475         stop $SINGLEMDS
31476
31477         # restore osp-syn threads
31478         stack_trap "fail $SINGLEMDS"
31479
31480         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
31481         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
31482         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
31483                 error "start $SINGLEMDS failed"
31484         rm -rf $DIR/$tdir
31485
31486         local testid=$(echo $TESTNAME | tr '_' ' ')
31487
31488         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
31489                 grep "run LFSCK" || error "run LFSCK is not suggested"
31490 }
31491 run_test 818 "unlink with failed llog"
31492
31493 test_819a() {
31494         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
31495         cancel_lru_locks osc
31496         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
31497         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
31498         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
31499         rm -f $TDIR/$tfile
31500 }
31501 run_test 819a "too big niobuf in read"
31502
31503 test_819b() {
31504         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
31505         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
31506         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
31507         cancel_lru_locks osc
31508         sleep 1
31509         rm -f $TDIR/$tfile
31510 }
31511 run_test 819b "too big niobuf in write"
31512
31513
31514 function test_820_start_ost() {
31515         sleep 5
31516
31517         for num in $(seq $OSTCOUNT); do
31518                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
31519         done
31520 }
31521
31522 test_820() {
31523         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
31524
31525         mkdir $DIR/$tdir
31526         umount_client $MOUNT || error "umount failed"
31527         for num in $(seq $OSTCOUNT); do
31528                 stop ost$num
31529         done
31530
31531         # mount client with no active OSTs
31532         # so that the client can't initialize max LOV EA size
31533         # from OSC notifications
31534         mount_client $MOUNT || error "mount failed"
31535         # delay OST starting to keep this 0 max EA size for a while
31536         test_820_start_ost &
31537
31538         # create a directory on MDS2
31539         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
31540                 error "Failed to create directory"
31541         # open intent should update default EA size
31542         # see mdc_update_max_ea_from_body()
31543         # notice this is the very first RPC to MDS2
31544         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
31545         ret=$?
31546         echo $out
31547         # With SSK, this situation can lead to -EPERM being returned.
31548         # In that case, simply retry.
31549         if [ $ret -ne 0 ] && $SHARED_KEY; then
31550                 if echo "$out" | grep -q "not permitted"; then
31551                         cp /etc/services $DIR/$tdir/mds2
31552                         ret=$?
31553                 fi
31554         fi
31555         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
31556 }
31557 run_test 820 "update max EA from open intent"
31558
31559 test_823() {
31560         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
31561         local OST_MAX_PRECREATE=20000
31562
31563         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
31564                 skip "Need MDS version at least 2.14.56"
31565
31566         save_lustre_params mds1 \
31567                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
31568         do_facet $SINGLEMDS "$LCTL set_param -n \
31569                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
31570         do_facet $SINGLEMDS "$LCTL set_param -n \
31571                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
31572
31573         stack_trap "restore_lustre_params < $p; rm $p"
31574
31575         do_facet $SINGLEMDS "$LCTL set_param -n \
31576                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
31577
31578         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
31579                       osp.$FSNAME-OST0000*MDT0000.create_count")
31580         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
31581                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
31582         local expect_count=$(((($max/2)/256) * 256))
31583
31584         log "setting create_count to 100200:"
31585         log " -result- count: $count with max: $max, expecting: $expect_count"
31586
31587         [[ $count -eq expect_count ]] ||
31588                 error "Create count not set to max precreate."
31589 }
31590 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
31591
31592 test_831() {
31593         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
31594                 skip "Need MDS version 2.14.56"
31595
31596         local sync_changes=$(do_facet $SINGLEMDS \
31597                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
31598
31599         [ "$sync_changes" -gt 100 ] &&
31600                 skip "Sync changes $sync_changes > 100 already"
31601
31602         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
31603
31604         $LFS mkdir -i 0 $DIR/$tdir
31605         $LFS setstripe -c 1 -i 0 $DIR/$tdir
31606
31607         save_lustre_params mds1 \
31608                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
31609         save_lustre_params mds1 \
31610                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
31611
31612         do_facet mds1 "$LCTL set_param -n \
31613                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
31614                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
31615         stack_trap "restore_lustre_params < $p" EXIT
31616
31617         createmany -o $DIR/$tdir/f- 1000
31618         unlinkmany $DIR/$tdir/f- 1000 &
31619         local UNLINK_PID=$!
31620
31621         while sleep 1; do
31622                 sync_changes=$(do_facet mds1 \
31623                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
31624                 # the check in the code is racy, fail the test
31625                 # if the value above the limit by 10.
31626                 [ $sync_changes -gt 110 ] && {
31627                         kill -2 $UNLINK_PID
31628                         wait
31629                         error "osp changes throttling failed, $sync_changes>110"
31630                 }
31631                 kill -0 $UNLINK_PID 2> /dev/null || break
31632         done
31633         wait
31634 }
31635 run_test 831 "throttling unlink/setattr queuing on OSP"
31636
31637 test_832() {
31638         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
31639         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
31640                 skip "Need MDS version 2.15.52+"
31641         is_rmentry_supported || skip "rm_entry not supported"
31642
31643         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
31644         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
31645         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
31646                 error "mkdir remote_dir failed"
31647         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
31648                 error "mkdir striped_dir failed"
31649         touch $DIR/$tdir/file || error "touch file failed"
31650         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
31651         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
31652 }
31653 run_test 832 "lfs rm_entry"
31654
31655 test_833() {
31656         local file=$DIR/$tfile
31657
31658         stack_trap "rm -f $file" EXIT
31659         dd if=/dev/zero of=$file bs=1M count=50 || error "Write $file failed"
31660
31661         local wpid
31662         local rpid
31663         local rpid2
31664
31665         # Buffered I/O write
31666         (
31667                 while [ ! -e $DIR/sanity.833.lck ]; do
31668                         dd if=/dev/zero of=$file bs=1M count=50 conv=notrunc ||
31669                                 error "failed to write $file"
31670                         sleep 0.$((RANDOM % 4 + 1))
31671                 done
31672         )&
31673         wpid=$!
31674
31675         # Buffered I/O read
31676         (
31677                 while [ ! -e $DIR/sanity.833.lck ]; do
31678                         dd if=$file of=/dev/null bs=1M count=50 ||
31679                                 error "failed to read $file"
31680                         sleep 0.$((RANDOM % 4 + 1))
31681                 done
31682         )&
31683         rpid=$!
31684
31685         # Direct I/O read
31686         (
31687                 while [ ! -e $DIR/sanity.833.lck ]; do
31688                         dd if=$file of=/dev/null bs=1M count=50 iflag=direct ||
31689                                 error "failed to read $file in direct I/O mode"
31690                         sleep 0.$((RANDOM % 4 + 1))
31691                 done
31692         )&
31693         rpid2=$!
31694
31695         sleep 30
31696         touch $DIR/sanity.833.lck
31697         wait $wpid || error "$?: buffered write failed"
31698         wait $rpid || error "$?: buffered read failed"
31699         wait $rpid2 || error "$?: direct read failed"
31700 }
31701 run_test 833 "Mixed buffered/direct read and write should not return -EIO"
31702
31703 test_850() {
31704         local dir=$DIR/$tdir
31705         local file=$dir/$tfile
31706         local statsfile=$dir/all_job_stats.txt
31707
31708         test_mkdir -p $dir || error "failed to create dir $dir"
31709         echo "abcdefg" > $file || error "failed to create file $file"
31710
31711         # read job_stats in the living system
31712         lljobstat -n 1 ||
31713                 error "failed to run lljobstat on living system"
31714
31715         $LCTL get_param *.*.job_stats > $statsfile
31716         lljobstat --statsfile=$statsfile ||
31717                 error "failed to run lljobstat on file $statsfile"
31718 }
31719 run_test 850 "lljobstat can parse living and aggregated job_stats"
31720
31721 #
31722 # tests that do cleanup/setup should be run at the end
31723 #
31724
31725 test_900() {
31726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31727         local ls
31728
31729         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
31730         $LCTL set_param fail_loc=0x903
31731
31732         cancel_lru_locks MGC
31733
31734         FAIL_ON_ERROR=true cleanup
31735         FAIL_ON_ERROR=true setup
31736 }
31737 run_test 900 "umount should not race with any mgc requeue thread"
31738
31739 # LUS-6253/LU-11185
31740 test_901() {
31741         local old
31742         local count
31743         local oldc
31744         local newc
31745         local olds
31746         local news
31747         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31748
31749         # some get_param have a bug to handle dot in param name
31750         cancel_lru_locks MGC
31751         old=$(mount -t lustre | wc -l)
31752         # 1 config+sptlrpc
31753         # 2 params
31754         # 3 nodemap
31755         # 4 IR
31756         old=$((old * 4))
31757         oldc=0
31758         count=0
31759         while [ $old -ne $oldc ]; do
31760                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
31761                 sleep 1
31762                 ((count++))
31763                 if [ $count -ge $TIMEOUT ]; then
31764                         error "too large timeout"
31765                 fi
31766         done
31767         umount_client $MOUNT || error "umount failed"
31768         mount_client $MOUNT || error "mount failed"
31769         cancel_lru_locks MGC
31770         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
31771
31772         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
31773
31774         return 0
31775 }
31776 run_test 901 "don't leak a mgc lock on client umount"
31777
31778 # LU-13377
31779 test_902() {
31780         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
31781                 skip "client does not have LU-13377 fix"
31782         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
31783         $LCTL set_param fail_loc=0x1415
31784         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
31785         cancel_lru_locks osc
31786         rm -f $DIR/$tfile
31787 }
31788 run_test 902 "test short write doesn't hang lustre"
31789
31790 # LU-14711
31791 test_903() {
31792         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
31793         echo "blah" > $DIR/${tfile}-2
31794         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
31795         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
31796         $LCTL set_param fail_loc=0x417 fail_val=20
31797
31798         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
31799         sleep 1 # To start the destroy
31800         wait_destroy_complete 150 || error "Destroy taking too long"
31801         cat $DIR/$tfile > /dev/null || error "Evicted"
31802 }
31803 run_test 903 "Test long page discard does not cause evictions"
31804
31805 test_904() {
31806         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
31807         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
31808                 grep -q project || skip "skip project quota not supported"
31809
31810         local testfile="$DIR/$tdir/$tfile"
31811         local xattr="trusted.projid"
31812         local projid
31813         local mdts=$(comma_list $(mdts_nodes))
31814         local saved=$(do_facet mds1 $LCTL get_param -n \
31815                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
31816
31817         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
31818         stack_trap "do_nodes $mdts $LCTL set_param \
31819                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
31820
31821         mkdir -p $DIR/$tdir
31822         touch $testfile
31823         #hide projid xattr on server
31824         $LFS project -p 1 $testfile ||
31825                 error "set $testfile project id failed"
31826         getfattr -m - $testfile | grep $xattr &&
31827                 error "do not show trusted.projid when disabled on server"
31828         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
31829         #should be hidden when projid is 0
31830         $LFS project -p 0 $testfile ||
31831                 error "set $testfile project id failed"
31832         getfattr -m - $testfile | grep $xattr &&
31833                 error "do not show trusted.projid with project ID 0"
31834
31835         #still can getxattr explicitly
31836         projid=$(getfattr -n $xattr $testfile |
31837                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
31838         [ $projid == "0" ] ||
31839                 error "projid expected 0 not $projid"
31840
31841         #set the projid via setxattr
31842         setfattr -n $xattr -v "1000" $testfile ||
31843                 error "setattr failed with $?"
31844         projid=($($LFS project $testfile))
31845         [ ${projid[0]} == "1000" ] ||
31846                 error "projid expected 1000 not $projid"
31847
31848         #check the new projid via getxattr
31849         $LFS project -p 1001 $testfile ||
31850                 error "set $testfile project id failed"
31851         getfattr -m - $testfile | grep $xattr ||
31852                 error "should show trusted.projid when project ID != 0"
31853         projid=$(getfattr -n $xattr $testfile |
31854                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
31855         [ $projid == "1001" ] ||
31856                 error "projid expected 1001 not $projid"
31857
31858         #try to set invalid projid
31859         setfattr -n $xattr -v "4294967295" $testfile &&
31860                 error "set invalid projid should fail"
31861
31862         #remove the xattr means setting projid to 0
31863         setfattr -x $xattr $testfile ||
31864                 error "setfattr failed with $?"
31865         projid=($($LFS project $testfile))
31866         [ ${projid[0]} == "0" ] ||
31867                 error "projid expected 0 not $projid"
31868
31869         #should be hidden when parent has inherit flag and same projid
31870         $LFS project -srp 1002 $DIR/$tdir ||
31871                 error "set $tdir project id failed"
31872         getfattr -m - $testfile | grep $xattr &&
31873                 error "do not show trusted.projid with inherit flag"
31874
31875         #still can getxattr explicitly
31876         projid=$(getfattr -n $xattr $testfile |
31877                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
31878         [ $projid == "1002" ] ||
31879                 error "projid expected 1002 not $projid"
31880 }
31881 run_test 904 "virtual project ID xattr"
31882
31883 # LU-8582
31884 test_905() {
31885         (( $OST1_VERSION >= $(version_code 2.15.50.220) )) ||
31886                 skip "need OST version >= 2.15.50.220 for fail_loc"
31887
31888         remote_ost_nodsh && skip "remote OST with nodsh"
31889         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
31890
31891         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
31892
31893         #define OBD_FAIL_OST_OPCODE 0x253
31894         # OST_LADVISE = 21
31895         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
31896         $LFS ladvise -a willread $DIR/$tfile &&
31897                 error "unexpected success of ladvise with fault injection"
31898         $LFS ladvise -a willread $DIR/$tfile |&
31899                 grep -q "Operation not supported"
31900         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
31901 }
31902 run_test 905 "bad or new opcode should not stuck client"
31903
31904 test_906() {
31905         grep -q io_uring_setup /proc/kallsyms ||
31906                 skip "Client OS does not support io_uring I/O engine"
31907         io_uring_probe || skip "kernel does not support io_uring fully"
31908         which fio || skip_env "no fio installed"
31909         fio --enghelp | grep -q io_uring ||
31910                 skip_env "fio does not support io_uring I/O engine"
31911
31912         local file=$DIR/$tfile
31913         local ioengine="io_uring"
31914         local numjobs=2
31915         local size=50M
31916
31917         fio --name=seqwrite --ioengine=$ioengine        \
31918                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
31919                 --iodepth=64 --size=$size --filename=$file --rw=write ||
31920                 error "fio seqwrite $file failed"
31921
31922         fio --name=seqread --ioengine=$ioengine \
31923                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
31924                 --iodepth=64 --size=$size --filename=$file --rw=read ||
31925                 error "fio seqread $file failed"
31926
31927         rm -f $file || error "rm -f $file failed"
31928 }
31929 run_test 906 "Simple test for io_uring I/O engine via fio"
31930
31931 test_907() {
31932         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
31933
31934         # set stripe size to max rpc size
31935         $LFS setstripe -i 0 -c 2 -S $((max_pages * PAGE_SIZE)) $DIR/$tfile
31936         $LFS getstripe $DIR/$tfile
31937 #define OBD_FAIL_OST_EROFS               0x216
31938         do_facet ost1 "$LCTL set_param fail_val=3 fail_loc=0x80000216"
31939
31940         local bs=$((max_pages * PAGE_SIZE / 16))
31941
31942         # write full one stripe and one block
31943         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=17 || error "dd failed"
31944
31945         rm $DIR/$tfile || error "rm failed"
31946 }
31947 run_test 907 "write rpc error during unlink"
31948
31949
31950 complete_test $SECONDS
31951 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
31952 check_and_cleanup_lustre
31953 if [ "$I_MOUNTED" != "yes" ]; then
31954         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
31955 fi
31956 exit_status