Whamcloud - gitweb
LU-17533 llite: call merge attr on all writes
[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 # minutes runtime:                   5              12     8   12   15   10
71 [[ "$SLOW" = "no" ]] && EXCEPT_SLOW="27m 60i 64b 68 71 135 136 230d 300o 842"
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 fi
116
117 build_test_filter
118 FAIL_ON_ERROR=false
119
120 cleanup() {
121         echo -n "cln.."
122         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
123         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
124 }
125 setup() {
126         echo -n "mnt.."
127         load_modules
128         setupall || exit 10
129         echo "done"
130 }
131
132 check_swap_layouts_support()
133 {
134         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
135                 skip "Does not support layout lock."
136 }
137
138 check_swap_layout_no_dom()
139 {
140         local FOLDER=$1
141         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
142         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
143 }
144
145 check_and_setup_lustre
146 DIR=${DIR:-$MOUNT}
147 assert_DIR
148
149 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
150
151 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
152 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
153 rm -rf $DIR/[Rdfs][0-9]*
154
155 # $RUNAS_ID may get set incorrectly somewhere else
156 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
157         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
158
159 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
160
161 if [ "${ONLY}" = "MOUNT" ] ; then
162         echo "Lustre is up, please go on"
163         exit
164 fi
165
166 echo "preparing for tests involving mounts"
167 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
168 touch $EXT2_DEV
169 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
170 echo # add a newline after mke2fs.
171
172 umask 077
173
174 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
175
176 # ensure all internal functions know we want full debug
177 export PTLDEBUG=all
178 lctl set_param debug=$PTLDEBUG 2> /dev/null || true
179
180 test_0a() {
181         touch $DIR/$tfile
182         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
183         rm $DIR/$tfile
184         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
185 }
186 run_test 0a "touch; rm ====================="
187
188 test_0b() {
189         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
190         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
191 }
192 run_test 0b "chmod 0755 $DIR ============================="
193
194 test_0c() {
195         $LCTL get_param mdc.*.import | grep "state: FULL" ||
196                 error "import not FULL"
197         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
198                 error "bad target"
199 }
200 run_test 0c "check import proc"
201
202 test_0d() { # LU-3397
203         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
204                 skip "proc exports not supported before 2.10.57"
205
206         local mgs_exp="mgs.MGS.exports"
207         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
208         local exp_client_nid
209         local exp_client_version
210         local exp_val
211         local imp_val
212         local temp_imp=$DIR/$tfile.import
213         local temp_exp=$DIR/$tfile.export
214
215         # save mgc import file to $temp_imp
216         $LCTL get_param mgc.*.import | tee $temp_imp
217         # Check if client uuid is found in MGS export
218         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
219                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
220                         $client_uuid ] &&
221                         break;
222         done
223         # save mgs export file to $temp_exp
224         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
225
226         # Compare the value of field "connect_flags"
227         imp_val=$(grep "connect_flags" $temp_imp)
228         exp_val=$(grep "connect_flags" $temp_exp)
229         [ "$exp_val" == "$imp_val" ] ||
230                 error "export flags '$exp_val' != import flags '$imp_val'"
231
232         # Compare client versions.  Only compare top-3 fields for compatibility
233         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
234         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
235         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
236         [ "$exp_val" == "$imp_val" ] ||
237                 error "exp version '$exp_client_version'($exp_val) != " \
238                         "'$(lustre_build_version client)'($imp_val)"
239 }
240 run_test 0d "check export proc ============================="
241
242 test_0e() { # LU-13417
243         (( $MDSCOUNT > 1 )) ||
244                 skip "We need at least 2 MDTs for this test"
245
246         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
247                 skip "Need server version at least 2.14.51"
248
249         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
250         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
251
252         [ $default_lmv_count -eq 1 ] ||
253                 error "$MOUNT default stripe count $default_lmv_count"
254
255         [ $default_lmv_index -eq -1 ] ||
256                 error "$MOUNT default stripe index $default_lmv_index"
257
258         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
259         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
260
261         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
262         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
263
264         [ $mdt_index1 -eq $mdt_index2 ] &&
265                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
266
267         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
268 }
269 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
270
271 test_0f() { # LU-17471
272         (( $MDS1_VERSION < $(version_code 2.17.53) )) ||
273                 skip "MDS >= 2.17.53 removes /proc/.../brw_stats symlink"
274         (( $MDS1_VERSION < $(version_code 2.14.55-100-g8a84c7f9c7) ||
275            $MDS1_VERSION > $(version_code 2.15.60-25) )) ||
276                 skip "MDS was missing /proc/.../brw_stats value"
277
278         local path="lustre/osd-$FSTYPE/$FSNAME-MDT0000/brw_stats"
279         local out_proc=$(do_facet mds1 grep snapshot_time /proc/fs/$path)
280
281         [[ -n "$out_proc" ]] || error "brw_stats /proc/fs/$path not found"
282 }
283 run_test 0f "Symlink to /sys/kernel/debug/*/*/brw_stats should work properly"
284
285 test_1() {
286         test_mkdir $DIR/$tdir
287         test_mkdir $DIR/$tdir/d2
288         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
289         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
290         rmdir $DIR/$tdir/d2
291         rmdir $DIR/$tdir
292         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
293 }
294 run_test 1 "mkdir; remkdir; rmdir"
295
296 test_2() {
297         test_mkdir $DIR/$tdir
298         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
299         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
300         rm -r $DIR/$tdir
301         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
302 }
303 run_test 2 "mkdir; touch; rmdir; check file"
304
305 test_3() {
306         test_mkdir $DIR/$tdir
307         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
308         touch $DIR/$tdir/$tfile
309         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
310         rm -r $DIR/$tdir
311         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
312 }
313 run_test 3 "mkdir; touch; rmdir; check dir"
314
315 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
316 test_4() {
317         test_mkdir -i 1 $DIR/$tdir
318
319         touch $DIR/$tdir/$tfile ||
320                 error "Create file under remote directory failed"
321
322         rmdir $DIR/$tdir &&
323                 error "Expect error removing in-use dir $DIR/$tdir"
324
325         test -d $DIR/$tdir || error "Remote directory disappeared"
326
327         rm -rf $DIR/$tdir || error "remove remote dir error"
328 }
329 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
330
331 test_5() {
332         test_mkdir $DIR/$tdir
333         test_mkdir $DIR/$tdir/d2
334         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
335         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
336         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
337 }
338 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
339
340 test_6a() {
341         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
342         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
343         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
344                 error "$tfile does not have perm 0666 or UID $UID"
345         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
346         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
347                 error "$tfile should be 0666 and owned by UID $UID"
348 }
349 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
350
351 test_6c() {
352         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
353
354         touch $DIR/$tfile
355         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
356         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
357                 error "$tfile should be owned by UID $RUNAS_ID"
358         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
359         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
360                 error "$tfile should be owned by UID $RUNAS_ID"
361 }
362 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
363
364 test_6e() {
365         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
366
367         touch $DIR/$tfile
368         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
369         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
370                 error "$tfile should be owned by GID $UID"
371         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
372         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
373                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
374 }
375 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
376
377 test_6g() {
378         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
379
380         test_mkdir $DIR/$tdir
381         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
382         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
383         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
384         test_mkdir $DIR/$tdir/d/subdir
385         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
386                 error "$tdir/d/subdir should be GID $RUNAS_GID"
387         if [[ $MDSCOUNT -gt 1 ]]; then
388                 # check remote dir sgid inherite
389                 $LFS mkdir -i 0 $DIR/$tdir.local ||
390                         error "mkdir $tdir.local failed"
391                 chmod g+s $DIR/$tdir.local ||
392                         error "chmod $tdir.local failed"
393                 chgrp $RUNAS_GID $DIR/$tdir.local ||
394                         error "chgrp $tdir.local failed"
395                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
396                         error "mkdir $tdir.remote failed"
397                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
398                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
399                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
400                         error "$tdir.remote should be mode 02755"
401         fi
402 }
403 run_test 6g "verify new dir in sgid dir inherits group"
404
405 test_6h() { # bug 7331
406         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
407
408         touch $DIR/$tfile || error "touch failed"
409         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
410         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
411                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
412         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
413                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
414 }
415 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
416
417 test_7a() {
418         test_mkdir $DIR/$tdir
419         $MCREATE $DIR/$tdir/$tfile
420         chmod 0666 $DIR/$tdir/$tfile
421         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
422                 error "$tdir/$tfile should be mode 0666"
423 }
424 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
425
426 test_7b() {
427         if [ ! -d $DIR/$tdir ]; then
428                 test_mkdir $DIR/$tdir
429         fi
430         $MCREATE $DIR/$tdir/$tfile
431         echo -n foo > $DIR/$tdir/$tfile
432         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
433         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
434 }
435 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
436
437 test_8() {
438         test_mkdir $DIR/$tdir
439         touch $DIR/$tdir/$tfile
440         chmod 0666 $DIR/$tdir/$tfile
441         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
442                 error "$tfile mode not 0666"
443 }
444 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
445
446 test_9() {
447         test_mkdir $DIR/$tdir
448         test_mkdir $DIR/$tdir/d2
449         test_mkdir $DIR/$tdir/d2/d3
450         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
451 }
452 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
453
454 test_10() {
455         test_mkdir $DIR/$tdir
456         test_mkdir $DIR/$tdir/d2
457         touch $DIR/$tdir/d2/$tfile
458         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
459                 error "$tdir/d2/$tfile not a file"
460 }
461 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
462
463 test_11() {
464         test_mkdir $DIR/$tdir
465         test_mkdir $DIR/$tdir/d2
466         chmod 0666 $DIR/$tdir/d2
467         chmod 0705 $DIR/$tdir/d2
468         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
469                 error "$tdir/d2 mode not 0705"
470 }
471 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
472
473 test_12() {
474         test_mkdir $DIR/$tdir
475         touch $DIR/$tdir/$tfile
476         chmod 0666 $DIR/$tdir/$tfile
477         chmod 0654 $DIR/$tdir/$tfile
478         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
479                 error "$tdir/d2 mode not 0654"
480 }
481 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
482
483 test_13() {
484         test_mkdir $DIR/$tdir
485         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
486         >  $DIR/$tdir/$tfile
487         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
488                 error "$tdir/$tfile size not 0 after truncate"
489 }
490 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
491
492 test_14() {
493         test_mkdir $DIR/$tdir
494         touch $DIR/$tdir/$tfile
495         rm $DIR/$tdir/$tfile
496         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
497 }
498 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
499
500 test_15() {
501         test_mkdir $DIR/$tdir
502         touch $DIR/$tdir/$tfile
503         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
504         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
505                 error "$tdir/${tfile_2} not a file after rename"
506         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
507 }
508 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
509
510 test_16() {
511         test_mkdir $DIR/$tdir
512         touch $DIR/$tdir/$tfile
513         rm -rf $DIR/$tdir/$tfile
514         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
515 }
516 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
517
518 test_17a() {
519         test_mkdir $DIR/$tdir
520         touch $DIR/$tdir/$tfile
521         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
522         ls -l $DIR/$tdir
523         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
524                 error "$tdir/l-exist not a symlink"
525         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
526                 error "$tdir/l-exist not referencing a file"
527         rm -f $DIR/$tdir/l-exist
528         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
529 }
530 run_test 17a "symlinks: create, remove (real)"
531
532 test_17b() {
533         test_mkdir $DIR/$tdir
534         ln -s no-such-file $DIR/$tdir/l-dangle
535         ls -l $DIR/$tdir
536         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
537                 error "$tdir/l-dangle not referencing no-such-file"
538         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
539                 error "$tdir/l-dangle not referencing non-existent file"
540         rm -f $DIR/$tdir/l-dangle
541         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
542 }
543 run_test 17b "symlinks: create, remove (dangling)"
544
545 test_17c() { # bug 3440 - don't save failed open RPC for replay
546         test_mkdir $DIR/$tdir
547         ln -s foo $DIR/$tdir/$tfile
548         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
549 }
550 run_test 17c "symlinks: open dangling (should return error)"
551
552 test_17d() {
553         test_mkdir $DIR/$tdir
554         ln -s foo $DIR/$tdir/$tfile
555         touch $DIR/$tdir/$tfile || error "creating to new symlink"
556 }
557 run_test 17d "symlinks: create dangling"
558
559 test_17e() {
560         test_mkdir $DIR/$tdir
561         local foo=$DIR/$tdir/$tfile
562         ln -s $foo $foo || error "create symlink failed"
563         ls -l $foo || error "ls -l failed"
564         ls $foo && error "ls not failed" || true
565 }
566 run_test 17e "symlinks: create recursive symlink (should return error)"
567
568 test_17f() {
569         test_mkdir $DIR/$tdir
570         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
571         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
572         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
573         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
574         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
575         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
576         ls -l  $DIR/$tdir
577 }
578 run_test 17f "symlinks: long and very long symlink name"
579
580 # str_repeat(S, N) generate a string that is string S repeated N times
581 str_repeat() {
582         local s=$1
583         local n=$2
584         local ret=''
585         while [ $((n -= 1)) -ge 0 ]; do
586                 ret=$ret$s
587         done
588         echo $ret
589 }
590
591 # Long symlinks and LU-2241
592 test_17g() {
593         test_mkdir $DIR/$tdir
594         local TESTS="59 60 61 4094 4095"
595
596         # Fix for inode size boundary in 2.1.4
597         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
598                 TESTS="4094 4095"
599
600         # Patch not applied to 2.2 or 2.3 branches
601         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
602         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
603                 TESTS="4094 4095"
604
605         for i in $TESTS; do
606                 local SYMNAME=$(str_repeat 'x' $i)
607                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
608                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
609         done
610 }
611 run_test 17g "symlinks: really long symlink name and inode boundaries"
612
613 test_17h() { #bug 17378
614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
615         remote_mds_nodsh && skip "remote MDS with nodsh"
616
617         local mdt_idx
618
619         test_mkdir $DIR/$tdir
620         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
621         $LFS setstripe -c -1 $DIR/$tdir
622         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
623         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
624         touch $DIR/$tdir/$tfile || true
625 }
626 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
627
628 test_17i() { #bug 20018
629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
630         remote_mds_nodsh && skip "remote MDS with nodsh"
631
632         local foo=$DIR/$tdir/$tfile
633         local mdt_idx
634
635         test_mkdir -c1 $DIR/$tdir
636         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
637         ln -s $foo $foo || error "create symlink failed"
638 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
639         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
640         ls -l $foo && error "error not detected"
641         return 0
642 }
643 run_test 17i "don't panic on short symlink (should return error)"
644
645 test_17k() { #bug 22301
646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
647         [[ -z "$(which rsync 2>/dev/null)" ]] &&
648                 skip "no rsync command"
649         rsync --help | grep -q xattr ||
650                 skip_env "$(rsync --version | head -n1) does not support xattrs"
651         test_mkdir $DIR/$tdir
652         test_mkdir $DIR/$tdir.new
653         touch $DIR/$tdir/$tfile
654         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
655         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
656                 error "rsync failed with xattrs enabled"
657 }
658 run_test 17k "symlinks: rsync with xattrs enabled"
659
660 test_17l() { # LU-279
661         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
662                 skip "no getfattr command"
663
664         test_mkdir $DIR/$tdir
665         touch $DIR/$tdir/$tfile
666         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
667         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
668                 # -h to not follow symlinks. -m '' to list all the xattrs.
669                 # grep to remove first line: '# file: $path'.
670                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
671                 do
672                         lgetxattr_size_check $path $xattr ||
673                                 error "lgetxattr_size_check $path $xattr failed"
674                 done
675         done
676 }
677 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
678
679 # LU-1540
680 test_17m() {
681         [ $PARALLEL == "yes" ] && skip "skip parallel run"
682         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
683         remote_mds_nodsh && skip "remote MDS with nodsh"
684         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
685         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
686                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
687
688         local short_sym="0123456789"
689         local wdir=$DIR/$tdir
690         local i
691
692         test_mkdir $wdir
693         long_sym=$short_sym
694         # create a long symlink file
695         for ((i = 0; i < 4; ++i)); do
696                 long_sym=${long_sym}${long_sym}
697         done
698
699         echo "create 512 short and long symlink files under $wdir"
700         for ((i = 0; i < 256; ++i)); do
701                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
702                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
703         done
704
705         echo "erase them"
706         rm -f $wdir/*
707         sync
708         wait_delete_completed
709
710         echo "recreate the 512 symlink files with a shorter string"
711         for ((i = 0; i < 512; ++i)); do
712                 # rewrite the symlink file with a shorter string
713                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
714                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
715         done
716
717         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
718
719         echo "stop and checking mds${mds_index}:"
720         # e2fsck should not return error
721         stop mds${mds_index}
722         local devname=$(mdsdevname $mds_index)
723         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
724         rc=$?
725
726         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
727                 error "start mds${mds_index} failed"
728         df $MOUNT > /dev/null 2>&1
729         [ $rc -eq 0 ] ||
730                 error "e2fsck detected error for short/long symlink: rc=$rc"
731         rm -f $wdir/*
732 }
733 run_test 17m "run e2fsck against MDT which contains short/long symlink"
734
735 check_fs_consistency_17n() {
736         local mdt_index
737         local rc=0
738
739         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
740         # so it only check MDT1/MDT2 instead of all of MDTs.
741         for mdt_index in 1 2; do
742                 # e2fsck should not return error
743                 stop mds${mdt_index}
744                 local devname=$(mdsdevname $mdt_index)
745                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
746                         rc=$((rc + $?))
747
748                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
749                         error "mount mds$mdt_index failed"
750                 df $MOUNT > /dev/null 2>&1
751         done
752         return $rc
753 }
754
755 test_17n() {
756         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
757         [ $PARALLEL == "yes" ] && skip "skip parallel run"
758         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
759         remote_mds_nodsh && skip "remote MDS with nodsh"
760         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
761         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
762                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
763
764         local i
765
766         test_mkdir $DIR/$tdir
767         for ((i=0; i<10; i++)); do
768                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
769                         error "create remote dir error $i"
770                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
771                         error "create files under remote dir failed $i"
772         done
773
774         check_fs_consistency_17n ||
775                 error "e2fsck report error after create files under remote dir"
776
777         for ((i = 0; i < 10; i++)); do
778                 rm -rf $DIR/$tdir/remote_dir_${i} ||
779                         error "destroy remote dir error $i"
780         done
781
782         check_fs_consistency_17n ||
783                 error "e2fsck report error after unlink files under remote dir"
784
785         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
786                 skip "lustre < 2.4.50 does not support migrate mv"
787
788         for ((i = 0; i < 10; i++)); do
789                 mkdir -p $DIR/$tdir/remote_dir_${i}
790                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
791                         error "create files under remote dir failed $i"
792                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
793                         error "migrate remote dir error $i"
794         done
795         check_fs_consistency_17n || error "e2fsck report error after migration"
796
797         for ((i = 0; i < 10; i++)); do
798                 rm -rf $DIR/$tdir/remote_dir_${i} ||
799                         error "destroy remote dir error $i"
800         done
801
802         check_fs_consistency_17n || error "e2fsck report error after unlink"
803 }
804 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
805
806 test_17o() {
807         remote_mds_nodsh && skip "remote MDS with nodsh"
808         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
809                 skip "Need MDS version at least 2.3.64"
810
811         local wdir=$DIR/${tdir}o
812         local mdt_index
813         local rc=0
814
815         test_mkdir $wdir
816         touch $wdir/$tfile
817         mdt_index=$($LFS getstripe -m $wdir/$tfile)
818         mdt_index=$((mdt_index + 1))
819
820         cancel_lru_locks mdc
821         #fail mds will wait the failover finish then set
822         #following fail_loc to avoid interfer the recovery process.
823         fail mds${mdt_index}
824
825         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
826         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
827         ls -l $wdir/$tfile && rc=1
828         do_facet mds${mdt_index} lctl set_param fail_loc=0
829         [[ $rc -eq 0 ]] || error "stat file should fail"
830 }
831 run_test 17o "stat file with incompat LMA feature"
832
833 test_18() {
834         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
835         ls $DIR || error "Failed to ls $DIR: $?"
836 }
837 run_test 18 "touch .../f ; ls ... =============================="
838
839 test_19a() {
840         touch $DIR/$tfile
841         ls -l $DIR
842         rm $DIR/$tfile
843         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
844 }
845 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
846
847 test_19b() {
848         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
849 }
850 run_test 19b "ls -l .../f19 (should return error) =============="
851
852 test_19c() {
853         [ $RUNAS_ID -eq $UID ] &&
854                 skip_env "RUNAS_ID = UID = $UID -- skipping"
855
856         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
857 }
858 run_test 19c "$RUNAS touch .../f19 (should return error) =="
859
860 test_19d() {
861         cat $DIR/f19 && error || true
862 }
863 run_test 19d "cat .../f19 (should return error) =============="
864
865 test_20() {
866         touch $DIR/$tfile
867         rm $DIR/$tfile
868         touch $DIR/$tfile
869         rm $DIR/$tfile
870         touch $DIR/$tfile
871         rm $DIR/$tfile
872         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
873 }
874 run_test 20 "touch .../f ; ls -l ..."
875
876 test_21() {
877         test_mkdir $DIR/$tdir
878         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
879         ln -s dangle $DIR/$tdir/link
880         echo foo >> $DIR/$tdir/link
881         cat $DIR/$tdir/dangle
882         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
883         $CHECKSTAT -f -t file $DIR/$tdir/link ||
884                 error "$tdir/link not linked to a file"
885 }
886 run_test 21 "write to dangling link"
887
888 test_22() {
889         local wdir=$DIR/$tdir
890         test_mkdir $wdir
891         chown $RUNAS_ID:$RUNAS_GID $wdir
892         (cd $wdir || error "cd $wdir failed";
893                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
894                 $RUNAS tar xf -)
895         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
896         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
897         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
898                 error "checkstat -u failed"
899 }
900 run_test 22 "unpack tar archive as non-root user"
901
902 # was test_23
903 test_23a() {
904         test_mkdir $DIR/$tdir
905         local file=$DIR/$tdir/$tfile
906
907         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
908         openfile -f O_CREAT:O_EXCL $file &&
909                 error "$file recreate succeeded" || true
910 }
911 run_test 23a "O_CREAT|O_EXCL in subdir"
912
913 test_23b() { # bug 18988
914         test_mkdir $DIR/$tdir
915         local file=$DIR/$tdir/$tfile
916
917         rm -f $file
918         echo foo > $file || error "write filed"
919         echo bar >> $file || error "append filed"
920         $CHECKSTAT -s 8 $file || error "wrong size"
921         rm $file
922 }
923 run_test 23b "O_APPEND check"
924
925 # LU-9409, size with O_APPEND and tiny writes
926 test_23c() {
927         local file=$DIR/$tfile
928
929         # single dd
930         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
931         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
932         rm -f $file
933
934         # racing tiny writes
935         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
936         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
937         wait
938         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
939         rm -f $file
940
941         #racing tiny & normal writes
942         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
943         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
944         wait
945         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
946         rm -f $file
947
948         #racing tiny & normal writes 2, ugly numbers
949         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
950         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
951         wait
952         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
953         rm -f $file
954 }
955 run_test 23c "O_APPEND size checks for tiny writes"
956
957 # LU-11069 file offset is correct after appending writes
958 test_23d() {
959         local file=$DIR/$tfile
960         local offset
961
962         echo CentaurHauls > $file
963         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
964         if ((offset != 26)); then
965                 error "wrong offset, expected 26, got '$offset'"
966         fi
967 }
968 run_test 23d "file offset is correct after appending writes"
969
970 # rename sanity
971 test_24a() {
972         echo '-- same directory rename'
973         test_mkdir $DIR/$tdir
974         touch $DIR/$tdir/$tfile.1
975         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
976         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
977 }
978 run_test 24a "rename file to non-existent target"
979
980 test_24b() {
981         test_mkdir $DIR/$tdir
982         touch $DIR/$tdir/$tfile.{1,2}
983         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
984         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
985         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
986 }
987 run_test 24b "rename file to existing target"
988
989 test_24c() {
990         test_mkdir $DIR/$tdir
991         test_mkdir $DIR/$tdir/d$testnum.1
992         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
993         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
994         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
995 }
996 run_test 24c "rename directory to non-existent target"
997
998 test_24d() {
999         test_mkdir -c1 $DIR/$tdir
1000         test_mkdir -c1 $DIR/$tdir/d$testnum.1
1001         test_mkdir -c1 $DIR/$tdir/d$testnum.2
1002         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
1003         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
1004         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
1005 }
1006 run_test 24d "rename directory to existing target"
1007
1008 test_24e() {
1009         echo '-- cross directory renames --'
1010         test_mkdir $DIR/R5a
1011         test_mkdir $DIR/R5b
1012         touch $DIR/R5a/f
1013         mv $DIR/R5a/f $DIR/R5b/g
1014         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
1015         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
1016 }
1017 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
1018
1019 test_24f() {
1020         test_mkdir $DIR/R6a
1021         test_mkdir $DIR/R6b
1022         touch $DIR/R6a/f $DIR/R6b/g
1023         mv $DIR/R6a/f $DIR/R6b/g
1024         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1025         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1026 }
1027 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1028
1029 test_24g() {
1030         test_mkdir $DIR/R7a
1031         test_mkdir $DIR/R7b
1032         test_mkdir $DIR/R7a/d
1033         mv $DIR/R7a/d $DIR/R7b/e
1034         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1035         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1036 }
1037 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1038
1039 test_24h() {
1040         test_mkdir -c1 $DIR/R8a
1041         test_mkdir -c1 $DIR/R8b
1042         test_mkdir -c1 $DIR/R8a/d
1043         test_mkdir -c1 $DIR/R8b/e
1044         mrename $DIR/R8a/d $DIR/R8b/e
1045         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1046         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1047 }
1048 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1049
1050 test_24i() {
1051         echo "-- rename error cases"
1052         test_mkdir $DIR/R9
1053         test_mkdir $DIR/R9/a
1054         touch $DIR/R9/f
1055         mrename $DIR/R9/f $DIR/R9/a
1056         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1057         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1058         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1059 }
1060 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1061
1062 test_24j() {
1063         test_mkdir $DIR/R10
1064         mrename $DIR/R10/f $DIR/R10/g
1065         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1066         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1067         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1068 }
1069 run_test 24j "source does not exist ============================"
1070
1071 test_24k() {
1072         test_mkdir $DIR/R11a
1073         test_mkdir $DIR/R11a/d
1074         touch $DIR/R11a/f
1075         mv $DIR/R11a/f $DIR/R11a/d
1076         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1077         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1078 }
1079 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1080
1081 # bug 2429 - rename foo foo foo creates invalid file
1082 test_24l() {
1083         f="$DIR/f24l"
1084         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1085 }
1086 run_test 24l "Renaming a file to itself ========================"
1087
1088 test_24m() {
1089         f="$DIR/f24m"
1090         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1091         # on ext3 this does not remove either the source or target files
1092         # though the "expected" operation would be to remove the source
1093         $CHECKSTAT -t file ${f} || error "${f} missing"
1094         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1095 }
1096 run_test 24m "Renaming a file to a hard link to itself ========="
1097
1098 test_24n() {
1099     f="$DIR/f24n"
1100     # this stats the old file after it was renamed, so it should fail
1101     touch ${f}
1102     $CHECKSTAT ${f} || error "${f} missing"
1103     mv ${f} ${f}.rename
1104     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1105     $CHECKSTAT -a ${f} || error "${f} exists"
1106 }
1107 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1108
1109 test_24o() {
1110         test_mkdir $DIR/$tdir
1111         rename_many -s random -v -n 10 $DIR/$tdir
1112 }
1113 run_test 24o "rename of files during htree split"
1114
1115 test_24p() {
1116         test_mkdir $DIR/R12a
1117         test_mkdir $DIR/R12b
1118         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1119         mrename $DIR/R12a $DIR/R12b
1120         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1121         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1122         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1123         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1124 }
1125 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1126
1127 cleanup_multiop_pause() {
1128         trap 0
1129         kill -USR1 $MULTIPID
1130 }
1131
1132 test_24q() {
1133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1134
1135         test_mkdir $DIR/R13a
1136         test_mkdir $DIR/R13b
1137         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1138         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1139         MULTIPID=$!
1140
1141         trap cleanup_multiop_pause EXIT
1142         mrename $DIR/R13a $DIR/R13b
1143         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1144         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1145         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1146         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1147         cleanup_multiop_pause
1148         wait $MULTIPID || error "multiop close failed"
1149 }
1150 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1151
1152 test_24r() { #bug 3789
1153         test_mkdir $DIR/R14a
1154         test_mkdir $DIR/R14a/b
1155         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1156         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1157         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1158 }
1159 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1160
1161 test_24s() {
1162         test_mkdir $DIR/R15a
1163         test_mkdir $DIR/R15a/b
1164         test_mkdir $DIR/R15a/b/c
1165         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1166         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1167         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1168 }
1169 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1170
1171 test_24t() {
1172         test_mkdir $DIR/R16a
1173         test_mkdir $DIR/R16a/b
1174         test_mkdir $DIR/R16a/b/c
1175         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1176         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1177         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1178 }
1179 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1180
1181 test_24u() { # bug12192
1182         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1183         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1184 }
1185 run_test 24u "create stripe file"
1186
1187 simple_cleanup_common() {
1188         local createmany=$1
1189         local rc=0
1190
1191         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1192
1193         local start=$SECONDS
1194
1195         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1196         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1197         rc=$?
1198         wait_delete_completed
1199         echo "cleanup time $((SECONDS - start))"
1200         return $rc
1201 }
1202
1203 max_pages_per_rpc() {
1204         local mdtname="$(printf "MDT%04x" ${1:-0})"
1205         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1206 }
1207
1208 test_24v() {
1209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1210
1211         local nrfiles=${COUNT:-100000}
1212         local fname="$DIR/$tdir/$tfile"
1213
1214         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1215         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1216
1217         test_mkdir "$(dirname $fname)"
1218         # assume MDT0000 has the fewest inodes
1219         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1220         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1221         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1222
1223         stack_trap "simple_cleanup_common $nrfiles"
1224
1225         createmany -m "$fname" $nrfiles
1226
1227         cancel_lru_locks mdc
1228         lctl set_param mdc.*.stats clear
1229
1230         # was previously test_24D: LU-6101
1231         # readdir() returns correct number of entries after cursor reload
1232         local num_ls=$(ls $DIR/$tdir | wc -l)
1233         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1234         local num_all=$(ls -a $DIR/$tdir | wc -l)
1235         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1236                 [ $num_all -ne $((nrfiles + 2)) ]; then
1237                         error "Expected $nrfiles files, got $num_ls " \
1238                                 "($num_uniq unique $num_all .&..)"
1239         fi
1240         # LU-5 large readdir
1241         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1242         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1243         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1244         # take into account of overhead in lu_dirpage header and end mark in
1245         # each page, plus one in rpc_num calculation.
1246         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1247         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1248         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1249         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1250         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1251         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1252         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1253         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1254                 error "large readdir doesn't take effect: " \
1255                       "$mds_readpage should be about $rpc_max"
1256 }
1257 run_test 24v "list large directory (test hash collision, b=17560)"
1258
1259 test_24w() { # bug21506
1260         SZ1=234852
1261         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1262         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1263         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1264         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1265         [[ "$SZ1" -eq "$SZ2" ]] ||
1266                 error "Error reading at the end of the file $tfile"
1267 }
1268 run_test 24w "Reading a file larger than 4Gb"
1269
1270 test_24x() {
1271         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1273         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1274                 skip "Need MDS version at least 2.7.56"
1275
1276         local MDTIDX=1
1277         local remote_dir=$DIR/$tdir/remote_dir
1278
1279         test_mkdir $DIR/$tdir
1280         $LFS mkdir -i $MDTIDX $remote_dir ||
1281                 error "create remote directory failed"
1282
1283         test_mkdir $DIR/$tdir/src_dir
1284         touch $DIR/$tdir/src_file
1285         test_mkdir $remote_dir/tgt_dir
1286         touch $remote_dir/tgt_file
1287
1288         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1289                 error "rename dir cross MDT failed!"
1290
1291         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1292                 error "rename file cross MDT failed!"
1293
1294         touch $DIR/$tdir/ln_file
1295         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1296                 error "ln file cross MDT failed"
1297
1298         rm -rf $DIR/$tdir || error "Can not delete directories"
1299 }
1300 run_test 24x "cross MDT rename/link"
1301
1302 test_24y() {
1303         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1304         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1305
1306         local remote_dir=$DIR/$tdir/remote_dir
1307         local mdtidx=1
1308
1309         test_mkdir $DIR/$tdir
1310         $LFS mkdir -i $mdtidx $remote_dir ||
1311                 error "create remote directory failed"
1312
1313         test_mkdir $remote_dir/src_dir
1314         touch $remote_dir/src_file
1315         test_mkdir $remote_dir/tgt_dir
1316         touch $remote_dir/tgt_file
1317
1318         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1319                 error "rename subdir in the same remote dir failed!"
1320
1321         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1322                 error "rename files in the same remote dir failed!"
1323
1324         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1325                 error "link files in the same remote dir failed!"
1326
1327         rm -rf $DIR/$tdir || error "Can not delete directories"
1328 }
1329 run_test 24y "rename/link on the same dir should succeed"
1330
1331 test_24z() {
1332         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1333         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1334                 skip "Need MDS version at least 2.12.51"
1335
1336         local index
1337
1338         for index in 0 1; do
1339                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1340                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1341         done
1342
1343         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1344
1345         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1346         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1347
1348         local mdts=$(comma_list $(mdts_nodes))
1349
1350         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1351         stack_trap "do_nodes $mdts $LCTL \
1352                 set_param mdt.*.enable_remote_rename=1" EXIT
1353
1354         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1355
1356         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1357         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1358 }
1359 run_test 24z "cross-MDT rename is done as cp"
1360
1361 test_24A() { # LU-3182
1362         local NFILES=5000
1363
1364         test_mkdir $DIR/$tdir
1365         stack_trap "simple_cleanup_common $NFILES"
1366         createmany -m $DIR/$tdir/$tfile $NFILES
1367         local t=$(ls $DIR/$tdir | wc -l)
1368         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1369         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1370
1371         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1372                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1373 }
1374 run_test 24A "readdir() returns correct number of entries."
1375
1376 test_24B() { # LU-4805
1377         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1378
1379         local count
1380
1381         test_mkdir $DIR/$tdir
1382         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir/ ||
1383                 error "create striped dir failed"
1384
1385         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1386         [ $count -eq 2 ] || error "Expected 2, got $count"
1387
1388         touch $DIR/$tdir/striped_dir/a
1389
1390         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1391         [ $count -eq 3 ] || error "Expected 3, got $count"
1392
1393         touch $DIR/$tdir/striped_dir/.f
1394
1395         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1396         [ $count -eq 4 ] || error "Expected 4, got $count"
1397
1398         rm -rf $DIR/$tdir || error "Can not delete directories"
1399 }
1400 run_test 24B "readdir for striped dir return correct number of entries"
1401
1402 test_24C() {
1403         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1404
1405         mkdir $DIR/$tdir
1406         mkdir $DIR/$tdir/d0
1407         mkdir $DIR/$tdir/d1
1408
1409         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1410                 error "create striped dir failed"
1411
1412         cd $DIR/$tdir/d0/striped_dir
1413
1414         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1415         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1416         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1417
1418         [ "$d0_ino" = "$parent_ino" ] ||
1419                 error ".. wrong, expect $d0_ino, get $parent_ino"
1420
1421         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1422                 error "mv striped dir failed"
1423
1424         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1425
1426         [ "$d1_ino" = "$parent_ino" ] ||
1427                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1428 }
1429 run_test 24C "check .. in striped dir"
1430
1431 test_24E() {
1432         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1434
1435         mkdir -p $DIR/$tdir
1436         mkdir $DIR/$tdir/src_dir
1437         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1438                 error "create remote source failed"
1439
1440         touch $DIR/$tdir/src_dir/src_child/a
1441
1442         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1443                 error "create remote target dir failed"
1444
1445         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1446                 error "create remote target child failed"
1447
1448         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1449                 error "rename dir cross MDT failed!"
1450
1451         find $DIR/$tdir
1452
1453         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1454                 error "src_child still exists after rename"
1455
1456         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1457                 error "missing file(a) after rename"
1458
1459         rm -rf $DIR/$tdir || error "Can not delete directories"
1460 }
1461 run_test 24E "cross MDT rename/link"
1462
1463 test_24F () {
1464         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1465
1466         local repeats=1000
1467         [ "$SLOW" = "no" ] && repeats=100
1468
1469         mkdir -p $DIR/$tdir
1470
1471         echo "$repeats repeats"
1472         for ((i = 0; i < repeats; i++)); do
1473                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1474                 touch $DIR/$tdir/test/a || error "touch fails"
1475                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1476                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1477         done
1478
1479         true
1480 }
1481 run_test 24F "hash order vs readdir (LU-11330)"
1482
1483 test_24G () {
1484         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1485
1486         local ino1
1487         local ino2
1488
1489         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1490         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1491         touch $DIR/$tdir-0/f1 || error "touch f1"
1492         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1493         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1494         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1495         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1496         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1497 }
1498 run_test 24G "migrate symlink in rename"
1499
1500 test_24H() {
1501         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1502         [[ $(hostname) != $(facet_active_host mds2) ]] ||
1503                 skip "MDT1 should be on another node"
1504
1505         test_mkdir -i 1 -c 1 $DIR/$tdir
1506 #define OBD_FAIL_FLD_QUERY_REQ           0x1103
1507         do_facet mds2 $LCTL set_param fail_loc=0x80001103
1508         touch $DIR/$tdir/$tfile || error "touch failed"
1509 }
1510 run_test 24H "repeat FLD_QUERY rpc"
1511
1512 test_25a() {
1513         echo '== symlink sanity ============================================='
1514
1515         test_mkdir $DIR/d25
1516         ln -s d25 $DIR/s25
1517         touch $DIR/s25/foo ||
1518                 error "File creation in symlinked directory failed"
1519 }
1520 run_test 25a "create file in symlinked directory ==============="
1521
1522 test_25b() {
1523         [ ! -d $DIR/d25 ] && test_25a
1524         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1525 }
1526 run_test 25b "lookup file in symlinked directory ==============="
1527
1528 test_26a() {
1529         test_mkdir $DIR/d26
1530         test_mkdir $DIR/d26/d26-2
1531         ln -s d26/d26-2 $DIR/s26
1532         touch $DIR/s26/foo || error "File creation failed"
1533 }
1534 run_test 26a "multiple component symlink ======================="
1535
1536 test_26b() {
1537         test_mkdir -p $DIR/$tdir/d26-2
1538         ln -s $tdir/d26-2/foo $DIR/s26-2
1539         touch $DIR/s26-2 || error "File creation failed"
1540 }
1541 run_test 26b "multiple component symlink at end of lookup ======"
1542
1543 test_26c() {
1544         test_mkdir $DIR/d26.2
1545         touch $DIR/d26.2/foo
1546         ln -s d26.2 $DIR/s26.2-1
1547         ln -s s26.2-1 $DIR/s26.2-2
1548         ln -s s26.2-2 $DIR/s26.2-3
1549         chmod 0666 $DIR/s26.2-3/foo
1550 }
1551 run_test 26c "chain of symlinks"
1552
1553 # recursive symlinks (bug 439)
1554 test_26d() {
1555         ln -s d26-3/foo $DIR/d26-3
1556 }
1557 run_test 26d "create multiple component recursive symlink"
1558
1559 test_26e() {
1560         [ ! -h $DIR/d26-3 ] && test_26d
1561         rm $DIR/d26-3
1562 }
1563 run_test 26e "unlink multiple component recursive symlink"
1564
1565 # recursive symlinks (bug 7022)
1566 test_26f() {
1567         test_mkdir $DIR/$tdir
1568         test_mkdir $DIR/$tdir/$tfile
1569         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1570         test_mkdir -p lndir/bar1
1571         test_mkdir $DIR/$tdir/$tfile/$tfile
1572         cd $tfile                || error "cd $tfile failed"
1573         ln -s .. dotdot          || error "ln dotdot failed"
1574         ln -s dotdot/lndir lndir || error "ln lndir failed"
1575         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1576         output=`ls $tfile/$tfile/lndir/bar1`
1577         [ "$output" = bar1 ] && error "unexpected output"
1578         rm -r $tfile             || error "rm $tfile failed"
1579         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1580 }
1581 run_test 26f "rm -r of a directory which has recursive symlink"
1582
1583 test_27a() {
1584         test_mkdir $DIR/$tdir
1585         $LFS getstripe $DIR/$tdir
1586         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1587         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1588         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1589 }
1590 run_test 27a "one stripe file"
1591
1592 test_27b() {
1593         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1594
1595         test_mkdir $DIR/$tdir
1596         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1597         $LFS getstripe -c $DIR/$tdir/$tfile
1598         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1599                 error "two-stripe file doesn't have two stripes"
1600
1601         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1602 }
1603 run_test 27b "create and write to two stripe file"
1604
1605 # 27c family tests specific striping, setstripe -o
1606 test_27ca() {
1607         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1608         test_mkdir -p $DIR/$tdir
1609         local osts="1"
1610
1611         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1612         $LFS getstripe -i $DIR/$tdir/$tfile
1613         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1614                 error "stripe not on specified OST"
1615
1616         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1617 }
1618 run_test 27ca "one stripe on specified OST"
1619
1620 test_27cb() {
1621         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1622         test_mkdir -p $DIR/$tdir
1623         local osts="1,0"
1624         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1625         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1626         echo "$getstripe"
1627
1628         # Strip getstripe output to a space separated list of OSTs
1629         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1630                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1631         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1632                 error "stripes not on specified OSTs"
1633
1634         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1635 }
1636 run_test 27cb "two stripes on specified OSTs"
1637
1638 test_27cc() {
1639         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1640         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1641                 skip "server does not support overstriping"
1642
1643         test_mkdir -p $DIR/$tdir
1644         local osts="0,0"
1645         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1646         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1647         echo "$getstripe"
1648
1649         # Strip getstripe output to a space separated list of OSTs
1650         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1651                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1652         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1653                 error "stripes not on specified OSTs"
1654
1655         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1656 }
1657 run_test 27cc "two stripes on the same OST"
1658
1659 test_27cd() {
1660         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1661         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1662                 skip "server does not support overstriping"
1663         test_mkdir -p $DIR/$tdir
1664         local osts="0,1,1,0"
1665         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1666         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1667         echo "$getstripe"
1668
1669         # Strip getstripe output to a space separated list of OSTs
1670         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1671                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1672         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1673                 error "stripes not on specified OSTs"
1674
1675         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1676 }
1677 run_test 27cd "four stripes on two OSTs"
1678
1679 test_27ce() {
1680         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1681                 skip_env "too many osts, skipping"
1682         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1683                 skip "server does not support overstriping"
1684         # We do one more stripe than we have OSTs
1685         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1686                 skip_env "ea_inode feature disabled"
1687
1688         test_mkdir -p $DIR/$tdir
1689         local osts=""
1690         for i in $(seq 0 $OSTCOUNT);
1691         do
1692                 osts=$osts"0"
1693                 if [ $i -ne $OSTCOUNT ]; then
1694                         osts=$osts","
1695                 fi
1696         done
1697         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1698         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1699         echo "$getstripe"
1700
1701         # Strip getstripe output to a space separated list of OSTs
1702         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1703                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1704         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1705                 error "stripes not on specified OSTs"
1706
1707         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1708 }
1709 run_test 27ce "more stripes than OSTs with -o"
1710
1711 test_27cf() {
1712         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1713         local pid=0
1714
1715         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1716         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1717         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1718         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1719                 error "failed to set $osp_proc=0"
1720
1721         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1722         pid=$!
1723         sleep 1
1724         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1725         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1726                 error "failed to set $osp_proc=1"
1727         wait $pid
1728         [[ $pid -ne 0 ]] ||
1729                 error "should return error due to $osp_proc=0"
1730 }
1731 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1732
1733 test_27cg() {
1734         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1735                 skip "server does not support overstriping"
1736         [[ $mds1_FSTYPE != "ldiskfs" ]] && skip_env "ldiskfs only test"
1737         large_xattr_enabled || skip_env "ea_inode feature disabled"
1738
1739         local osts="0"
1740
1741         for ((i=1;i<1000;i++)); do
1742                 osts+=",$((i % OSTCOUNT))"
1743         done
1744
1745         local mdts=$(comma_list $(mdts_nodes))
1746         local before=$(do_nodes $mdts \
1747                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1748                 awk '/many credits/{print $3}' |
1749                 calc_sum)
1750
1751         $LFS setstripe -o $osts $DIR/$tfile || error "setstripe failed"
1752         $LFS getstripe $DIR/$tfile | grep stripe
1753
1754         rm -f $DIR/$tfile || error "can't unlink"
1755
1756         after=$(do_nodes $mdts \
1757                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1758                 awk '/many credits/{print $3}' |
1759                 calc_sum)
1760
1761         (( before == after )) ||
1762                 error "too many credits happened: $after > $before"
1763 }
1764 run_test 27cg "1000 shouldn't cause too many credits"
1765
1766 test_27d() {
1767         test_mkdir $DIR/$tdir
1768         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1769                 error "setstripe failed"
1770         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1771         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1772 }
1773 run_test 27d "create file with default settings"
1774
1775 test_27e() {
1776         # LU-5839 adds check for existed layout before setting it
1777         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1778                 skip "Need MDS version at least 2.7.56"
1779
1780         test_mkdir $DIR/$tdir
1781         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1782         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1783         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1784 }
1785 run_test 27e "setstripe existing file (should return error)"
1786
1787 test_27f() {
1788         test_mkdir $DIR/$tdir
1789         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1790                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1791         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1792                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1793         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1794         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1795 }
1796 run_test 27f "setstripe with bad stripe size (should return error)"
1797
1798 test_27g() {
1799         test_mkdir $DIR/$tdir
1800         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1801         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1802                 error "$DIR/$tdir/$tfile has object"
1803 }
1804 run_test 27g "$LFS getstripe with no objects"
1805
1806 test_27ga() {
1807         test_mkdir $DIR/$tdir
1808         touch $DIR/$tdir/$tfile || error "touch failed"
1809         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1810         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1811         local rc=$?
1812         (( rc == 2 )) || error "getstripe did not return ENOENT"
1813
1814         local err_msg=$($LFS getstripe $DIR/$tdir/typo $DIR/$tdir/$tfile \
1815                         2>&1 > /dev/null)
1816         [[ $err_msg =~ "typo" ]] ||
1817                 error "expected message with correct filename, got '$err_msg'"
1818 }
1819 run_test 27ga "$LFS getstripe with missing file (should return error)"
1820
1821 test_27i() {
1822         test_mkdir $DIR/$tdir
1823         touch $DIR/$tdir/$tfile || error "touch failed"
1824         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1825                 error "missing objects"
1826 }
1827 run_test 27i "$LFS getstripe with some objects"
1828
1829 test_27j() {
1830         test_mkdir $DIR/$tdir
1831         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1832                 error "setstripe failed" || true
1833 }
1834 run_test 27j "setstripe with bad stripe offset (should return error)"
1835
1836 test_27k() { # bug 2844
1837         test_mkdir $DIR/$tdir
1838         local file=$DIR/$tdir/$tfile
1839         local ll_max_blksize=$((4 * 1024 * 1024))
1840         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1841         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1842         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1843         dd if=/dev/zero of=$file bs=4k count=1
1844         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1845         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1846 }
1847 run_test 27k "limit i_blksize for broken user apps"
1848
1849 test_27l() {
1850         mcreate $DIR/$tfile || error "creating file"
1851         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1852                 error "setstripe should have failed" || true
1853 }
1854 run_test 27l "check setstripe permissions (should return error)"
1855
1856 test_27m() {
1857         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1858
1859         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1860                 skip_env "multiple clients -- skipping"
1861
1862         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1863                    head -n1)
1864         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1865                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1866         fi
1867         stack_trap simple_cleanup_common
1868         test_mkdir $DIR/$tdir
1869         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1870         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1871                 error "dd should fill OST0"
1872         i=2
1873         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1874                 i=$((i + 1))
1875                 [ $i -gt 256 ] && break
1876         done
1877         i=$((i + 1))
1878         touch $DIR/$tdir/$tfile.$i
1879         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1880             awk '{print $1}'| grep -w "0") ] &&
1881                 error "OST0 was full but new created file still use it"
1882         i=$((i + 1))
1883         touch $DIR/$tdir/$tfile.$i
1884         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1885             awk '{print $1}'| grep -w "0") ] &&
1886                 error "OST0 was full but new created file still use it" || true
1887 }
1888 run_test 27m "create file while OST0 was full"
1889
1890 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1891 # if the OST isn't full anymore.
1892 reset_enospc() {
1893         local ostidx=${1:-""}
1894         local delay
1895         local ready
1896         local get_prealloc
1897
1898         local list=$(comma_list $(osts_nodes))
1899         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1900
1901         do_nodes $list lctl set_param fail_loc=0
1902         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1903         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1904                 awk '{print $1 * 2;exit;}')
1905         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1906                         grep -v \"^0$\""
1907         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1908 }
1909
1910 test_27n() {
1911         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1913         remote_mds_nodsh && skip "remote MDS with nodsh"
1914         remote_ost_nodsh && skip "remote OST with nodsh"
1915
1916         reset_enospc
1917         rm -f $DIR/$tdir/$tfile
1918         exhaust_precreations 0 0x80000215
1919         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1920         touch $DIR/$tdir/$tfile || error "touch failed"
1921         $LFS getstripe $DIR/$tdir/$tfile
1922         reset_enospc
1923 }
1924 run_test 27n "create file with some full OSTs"
1925
1926 test_27o() {
1927         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1929         remote_mds_nodsh && skip "remote MDS with nodsh"
1930         remote_ost_nodsh && skip "remote OST with nodsh"
1931
1932         reset_enospc
1933         rm -f $DIR/$tdir/$tfile
1934         exhaust_all_precreations 0x215
1935
1936         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1937
1938         reset_enospc
1939         rm -rf $DIR/$tdir/*
1940 }
1941 run_test 27o "create file with all full OSTs (should error)"
1942
1943 function create_and_checktime() {
1944         local fname=$1
1945         local loops=$2
1946         local i
1947
1948         for ((i=0; i < $loops; i++)); do
1949                 local start=$SECONDS
1950                 multiop $fname-$i Oc
1951                 ((SECONDS-start < TIMEOUT)) ||
1952                         error "creation took " $((SECONDS-$start)) && return 1
1953         done
1954 }
1955
1956 test_27oo() {
1957         local mdts=$(comma_list $(mdts_nodes))
1958
1959         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1960                 skip "Need MDS version at least 2.13.57"
1961
1962         local f0=$DIR/${tfile}-0
1963         local f1=$DIR/${tfile}-1
1964
1965         wait_delete_completed
1966
1967         # refill precreated objects
1968         $LFS setstripe -i0 -c1 $f0
1969
1970         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1971         # force QoS allocation policy
1972         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1973         stack_trap "do_nodes $mdts $LCTL set_param \
1974                 lov.*.qos_threshold_rr=$saved" EXIT
1975         sleep_maxage
1976
1977         # one OST is unavailable, but still have few objects preallocated
1978         stop ost1
1979         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1980                 rm -rf $f1 $DIR/$tdir*" EXIT
1981
1982         for ((i=0; i < 7; i++)); do
1983                 mkdir $DIR/$tdir$i || error "can't create dir"
1984                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1985                         error "can't set striping"
1986         done
1987         for ((i=0; i < 7; i++)); do
1988                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1989         done
1990         wait
1991 }
1992 run_test 27oo "don't let few threads to reserve too many objects"
1993
1994 test_27p() {
1995         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1997         remote_mds_nodsh && skip "remote MDS with nodsh"
1998         remote_ost_nodsh && skip "remote OST with nodsh"
1999
2000         reset_enospc
2001         rm -f $DIR/$tdir/$tfile
2002         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
2003
2004         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
2005         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
2006         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
2007
2008         exhaust_precreations 0 0x80000215
2009         echo foo >> $DIR/$tdir/$tfile || error "append failed"
2010         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
2011         $LFS getstripe $DIR/$tdir/$tfile
2012
2013         reset_enospc
2014 }
2015 run_test 27p "append to a truncated file with some full OSTs"
2016
2017 test_27q() {
2018         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2019         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2020         remote_mds_nodsh && skip "remote MDS with nodsh"
2021         remote_ost_nodsh && skip "remote OST with nodsh"
2022
2023         reset_enospc
2024         rm -f $DIR/$tdir/$tfile
2025
2026         mkdir_on_mdt0 $DIR/$tdir
2027         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
2028         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
2029                 error "truncate $DIR/$tdir/$tfile failed"
2030         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
2031
2032         exhaust_all_precreations 0x215
2033
2034         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
2035         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
2036
2037         reset_enospc
2038 }
2039 run_test 27q "append to truncated file with all OSTs full (should error)"
2040
2041 test_27r() {
2042         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2044         remote_mds_nodsh && skip "remote MDS with nodsh"
2045         remote_ost_nodsh && skip "remote OST with nodsh"
2046
2047         reset_enospc
2048         rm -f $DIR/$tdir/$tfile
2049         exhaust_precreations 0 0x80000215
2050
2051         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2052
2053         reset_enospc
2054 }
2055 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2056
2057 test_27s() { # bug 10725
2058         test_mkdir $DIR/$tdir
2059         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2060         local stripe_count=0
2061         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2062         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2063                 error "stripe width >= 2^32 succeeded" || true
2064
2065 }
2066 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2067
2068 test_27t() { # bug 10864
2069         WDIR=$(pwd)
2070         WLFS=$(which lfs)
2071         cd $DIR
2072         touch $tfile
2073         $WLFS getstripe $tfile
2074         cd $WDIR
2075 }
2076 run_test 27t "check that utils parse path correctly"
2077
2078 test_27u() { # bug 4900
2079         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2080         remote_mds_nodsh && skip "remote MDS with nodsh"
2081
2082         local index
2083         local list=$(comma_list $(mdts_nodes))
2084
2085 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2086         do_nodes $list $LCTL set_param fail_loc=0x139
2087         test_mkdir -p $DIR/$tdir
2088         stack_trap "simple_cleanup_common 1000"
2089         createmany -o $DIR/$tdir/$tfile 1000
2090         do_nodes $list $LCTL set_param fail_loc=0
2091
2092         TLOG=$TMP/$tfile.getstripe
2093         $LFS getstripe $DIR/$tdir > $TLOG
2094         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2095         [[ $OBJS -gt 0 ]] &&
2096                 error "$OBJS objects created on OST-0. See $TLOG" ||
2097                 rm -f $TLOG
2098 }
2099 run_test 27u "skip object creation on OSC w/o objects"
2100
2101 test_27v() { # bug 4900
2102         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2104         remote_mds_nodsh && skip "remote MDS with nodsh"
2105         remote_ost_nodsh && skip "remote OST with nodsh"
2106
2107         exhaust_all_precreations 0x215
2108         reset_enospc
2109
2110         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2111
2112         touch $DIR/$tdir/$tfile
2113         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2114         # all except ost1
2115         for (( i=1; i < OSTCOUNT; i++ )); do
2116                 do_facet ost$i lctl set_param fail_loc=0x705
2117         done
2118         local START=`date +%s`
2119         createmany -o $DIR/$tdir/$tfile 32
2120
2121         local FINISH=`date +%s`
2122         local TIMEOUT=`lctl get_param -n timeout`
2123         local PROCESS=$((FINISH - START))
2124         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2125                error "$FINISH - $START >= $TIMEOUT / 2"
2126         sleep $((TIMEOUT / 2 - PROCESS))
2127         reset_enospc
2128 }
2129 run_test 27v "skip object creation on slow OST"
2130
2131 test_27w() { # bug 10997
2132         test_mkdir $DIR/$tdir
2133         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2134         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2135                 error "stripe size $size != 65536" || true
2136         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2137                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2138 }
2139 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2140
2141 test_27wa() {
2142         [[ $OSTCOUNT -lt 2 ]] &&
2143                 skip_env "skipping multiple stripe count/offset test"
2144
2145         test_mkdir $DIR/$tdir
2146         for i in $(seq 1 $OSTCOUNT); do
2147                 offset=$((i - 1))
2148                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2149                         error "setstripe -c $i -i $offset failed"
2150                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2151                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2152                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2153                 [ $index -ne $offset ] &&
2154                         error "stripe offset $index != $offset" || true
2155         done
2156 }
2157 run_test 27wa "check $LFS setstripe -c -i options"
2158
2159 test_27x() {
2160         remote_ost_nodsh && skip "remote OST with nodsh"
2161         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2163
2164         OFFSET=$(($OSTCOUNT - 1))
2165         OSTIDX=0
2166         local OST=$(ostname_from_index $OSTIDX)
2167
2168         test_mkdir $DIR/$tdir
2169         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2170         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2171         sleep_maxage
2172         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2173         for i in $(seq 0 $OFFSET); do
2174                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2175                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2176                 error "OST0 was degraded but new created file still use it"
2177         done
2178         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2179 }
2180 run_test 27x "create files while OST0 is degraded"
2181
2182 test_27y() {
2183         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2184         remote_mds_nodsh && skip "remote MDS with nodsh"
2185         remote_ost_nodsh && skip "remote OST with nodsh"
2186         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2187
2188         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2189         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2190                 osp.$mdtosc.prealloc_last_id)
2191         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2192                 osp.$mdtosc.prealloc_next_id)
2193         local fcount=$((last_id - next_id))
2194         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2195         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2196
2197         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2198                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2199         local OST_DEACTIVE_IDX=-1
2200         local OSC
2201         local OSTIDX
2202         local OST
2203
2204         for OSC in $MDS_OSCS; do
2205                 OST=$(osc_to_ost $OSC)
2206                 OSTIDX=$(index_from_ostuuid $OST)
2207                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2208                         OST_DEACTIVE_IDX=$OSTIDX
2209                 fi
2210                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2211                         echo $OSC "is Deactivated:"
2212                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2213                 fi
2214         done
2215
2216         OSTIDX=$(index_from_ostuuid $OST)
2217         test_mkdir $DIR/$tdir
2218         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2219
2220         for OSC in $MDS_OSCS; do
2221                 OST=$(osc_to_ost $OSC)
2222                 OSTIDX=$(index_from_ostuuid $OST)
2223                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2224                         echo $OST "is degraded:"
2225                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2226                                                 obdfilter.$OST.degraded=1
2227                 fi
2228         done
2229
2230         sleep_maxage
2231         createmany -o $DIR/$tdir/$tfile $fcount
2232
2233         for OSC in $MDS_OSCS; do
2234                 OST=$(osc_to_ost $OSC)
2235                 OSTIDX=$(index_from_ostuuid $OST)
2236                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2237                         echo $OST "is recovered from degraded:"
2238                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2239                                                 obdfilter.$OST.degraded=0
2240                 else
2241                         do_facet $SINGLEMDS lctl --device %$OSC activate
2242                 fi
2243         done
2244
2245         # all osp devices get activated, hence -1 stripe count restored
2246         local stripe_count=0
2247
2248         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2249         # devices get activated.
2250         sleep_maxage
2251         $LFS setstripe -c -1 $DIR/$tfile
2252         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2253         rm -f $DIR/$tfile
2254         [ $stripe_count -ne $OSTCOUNT ] &&
2255                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2256         return 0
2257 }
2258 run_test 27y "create files while OST0 is degraded and the rest inactive"
2259
2260 check_seq_oid()
2261 {
2262         log "check file $1"
2263
2264         lmm_count=$($LFS getstripe -c $1)
2265         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2266         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2267
2268         local old_ifs="$IFS"
2269         IFS=$'[:]'
2270         fid=($($LFS path2fid $1))
2271         IFS="$old_ifs"
2272
2273         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2274         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2275
2276         # compare lmm_seq and lu_fid->f_seq
2277         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2278         # compare lmm_object_id and lu_fid->oid
2279         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2280
2281         # check the trusted.fid attribute of the OST objects of the file
2282         local have_obdidx=false
2283         local stripe_nr=0
2284         $LFS getstripe $1 | while read obdidx oid hex seq; do
2285                 # skip lines up to and including "obdidx"
2286                 [ -z "$obdidx" ] && break
2287                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2288                 $have_obdidx || continue
2289
2290                 local ost=$((obdidx + 1))
2291                 local dev=$(ostdevname $ost)
2292                 local oid_hex
2293
2294                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2295
2296                 seq=$(echo $seq | sed -e "s/^0x//g")
2297                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2298                         oid_hex=$(echo $oid)
2299                 else
2300                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2301                 fi
2302                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2303
2304                 local ff=""
2305                 #
2306                 # Don't unmount/remount the OSTs if we don't need to do that.
2307                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2308                 # update too, until that use mount/ll_decode_filter_fid/mount.
2309                 # Re-enable when debugfs will understand new filter_fid.
2310                 #
2311                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2312                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2313                                 $dev 2>/dev/null" | grep "parent=")
2314                 fi
2315                 if [ -z "$ff" ]; then
2316                         stop ost$ost
2317                         mount_fstype ost$ost
2318                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2319                                 $(facet_mntpt ost$ost)/$obj_file)
2320                         unmount_fstype ost$ost
2321                         start ost$ost $dev $OST_MOUNT_OPTS
2322                         clients_up
2323                 fi
2324
2325                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2326
2327                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2328
2329                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2330                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2331                 #
2332                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2333                 #       stripe_size=1048576 component_id=1 component_start=0 \
2334                 #       component_end=33554432
2335                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2336                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2337                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2338                 local ff_pstripe
2339                 if grep -q 'stripe=' <<<$ff; then
2340                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2341                 else
2342                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2343                         # into f_ver in this case.  See comment on ff_parent.
2344                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2345                 fi
2346
2347                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2348                 [ $ff_pseq = $lmm_seq ] ||
2349                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2350                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2351                 [ $ff_poid = $lmm_oid ] ||
2352                         error "FF parent OID $ff_poid != $lmm_oid"
2353                 (($ff_pstripe == $stripe_nr)) ||
2354                         error "FF stripe $ff_pstripe != $stripe_nr"
2355
2356                 stripe_nr=$((stripe_nr + 1))
2357                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2358                         continue
2359                 if grep -q 'stripe_count=' <<<$ff; then
2360                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2361                                             -e 's/ .*//' <<<$ff)
2362                         [ $lmm_count = $ff_scnt ] ||
2363                                 error "FF stripe count $lmm_count != $ff_scnt"
2364                 fi
2365         done
2366 }
2367
2368 test_27z() {
2369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2370         remote_ost_nodsh && skip "remote OST with nodsh"
2371
2372         test_mkdir $DIR/$tdir
2373         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2374                 { error "setstripe -c -1 failed"; return 1; }
2375         # We need to send a write to every object to get parent FID info set.
2376         # This _should_ also work for setattr, but does not currently.
2377         # touch $DIR/$tdir/$tfile-1 ||
2378         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2379                 { error "dd $tfile-1 failed"; return 2; }
2380         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2381                 { error "setstripe -c -1 failed"; return 3; }
2382         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2383                 { error "dd $tfile-2 failed"; return 4; }
2384
2385         # make sure write RPCs have been sent to OSTs
2386         sync; sleep 5; sync
2387
2388         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2389         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2390 }
2391 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2392
2393 test_27A() { # b=19102
2394         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2395
2396         save_layout_restore_at_exit $MOUNT
2397         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2398         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2399                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2400         local default_size=$($LFS getstripe -S $MOUNT)
2401         local default_offset=$($LFS getstripe -i $MOUNT)
2402         local dsize=$(do_facet $SINGLEMDS \
2403                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2404         [ $default_size -eq $dsize ] ||
2405                 error "stripe size $default_size != $dsize"
2406         [ $default_offset -eq -1 ] ||
2407                 error "stripe offset $default_offset != -1"
2408 }
2409 run_test 27A "check filesystem-wide default LOV EA values"
2410
2411 test_27B() { # LU-2523
2412         test_mkdir $DIR/$tdir
2413         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2414         touch $DIR/$tdir/f0
2415         # open f1 with O_LOV_DELAY_CREATE
2416         # rename f0 onto f1
2417         # call setstripe ioctl on open file descriptor for f1
2418         # close
2419         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2420                 $DIR/$tdir/f0
2421
2422         rm -f $DIR/$tdir/f1
2423         # open f1 with O_LOV_DELAY_CREATE
2424         # unlink f1
2425         # call setstripe ioctl on open file descriptor for f1
2426         # close
2427         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2428
2429         # Allow multiop to fail in imitation of NFS's busted semantics.
2430         true
2431 }
2432 run_test 27B "call setstripe on open unlinked file/rename victim"
2433
2434 # 27C family tests full striping and overstriping
2435 test_27Ca() { #LU-2871
2436         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2437
2438         declare -a ost_idx
2439         local index
2440         local found
2441         local i
2442         local j
2443
2444         test_mkdir $DIR/$tdir
2445         cd $DIR/$tdir
2446         for i in $(seq 0 $((OSTCOUNT - 1))); do
2447                 # set stripe across all OSTs starting from OST$i
2448                 $LFS setstripe -i $i -c -1 $tfile$i
2449                 # get striping information
2450                 ost_idx=($($LFS getstripe $tfile$i |
2451                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2452                 echo "OST Index: ${ost_idx[*]}"
2453
2454                 # check the layout
2455                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2456                         error "${#ost_idx[@]} != $OSTCOUNT"
2457
2458                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2459                         found=0
2460                         for j in "${ost_idx[@]}"; do
2461                                 if [ $index -eq $j ]; then
2462                                         found=1
2463                                         break
2464                                 fi
2465                         done
2466                         [ $found = 1 ] ||
2467                                 error "Can not find $index in ${ost_idx[*]}"
2468                 done
2469         done
2470 }
2471 run_test 27Ca "check full striping across all OSTs"
2472
2473 test_27Cb() {
2474         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2475                 skip "server does not support overstriping"
2476         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2477                 skip_env "too many osts, skipping"
2478
2479         test_mkdir -p $DIR/$tdir
2480         local setcount=$(($OSTCOUNT * 2))
2481         [ $setcount -lt 160 ] || large_xattr_enabled ||
2482                 skip_env "ea_inode feature disabled"
2483
2484         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2485                 error "setstripe failed"
2486
2487         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2488         [ $count -eq $setcount ] ||
2489                 error "stripe count $count, should be $setcount"
2490
2491         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2492                 error "overstriped should be set in pattern"
2493
2494         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2495                 error "dd failed"
2496 }
2497 run_test 27Cb "more stripes than OSTs with -C"
2498
2499 test_27Cc() {
2500         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2501                 skip "server does not support overstriping"
2502         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2503
2504         test_mkdir -p $DIR/$tdir
2505         local setcount=$(($OSTCOUNT - 1))
2506
2507         [ $setcount -lt 160 ] || large_xattr_enabled ||
2508                 skip_env "ea_inode feature disabled"
2509
2510         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2511                 error "setstripe failed"
2512
2513         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2514         [ $count -eq $setcount ] ||
2515                 error "stripe count $count, should be $setcount"
2516
2517         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2518                 error "overstriped should not be set in pattern"
2519
2520         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2521                 error "dd failed"
2522 }
2523 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2524
2525 test_27Cd() {
2526         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2527                 skip "server does not support overstriping"
2528         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2529         large_xattr_enabled || skip_env "ea_inode feature disabled"
2530
2531         force_new_seq_all
2532
2533         test_mkdir -p $DIR/$tdir
2534         local setcount=$LOV_MAX_STRIPE_COUNT
2535
2536         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2537                 error "setstripe failed"
2538
2539         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2540         [ $count -eq $setcount ] ||
2541                 error "stripe count $count, should be $setcount"
2542
2543         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2544                 error "overstriped should be set in pattern"
2545
2546         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2547                 error "dd failed"
2548
2549         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2550 }
2551 run_test 27Cd "test maximum stripe count"
2552
2553 test_27Ce() {
2554         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2555                 skip "server does not support overstriping"
2556         test_mkdir -p $DIR/$tdir
2557
2558         pool_add $TESTNAME || error "Pool creation failed"
2559         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2560
2561         local setcount=8
2562
2563         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2564                 error "setstripe failed"
2565
2566         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2567         [ $count -eq $setcount ] ||
2568                 error "stripe count $count, should be $setcount"
2569
2570         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2571                 error "overstriped should be set in pattern"
2572
2573         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2574                 error "dd failed"
2575
2576         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2577 }
2578 run_test 27Ce "test pool with overstriping"
2579
2580 test_27Cf() {
2581         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2582                 skip "server does not support overstriping"
2583         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2584                 skip_env "too many osts, skipping"
2585
2586         test_mkdir -p $DIR/$tdir
2587
2588         local setcount=$(($OSTCOUNT * 2))
2589         [ $setcount -lt 160 ] || large_xattr_enabled ||
2590                 skip_env "ea_inode feature disabled"
2591
2592         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2593                 error "setstripe failed"
2594
2595         echo 1 > $DIR/$tdir/$tfile
2596
2597         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2598         [ $count -eq $setcount ] ||
2599                 error "stripe count $count, should be $setcount"
2600
2601         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2602                 error "overstriped should be set in pattern"
2603
2604         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2605                 error "dd failed"
2606
2607         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2608 }
2609 run_test 27Cf "test default inheritance with overstriping"
2610
2611 test_27Cg() {
2612         (( MDS1_VERSION >= $(version_code v2_15_55-80-gd96b98ee6b) )) ||
2613                 skip "need MDS version at least v2_15_55-80-gd96b98ee6b for fix"
2614
2615         $LFS setstripe -o 0,$OSTCOUNT $DIR/$tfile
2616         (( $? != 0 )) || error "must be an error for not existent OST#"
2617 }
2618 run_test 27Cg "test setstripe with wrong OST idx"
2619
2620 test_27Ci() {
2621         local tf=$DIR/$tfile
2622
2623         stack_trap "rm -f $DIR/$tfile"
2624
2625         $LFS setstripe -E1M $tf || error "create $tf failed"
2626         $LFS setstripe -Eeof --component-add -C 100 $tf ||
2627                 error "add component failed"
2628
2629         $LFS getstripe -I2 $tf | awk '/lmm_pattern/ { print $2 }' |
2630                 grep "overstriped" || {
2631                 $LFS getstripe $tf
2632                 echo "lose overstriping setting"
2633         }
2634         sc=$($LFS getstripe -I2 --stripe-count $tf)
2635         (( $sc == 100 )) || {
2636                 $LFS getstripe $tf
2637                 echo "lose overstriping setting"
2638         }
2639
2640         stack_trap "rm -f $tf"
2641         dd if=/dev/zero of=$tf bs=1M count=10 || error "write $tf"
2642         sc=$($LFS getstripe -I2 --stripe-count $tf)
2643         (( $sc == 100 )) || {
2644                 $LFS getstripe $tf
2645                 echo "lose overstriping setting after instantiation"
2646         }
2647 }
2648 run_test 27Ci "add an overstriping component"
2649
2650 test_27D() {
2651         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2652         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2653         remote_mds_nodsh && skip "remote MDS with nodsh"
2654
2655         local POOL=${POOL:-testpool}
2656         local first_ost=0
2657         local last_ost=$(($OSTCOUNT - 1))
2658         local ost_step=1
2659         local ost_list=$(seq $first_ost $ost_step $last_ost)
2660         local ost_range="$first_ost $last_ost $ost_step"
2661
2662         test_mkdir $DIR/$tdir
2663         pool_add $POOL || error "pool_add failed"
2664         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2665
2666         local skip27D
2667         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2668                 skip27D+="-s 29"
2669         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2670                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2671                         skip27D+=" -s 30,31"
2672         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2673           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2674                 skip27D+=" -s 32,33"
2675         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2676                 skip27D+=" -s 34"
2677         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2678                 error "llapi_layout_test failed"
2679
2680         destroy_test_pools || error "destroy test pools failed"
2681 }
2682 run_test 27D "validate llapi_layout API"
2683
2684 # Verify that default_easize is increased from its initial value after
2685 # accessing a widely striped file.
2686 test_27E() {
2687         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2688         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2689                 skip "client does not have LU-3338 fix"
2690
2691         # 72 bytes is the minimum space required to store striping
2692         # information for a file striped across one OST:
2693         # (sizeof(struct lov_user_md_v3) +
2694         #  sizeof(struct lov_user_ost_data_v1))
2695         local min_easize=72
2696         $LCTL set_param -n llite.*.default_easize $min_easize ||
2697                 error "lctl set_param failed"
2698         local easize=$($LCTL get_param -n llite.*.default_easize)
2699
2700         [ $easize -eq $min_easize ] ||
2701                 error "failed to set default_easize"
2702
2703         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2704                 error "setstripe failed"
2705         # In order to ensure stat() call actually talks to MDS we need to
2706         # do something drastic to this file to shake off all lock, e.g.
2707         # rename it (kills lookup lock forcing cache cleaning)
2708         mv $DIR/$tfile $DIR/${tfile}-1
2709         ls -l $DIR/${tfile}-1
2710         rm $DIR/${tfile}-1
2711
2712         easize=$($LCTL get_param -n llite.*.default_easize)
2713
2714         [ $easize -gt $min_easize ] ||
2715                 error "default_easize not updated"
2716 }
2717 run_test 27E "check that default extended attribute size properly increases"
2718
2719 test_27F() { # LU-5346/LU-7975
2720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2721         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2722         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2723                 skip "Need MDS version at least 2.8.51"
2724         remote_ost_nodsh && skip "remote OST with nodsh"
2725
2726         test_mkdir $DIR/$tdir
2727         rm -f $DIR/$tdir/f0
2728         $LFS setstripe -c 2 $DIR/$tdir
2729
2730         # stop all OSTs to reproduce situation for LU-7975 ticket
2731         for num in $(seq $OSTCOUNT); do
2732                 stop ost$num
2733         done
2734
2735         # open/create f0 with O_LOV_DELAY_CREATE
2736         # truncate f0 to a non-0 size
2737         # close
2738         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2739
2740         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2741         # open/write it again to force delayed layout creation
2742         cat /etc/hosts > $DIR/$tdir/f0 &
2743         catpid=$!
2744
2745         # restart OSTs
2746         for num in $(seq $OSTCOUNT); do
2747                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2748                         error "ost$num failed to start"
2749         done
2750
2751         wait $catpid || error "cat failed"
2752
2753         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2754         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2755                 error "wrong stripecount"
2756
2757 }
2758 run_test 27F "Client resend delayed layout creation with non-zero size"
2759
2760 test_27G() { #LU-10629
2761         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2762                 skip "Need MDS version at least 2.11.51"
2763         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2764         remote_mds_nodsh && skip "remote MDS with nodsh"
2765         local POOL=${POOL:-testpool}
2766         local ostrange="0 0 1"
2767
2768         test_mkdir $DIR/$tdir
2769         touch $DIR/$tdir/$tfile.nopool
2770         pool_add $POOL || error "pool_add failed"
2771         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2772         $LFS setstripe -p $POOL $DIR/$tdir
2773
2774         local pool=$($LFS getstripe -p $DIR/$tdir)
2775
2776         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2777         touch $DIR/$tdir/$tfile.default
2778         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2779         $LFS find $DIR/$tdir -type f --pool $POOL
2780         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2781         [[ "$found" == "2" ]] ||
2782                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2783
2784         $LFS setstripe -d $DIR/$tdir
2785
2786         pool=$($LFS getstripe -p -d $DIR/$tdir)
2787
2788         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2789 }
2790 run_test 27G "Clear OST pool from stripe"
2791
2792 test_27H() {
2793         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2794                 skip "Need MDS version newer than 2.11.54"
2795         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2796         test_mkdir $DIR/$tdir
2797         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2798         touch $DIR/$tdir/$tfile
2799         $LFS getstripe -c $DIR/$tdir/$tfile
2800         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2801                 error "two-stripe file doesn't have two stripes"
2802
2803         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2804         $LFS getstripe -y $DIR/$tdir/$tfile
2805         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2806              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2807                 error "expected l_ost_idx: [02]$ not matched"
2808
2809         # make sure ost list has been cleared
2810         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2811         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2812                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2813         touch $DIR/$tdir/f3
2814         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2815 }
2816 run_test 27H "Set specific OSTs stripe"
2817
2818 test_27I() {
2819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2820         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2821         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2822                 skip "Need MDS version newer than 2.12.52"
2823         local pool=$TESTNAME
2824         local ostrange="1 1 1"
2825
2826         save_layout_restore_at_exit $MOUNT
2827         $LFS setstripe -c 2 -i 0 $MOUNT
2828         pool_add $pool || error "pool_add failed"
2829         pool_add_targets $pool $ostrange ||
2830                 error "pool_add_targets failed"
2831         test_mkdir $DIR/$tdir
2832         $LFS setstripe -p $pool $DIR/$tdir
2833         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2834         $LFS getstripe $DIR/$tdir/$tfile
2835 }
2836 run_test 27I "check that root dir striping does not break parent dir one"
2837
2838 test_27J() {
2839         (( $MDS1_VERSION > $(version_code 2.12.51) )) ||
2840                 skip "Need MDS version newer than 2.12.51"
2841
2842         # skip basic ops on file with foreign LOV tests on 5.12-6.2 kernels
2843         # until the filemap_read() issue is fixed by v6.2-rc4-61-g5956592ce337
2844         (( $LINUX_VERSION_CODE < $(version_code 5.12.0) ||
2845            $LINUX_VERSION_CODE >= $(version_code 6.2.0) )) ||
2846                 skip "Need kernel < 5.12.0 or >= 6.2.0 for filemap_read() fix"
2847
2848         test_mkdir $DIR/$tdir
2849         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2850         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2851
2852         # create foreign file (raw way)
2853         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2854                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2855
2856         ! $LFS setstripe --foreign --flags foo \
2857                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2858                         error "creating $tfile with '--flags foo' should fail"
2859
2860         ! $LFS setstripe --foreign --flags 0xffffffff \
2861                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2862                         error "creating $tfile w/ 0xffffffff flags should fail"
2863
2864         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2865                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2866
2867         # verify foreign file (raw way)
2868         parse_foreign_file -f $DIR/$tdir/$tfile |
2869                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2870                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2871         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2872                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2873         parse_foreign_file -f $DIR/$tdir/$tfile |
2874                 grep "lov_foreign_size: 73" ||
2875                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2876         parse_foreign_file -f $DIR/$tdir/$tfile |
2877                 grep "lov_foreign_type: 1" ||
2878                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2879         parse_foreign_file -f $DIR/$tdir/$tfile |
2880                 grep "lov_foreign_flags: 0x0000DA08" ||
2881                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2882         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2883                 grep "lov_foreign_value: 0x" |
2884                 sed -e 's/lov_foreign_value: 0x//')
2885         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2886         [[ $lov = ${lov2// /} ]] ||
2887                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2888
2889         # create foreign file (lfs + API)
2890         $LFS setstripe --foreign=none --flags 0xda08 \
2891                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2892                 error "$DIR/$tdir/${tfile}2: create failed"
2893
2894         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2895                 grep "lfm_magic:.*0x0BD70BD0" ||
2896                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2897         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2898         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2899                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2900         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2901                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2902         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2903                 grep "lfm_flags:.*0x0000DA08" ||
2904                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2905         $LFS getstripe $DIR/$tdir/${tfile}2 |
2906                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2907                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2908
2909         # modify striping should fail
2910         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2911                 error "$DIR/$tdir/$tfile: setstripe should fail"
2912         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2913                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2914
2915         # R/W should fail
2916         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2917         cat $DIR/$tdir/${tfile}2 &&
2918                 error "$DIR/$tdir/${tfile}2: read should fail"
2919         cat /etc/passwd > $DIR/$tdir/$tfile &&
2920                 error "$DIR/$tdir/$tfile: write should fail"
2921         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2922                 error "$DIR/$tdir/${tfile}2: write should fail"
2923
2924         # chmod should work
2925         chmod 222 $DIR/$tdir/$tfile ||
2926                 error "$DIR/$tdir/$tfile: chmod failed"
2927         chmod 222 $DIR/$tdir/${tfile}2 ||
2928                 error "$DIR/$tdir/${tfile}2: chmod failed"
2929
2930         # chown should work
2931         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2932                 error "$DIR/$tdir/$tfile: chown failed"
2933         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2934                 error "$DIR/$tdir/${tfile}2: chown failed"
2935
2936         # rename should work
2937         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2938                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2939         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2940                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2941
2942         #remove foreign file
2943         rm $DIR/$tdir/${tfile}.new ||
2944                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2945         rm $DIR/$tdir/${tfile}2.new ||
2946                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2947 }
2948 run_test 27J "basic ops on file with foreign LOV"
2949
2950 test_27K() {
2951         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2952                 skip "Need MDS version newer than 2.12.49"
2953
2954         test_mkdir $DIR/$tdir
2955         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2956         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2957
2958         # create foreign dir (raw way)
2959         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2960                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2961
2962         ! $LFS setdirstripe --foreign --flags foo \
2963                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2964                         error "creating $tdir with '--flags foo' should fail"
2965
2966         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2967                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2968                         error "creating $tdir w/ 0xffffffff flags should fail"
2969
2970         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2971                 error "create_foreign_dir FAILED"
2972
2973         # verify foreign dir (raw way)
2974         parse_foreign_dir -d $DIR/$tdir/$tdir |
2975                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2976                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2977         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2978                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2979         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2980                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2981         parse_foreign_dir -d $DIR/$tdir/$tdir |
2982                 grep "lmv_foreign_flags: 55813$" ||
2983                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2984         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2985                 grep "lmv_foreign_value: 0x" |
2986                 sed 's/lmv_foreign_value: 0x//')
2987         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2988                 sed 's/ //g')
2989         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2990
2991         # create foreign dir (lfs + API)
2992         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2993                 $DIR/$tdir/${tdir}2 ||
2994                 error "$DIR/$tdir/${tdir}2: create failed"
2995
2996         $LFS getdirstripe -v $DIR/$tdir/${tdir}2
2997
2998         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2999                 grep "lfm_magic:.*0x0CD50CD0" ||
3000                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
3001         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
3002         # - sizeof(lfm_type) - sizeof(lfm_flags)
3003         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
3004                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
3005         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
3006                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
3007         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
3008                 grep "lfm_flags:.*0x0000DA05" ||
3009                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
3010         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
3011                 grep "lfm_value.*${uuid1}@${uuid2}" ||
3012                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
3013
3014         # file create in dir should fail
3015         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3016         touch $DIR/$tdir/${tdir}2/$tfile &&
3017                 error "$DIR/${tdir}2: file create should fail"
3018
3019         # chmod should work
3020         chmod 777 $DIR/$tdir/$tdir ||
3021                 error "$DIR/$tdir: chmod failed"
3022         chmod 777 $DIR/$tdir/${tdir}2 ||
3023                 error "$DIR/${tdir}2: chmod failed"
3024
3025         # chown should work
3026         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
3027                 error "$DIR/$tdir: chown failed"
3028         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
3029                 error "$DIR/${tdir}2: chown failed"
3030
3031         # rename should work
3032         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3033                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
3034         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
3035                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
3036
3037         #remove foreign dir
3038         rmdir $DIR/$tdir/${tdir}.new ||
3039                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
3040         rmdir $DIR/$tdir/${tdir}2.new ||
3041                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
3042 }
3043 run_test 27K "basic ops on dir with foreign LMV"
3044
3045 test_27L() {
3046         remote_mds_nodsh && skip "remote MDS with nodsh"
3047
3048         local POOL=${POOL:-$TESTNAME}
3049
3050         pool_add $POOL || error "pool_add failed"
3051
3052         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
3053                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
3054                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
3055 }
3056 run_test 27L "lfs pool_list gives correct pool name"
3057
3058 test_27M() {
3059         (( $MDS1_VERSION >= $(version_code 2.12.57) )) ||
3060                 skip "Need MDS version >= than 2.12.57"
3061         remote_mds_nodsh && skip "remote MDS with nodsh"
3062         (( $OSTCOUNT > 1 )) || skip "need > 1 OST"
3063
3064         # Set default striping on directory
3065         local setcount=4
3066         local stripe_opt
3067         local mdts=$(comma_list $(mdts_nodes))
3068
3069         # if we run against a 2.12 server which lacks overstring support
3070         # then the connect_flag will not report overstriping, even if client
3071         # is 2.14+
3072         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
3073                 stripe_opt="-C $setcount"
3074         elif (( $OSTCOUNT >= $setcount )); then
3075                 stripe_opt="-c $setcount"
3076         else
3077                 skip "server does not support overstriping"
3078         fi
3079
3080         test_mkdir $DIR/$tdir
3081
3082         # Validate existing append_* params and ensure restore
3083         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3084         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3085         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3086
3087         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3088         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
3089         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
3090
3091         $LFS setstripe $stripe_opt $DIR/$tdir
3092
3093         echo 1 > $DIR/$tdir/${tfile}.1
3094         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
3095         (( $count == $setcount )) ||
3096                 error "(1) stripe count $count, should be $setcount"
3097
3098         local appendcount=$orig_count
3099         echo 1 >> $DIR/$tdir/${tfile}.2_append
3100         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3101         (( $count == $appendcount )) ||
3102                 error "(2)stripe count $count, should be $appendcount for append"
3103
3104         # Disable O_APPEND striping, verify it works
3105         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3106
3107         # Should now get the default striping, which is 4
3108         setcount=4
3109         echo 1 >> $DIR/$tdir/${tfile}.3_append
3110         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3111         (( $count == $setcount )) ||
3112                 error "(3) stripe count $count, should be $setcount"
3113
3114         # Try changing the stripe count for append files
3115         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3116
3117         # Append striping is now 2 (directory default is still 4)
3118         appendcount=2
3119         echo 1 >> $DIR/$tdir/${tfile}.4_append
3120         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3121         (( $count == $appendcount )) ||
3122                 error "(4) stripe count $count, should be $appendcount for append"
3123
3124         # Test append stripe count of -1
3125         # Exercise LU-16872 patch with specific striping, only if MDS has fix
3126         (( $MDS1_VERSION > $(version_code 2.15.56.46) )) &&
3127                 $LFS setstripe -o 0,$((OSTCOUNT - 1)) $DIR/$tdir &&
3128                 touch $DIR/$tdir/$tfile.specific.{1..128}
3129         stack_trap "rm -f $DIR/$tdir/$tfile.*"
3130
3131         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3132         appendcount=$OSTCOUNT
3133         echo 1 >> $DIR/$tdir/${tfile}.5
3134         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3135         (( $count == $appendcount )) ||
3136                 error "(5) stripe count $count, should be $appendcount for append"
3137
3138         # Set append striping back to default of 1
3139         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3140
3141         # Try a new default striping, PFL + DOM
3142         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3143
3144         # Create normal DOM file, DOM returns stripe count == 0
3145         setcount=0
3146         touch $DIR/$tdir/${tfile}.6
3147         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3148         (( $count == $setcount )) ||
3149                 error "(6) stripe count $count, should be $setcount"
3150
3151         # Show
3152         appendcount=1
3153         echo 1 >> $DIR/$tdir/${tfile}.7_append
3154         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3155         (( $count == $appendcount )) ||
3156                 error "(7) stripe count $count, should be $appendcount for append"
3157
3158         # Clean up DOM layout
3159         $LFS setstripe -d $DIR/$tdir
3160
3161         save_layout_restore_at_exit $MOUNT
3162         # Now test that append striping works when layout is from root
3163         $LFS setstripe -c 2 $MOUNT
3164         # Make a special directory for this
3165         mkdir $DIR/${tdir}/${tdir}.2
3166
3167         # Verify for normal file
3168         setcount=2
3169         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3170         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3171         (( $count == $setcount )) ||
3172                 error "(8) stripe count $count, should be $setcount"
3173
3174         appendcount=1
3175         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3176         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3177         (( $count == $appendcount )) ||
3178                 error "(9) stripe count $count, should be $appendcount for append"
3179
3180         # Now test O_APPEND striping with pools
3181         pool_add $TESTNAME || error "pool creation failed"
3182         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3183         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3184
3185         echo 1 >> $DIR/$tdir/${tfile}.10_append
3186
3187         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3188         [[ "$pool" == "$TESTNAME" ]] || error "(10) incorrect pool: $pool"
3189
3190         # Check that count is still correct
3191         appendcount=1
3192         echo 1 >> $DIR/$tdir/${tfile}.11_append
3193         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3194         (( $count == $appendcount )) ||
3195                 error "(11) stripe count $count, should be $appendcount for append"
3196
3197         # Disable O_APPEND stripe count, verify pool works separately
3198         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3199
3200         echo 1 >> $DIR/$tdir/${tfile}.12_append
3201
3202         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3203         [[ "$pool" == "$TESTNAME" ]] || error "(12) incorrect pool: $pool"
3204
3205         # Remove pool setting, verify it's not applied
3206         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3207
3208         echo 1 >> $DIR/$tdir/${tfile}.13_append
3209
3210         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3211         [[ -z "$pool" ]] || error "(13) pool found: $pool"
3212 }
3213 run_test 27M "test O_APPEND striping"
3214
3215 test_27N() {
3216         combined_mgs_mds && skip "needs separate MGS/MDT"
3217
3218         pool_add $TESTNAME || error "pool_add failed"
3219         do_facet mgs "$LCTL pool_list $FSNAME" |
3220                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3221                 error "lctl pool_list on MGS failed"
3222 }
3223 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3224
3225 clean_foreign_symlink() {
3226         trap 0
3227         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3228         for i in $DIR/$tdir/* ; do
3229                 $LFS unlink_foreign $i || true
3230         done
3231 }
3232
3233 test_27O() {
3234         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3235                 skip "Need MDS version newer than 2.12.51"
3236
3237         test_mkdir $DIR/$tdir
3238         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3239         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3240
3241         trap clean_foreign_symlink EXIT
3242
3243         # enable foreign_symlink behaviour
3244         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3245
3246         # foreign symlink LOV format is a partial path by default
3247
3248         # create foreign file (lfs + API)
3249         $LFS setstripe --foreign=symlink --flags 0xda05 \
3250                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3251                 error "$DIR/$tdir/${tfile}: create failed"
3252
3253         $LFS getstripe -v $DIR/$tdir/${tfile} |
3254                 grep "lfm_magic:.*0x0BD70BD0" ||
3255                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3256         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3257                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3258         $LFS getstripe -v $DIR/$tdir/${tfile} |
3259                 grep "lfm_flags:.*0x0000DA05" ||
3260                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3261         $LFS getstripe $DIR/$tdir/${tfile} |
3262                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3263                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3264
3265         # modify striping should fail
3266         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3267                 error "$DIR/$tdir/$tfile: setstripe should fail"
3268
3269         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3270         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3271         cat /etc/passwd > $DIR/$tdir/$tfile &&
3272                 error "$DIR/$tdir/$tfile: write should fail"
3273
3274         # rename should succeed
3275         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3276                 error "$DIR/$tdir/$tfile: rename has failed"
3277
3278         #remove foreign_symlink file should fail
3279         rm $DIR/$tdir/${tfile}.new &&
3280                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3281
3282         #test fake symlink
3283         mkdir /tmp/${uuid1} ||
3284                 error "/tmp/${uuid1}: mkdir has failed"
3285         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3286                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3287         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3288         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3289                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3290         #read should succeed now
3291         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3292                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3293         #write should succeed now
3294         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3295                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3296         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3297                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3298         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3299                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3300
3301         #check that getstripe still works
3302         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3303                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3304
3305         # chmod should still succeed
3306         chmod 644 $DIR/$tdir/${tfile}.new ||
3307                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3308
3309         # chown should still succeed
3310         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3311                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3312
3313         # rename should still succeed
3314         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3315                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3316
3317         #remove foreign_symlink file should still fail
3318         rm $DIR/$tdir/${tfile} &&
3319                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3320
3321         #use special ioctl() to unlink foreign_symlink file
3322         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3323                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3324
3325 }
3326 run_test 27O "basic ops on foreign file of symlink type"
3327
3328 test_27P() {
3329         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3330                 skip "Need MDS version newer than 2.12.49"
3331
3332         test_mkdir $DIR/$tdir
3333         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3334         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3335
3336         trap clean_foreign_symlink EXIT
3337
3338         # enable foreign_symlink behaviour
3339         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3340
3341         # foreign symlink LMV format is a partial path by default
3342
3343         # create foreign dir (lfs + API)
3344         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3345                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3346                 error "$DIR/$tdir/${tdir}: create failed"
3347
3348         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3349
3350         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3351                 grep "lfm_magic:.*0x0CD50CD0" ||
3352                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3353         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3354                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3355         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3356                 grep "lfm_flags:.*0x0000DA05" ||
3357                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3358         $LFS getdirstripe $DIR/$tdir/${tdir} |
3359                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3360                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3361
3362         # file create in dir should fail
3363         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3364         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3365
3366         # rename should succeed
3367         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3368                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3369
3370         #remove foreign_symlink dir should fail
3371         rmdir $DIR/$tdir/${tdir}.new &&
3372                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3373
3374         #test fake symlink
3375         mkdir -p /tmp/${uuid1}/${uuid2} ||
3376                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3377         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3378                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3379         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3380         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3381                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3382         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3383                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3384
3385         #check that getstripe fails now that foreign_symlink enabled
3386         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3387                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3388
3389         # file create in dir should work now
3390         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3391                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3392         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3393                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3394         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3395                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3396
3397         # chmod should still succeed
3398         chmod 755 $DIR/$tdir/${tdir}.new ||
3399                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3400
3401         # chown should still succeed
3402         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3403                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3404
3405         # rename should still succeed
3406         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3407                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3408
3409         #remove foreign_symlink dir should still fail
3410         rmdir $DIR/$tdir/${tdir} &&
3411                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3412
3413         #use special ioctl() to unlink foreign_symlink file
3414         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3415                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3416
3417         #created file should still exist
3418         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3419                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3420         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3421                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3422 }
3423 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3424
3425 test_27Q() {
3426         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3427         stack_trap "rm -f $TMP/$tfile*"
3428
3429         test_mkdir $DIR/$tdir-1
3430         test_mkdir $DIR/$tdir-2
3431
3432         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3433         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3434
3435         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3436         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3437
3438         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3439         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3440
3441         # Create some bad symlinks and ensure that we don't loop
3442         # forever or something. These should return ELOOP (40) and
3443         # ENOENT (2) but I don't want to test for that because there's
3444         # always some weirdo architecture that needs to ruin
3445         # everything by defining these error numbers differently.
3446
3447         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3448         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3449
3450         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3451         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3452
3453         return 0
3454 }
3455 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3456
3457 test_27R() {
3458         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3459                 skip "need MDS 2.14.55 or later"
3460         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3461
3462         local testdir="$DIR/$tdir"
3463         test_mkdir -p $testdir
3464         stack_trap "rm -rf $testdir"
3465         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3466
3467         local f1="$testdir/f1"
3468         touch $f1 || error "failed to touch $f1"
3469         local count=$($LFS getstripe -c $f1)
3470         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3471
3472         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3473         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3474
3475         local maxcount=$(($OSTCOUNT - 1))
3476         local mdts=$(comma_list $(mdts_nodes))
3477         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3478         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3479
3480         local f2="$testdir/f2"
3481         touch $f2 || error "failed to touch $f2"
3482         local count=$($LFS getstripe -c $f2)
3483         (( $count == $maxcount )) || error "wrong stripe count"
3484 }
3485 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3486
3487 test_27T() {
3488         [ $(facet_host client) == $(facet_host ost1) ] &&
3489                 skip "need ost1 and client on different nodes"
3490
3491 #define OBD_FAIL_OSC_NO_GRANT            0x411
3492         $LCTL set_param fail_loc=0x20000411 fail_val=1
3493 #define OBD_FAIL_OST_ENOSPC              0x215
3494         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3495         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3496         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3497                 error "multiop failed"
3498 }
3499 run_test 27T "no eio on close on partial write due to enosp"
3500
3501 test_27U() {
3502         local dir=$DIR/$tdir
3503         local file=$dir/$tfile
3504         local append_pool=${TESTNAME}-append
3505         local normal_pool=${TESTNAME}-normal
3506         local pool
3507         local stripe_count
3508         local stripe_count2
3509         local mdts=$(comma_list $(mdts_nodes))
3510
3511         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
3512                 skip "Need MDS version at least 2.15.51 for append pool feature"
3513
3514         # Validate existing append_* params and ensure restore
3515         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3516         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3517         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3518
3519         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3520         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3521         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3522
3523         pool_add $append_pool || error "pool creation failed"
3524         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3525
3526         pool_add $normal_pool || error "pool creation failed"
3527         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3528
3529         test_mkdir $dir
3530         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3531
3532         echo XXX >> $file.1
3533         $LFS getstripe $file.1
3534
3535         pool=$($LFS getstripe -p $file.1)
3536         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3537
3538         stripe_count2=$($LFS getstripe -c $file.1)
3539         ((stripe_count2 == stripe_count)) ||
3540                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3541
3542         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3543
3544         echo XXX >> $file.2
3545         $LFS getstripe $file.2
3546
3547         pool=$($LFS getstripe -p $file.2)
3548         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3549
3550         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3551
3552         echo XXX >> $file.3
3553         $LFS getstripe $file.3
3554
3555         stripe_count2=$($LFS getstripe -c $file.3)
3556         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3557 }
3558 run_test 27U "append pool and stripe count work with composite default layout"
3559
3560 test_27V() {
3561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3562         (( $OSTCOUNT >= 4 )) || skip_env "needs >= 4 OSTs"
3563
3564         local dir=$DIR/$tdir
3565         local osp_param=osp.$FSNAME-OST0000-osc-MDT0000.max_create_count
3566         local lod_param=lod.$FSNAME-MDT0000-mdtlov.qos_threshold_rr
3567         local saved_max=$(do_facet mds1 $LCTL get_param -n $osp_param)
3568         local saved_qos=$(do_facet mds1 $LCTL get_param -n $lod_param)
3569         local pid
3570
3571         stack_trap "do_facet mds1 $LCTL set_param $osp_param=$saved_max"
3572
3573         do_facet mds1 $LCTL set_param $lod_param=0
3574         stack_trap "do_facet mds1 $LCTL set_param $lod_param=$saved_qos"
3575
3576         $LFS setdirstripe --mdt-count=1 --mdt-index=0 $dir
3577         stack_trap "rm -rf $dir"
3578
3579         # exercise race in LU-16981 with deactivating OST while creating a file
3580         (
3581                 while true; do
3582                         do_facet mds1 $LCTL set_param $osp_param=0 > /dev/null
3583                         sleep 0.1
3584                         do_facet mds1 \
3585                                 $LCTL set_param $osp_param=$saved_max > /dev/null
3586                 done
3587         ) &
3588
3589         pid=$!
3590         stack_trap "kill -9 $pid"
3591
3592         # errors here are OK so ignore them (just don't want to crash)
3593         $LFS setstripe -c -1 $dir/f.{1..200} 2> /dev/null
3594
3595         return 0
3596 }
3597 run_test 27V "creating widely striped file races with deactivating OST"
3598
3599 # createtest also checks that device nodes are created and
3600 # then visible correctly (#2091)
3601 test_28() { # bug 2091
3602         test_mkdir $DIR/d28
3603         $CREATETEST $DIR/d28/ct || error "createtest failed"
3604 }
3605 run_test 28 "create/mknod/mkdir with bad file types ============"
3606
3607 test_29() {
3608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3609
3610         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3611                 disable_opencache
3612                 stack_trap "restore_opencache"
3613         }
3614
3615         sync; sleep 1; sync # flush out any dirty pages from previous tests
3616         cancel_lru_locks
3617         test_mkdir $DIR/d29
3618         touch $DIR/d29/foo
3619         log 'first d29'
3620         ls -l $DIR/d29
3621
3622         local locks_orig=$(total_used_locks mdc)
3623         (( $locks_orig != 0 )) || error "No mdc lock count"
3624
3625         local locks_unused_orig=$(total_unused_locks mdc)
3626
3627         log 'second d29'
3628         ls -l $DIR/d29
3629         log 'done'
3630
3631         local locks_current=$(total_used_locks mdc)
3632
3633         local locks_unused_current=$(total_unused_locks mdc)
3634
3635         if (( $locks_current > $locks_orig )); then
3636                 $LCTL set_param -n ldlm.dump_namespaces ""
3637                 error "CURRENT: $locks_current > $locks_orig"
3638         fi
3639         if (( $locks_unused_current > $locks_unused_orig )); then
3640                 error "UNUSED: $locks_unused_current > $locks_unused_orig"
3641         fi
3642 }
3643 run_test 29 "IT_GETATTR regression  ============================"
3644
3645 test_30a() { # was test_30
3646         cp $(which ls) $DIR || cp /bin/ls $DIR
3647         $DIR/ls / || error "Can't execute binary from lustre"
3648         rm $DIR/ls
3649 }
3650 run_test 30a "execute binary from Lustre (execve) =============="
3651
3652 test_30b() {
3653         cp `which ls` $DIR || cp /bin/ls $DIR
3654         chmod go+rx $DIR/ls
3655         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3656         rm $DIR/ls
3657 }
3658 run_test 30b "execute binary from Lustre as non-root ==========="
3659
3660 test_30c() { # b=22376
3661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3662
3663         cp $(which ls) $DIR || cp /bin/ls $DIR
3664         chmod a-rw $DIR/ls
3665         cancel_lru_locks mdc
3666         cancel_lru_locks osc
3667         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3668         rm -f $DIR/ls
3669 }
3670 run_test 30c "execute binary from Lustre without read perms ===="
3671
3672 test_30d() {
3673         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3674
3675         for i in {1..10}; do
3676                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3677                 local PID=$!
3678                 sleep 1
3679                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3680                 wait $PID || error "executing dd from Lustre failed"
3681                 rm -f $DIR/$tfile
3682         done
3683
3684         rm -f $DIR/dd
3685 }
3686 run_test 30d "execute binary from Lustre while clear locks"
3687
3688 test_31a() {
3689         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3690         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3691 }
3692 run_test 31a "open-unlink file =================================="
3693
3694 test_31b() {
3695         touch $DIR/f31 || error "touch $DIR/f31 failed"
3696         ln $DIR/f31 $DIR/f31b || error "ln failed"
3697         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3698         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3699 }
3700 run_test 31b "unlink file with multiple links while open ======="
3701
3702 test_31c() {
3703         touch $DIR/f31 || error "touch $DIR/f31 failed"
3704         ln $DIR/f31 $DIR/f31c || error "ln failed"
3705         multiop_bg_pause $DIR/f31 O_uc ||
3706                 error "multiop_bg_pause for $DIR/f31 failed"
3707         MULTIPID=$!
3708         $MULTIOP $DIR/f31c Ouc
3709         kill -USR1 $MULTIPID
3710         wait $MULTIPID
3711 }
3712 run_test 31c "open-unlink file with multiple links ============="
3713
3714 test_31d() {
3715         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3716         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3717 }
3718 run_test 31d "remove of open directory ========================="
3719
3720 test_31e() { # bug 2904
3721         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3722 }
3723 run_test 31e "remove of open non-empty directory ==============="
3724
3725 test_31f() { # bug 4554
3726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3727
3728         set -vx
3729         test_mkdir $DIR/d31f
3730         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3731         cp /etc/hosts $DIR/d31f
3732         ls -l $DIR/d31f
3733         $LFS getstripe $DIR/d31f/hosts
3734         multiop_bg_pause $DIR/d31f D_c || return 1
3735         MULTIPID=$!
3736
3737         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3738         test_mkdir $DIR/d31f
3739         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3740         cp /etc/hosts $DIR/d31f
3741         ls -l $DIR/d31f
3742         $LFS getstripe $DIR/d31f/hosts
3743         multiop_bg_pause $DIR/d31f D_c || return 1
3744         MULTIPID2=$!
3745
3746         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3747         wait $MULTIPID || error "first opendir $MULTIPID failed"
3748
3749         sleep 6
3750
3751         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3752         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3753         set +vx
3754 }
3755 run_test 31f "remove of open directory with open-unlink file ==="
3756
3757 test_31g() {
3758         echo "-- cross directory link --"
3759         test_mkdir -c1 $DIR/${tdir}ga
3760         test_mkdir -c1 $DIR/${tdir}gb
3761         touch $DIR/${tdir}ga/f
3762         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3763         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3764         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3765         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3766         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3767 }
3768 run_test 31g "cross directory link==============="
3769
3770 test_31h() {
3771         echo "-- cross directory link --"
3772         test_mkdir -c1 $DIR/${tdir}
3773         test_mkdir -c1 $DIR/${tdir}/dir
3774         touch $DIR/${tdir}/f
3775         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3776         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3777         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3778         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3779         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3780 }
3781 run_test 31h "cross directory link under child==============="
3782
3783 test_31i() {
3784         echo "-- cross directory link --"
3785         test_mkdir -c1 $DIR/$tdir
3786         test_mkdir -c1 $DIR/$tdir/dir
3787         touch $DIR/$tdir/dir/f
3788         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3789         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3790         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3791         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3792         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3793 }
3794 run_test 31i "cross directory link under parent==============="
3795
3796 test_31j() {
3797         test_mkdir -c1 -p $DIR/$tdir
3798         test_mkdir -c1 -p $DIR/$tdir/dir1
3799         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3800         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3801         link $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "link to the same dir"
3802         return 0
3803 }
3804 run_test 31j "link for directory"
3805
3806 test_31k() {
3807         test_mkdir -c1 -p $DIR/$tdir
3808         touch $DIR/$tdir/s
3809         touch $DIR/$tdir/exist
3810         link $DIR/$tdir/s $DIR/$tdir/t || error "link"
3811         link $DIR/$tdir/s $DIR/$tdir/exist && error "link to exist file"
3812         link $DIR/$tdir/s $DIR/$tdir/s && error "link to the same file"
3813         link $DIR/$tdir/s $DIR/$tdir && error "link to parent dir"
3814         link $DIR/$tdir $DIR/$tdir/s && error "link parent dir to target"
3815         link $DIR/$tdir/not-exist $DIR/$tdir/foo && error "link non-existing to new"
3816         link $DIR/$tdir/not-exist $DIR/$tdir/s && error "link non-existing to exist"
3817         return 0
3818 }
3819 run_test 31k "link to file: the same, non-existing, dir"
3820
3821 test_31l() {
3822         local ln_ver=$(ln --version | awk '/coreutils/ { print $4 }')
3823
3824         (( $(version_code $ln_ver) < $(version_code 8.31) )) ||
3825         (( $(version_code $(uname -r)) >= $(version_code 5.18) )) ||
3826                 skip "need coreutils < 8.31 or kernel >= 5.18 for ln"
3827
3828         touch $DIR/$tfile || error "create failed"
3829         mkdir $DIR/$tdir || error "mkdir failed"
3830         ln $DIR/$tfile $DIR/$tdir/ || error "ln to '$tdir/' failed"
3831 }
3832 run_test 31l "link to file: target dir has trailing slash"
3833
3834 test_31m() {
3835         mkdir $DIR/d31m
3836         touch $DIR/d31m/s
3837         mkdir $DIR/d31m2
3838         touch $DIR/d31m2/exist
3839         link $DIR/d31m/s $DIR/d31m2/t || error "link"
3840         link $DIR/d31m/s $DIR/d31m2/exist && error "link to exist file"
3841         link $DIR/d31m/s $DIR/d31m2 && error "link to parent dir"
3842         link $DIR/d31m2 $DIR/d31m/s && error "link parent dir to target"
3843         link $DIR/d31m/not-exist $DIR/d31m2/foo && error "link non-existing to new"
3844         link $DIR/d31m/not-exist $DIR/d31m2/s && error "link non-existing to exist"
3845         return 0
3846 }
3847 run_test 31m "link to file: the same, non-existing, dir"
3848
3849 test_31n() {
3850         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3851         nlink=$(stat --format=%h $DIR/$tfile)
3852         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3853         local fd=$(free_fd)
3854         local cmd="exec $fd<$DIR/$tfile"
3855         eval $cmd
3856         cmd="exec $fd<&-"
3857         trap "eval $cmd" EXIT
3858         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3859         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3860         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3861         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3862         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3863         eval $cmd
3864 }
3865 run_test 31n "check link count of unlinked file"
3866
3867 link_one() {
3868         local tempfile=$(mktemp $1_XXXXXX)
3869         link $tempfile $1 2> /dev/null &&
3870                 echo "$BASHPID: link $tempfile to $1 succeeded"
3871         unlink $tempfile
3872 }
3873
3874 test_31o() { # LU-2901
3875         test_mkdir $DIR/$tdir
3876         for LOOP in $(seq 100); do
3877                 rm -f $DIR/$tdir/$tfile*
3878                 for THREAD in $(seq 8); do
3879                         link_one $DIR/$tdir/$tfile.$LOOP &
3880                 done
3881                 wait
3882                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3883                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3884                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3885                         break || true
3886         done
3887 }
3888 run_test 31o "duplicate hard links with same filename"
3889
3890 test_31p() {
3891         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3892
3893         test_mkdir $DIR/$tdir
3894         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3895         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3896
3897         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3898                 error "open unlink test1 failed"
3899         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3900                 error "open unlink test2 failed"
3901
3902         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3903                 error "test1 still exists"
3904         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3905                 error "test2 still exists"
3906 }
3907 run_test 31p "remove of open striped directory"
3908
3909 test_31q() {
3910         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3911
3912         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3913         index=$($LFS getdirstripe -i $DIR/$tdir)
3914         [ $index -eq 3 ] || error "first stripe index $index != 3"
3915         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3916         [ $index -eq 1 ] || error "second stripe index $index != 1"
3917
3918         # when "-c <stripe_count>" is set, the number of MDTs specified after
3919         # "-i" should equal to the stripe count
3920         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3921 }
3922 run_test 31q "create striped directory on specific MDTs"
3923
3924 #LU-14949
3925 test_31r() {
3926         touch $DIR/$tfile.target
3927         touch $DIR/$tfile.source
3928
3929         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3930         $LCTL set_param fail_loc=0x1419 fail_val=3
3931         cat $DIR/$tfile.target &
3932         CATPID=$!
3933
3934         # Guarantee open is waiting before we get here
3935         sleep 1
3936         mv $DIR/$tfile.source $DIR/$tfile.target
3937
3938         wait $CATPID
3939         RC=$?
3940         if [[ $RC -ne 0 ]]; then
3941                 error "open with cat failed, rc=$RC"
3942         fi
3943 }
3944 run_test 31r "open-rename(replace) race"
3945
3946 cleanup_test32_mount() {
3947         local rc=0
3948         trap 0
3949         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3950         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3951         losetup -d $loopdev || true
3952         rm -rf $DIR/$tdir
3953         return $rc
3954 }
3955
3956 test_32a() {
3957         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3958
3959         echo "== more mountpoints and symlinks ================="
3960         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3961         trap cleanup_test32_mount EXIT
3962         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3963         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3964                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3965         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3966                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3967         cleanup_test32_mount
3968 }
3969 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3970
3971 test_32b() {
3972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3973
3974         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3975         trap cleanup_test32_mount EXIT
3976         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3977         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3978                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3979         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3980                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3981         cleanup_test32_mount
3982 }
3983 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3984
3985 test_32c() {
3986         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3987
3988         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3989         trap cleanup_test32_mount EXIT
3990         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3991         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3992                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3993         test_mkdir -p $DIR/$tdir/d2/test_dir
3994         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3995                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3996         cleanup_test32_mount
3997 }
3998 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3999
4000 test_32d() {
4001         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4002
4003         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4004         trap cleanup_test32_mount EXIT
4005         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4006         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4007                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4008         test_mkdir -p $DIR/$tdir/d2/test_dir
4009         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
4010                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
4011         cleanup_test32_mount
4012 }
4013 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
4014
4015 test_32e() {
4016         rm -fr $DIR/$tdir
4017         test_mkdir -p $DIR/$tdir/tmp
4018         local tmp_dir=$DIR/$tdir/tmp
4019         ln -s $DIR/$tdir $tmp_dir/symlink11
4020         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
4021         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
4022         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
4023 }
4024 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
4025
4026 test_32f() {
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         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
4033         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
4034 }
4035 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
4036
4037 test_32g() {
4038         local tmp_dir=$DIR/$tdir/tmp
4039         test_mkdir -p $tmp_dir
4040         test_mkdir $DIR/${tdir}2
4041         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
4042         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
4043         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
4044         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
4045         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
4046         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
4047 }
4048 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
4049
4050 test_32h() {
4051         rm -fr $DIR/$tdir $DIR/${tdir}2
4052         tmp_dir=$DIR/$tdir/tmp
4053         test_mkdir -p $tmp_dir
4054         test_mkdir $DIR/${tdir}2
4055         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
4056         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
4057         ls $tmp_dir/symlink12 || error "listing symlink12"
4058         ls $DIR/$tdir/symlink02  || error "listing symlink02"
4059 }
4060 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
4061
4062 test_32i() {
4063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4064
4065         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4066         trap cleanup_test32_mount EXIT
4067         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4068         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4069                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4070         touch $DIR/$tdir/test_file
4071         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
4072                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
4073         cleanup_test32_mount
4074 }
4075 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
4076
4077 test_32j() {
4078         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4079
4080         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4081         trap cleanup_test32_mount EXIT
4082         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4083         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4084                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4085         touch $DIR/$tdir/test_file
4086         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
4087                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
4088         cleanup_test32_mount
4089 }
4090 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
4091
4092 test_32k() {
4093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4094
4095         rm -fr $DIR/$tdir
4096         trap cleanup_test32_mount EXIT
4097         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4098         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4099                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4100         test_mkdir -p $DIR/$tdir/d2
4101         touch $DIR/$tdir/d2/test_file || error "touch failed"
4102         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4103                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
4104         cleanup_test32_mount
4105 }
4106 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
4107
4108 test_32l() {
4109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4110
4111         rm -fr $DIR/$tdir
4112         trap cleanup_test32_mount EXIT
4113         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4114         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4115                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4116         test_mkdir -p $DIR/$tdir/d2
4117         touch $DIR/$tdir/d2/test_file || error "touch failed"
4118         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4119                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
4120         cleanup_test32_mount
4121 }
4122 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
4123
4124 test_32m() {
4125         rm -fr $DIR/d32m
4126         test_mkdir -p $DIR/d32m/tmp
4127         TMP_DIR=$DIR/d32m/tmp
4128         ln -s $DIR $TMP_DIR/symlink11
4129         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4130         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
4131                 error "symlink11 not a link"
4132         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
4133                 error "symlink01 not a link"
4134 }
4135 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
4136
4137 test_32n() {
4138         rm -fr $DIR/d32n
4139         test_mkdir -p $DIR/d32n/tmp
4140         TMP_DIR=$DIR/d32n/tmp
4141         ln -s $DIR $TMP_DIR/symlink11
4142         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4143         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4144         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4145 }
4146 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4147
4148 test_32o() {
4149         touch $DIR/$tfile
4150         test_mkdir -p $DIR/d32o/tmp
4151         TMP_DIR=$DIR/d32o/tmp
4152         ln -s $DIR/$tfile $TMP_DIR/symlink12
4153         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4154         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4155                 error "symlink12 not a link"
4156         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4157         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4158                 error "$DIR/d32o/tmp/symlink12 not file type"
4159         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4160                 error "$DIR/d32o/symlink02 not file type"
4161 }
4162 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4163
4164 test_32p() {
4165         log 32p_1
4166         rm -fr $DIR/d32p
4167         log 32p_2
4168         rm -f $DIR/$tfile
4169         log 32p_3
4170         touch $DIR/$tfile
4171         log 32p_4
4172         test_mkdir -p $DIR/d32p/tmp
4173         log 32p_5
4174         TMP_DIR=$DIR/d32p/tmp
4175         log 32p_6
4176         ln -s $DIR/$tfile $TMP_DIR/symlink12
4177         log 32p_7
4178         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4179         log 32p_8
4180         cat $DIR/d32p/tmp/symlink12 ||
4181                 error "Can't open $DIR/d32p/tmp/symlink12"
4182         log 32p_9
4183         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4184         log 32p_10
4185 }
4186 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4187
4188 test_32q() {
4189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4190
4191         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4192         trap cleanup_test32_mount EXIT
4193         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4194         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4195         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4196                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4197         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4198         cleanup_test32_mount
4199 }
4200 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4201
4202 test_32r() {
4203         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4204
4205         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4206         trap cleanup_test32_mount EXIT
4207         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4208         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4209         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4210                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4211         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4212         cleanup_test32_mount
4213 }
4214 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4215
4216 test_33aa() {
4217         rm -f $DIR/$tfile
4218         touch $DIR/$tfile
4219         chmod 444 $DIR/$tfile
4220         chown $RUNAS_ID $DIR/$tfile
4221         log 33_1
4222         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4223         log 33_2
4224 }
4225 run_test 33aa "write file with mode 444 (should return error)"
4226
4227 test_33a() {
4228         rm -fr $DIR/$tdir
4229         test_mkdir $DIR/$tdir
4230         chown $RUNAS_ID $DIR/$tdir
4231         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4232                 error "$RUNAS create $tdir/$tfile failed"
4233         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4234                 error "open RDWR" || true
4235 }
4236 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4237
4238 test_33b() {
4239         rm -fr $DIR/$tdir
4240         test_mkdir $DIR/$tdir
4241         chown $RUNAS_ID $DIR/$tdir
4242         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4243 }
4244 run_test 33b "test open file with malformed flags (No panic)"
4245
4246 test_33c() {
4247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4248         remote_ost_nodsh && skip "remote OST with nodsh"
4249
4250         local ostnum
4251         local ostname
4252         local write_bytes
4253         local all_zeros
4254
4255         all_zeros=true
4256         test_mkdir $DIR/$tdir
4257         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4258
4259         sync
4260         for ostnum in $(seq $OSTCOUNT); do
4261                 # test-framework's OST numbering is one-based, while Lustre's
4262                 # is zero-based
4263                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4264                 # check if at least some write_bytes stats are counted
4265                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4266                               obdfilter.$ostname.stats |
4267                               awk '/^write_bytes/ {print $7}' )
4268                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4269                 if (( ${write_bytes:-0} > 0 )); then
4270                         all_zeros=false
4271                         break
4272                 fi
4273         done
4274
4275         $all_zeros || return 0
4276
4277         # Write four bytes
4278         echo foo > $DIR/$tdir/bar
4279         # Really write them
4280         sync
4281
4282         # Total up write_bytes after writing.  We'd better find non-zeros.
4283         for ostnum in $(seq $OSTCOUNT); do
4284                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4285                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4286                               obdfilter/$ostname/stats |
4287                               awk '/^write_bytes/ {print $7}' )
4288                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4289                 if (( ${write_bytes:-0} > 0 )); then
4290                         all_zeros=false
4291                         break
4292                 fi
4293         done
4294
4295         if $all_zeros; then
4296                 for ostnum in $(seq $OSTCOUNT); do
4297                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4298                         echo "Check write_bytes is in obdfilter.*.stats:"
4299                         do_facet ost$ostnum lctl get_param -n \
4300                                 obdfilter.$ostname.stats
4301                 done
4302                 error "OST not keeping write_bytes stats (b=22312)"
4303         fi
4304 }
4305 run_test 33c "test write_bytes stats"
4306
4307 test_33d() {
4308         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4309         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4310
4311         local MDTIDX=1
4312         local remote_dir=$DIR/$tdir/remote_dir
4313
4314         test_mkdir $DIR/$tdir
4315         $LFS mkdir -i $MDTIDX $remote_dir ||
4316                 error "create remote directory failed"
4317
4318         touch $remote_dir/$tfile
4319         chmod 444 $remote_dir/$tfile
4320         chown $RUNAS_ID $remote_dir/$tfile
4321
4322         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4323
4324         chown $RUNAS_ID $remote_dir
4325         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4326                                         error "create" || true
4327         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4328                                     error "open RDWR" || true
4329         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4330 }
4331 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4332
4333 test_33e() {
4334         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4335
4336         mkdir $DIR/$tdir
4337
4338         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4339         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4340         mkdir $DIR/$tdir/local_dir
4341
4342         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4343         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4344         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4345
4346         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4347                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4348
4349         rmdir $DIR/$tdir/* || error "rmdir failed"
4350
4351         umask 777
4352         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4353         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4354         mkdir $DIR/$tdir/local_dir
4355
4356         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4357         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4358         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4359
4360         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4361                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4362
4363         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4364
4365         umask 000
4366         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4367         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4368         mkdir $DIR/$tdir/local_dir
4369
4370         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4371         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4372         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4373
4374         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4375                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4376 }
4377 run_test 33e "mkdir and striped directory should have same mode"
4378
4379 cleanup_33f() {
4380         trap 0
4381         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4382 }
4383
4384 test_33f() {
4385         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4386         remote_mds_nodsh && skip "remote MDS with nodsh"
4387
4388         mkdir $DIR/$tdir
4389         chmod go+rwx $DIR/$tdir
4390         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4391         trap cleanup_33f EXIT
4392
4393         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4394                 error "cannot create striped directory"
4395
4396         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4397                 error "cannot create files in striped directory"
4398
4399         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4400                 error "cannot remove files in striped directory"
4401
4402         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4403                 error "cannot remove striped directory"
4404
4405         cleanup_33f
4406 }
4407 run_test 33f "nonroot user can create, access, and remove a striped directory"
4408
4409 test_33g() {
4410         mkdir -p $DIR/$tdir/dir2
4411
4412         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4413         echo $err
4414         [[ $err =~ "exists" ]] || error "Not exists error"
4415 }
4416 run_test 33g "nonroot user create already existing root created file"
4417
4418 sub_33h() {
4419         local hash_type=$1
4420         local count=250
4421
4422         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4423                 error "lfs mkdir -H $hash_type $tdir failed"
4424         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4425
4426         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4427         local index2
4428         local fname
4429
4430         for fname in $DIR/$tdir/$tfile.bak \
4431                      $DIR/$tdir/$tfile.SAV \
4432                      $DIR/$tdir/$tfile.orig \
4433                      $DIR/$tdir/$tfile~; do
4434                 touch $fname || error "touch $fname failed"
4435                 index2=$($LFS getstripe -m $fname)
4436                 (( $index == $index2 )) ||
4437                         error "$fname MDT index mismatch $index != $index2"
4438         done
4439
4440         local failed=0
4441         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4442         local pattern
4443
4444         for pattern in ${patterns[*]}; do
4445                 echo "pattern $pattern"
4446                 fname=$DIR/$tdir/$pattern
4447                 for (( i = 0; i < $count; i++ )); do
4448                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4449                                 error "mktemp $DIR/$tdir/$pattern failed"
4450                         index2=$($LFS getstripe -m $fname)
4451                         (( $index == $index2 )) && continue
4452
4453                         failed=$((failed + 1))
4454                         echo "$fname MDT index mismatch $index != $index2"
4455                 done
4456         done
4457
4458         echo "$failed/$count MDT index mismatches, expect ~2-4"
4459         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4460
4461         local same=0
4462         local expect
4463
4464         # verify that "crush" is still broken with all files on same MDT,
4465         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4466         [[ "$hash_type" == "crush" ]] && expect=$count ||
4467                 expect=$((count / MDSCOUNT))
4468
4469         # crush2 doesn't put all-numeric suffixes on the same MDT,
4470         # filename like $tfile.12345678 should *not* be considered temp
4471         for pattern in ${patterns[*]}; do
4472                 local base=${pattern%%X*}
4473                 local suff=${pattern#$base}
4474
4475                 echo "pattern $pattern"
4476                 for (( i = 0; i < $count; i++ )); do
4477                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4478                         touch $fname || error "touch $fname failed"
4479                         index2=$($LFS getstripe -m $fname)
4480                         (( $index != $index2 )) && continue
4481
4482                         same=$((same + 1))
4483                 done
4484         done
4485
4486         # the number of "bad" hashes is random, as it depends on the random
4487         # filenames generated by "mktemp".  Allow some margin in the results.
4488         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4489         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4490            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4491                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4492         same=0
4493
4494         # crush2 doesn't put suffixes with special characters on the same MDT
4495         # filename like $tfile.txt.1234 should *not* be considered temp
4496         for pattern in ${patterns[*]}; do
4497                 local base=${pattern%%X*}
4498                 local suff=${pattern#$base}
4499
4500                 pattern=$base...${suff/XXX}
4501                 echo "pattern=$pattern"
4502                 for (( i = 0; i < $count; i++ )); do
4503                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4504                                 error "touch $fname failed"
4505                         index2=$($LFS getstripe -m $fname)
4506                         (( $index != $index2 )) && continue
4507
4508                         same=$((same + 1))
4509                 done
4510         done
4511
4512         # the number of "bad" hashes is random, as it depends on the random
4513         # filenames generated by "mktemp".  Allow some margin in the results.
4514         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4515         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4516            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4517                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4518 }
4519
4520 test_33h() {
4521         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4522         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4523                 skip "Need MDS version at least 2.13.50"
4524
4525         sub_33h crush
4526 }
4527 run_test 33h "temp file is located on the same MDT as target (crush)"
4528
4529 test_33hh() {
4530         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4531         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4532         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4533                 skip "Need MDS version at least 2.15.0 for crush2"
4534
4535         sub_33h crush2
4536 }
4537 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4538
4539 test_33i()
4540 {
4541         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4542
4543         local FNAME=$(str_repeat 'f' 250)
4544
4545         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4546         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4547
4548         local count
4549         local total
4550
4551         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4552
4553         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4554
4555         lctl --device %$MDC deactivate
4556         stack_trap "lctl --device %$MDC activate"
4557         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4558         total=$(\ls -l $DIR/$tdir | wc -l)
4559         # "ls -l" will list total in the first line
4560         total=$((total - 1))
4561         (( total + count == 1000 )) ||
4562                 error "ls list $total files, $count files on MDT1"
4563 }
4564 run_test 33i "striped directory can be accessed when one MDT is down"
4565
4566 test_33j() {
4567         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4568
4569         mkdir -p $DIR/$tdir/
4570
4571         $LFS setdirstripe -D -i0,1 $DIR/$tdir/striped_dir_a &&
4572                 error "setdirstripe -D -i0,1 incorrectly succeeded"
4573
4574         $LFS setdirstripe -D -i0,1 -c1 $DIR/$tdir/striped_dir_b &&
4575                 error "setdirstripe -D -i0,1 -c1 incorrectly succeeded"
4576
4577         $LFS setdirstripe -D -i0,1 -c3 $DIR/$tdir/striped_dir_c &&
4578                 error "setdirstripe -D -i0,1 -c3 incorrectly succeeded"
4579
4580         $LFS setdirstripe -i0,1 $DIR/$tdir/striped_dir_e ||
4581                 error "-D was not specified, but still failed"
4582 }
4583 run_test 33j "lfs setdirstripe -D -i x,y,x should fail"
4584
4585 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4586 test_34a() {
4587         rm -f $DIR/f34
4588         $MCREATE $DIR/f34 || error "mcreate failed"
4589         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4590                 error "getstripe failed"
4591         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4592         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4593                 error "getstripe failed"
4594         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4595                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4596 }
4597 run_test 34a "truncate file that has not been opened ==========="
4598
4599 test_34b() {
4600         [ ! -f $DIR/f34 ] && test_34a
4601         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4602                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4603         $OPENFILE -f O_RDONLY $DIR/f34
4604         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4605                 error "getstripe failed"
4606         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4607                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4608 }
4609 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4610
4611 test_34c() {
4612         [ ! -f $DIR/f34 ] && test_34a
4613         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4614                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4615         $OPENFILE -f O_RDWR $DIR/f34
4616         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4617                 error "$LFS getstripe failed"
4618         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4619                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4620 }
4621 run_test 34c "O_RDWR opening file-with-size works =============="
4622
4623 test_34d() {
4624         [ ! -f $DIR/f34 ] && test_34a
4625         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4626                 error "dd failed"
4627         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4628                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4629         rm $DIR/f34
4630 }
4631 run_test 34d "write to sparse file ============================="
4632
4633 test_34e() {
4634         rm -f $DIR/f34e
4635         $MCREATE $DIR/f34e || error "mcreate failed"
4636         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4637         $CHECKSTAT -s 1000 $DIR/f34e ||
4638                 error "Size of $DIR/f34e not equal to 1000 bytes"
4639         $OPENFILE -f O_RDWR $DIR/f34e
4640         $CHECKSTAT -s 1000 $DIR/f34e ||
4641                 error "Size of $DIR/f34e not equal to 1000 bytes"
4642 }
4643 run_test 34e "create objects, some with size and some without =="
4644
4645 test_34f() { # bug 6242, 6243
4646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4647
4648         SIZE34F=48000
4649         rm -f $DIR/f34f
4650         $MCREATE $DIR/f34f || error "mcreate failed"
4651         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4652         dd if=$DIR/f34f of=$TMP/f34f
4653         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4654         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4655         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4656         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4657         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4658 }
4659 run_test 34f "read from a file with no objects until EOF ======="
4660
4661 test_34g() {
4662         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4663
4664         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4665                 error "dd failed"
4666         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4667         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4668                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4669         cancel_lru_locks osc
4670         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4671                 error "wrong size after lock cancel"
4672
4673         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4674         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4675                 error "expanding truncate failed"
4676         cancel_lru_locks osc
4677         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4678                 error "wrong expanded size after lock cancel"
4679 }
4680 run_test 34g "truncate long file ==============================="
4681
4682 test_34h() {
4683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4684
4685         local gid=10
4686         local sz=1000
4687
4688         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4689         sync # Flush the cache so that multiop below does not block on cache
4690              # flush when getting the group lock
4691         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4692         MULTIPID=$!
4693
4694         # Since just timed wait is not good enough, let's do a sync write
4695         # that way we are sure enough time for a roundtrip + processing
4696         # passed + 2 seconds of extra margin.
4697         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4698         rm $DIR/${tfile}-1
4699         sleep 2
4700
4701         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4702                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4703                 kill -9 $MULTIPID
4704         fi
4705         wait $MULTIPID
4706         local nsz=`stat -c %s $DIR/$tfile`
4707         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4708 }
4709 run_test 34h "ftruncate file under grouplock should not block"
4710
4711 test_35a() {
4712         cp /bin/sh $DIR/f35a
4713         chmod 444 $DIR/f35a
4714         chown $RUNAS_ID $DIR/f35a
4715         $RUNAS $DIR/f35a && error || true
4716         rm $DIR/f35a
4717 }
4718 run_test 35a "exec file with mode 444 (should return and not leak)"
4719
4720 test_36a() {
4721         rm -f $DIR/f36
4722         utime $DIR/f36 || error "utime failed for MDS"
4723 }
4724 run_test 36a "MDS utime check (mknod, utime)"
4725
4726 test_36b() {
4727         echo "" > $DIR/f36
4728         utime $DIR/f36 || error "utime failed for OST"
4729 }
4730 run_test 36b "OST utime check (open, utime)"
4731
4732 test_36c() {
4733         rm -f $DIR/d36/f36
4734         test_mkdir $DIR/d36
4735         chown $RUNAS_ID $DIR/d36
4736         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4737 }
4738 run_test 36c "non-root MDS utime check (mknod, utime)"
4739
4740 test_36d() {
4741         [ ! -d $DIR/d36 ] && test_36c
4742         echo "" > $DIR/d36/f36
4743         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4744 }
4745 run_test 36d "non-root OST utime check (open, utime)"
4746
4747 test_36e() {
4748         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4749
4750         test_mkdir $DIR/$tdir
4751         touch $DIR/$tdir/$tfile
4752         $RUNAS utime $DIR/$tdir/$tfile &&
4753                 error "utime worked, expected failure" || true
4754 }
4755 run_test 36e "utime on non-owned file (should return error)"
4756
4757 subr_36fh() {
4758         local fl="$1"
4759         local LANG_SAVE=$LANG
4760         local LC_LANG_SAVE=$LC_LANG
4761         export LANG=C LC_LANG=C # for date language
4762
4763         DATESTR="Dec 20  2000"
4764         test_mkdir $DIR/$tdir
4765         lctl set_param fail_loc=$fl
4766         date; date +%s
4767         cp /etc/hosts $DIR/$tdir/$tfile
4768         sync & # write RPC generated with "current" inode timestamp, but delayed
4769         sleep 1
4770         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4771         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4772         cancel_lru_locks $OSC
4773         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4774         date; date +%s
4775         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4776                 echo "BEFORE: $LS_BEFORE" && \
4777                 echo "AFTER : $LS_AFTER" && \
4778                 echo "WANT  : $DATESTR" && \
4779                 error "$DIR/$tdir/$tfile timestamps changed" || true
4780
4781         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4782 }
4783
4784 test_36f() {
4785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4786
4787         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4788         subr_36fh "0x80000214"
4789 }
4790 run_test 36f "utime on file racing with OST BRW write =========="
4791
4792 test_36g() {
4793         remote_ost_nodsh && skip "remote OST with nodsh"
4794         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4795         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4796                 skip "Need MDS version at least 2.12.51"
4797
4798         local fmd_max_age
4799         local fmd
4800         local facet="ost1"
4801         local tgt="obdfilter"
4802
4803         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4804
4805         test_mkdir $DIR/$tdir
4806         fmd_max_age=$(do_facet $facet \
4807                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4808                 head -n 1")
4809
4810         echo "FMD max age: ${fmd_max_age}s"
4811         touch $DIR/$tdir/$tfile
4812         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4813                 gawk '{cnt=cnt+$1}  END{print cnt}')
4814         echo "FMD before: $fmd"
4815         [[ $fmd == 0 ]] &&
4816                 error "FMD wasn't create by touch"
4817         sleep $((fmd_max_age + 12))
4818         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4819                 gawk '{cnt=cnt+$1}  END{print cnt}')
4820         echo "FMD after: $fmd"
4821         [[ $fmd == 0 ]] ||
4822                 error "FMD wasn't expired by ping"
4823 }
4824 run_test 36g "FMD cache expiry ====================="
4825
4826 test_36h() {
4827         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4828
4829         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4830         subr_36fh "0x80000227"
4831 }
4832 run_test 36h "utime on file racing with OST BRW write =========="
4833
4834 test_36i() {
4835         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4836
4837         test_mkdir $DIR/$tdir
4838         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4839
4840         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4841         local new_mtime=$((mtime + 200))
4842
4843         #change Modify time of striped dir
4844         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4845                         error "change mtime failed"
4846
4847         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4848
4849         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4850 }
4851 run_test 36i "change mtime on striped directory"
4852
4853 # test_37 - duplicate with tests 32q 32r
4854
4855 test_38() {
4856         local file=$DIR/$tfile
4857         touch $file
4858         openfile -f O_DIRECTORY $file
4859         local RC=$?
4860         local ENOTDIR=20
4861         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4862         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4863 }
4864 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4865
4866 test_39a() { # was test_39
4867         touch $DIR/$tfile
4868         touch $DIR/${tfile}2
4869 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4870 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4871 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4872         sleep 2
4873         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4874         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4875                 echo "mtime"
4876                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4877                 echo "atime"
4878                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4879                 echo "ctime"
4880                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4881                 error "O_TRUNC didn't change timestamps"
4882         fi
4883 }
4884 run_test 39a "mtime changed on create"
4885
4886 test_39b() {
4887         test_mkdir -c1 $DIR/$tdir
4888         cp -p /etc/passwd $DIR/$tdir/fopen
4889         cp -p /etc/passwd $DIR/$tdir/flink
4890         cp -p /etc/passwd $DIR/$tdir/funlink
4891         cp -p /etc/passwd $DIR/$tdir/frename
4892         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4893
4894         sleep 1
4895         echo "aaaaaa" >> $DIR/$tdir/fopen
4896         echo "aaaaaa" >> $DIR/$tdir/flink
4897         echo "aaaaaa" >> $DIR/$tdir/funlink
4898         echo "aaaaaa" >> $DIR/$tdir/frename
4899
4900         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4901         local link_new=`stat -c %Y $DIR/$tdir/flink`
4902         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4903         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4904
4905         cat $DIR/$tdir/fopen > /dev/null
4906         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4907         rm -f $DIR/$tdir/funlink2
4908         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4909
4910         for (( i=0; i < 2; i++ )) ; do
4911                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4912                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4913                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4914                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4915
4916                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4917                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4918                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4919                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4920
4921                 cancel_lru_locks $OSC
4922                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4923         done
4924 }
4925 run_test 39b "mtime change on open, link, unlink, rename  ======"
4926
4927 # this should be set to past
4928 TEST_39_MTIME=`date -d "1 year ago" +%s`
4929
4930 # bug 11063
4931 test_39c() {
4932         touch $DIR1/$tfile
4933         sleep 2
4934         local mtime0=`stat -c %Y $DIR1/$tfile`
4935
4936         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4937         local mtime1=`stat -c %Y $DIR1/$tfile`
4938         [ "$mtime1" = $TEST_39_MTIME ] || \
4939                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4940
4941         local d1=`date +%s`
4942         echo hello >> $DIR1/$tfile
4943         local d2=`date +%s`
4944         local mtime2=`stat -c %Y $DIR1/$tfile`
4945         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4946                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4947
4948         mv $DIR1/$tfile $DIR1/$tfile-1
4949
4950         for (( i=0; i < 2; i++ )) ; do
4951                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4952                 [ "$mtime2" = "$mtime3" ] || \
4953                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4954
4955                 cancel_lru_locks $OSC
4956                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4957         done
4958 }
4959 run_test 39c "mtime change on rename ==========================="
4960
4961 # bug 21114
4962 test_39d() {
4963         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4964
4965         touch $DIR1/$tfile
4966         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4967
4968         for (( i=0; i < 2; i++ )) ; do
4969                 local mtime=`stat -c %Y $DIR1/$tfile`
4970                 [ $mtime = $TEST_39_MTIME ] || \
4971                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4972
4973                 cancel_lru_locks $OSC
4974                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4975         done
4976 }
4977 run_test 39d "create, utime, stat =============================="
4978
4979 # bug 21114
4980 test_39e() {
4981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4982
4983         touch $DIR1/$tfile
4984         local mtime1=`stat -c %Y $DIR1/$tfile`
4985
4986         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4987
4988         for (( i=0; i < 2; i++ )) ; do
4989                 local mtime2=`stat -c %Y $DIR1/$tfile`
4990                 [ $mtime2 = $TEST_39_MTIME ] || \
4991                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4992
4993                 cancel_lru_locks $OSC
4994                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4995         done
4996 }
4997 run_test 39e "create, stat, utime, stat ========================"
4998
4999 # bug 21114
5000 test_39f() {
5001         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5002
5003         touch $DIR1/$tfile
5004         mtime1=`stat -c %Y $DIR1/$tfile`
5005
5006         sleep 2
5007         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5008
5009         for (( i=0; i < 2; i++ )) ; do
5010                 local mtime2=`stat -c %Y $DIR1/$tfile`
5011                 [ $mtime2 = $TEST_39_MTIME ] || \
5012                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
5013
5014                 cancel_lru_locks $OSC
5015                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5016         done
5017 }
5018 run_test 39f "create, stat, sleep, utime, stat ================="
5019
5020 # bug 11063
5021 test_39g() {
5022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5023
5024         echo hello >> $DIR1/$tfile
5025         local mtime1=`stat -c %Y $DIR1/$tfile`
5026
5027         sleep 2
5028         chmod o+r $DIR1/$tfile
5029
5030         for (( i=0; i < 2; i++ )) ; do
5031                 local mtime2=`stat -c %Y $DIR1/$tfile`
5032                 [ "$mtime1" = "$mtime2" ] || \
5033                         error "lost mtime: $mtime2, should be $mtime1"
5034
5035                 cancel_lru_locks $OSC
5036                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5037         done
5038 }
5039 run_test 39g "write, chmod, stat ==============================="
5040
5041 # bug 11063
5042 test_39h() {
5043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5044
5045         touch $DIR1/$tfile
5046         sleep 1
5047
5048         local d1=`date`
5049         echo hello >> $DIR1/$tfile
5050         local mtime1=`stat -c %Y $DIR1/$tfile`
5051
5052         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5053         local d2=`date`
5054         if [ "$d1" != "$d2" ]; then
5055                 echo "write and touch not within one second"
5056         else
5057                 for (( i=0; i < 2; i++ )) ; do
5058                         local mtime2=`stat -c %Y $DIR1/$tfile`
5059                         [ "$mtime2" = $TEST_39_MTIME ] || \
5060                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
5061
5062                         cancel_lru_locks $OSC
5063                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5064                 done
5065         fi
5066 }
5067 run_test 39h "write, utime within one second, stat ============="
5068
5069 test_39i() {
5070         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5071
5072         touch $DIR1/$tfile
5073         sleep 1
5074
5075         echo hello >> $DIR1/$tfile
5076         local mtime1=`stat -c %Y $DIR1/$tfile`
5077
5078         mv $DIR1/$tfile $DIR1/$tfile-1
5079
5080         for (( i=0; i < 2; i++ )) ; do
5081                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5082
5083                 [ "$mtime1" = "$mtime2" ] || \
5084                         error "lost mtime: $mtime2, should be $mtime1"
5085
5086                 cancel_lru_locks $OSC
5087                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5088         done
5089 }
5090 run_test 39i "write, rename, stat =============================="
5091
5092 test_39j() {
5093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5094
5095         start_full_debug_logging
5096         touch $DIR1/$tfile
5097         sleep 1
5098
5099         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
5100         lctl set_param fail_loc=0x80000412
5101         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
5102                 error "multiop failed"
5103         local multipid=$!
5104         local mtime1=`stat -c %Y $DIR1/$tfile`
5105
5106         mv $DIR1/$tfile $DIR1/$tfile-1
5107
5108         kill -USR1 $multipid
5109         wait $multipid || error "multiop close failed"
5110
5111         for (( i=0; i < 2; i++ )) ; do
5112                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5113                 [ "$mtime1" = "$mtime2" ] ||
5114                         error "mtime is lost on close: $mtime2, " \
5115                               "should be $mtime1"
5116
5117                 cancel_lru_locks
5118                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5119         done
5120         lctl set_param fail_loc=0
5121         stop_full_debug_logging
5122 }
5123 run_test 39j "write, rename, close, stat ======================="
5124
5125 test_39k() {
5126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5127
5128         touch $DIR1/$tfile
5129         sleep 1
5130
5131         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
5132         local multipid=$!
5133         local mtime1=`stat -c %Y $DIR1/$tfile`
5134
5135         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5136
5137         kill -USR1 $multipid
5138         wait $multipid || error "multiop close failed"
5139
5140         for (( i=0; i < 2; i++ )) ; do
5141                 local mtime2=`stat -c %Y $DIR1/$tfile`
5142
5143                 [ "$mtime2" = $TEST_39_MTIME ] || \
5144                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
5145
5146                 cancel_lru_locks
5147                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5148         done
5149 }
5150 run_test 39k "write, utime, close, stat ========================"
5151
5152 # this should be set to future
5153 TEST_39_ATIME=`date -d "1 year" +%s`
5154
5155 test_39l() {
5156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5157         remote_mds_nodsh && skip "remote MDS with nodsh"
5158
5159         local atime_diff=$(do_facet $SINGLEMDS \
5160                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5161         rm -rf $DIR/$tdir
5162         mkdir_on_mdt0 $DIR/$tdir
5163
5164         # test setting directory atime to future
5165         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5166         local atime=$(stat -c %X $DIR/$tdir)
5167         [ "$atime" = $TEST_39_ATIME ] ||
5168                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5169
5170         # test setting directory atime from future to now
5171         local now=$(date +%s)
5172         touch -a -d @$now $DIR/$tdir
5173
5174         atime=$(stat -c %X $DIR/$tdir)
5175         [ "$atime" -eq "$now"  ] ||
5176                 error "atime is not updated from future: $atime, $now"
5177
5178         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5179         sleep 3
5180
5181         # test setting directory atime when now > dir atime + atime_diff
5182         local d1=$(date +%s)
5183         ls $DIR/$tdir
5184         local d2=$(date +%s)
5185         cancel_lru_locks mdc
5186         atime=$(stat -c %X $DIR/$tdir)
5187         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5188                 error "atime is not updated  : $atime, should be $d2"
5189
5190         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5191         sleep 3
5192
5193         # test not setting directory atime when now < dir atime + atime_diff
5194         ls $DIR/$tdir
5195         cancel_lru_locks mdc
5196         atime=$(stat -c %X $DIR/$tdir)
5197         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5198                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5199
5200         do_facet $SINGLEMDS \
5201                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5202 }
5203 run_test 39l "directory atime update ==========================="
5204
5205 test_39m() {
5206         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5207
5208         touch $DIR1/$tfile
5209         sleep 2
5210         local far_past_mtime=$(date -d "May 29 1953" +%s)
5211         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5212
5213         touch -m -d @$far_past_mtime $DIR1/$tfile
5214         touch -a -d @$far_past_atime $DIR1/$tfile
5215
5216         for (( i=0; i < 2; i++ )) ; do
5217                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5218                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5219                         error "atime or mtime set incorrectly"
5220
5221                 cancel_lru_locks $OSC
5222                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5223         done
5224 }
5225 run_test 39m "test atime and mtime before 1970"
5226
5227 test_39n() { # LU-3832
5228         remote_mds_nodsh && skip "remote MDS with nodsh"
5229
5230         local atime_diff=$(do_facet $SINGLEMDS \
5231                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5232         local atime0
5233         local atime1
5234         local atime2
5235
5236         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5237
5238         rm -rf $DIR/$tfile
5239         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5240         atime0=$(stat -c %X $DIR/$tfile)
5241
5242         sleep 5
5243         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5244         atime1=$(stat -c %X $DIR/$tfile)
5245
5246         sleep 5
5247         cancel_lru_locks mdc
5248         cancel_lru_locks osc
5249         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5250         atime2=$(stat -c %X $DIR/$tfile)
5251
5252         do_facet $SINGLEMDS \
5253                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5254
5255         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5256         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5257 }
5258 run_test 39n "check that O_NOATIME is honored"
5259
5260 test_39o() {
5261         TESTDIR=$DIR/$tdir/$tfile
5262         [ -e $TESTDIR ] && rm -rf $TESTDIR
5263         mkdir -p $TESTDIR
5264         cd $TESTDIR
5265         links1=2
5266         ls
5267         mkdir a b
5268         ls
5269         links2=$(stat -c %h .)
5270         [ $(($links1 + 2)) != $links2 ] &&
5271                 error "wrong links count $(($links1 + 2)) != $links2"
5272         rmdir b
5273         links3=$(stat -c %h .)
5274         [ $(($links1 + 1)) != $links3 ] &&
5275                 error "wrong links count $links1 != $links3"
5276         return 0
5277 }
5278 run_test 39o "directory cached attributes updated after create"
5279
5280 test_39p() {
5281         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5282
5283         local MDTIDX=1
5284         TESTDIR=$DIR/$tdir/$tdir
5285         [ -e $TESTDIR ] && rm -rf $TESTDIR
5286         test_mkdir -p $TESTDIR
5287         cd $TESTDIR
5288         links1=2
5289         ls
5290         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5291         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5292         ls
5293         links2=$(stat -c %h .)
5294         [ $(($links1 + 2)) != $links2 ] &&
5295                 error "wrong links count $(($links1 + 2)) != $links2"
5296         rmdir remote_dir2
5297         links3=$(stat -c %h .)
5298         [ $(($links1 + 1)) != $links3 ] &&
5299                 error "wrong links count $links1 != $links3"
5300         return 0
5301 }
5302 run_test 39p "remote directory cached attributes updated after create ========"
5303
5304 test_39r() {
5305         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5306                 skip "no atime update on old OST"
5307         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5308                 skip_env "ldiskfs only test"
5309         fi
5310
5311         local saved_adiff
5312         local ahost=$(facet_active_host ost1)
5313         saved_adiff=$(do_facet ost1 \
5314                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5315         stack_trap "do_facet ost1 \
5316                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5317
5318         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5319
5320         $LFS setstripe -i 0 $DIR/$tfile
5321         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5322                 error "can't write initial file"
5323         cancel_lru_locks osc
5324
5325         # exceed atime_diff and access file
5326         sleep 10
5327         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5328                 error "can't udpate atime"
5329
5330         # atime_cli value is in decimal
5331         local atime_cli=$(stat -c %X $DIR/$tfile)
5332         echo "client atime: $atime_cli"
5333
5334         local ostdev=$(ostdevname 1)
5335         local fid=($($LFS getstripe $DIR/$tfile | grep 0x))
5336         local seq=${fid[3]#0x}
5337         local oid=${fid[1]}
5338         local oid_hex
5339
5340         if [ $seq == 0 ]; then
5341                 oid_hex=${fid[1]}
5342         else
5343                 oid_hex=${fid[2]#0x}
5344         fi
5345         local objpath="O/$seq/d$(($oid % 32))/$oid_hex"
5346         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5347
5348         # allow atime update to be written to device
5349         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync=1"
5350         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5351
5352         # Give enough time for server to get updated. Until then
5353         # the value read is defaulted to "0x00000000:00000000"
5354         # Wait until atime read via debugfs is not equal to zero.
5355         # Max limit to wait is 30 seconds.
5356         wait_update_cond $ahost                                         \
5357                 "$cmd |& awk -F'[: ]' '/atime:/ { print \\\$4 }'"       \
5358                 "-gt" "0" 30 || error "atime on ost is still 0 after 30 seconds"
5359         # atime_ost value is in hex
5360         local atime_ost=$(do_facet ost1 "$cmd" |&
5361                           awk -F'[: ]' '/atime:/ { print $4 }')
5362         # debugfs returns atime in 0xNNNNNNNN:00000000 format
5363         # convert Hex to decimal before comparing
5364         local atime_ost_dec=$((atime_ost))
5365
5366         # The test pass criteria is that the client time and server should
5367         # be same (2s gap accepted). This gap could arise due to VFS updating
5368         # the atime after the read(dd), stat and the updated time from the
5369         # inode
5370         (( $((atime_cli - atime_ost_dec)) <= 2 )) ||
5371                 error "atime on client $atime_cli != ost $atime_ost_dec"
5372 }
5373 run_test 39r "lazy atime update on OST"
5374
5375 test_39q() { # LU-8041
5376         local testdir=$DIR/$tdir
5377         mkdir -p $testdir
5378         multiop_bg_pause $testdir D_c || error "multiop failed"
5379         local multipid=$!
5380         cancel_lru_locks mdc
5381         kill -USR1 $multipid
5382         local atime=$(stat -c %X $testdir)
5383         [ "$atime" -ne 0 ] || error "atime is zero"
5384 }
5385 run_test 39q "close won't zero out atime"
5386
5387 test_39s() {
5388         local atime0
5389         local atime1
5390         local atime2
5391         local atime3
5392         local atime4
5393
5394         umount_client $MOUNT
5395         mount_client $MOUNT relatime
5396
5397         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer conv=fsync
5398         atime0=$(stat -c %X $DIR/$tfile)
5399
5400         # First read updates atime
5401         sleep 1
5402         cat $DIR/$tfile >/dev/null
5403         atime1=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5404
5405         # Next reads do not update atime
5406         sleep 1
5407         cat $DIR/$tfile >/dev/null
5408         atime2=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5409
5410         # If mtime is greater than atime, atime is updated
5411         sleep 1
5412         touch -m $DIR/$tfile # (mtime = now)
5413         sleep 1
5414         cat $DIR/$tfile >/dev/null # (atime is updated because atime < mtime)
5415         atime3=$(stat -c %X $DIR/$tfile) # (atime = mtime = atime0 + 3)
5416
5417         # Next reads do not update atime
5418         sleep 1
5419         cat $DIR/$tfile >/dev/null
5420         atime4=$(stat -c %X $DIR/$tfile)
5421
5422         # Remount the client to clear 'relatime' option
5423         remount_client $MOUNT
5424
5425         (( atime0 < atime1 )) ||
5426                 error "atime $atime0 should be smaller than $atime1"
5427         (( atime1 == atime2 )) ||
5428                 error "atime $atime1 was updated to $atime2"
5429         (( atime1 < atime3 )) || error "atime1 $atime1 != atime3 $atime3"
5430         (( atime3 == atime4 )) || error "atime3 $atime3 != atime4 $atime4"
5431 }
5432 run_test 39s "relatime is supported"
5433
5434 test_40() {
5435         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5436         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5437                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5438         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5439                 error "$tfile is not 4096 bytes in size"
5440 }
5441 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5442
5443 test_41() {
5444         # bug 1553
5445         small_write $DIR/f41 18
5446 }
5447 run_test 41 "test small file write + fstat ====================="
5448
5449 count_ost_writes() {
5450         lctl get_param -n ${OSC}.*.stats |
5451                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5452                         END { printf("%0.0f", writes) }'
5453 }
5454
5455 # decent default
5456 WRITEBACK_SAVE=500
5457 DIRTY_RATIO_SAVE=40
5458 MAX_DIRTY_RATIO=50
5459 BG_DIRTY_RATIO_SAVE=10
5460 MAX_BG_DIRTY_RATIO=25
5461
5462 start_writeback() {
5463         trap 0
5464         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5465         # dirty_ratio, dirty_background_ratio
5466         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5467                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5468                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5469                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5470         else
5471                 # if file not here, we are a 2.4 kernel
5472                 kill -CONT `pidof kupdated`
5473         fi
5474 }
5475
5476 stop_writeback() {
5477         # setup the trap first, so someone cannot exit the test at the
5478         # exact wrong time and mess up a machine
5479         trap start_writeback EXIT
5480         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5481         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5482                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5483                 sysctl -w vm.dirty_writeback_centisecs=0
5484                 sysctl -w vm.dirty_writeback_centisecs=0
5485                 # save and increase /proc/sys/vm/dirty_ratio
5486                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5487                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5488                 # save and increase /proc/sys/vm/dirty_background_ratio
5489                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5490                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5491         else
5492                 # if file not here, we are a 2.4 kernel
5493                 kill -STOP `pidof kupdated`
5494         fi
5495 }
5496
5497 # ensure that all stripes have some grant before we test client-side cache
5498 setup_test42() {
5499         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5500                 dd if=/dev/zero of=$i bs=4k count=1
5501                 rm $i
5502         done
5503 }
5504
5505 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5506 # file truncation, and file removal.
5507 test_42a() {
5508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5509
5510         setup_test42
5511         cancel_lru_locks $OSC
5512         stop_writeback
5513         sync; sleep 1; sync # just to be safe
5514         BEFOREWRITES=`count_ost_writes`
5515         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5516         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5517         AFTERWRITES=`count_ost_writes`
5518         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5519                 error "$BEFOREWRITES < $AFTERWRITES"
5520         start_writeback
5521 }
5522 run_test 42a "ensure that we don't flush on close"
5523
5524 test_42b() {
5525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5526
5527         setup_test42
5528         cancel_lru_locks $OSC
5529         stop_writeback
5530         sync
5531         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5532         BEFOREWRITES=$(count_ost_writes)
5533         unlink $DIR/f42b || error "unlink $DIR/f42b: $?"
5534         AFTERWRITES=$(count_ost_writes)
5535         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5536                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5537         fi
5538         BEFOREWRITES=$(count_ost_writes)
5539         sync || error "sync: $?"
5540         AFTERWRITES=$(count_ost_writes)
5541         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5542                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5543         fi
5544         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5545         start_writeback
5546         return 0
5547 }
5548 run_test 42b "test destroy of file with cached dirty data ======"
5549
5550 # if these tests just want to test the effect of truncation,
5551 # they have to be very careful.  consider:
5552 # - the first open gets a {0,EOF}PR lock
5553 # - the first write conflicts and gets a {0, count-1}PW
5554 # - the rest of the writes are under {count,EOF}PW
5555 # - the open for truncate tries to match a {0,EOF}PR
5556 #   for the filesize and cancels the PWs.
5557 # any number of fixes (don't get {0,EOF} on open, match
5558 # composite locks, do smarter file size management) fix
5559 # this, but for now we want these tests to verify that
5560 # the cancellation with truncate intent works, so we
5561 # start the file with a full-file pw lock to match against
5562 # until the truncate.
5563 trunc_test() {
5564         test=$1
5565         file=$DIR/$test
5566         offset=$2
5567         cancel_lru_locks $OSC
5568         stop_writeback
5569         # prime the file with 0,EOF PW to match
5570         touch $file
5571         $TRUNCATE $file 0
5572         sync; sync
5573         # now the real test..
5574         dd if=/dev/zero of=$file bs=1024 count=100
5575         BEFOREWRITES=`count_ost_writes`
5576         $TRUNCATE $file $offset
5577         cancel_lru_locks $OSC
5578         AFTERWRITES=`count_ost_writes`
5579         start_writeback
5580 }
5581
5582 test_42c() {
5583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5584
5585         trunc_test 42c 1024
5586         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5587                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5588         rm $file
5589 }
5590 run_test 42c "test partial truncate of file with cached dirty data"
5591
5592 test_42d() {
5593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5594
5595         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5596         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5597         $LCTL set_param debug=+cache
5598
5599         trunc_test 42d 0
5600         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5601                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5602         rm $file
5603 }
5604 run_test 42d "test complete truncate of file with cached dirty data"
5605
5606 test_42e() { # bug22074
5607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5608
5609         local TDIR=$DIR/${tdir}e
5610         local pages=16 # hardcoded 16 pages, don't change it.
5611         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5612         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5613         local max_dirty_mb
5614         local warmup_files
5615
5616         test_mkdir $DIR/${tdir}e
5617         $LFS setstripe -c 1 $TDIR
5618         createmany -o $TDIR/f $files
5619
5620         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5621
5622         # we assume that with $OSTCOUNT files, at least one of them will
5623         # be allocated on OST0.
5624         warmup_files=$((OSTCOUNT * max_dirty_mb))
5625         createmany -o $TDIR/w $warmup_files
5626
5627         # write a large amount of data into one file and sync, to get good
5628         # avail_grant number from OST.
5629         for ((i=0; i<$warmup_files; i++)); do
5630                 idx=$($LFS getstripe -i $TDIR/w$i)
5631                 [ $idx -ne 0 ] && continue
5632                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5633                 break
5634         done
5635         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5636         sync
5637         $LCTL get_param $proc_osc0/cur_dirty_bytes
5638         $LCTL get_param $proc_osc0/cur_grant_bytes
5639
5640         # create as much dirty pages as we can while not to trigger the actual
5641         # RPCs directly. but depends on the env, VFS may trigger flush during this
5642         # period, hopefully we are good.
5643         for ((i=0; i<$warmup_files; i++)); do
5644                 idx=$($LFS getstripe -i $TDIR/w$i)
5645                 [ $idx -ne 0 ] && continue
5646                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5647         done
5648         $LCTL get_param $proc_osc0/cur_dirty_bytes
5649         $LCTL get_param $proc_osc0/cur_grant_bytes
5650
5651         # perform the real test
5652         $LCTL set_param $proc_osc0/rpc_stats 0
5653         for ((;i<$files; i++)); do
5654                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5655                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5656         done
5657         sync
5658         $LCTL get_param $proc_osc0/rpc_stats
5659
5660         local percent=0
5661         local have_ppr=false
5662         $LCTL get_param $proc_osc0/rpc_stats |
5663                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5664                         # skip lines until we are at the RPC histogram data
5665                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5666                         $have_ppr || continue
5667
5668                         # we only want the percent stat for < 16 pages
5669                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5670
5671                         percent=$((percent + WPCT))
5672                         if [[ $percent -gt 15 ]]; then
5673                                 error "less than 16-pages write RPCs" \
5674                                       "$percent% > 15%"
5675                                 break
5676                         fi
5677                 done
5678         rm -rf $TDIR
5679 }
5680 run_test 42e "verify sub-RPC writes are not done synchronously"
5681
5682 test_43A() { # was test_43
5683         test_mkdir $DIR/$tdir
5684         cp -p /bin/ls $DIR/$tdir/$tfile
5685         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5686         pid=$!
5687         # give multiop a chance to open
5688         sleep 1
5689
5690         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5691         kill -USR1 $pid
5692         # Wait for multiop to exit
5693         wait $pid
5694 }
5695 run_test 43A "execution of file opened for write should return -ETXTBSY"
5696
5697 test_43a() {
5698         test_mkdir $DIR/$tdir
5699         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5700         $DIR/$tdir/sleep 60 &
5701         SLEEP_PID=$!
5702         # Make sure exec of $tdir/sleep wins race with truncate
5703         sleep 1
5704         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5705         kill $SLEEP_PID
5706 }
5707 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5708
5709 test_43b() {
5710         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5711
5712         test_mkdir $DIR/$tdir
5713         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5714         $DIR/$tdir/sleep 60 &
5715         SLEEP_PID=$!
5716         # Make sure exec of $tdir/sleep wins race with truncate
5717         sleep 1
5718         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5719         kill $SLEEP_PID
5720 }
5721 run_test 43b "truncate of file being executed should return -ETXTBSY"
5722
5723 test_43c() {
5724         local testdir="$DIR/$tdir"
5725         test_mkdir $testdir
5726         cp $SHELL $testdir/
5727         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5728                 ( cd $testdir && md5sum -c )
5729 }
5730 run_test 43c "md5sum of copy into lustre"
5731
5732 test_44A() { # was test_44
5733         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5734
5735         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5736         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5737 }
5738 run_test 44A "zero length read from a sparse stripe"
5739
5740 test_44a() {
5741         local nstripe=$($LFS getstripe -c -d $DIR)
5742         [ -z "$nstripe" ] && skip "can't get stripe info"
5743         [[ $nstripe -gt $OSTCOUNT ]] &&
5744                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5745
5746         local stride=$($LFS getstripe -S -d $DIR)
5747         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5748                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5749         fi
5750
5751         OFFSETS="0 $((stride/2)) $((stride-1))"
5752         for offset in $OFFSETS; do
5753                 for i in $(seq 0 $((nstripe-1))); do
5754                         local GLOBALOFFSETS=""
5755                         # size in Bytes
5756                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5757                         local myfn=$DIR/d44a-$size
5758                         echo "--------writing $myfn at $size"
5759                         ll_sparseness_write $myfn $size ||
5760                                 error "ll_sparseness_write"
5761                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5762                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5763                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5764
5765                         for j in $(seq 0 $((nstripe-1))); do
5766                                 # size in Bytes
5767                                 size=$((((j + $nstripe )*$stride + $offset)))
5768                                 ll_sparseness_write $myfn $size ||
5769                                         error "ll_sparseness_write"
5770                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5771                         done
5772                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5773                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5774                         rm -f $myfn
5775                 done
5776         done
5777 }
5778 run_test 44a "test sparse pwrite ==============================="
5779
5780 dirty_osc_total() {
5781         tot=0
5782         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5783                 tot=$(($tot + $d))
5784         done
5785         echo $tot
5786 }
5787 do_dirty_record() {
5788         before=`dirty_osc_total`
5789         echo executing "\"$*\""
5790         eval $*
5791         after=`dirty_osc_total`
5792         echo before $before, after $after
5793 }
5794 test_45() {
5795         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5796
5797         f="$DIR/f45"
5798         # Obtain grants from OST if it supports it
5799         echo blah > ${f}_grant
5800         stop_writeback
5801         sync
5802         do_dirty_record "echo blah > $f"
5803         [[ $before -eq $after ]] && error "write wasn't cached"
5804         do_dirty_record "> $f"
5805         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5806         do_dirty_record "echo blah > $f"
5807         [[ $before -eq $after ]] && error "write wasn't cached"
5808         do_dirty_record "sync"
5809         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5810         do_dirty_record "echo blah > $f"
5811         [[ $before -eq $after ]] && error "write wasn't cached"
5812         do_dirty_record "cancel_lru_locks osc"
5813         [[ $before -gt $after ]] ||
5814                 error "lock cancellation didn't lower dirty count"
5815         start_writeback
5816 }
5817 run_test 45 "osc io page accounting ============================"
5818
5819 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5820 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5821 # objects offset and an assert hit when an rpc was built with 1023's mapped
5822 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5823 test_46() {
5824         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5825
5826         f="$DIR/f46"
5827         stop_writeback
5828         sync
5829         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5830         sync
5831         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5832         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5833         sync
5834         start_writeback
5835 }
5836 run_test 46 "dirtying a previously written page ================"
5837
5838 # test_47 is removed "Device nodes check" is moved to test_28
5839
5840 test_48a() { # bug 2399
5841         [ "$mds1_FSTYPE" = "zfs" ] &&
5842         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5843                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5844
5845         test_mkdir $DIR/$tdir
5846         cd $DIR/$tdir
5847         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5848         test_mkdir $DIR/$tdir
5849         touch foo || error "'touch foo' failed after recreating cwd"
5850         test_mkdir bar
5851         touch .foo || error "'touch .foo' failed after recreating cwd"
5852         test_mkdir .bar
5853         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5854         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5855         cd . || error "'cd .' failed after recreating cwd"
5856         mkdir . && error "'mkdir .' worked after recreating cwd"
5857         rmdir . && error "'rmdir .' worked after recreating cwd"
5858         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5859         cd .. || error "'cd ..' failed after recreating cwd"
5860 }
5861 run_test 48a "Access renamed working dir (should return errors)="
5862
5863 test_48b() { # bug 2399
5864         rm -rf $DIR/$tdir
5865         test_mkdir $DIR/$tdir
5866         cd $DIR/$tdir
5867         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5868         touch foo && error "'touch foo' worked after removing cwd"
5869         mkdir foo && error "'mkdir foo' worked after removing cwd"
5870         touch .foo && error "'touch .foo' worked after removing cwd"
5871         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5872         ls . > /dev/null && error "'ls .' worked after removing cwd"
5873         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5874         mkdir . && error "'mkdir .' worked after removing cwd"
5875         rmdir . && error "'rmdir .' worked after removing cwd"
5876         ln -s . foo && error "'ln -s .' worked after removing cwd"
5877         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5878 }
5879 run_test 48b "Access removed working dir (should return errors)="
5880
5881 test_48c() { # bug 2350
5882         #lctl set_param debug=-1
5883         #set -vx
5884         rm -rf $DIR/$tdir
5885         test_mkdir -p $DIR/$tdir/dir
5886         cd $DIR/$tdir/dir
5887         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5888         $TRACE touch foo && error "touch foo worked after removing cwd"
5889         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5890         touch .foo && error "touch .foo worked after removing cwd"
5891         mkdir .foo && error "mkdir .foo worked after removing cwd"
5892         $TRACE ls . && error "'ls .' worked after removing cwd"
5893         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5894         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5895         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5896         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5897         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5898 }
5899 run_test 48c "Access removed working subdir (should return errors)"
5900
5901 test_48d() { # bug 2350
5902         #lctl set_param debug=-1
5903         #set -vx
5904         rm -rf $DIR/$tdir
5905         test_mkdir -p $DIR/$tdir/dir
5906         cd $DIR/$tdir/dir
5907         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5908         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5909         $TRACE touch foo && error "'touch foo' worked after removing parent"
5910         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5911         touch .foo && error "'touch .foo' worked after removing parent"
5912         mkdir .foo && error "mkdir .foo worked after removing parent"
5913         $TRACE ls . && error "'ls .' worked after removing parent"
5914         $TRACE ls .. && error "'ls ..' worked after removing parent"
5915         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5916         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5917         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5918         true
5919 }
5920 run_test 48d "Access removed parent subdir (should return errors)"
5921
5922 test_48e() { # bug 4134
5923         #lctl set_param debug=-1
5924         #set -vx
5925         rm -rf $DIR/$tdir
5926         test_mkdir -p $DIR/$tdir/dir
5927         cd $DIR/$tdir/dir
5928         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5929         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5930         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5931         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5932         # On a buggy kernel addition of "touch foo" after cd .. will
5933         # produce kernel oops in lookup_hash_it
5934         touch ../foo && error "'cd ..' worked after recreate parent"
5935         cd $DIR
5936         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5937 }
5938 run_test 48e "Access to recreated parent subdir (should return errors)"
5939
5940 test_48f() {
5941         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5942                 skip "need MDS >= 2.13.55"
5943         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5944         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5945                 skip "needs different host for mdt1 mdt2"
5946         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5947
5948         $LFS mkdir -i0 $DIR/$tdir
5949         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5950
5951         for d in sub1 sub2 sub3; do
5952                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5953                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5954                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5955         done
5956
5957         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5958 }
5959 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5960
5961 test_49() { # LU-1030
5962         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5963         remote_ost_nodsh && skip "remote OST with nodsh"
5964
5965         # get ost1 size - $FSNAME-OST0000
5966         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5967                 awk '{ print $4 }')
5968         # write 800M at maximum
5969         [[ $ost1_size -lt 2 ]] && ost1_size=2
5970         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5971
5972         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5973         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5974         local dd_pid=$!
5975
5976         # change max_pages_per_rpc while writing the file
5977         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5978         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5979         # loop until dd process exits
5980         while ps ax -opid | grep -wq $dd_pid; do
5981                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5982                 sleep $((RANDOM % 5 + 1))
5983         done
5984         # restore original max_pages_per_rpc
5985         $LCTL set_param $osc1_mppc=$orig_mppc
5986         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5987 }
5988 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5989
5990 test_50() {
5991         # bug 1485
5992         test_mkdir $DIR/$tdir
5993         cd $DIR/$tdir
5994         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5995 }
5996 run_test 50 "special situations: /proc symlinks  ==============="
5997
5998 test_51a() {    # was test_51
5999         # bug 1516 - create an empty entry right after ".." then split dir
6000         test_mkdir -c1 $DIR/$tdir
6001         touch $DIR/$tdir/foo
6002         $MCREATE $DIR/$tdir/bar
6003         rm $DIR/$tdir/foo
6004         createmany -m $DIR/$tdir/longfile 201
6005         FNUM=202
6006         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
6007                 $MCREATE $DIR/$tdir/longfile$FNUM
6008                 FNUM=$(($FNUM + 1))
6009                 echo -n "+"
6010         done
6011         echo
6012         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
6013 }
6014 run_test 51a "special situations: split htree with empty entry =="
6015
6016 cleanup_print_lfs_df () {
6017         trap 0
6018         $LFS df
6019         $LFS df -i
6020 }
6021
6022 test_51b() {
6023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6024
6025         local dir=$DIR/$tdir
6026         local nrdirs=$((65536 + 100))
6027
6028         # cleanup the directory
6029         rm -fr $dir
6030
6031         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
6032
6033         $LFS df
6034         $LFS df -i
6035         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
6036         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
6037         [[ $numfree -lt $nrdirs ]] &&
6038                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
6039
6040         # need to check free space for the directories as well
6041         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
6042         numfree=$(( blkfree / $(fs_inode_ksize) ))
6043         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
6044
6045         trap cleanup_print_lfs_df EXIT
6046
6047         # create files
6048         createmany -d $dir/d $nrdirs || {
6049                 unlinkmany $dir/d $nrdirs
6050                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
6051         }
6052
6053         # really created :
6054         nrdirs=$(ls -U $dir | wc -l)
6055
6056         # unlink all but 100 subdirectories, then check it still works
6057         local left=100
6058         local delete=$((nrdirs - left))
6059
6060         $LFS df
6061         $LFS df -i
6062
6063         # for ldiskfs the nlink count should be 1, but this is OSD specific
6064         # and so this is listed for informational purposes only
6065         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
6066         unlinkmany -d $dir/d $delete ||
6067                 error "unlink of first $delete subdirs failed"
6068
6069         echo "nlink between: $(stat -c %h $dir)"
6070         local found=$(ls -U $dir | wc -l)
6071         [ $found -ne $left ] &&
6072                 error "can't find subdirs: found only $found, expected $left"
6073
6074         unlinkmany -d $dir/d $delete $left ||
6075                 error "unlink of second $left subdirs failed"
6076         # regardless of whether the backing filesystem tracks nlink accurately
6077         # or not, the nlink count shouldn't be more than "." and ".." here
6078         local after=$(stat -c %h $dir)
6079         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
6080                 echo "nlink after: $after"
6081
6082         cleanup_print_lfs_df
6083 }
6084 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
6085
6086 test_51d_sub() {
6087         local stripecount=$1
6088         local nfiles=$2
6089
6090         log "create files with stripecount=$stripecount"
6091         $LFS setstripe -C $stripecount $DIR/$tdir
6092         createmany -o $DIR/$tdir/t- $nfiles
6093         $LFS getstripe $DIR/$tdir > $TMP/$tfile
6094         for ((n = 0; n < $OSTCOUNT; n++)); do
6095                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
6096                            END { printf("%0.0f", objs) }' $TMP/$tfile)
6097                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
6098                             '($1 == '$n') { objs += 1 } \
6099                             END { printf("%0.0f", objs) }')
6100                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
6101         done
6102         unlinkmany $DIR/$tdir/t- $nfiles
6103         rm  -f $TMP/$tfile
6104
6105         local nlast
6106         local min=4
6107         local max=6 # allow variance of (1 - $min/$max) = 33% by default
6108
6109         # For some combinations of stripecount and OSTCOUNT current code
6110         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
6111         # than others. Rather than skipping this test entirely, check that
6112         # and keep testing to ensure imbalance does not get worse. LU-15282
6113         (( (OSTCOUNT == 6 && stripecount == 4) ||
6114            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
6115            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
6116         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
6117                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
6118                         { $LFS df && $LFS df -i &&
6119                         error "stripecount=$stripecount: " \
6120                               "OST $n has fewer objects vs. OST $nlast " \
6121                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
6122                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
6123                         { $LFS df && $LFS df -i &&
6124                         error "stripecount=$stripecount: " \
6125                               "OST $n has more objects vs. OST $nlast " \
6126                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
6127
6128                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
6129                         { $LFS df && $LFS df -i &&
6130                         error "stripecount=$stripecount: " \
6131                               "OST $n has fewer #0 objects vs. OST $nlast " \
6132                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
6133                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
6134                         { $LFS df && $LFS df -i &&
6135                         error "stripecount=$stripecount: " \
6136                               "OST $n has more #0 objects vs. OST $nlast " \
6137                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
6138         done
6139 }
6140
6141 test_51d() {
6142         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6143         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
6144
6145         local stripecount
6146         local per_ost=100
6147         local nfiles=$((per_ost * OSTCOUNT))
6148         local mdts=$(comma_list $(mdts_nodes))
6149         local param="osp.*.create_count"
6150         local qos_old=$(do_facet mds1 \
6151                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
6152
6153         do_nodes $mdts \
6154                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
6155         stack_trap "do_nodes $mdts \
6156                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
6157
6158         test_mkdir $DIR/$tdir
6159         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
6160         (( dirstripes > 0 )) || dirstripes=1
6161
6162         # Ensure enough OST objects precreated for tests to pass without
6163         # running out of objects.  This is an LOV r-r OST algorithm test,
6164         # not an OST object precreation test.
6165         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
6166         (( old >= nfiles )) ||
6167         {
6168                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
6169
6170                 do_nodes $mdts "$LCTL set_param $param=$create_count"
6171                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
6172
6173                 # trigger precreation from all MDTs for all OSTs
6174                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
6175                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
6176                 done
6177         }
6178
6179         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
6180                 sleep 8  # allow object precreation to catch up
6181                 test_51d_sub $stripecount $nfiles
6182         done
6183 }
6184 run_test 51d "check LOV round-robin OST object distribution"
6185
6186 test_51e() {
6187         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6188                 skip_env "ldiskfs only test"
6189         fi
6190
6191         test_mkdir -c1 $DIR/$tdir
6192         test_mkdir -c1 $DIR/$tdir/d0
6193
6194         touch $DIR/$tdir/d0/foo
6195         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
6196                 error "file exceed 65000 nlink limit!"
6197         unlinkmany $DIR/$tdir/d0/f- 65001
6198         return 0
6199 }
6200 run_test 51e "check file nlink limit"
6201
6202 test_51f() {
6203         test_mkdir $DIR/$tdir
6204
6205         local max=100000
6206         local ulimit_old=$(ulimit -n)
6207         local spare=20 # number of spare fd's for scripts/libraries, etc.
6208         local mdt=$($LFS getstripe -m $DIR/$tdir)
6209         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
6210
6211         echo "MDT$mdt numfree=$numfree, max=$max"
6212         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
6213         if [ $((numfree + spare)) -gt $ulimit_old ]; then
6214                 while ! ulimit -n $((numfree + spare)); do
6215                         numfree=$((numfree * 3 / 4))
6216                 done
6217                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
6218         else
6219                 echo "left ulimit at $ulimit_old"
6220         fi
6221
6222         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
6223                 unlinkmany $DIR/$tdir/f $numfree
6224                 error "create+open $numfree files in $DIR/$tdir failed"
6225         }
6226         ulimit -n $ulimit_old
6227
6228         # if createmany exits at 120s there will be fewer than $numfree files
6229         unlinkmany $DIR/$tdir/f $numfree || true
6230 }
6231 run_test 51f "check many open files limit"
6232
6233 test_52a() {
6234         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
6235         test_mkdir $DIR/$tdir
6236         touch $DIR/$tdir/foo
6237         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6238         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6239         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6240         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6241         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6242                                         error "link worked"
6243         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6244         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6245         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6246                                                      error "lsattr"
6247         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6248         cp -r $DIR/$tdir $TMP/
6249         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6250 }
6251 run_test 52a "append-only flag test (should return errors)"
6252
6253 test_52b() {
6254         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6255         test_mkdir $DIR/$tdir
6256         touch $DIR/$tdir/foo
6257         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6258         cat test > $DIR/$tdir/foo && error "cat test worked"
6259         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6260         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6261         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6262                                         error "link worked"
6263         echo foo >> $DIR/$tdir/foo && error "echo worked"
6264         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6265         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6266         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6267         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6268                                                         error "lsattr"
6269         chattr -i $DIR/$tdir/foo || error "chattr failed"
6270
6271         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6272 }
6273 run_test 52b "immutable flag test (should return errors) ======="
6274
6275 test_53() {
6276         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6277         remote_mds_nodsh && skip "remote MDS with nodsh"
6278         remote_ost_nodsh && skip "remote OST with nodsh"
6279
6280         local param
6281         local param_seq
6282         local ostname
6283         local mds_last
6284         local mds_last_seq
6285         local ost_last
6286         local ost_last_seq
6287         local ost_last_id
6288         local ostnum
6289         local node
6290         local found=false
6291         local support_last_seq=true
6292
6293         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6294                 support_last_seq=false
6295
6296         # only test MDT0000
6297         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6298         local value
6299         for value in $(do_facet $SINGLEMDS \
6300                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6301                 param=$(echo ${value[0]} | cut -d "=" -f1)
6302                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6303
6304                 if $support_last_seq; then
6305                         param_seq=$(echo $param |
6306                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6307                         mds_last_seq=$(do_facet $SINGLEMDS \
6308                                        $LCTL get_param -n $param_seq)
6309                 fi
6310                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6311
6312                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6313                 node=$(facet_active_host ost$((ostnum+1)))
6314                 param="obdfilter.$ostname.last_id"
6315                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6316                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6317                         ost_last_id=$ost_last
6318
6319                         if $support_last_seq; then
6320                                 ost_last_id=$(echo $ost_last |
6321                                               awk -F':' '{print $2}' |
6322                                               sed -e "s/^0x//g")
6323                                 ost_last_seq=$(echo $ost_last |
6324                                                awk -F':' '{print $1}')
6325                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6326                         fi
6327
6328                         if [[ $ost_last_id != $mds_last ]]; then
6329                                 error "$ost_last_id != $mds_last"
6330                         else
6331                                 found=true
6332                                 break
6333                         fi
6334                 done
6335         done
6336         $found || error "can not match last_seq/last_id for $mdtosc"
6337         return 0
6338 }
6339 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6340
6341 test_54a() {
6342         $SOCKETSERVER $DIR/socket ||
6343                 error "$SOCKETSERVER $DIR/socket failed: $?"
6344         $SOCKETCLIENT $DIR/socket ||
6345                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6346         unlink $DIR/socket || error "unlink $DIR/socket failed: $?"
6347 }
6348 run_test 54a "unix domain socket test"
6349
6350 test_54b() {
6351         f="$DIR/f54b"
6352         mknod $f c 1 3
6353         chmod 0666 $f
6354         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6355 }
6356 run_test 54b "char device works in lustre ======================"
6357
6358 find_loop_dev() {
6359         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6360         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6361         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6362
6363         for i in $(seq 3 7); do
6364                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6365                 LOOPDEV=$LOOPBASE$i
6366                 LOOPNUM=$i
6367                 break
6368         done
6369 }
6370
6371 cleanup_54c() {
6372         local rc=0
6373         loopdev="$DIR/loop54c"
6374
6375         trap 0
6376         $UMOUNT $DIR/$tdir || rc=$?
6377         losetup -d $loopdev || true
6378         losetup -d $LOOPDEV || true
6379         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6380         return $rc
6381 }
6382
6383 test_54c() {
6384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6385
6386         loopdev="$DIR/loop54c"
6387
6388         find_loop_dev
6389         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6390         trap cleanup_54c EXIT
6391         mknod $loopdev b 7 $LOOPNUM
6392         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6393         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6394         losetup $loopdev $DIR/$tfile ||
6395                 error "can't set up $loopdev for $DIR/$tfile"
6396         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6397         test_mkdir $DIR/$tdir
6398         mount -t ext2 $loopdev $DIR/$tdir ||
6399                 error "error mounting $loopdev on $DIR/$tdir"
6400         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6401                 error "dd write"
6402         df $DIR/$tdir
6403         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6404                 error "dd read"
6405         cleanup_54c
6406 }
6407 run_test 54c "block device works in lustre ====================="
6408
6409 test_54d() {
6410         local pipe="$DIR/$tfile.pipe"
6411         local string="aaaaaa"
6412
6413         mknod $pipe p
6414         echo -n "$string" > $pipe &
6415         local result=$(cat $pipe)
6416         [[ "$result" == "$string" ]] || error "$result != $string"
6417 }
6418 run_test 54d "fifo device works in lustre ======================"
6419
6420 test_54e() {
6421         f="$DIR/f54e"
6422         string="aaaaaa"
6423         cp -aL /dev/console $f
6424         echo $string > $f || error "echo $string to $f failed"
6425 }
6426 run_test 54e "console/tty device works in lustre ======================"
6427
6428 test_55a() {
6429         local dev_path="/sys/kernel/debug/lustre/devices"
6430
6431         load_module kunit/obd_test verbose=2 || error "load_module failed"
6432
6433         # This must be run in iteractive mode, since attach and setup
6434         # are stateful
6435         eval "$LCTL <<-EOF || error 'OBD device creation failed'
6436                 attach obd_test obd_name obd_uuid
6437                 setup obd_test
6438         EOF"
6439
6440         echo "Devices:"
6441         cat "$dev_path" | tail -n 10
6442
6443         $LCTL --device "obd_name" cleanup
6444         $LCTL --device "obd_name" detach
6445
6446         dmesg | tail -n 25 | grep "Lustre: OBD:.*FAIL" &&
6447                 error "OBD unit test failed"
6448
6449         rmmod -v obd_test ||
6450                 error "rmmod failed (may trigger a failure in a later test)"
6451 }
6452 run_test 55a "OBD device life cycle unit tests"
6453
6454 test_55b() {
6455         local dev_path="/sys/kernel/debug/lustre/devices"
6456         local dev_count="$(wc -l $dev_path | awk '{print $1}')"
6457
6458         # Set up a large number of devices, using the number
6459         # that can be set up in about a minute (based on prior
6460         # testing). We don't want to run this test forever.
6461         local num_dev_to_create="$(( 24000 - $dev_count))"
6462
6463         load_module kunit/obd_test || error "load_module failed"
6464
6465         local start=$SECONDS
6466
6467         # This must be run in iteractive mode, since attach and setup
6468         # are stateful
6469         for ((i = 1; i <= num_dev_to_create; i++)); do
6470                 echo "attach obd_test obd_name_$i obd_uuid_$i"
6471                 echo "setup obd_test_$i"
6472         done | $LCTL || error "OBD device creation failed"
6473
6474         echo "Load time: $((SECONDS - start))"
6475         echo "Devices:"
6476         cat "$dev_path" | tail -n 10
6477
6478         for ((i = 1; i <= num_dev_to_create; i++)); do
6479                 echo "--device obd_name_$i cleanup"
6480                 echo "--device obd_name_$i detach"
6481         done | $LCTL || error "OBD device cleanup failed"
6482
6483         echo "Unload time: $((SECONDS - start))"
6484
6485         rmmod -v obd_test ||
6486                 error "rmmod failed (may trigger a failure in a later test)"
6487 }
6488 run_test 55b "Load and unload max OBD devices"
6489
6490 test_56a() {
6491         local numfiles=3
6492         local numdirs=2
6493         local dir=$DIR/$tdir
6494
6495         rm -rf $dir
6496         test_mkdir -p $dir/dir
6497         for i in $(seq $numfiles); do
6498                 touch $dir/file$i
6499                 touch $dir/dir/file$i
6500         done
6501
6502         local numcomp=$($LFS getstripe --component-count $dir)
6503
6504         [[ $numcomp == 0 ]] && numcomp=1
6505
6506         # test lfs getstripe with --recursive
6507         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6508
6509         [[ $filenum -eq $((numfiles * 2)) ]] ||
6510                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6511         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6512         [[ $filenum -eq $numfiles ]] ||
6513                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6514         echo "$LFS getstripe showed obdidx or l_ost_idx"
6515
6516         # test lfs getstripe with file instead of dir
6517         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6518         [[ $filenum -eq 1 ]] ||
6519                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6520         echo "$LFS getstripe file1 passed"
6521
6522         #test lfs getstripe with --verbose
6523         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6524         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6525                 error "$LFS getstripe --verbose $dir: "\
6526                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6527         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6528                 error "$LFS getstripe $dir: showed lmm_magic"
6529
6530         #test lfs getstripe with -v prints lmm_fid
6531         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6532         local countfids=$(((numdirs + numfiles) * numcomp))
6533         [[ $filenum -eq $countfids ]] ||
6534                 error "$LFS getstripe -v $dir: "\
6535                       "got $filenum want $countfids lmm_fid"
6536         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6537                 error "$LFS getstripe $dir: showed lmm_fid by default"
6538         echo "$LFS getstripe --verbose passed"
6539
6540         #check for FID information
6541         local fid1=$($LFS getstripe --fid $dir/file1)
6542         local fid2=$($LFS getstripe --verbose $dir/file1 |
6543                      awk '/lmm_fid: / { print $2; exit; }')
6544         local fid3=$($LFS path2fid $dir/file1)
6545
6546         [ "$fid1" != "$fid2" ] &&
6547                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6548         [ "$fid1" != "$fid3" ] &&
6549                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6550         echo "$LFS getstripe --fid passed"
6551
6552         #test lfs getstripe with --obd
6553         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6554                 error "$LFS getstripe --obd wrong_uuid: should return error"
6555
6556         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6557
6558         local ostidx=1
6559         local obduuid=$(ostuuid_from_index $ostidx)
6560         local found=$($LFS getstripe -r --obd $obduuid $dir |
6561                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6562
6563         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6564         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6565                 ((filenum--))
6566         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6567                 ((filenum--))
6568
6569         [[ $found -eq $filenum ]] ||
6570                 error "$LFS getstripe --obd: found $found expect $filenum"
6571         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6572                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6573                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6574                 error "$LFS getstripe --obd: should not show file on other obd"
6575         echo "$LFS getstripe --obd passed"
6576 }
6577 run_test 56a "check $LFS getstripe"
6578
6579 test_56b() {
6580         local dir=$DIR/$tdir
6581         local numdirs=3
6582
6583         test_mkdir $dir
6584         for i in $(seq $numdirs); do
6585                 test_mkdir $dir/dir$i
6586         done
6587
6588         # test lfs getdirstripe default mode is non-recursion, which is
6589         # different from lfs getstripe
6590         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6591
6592         [[ $dircnt -eq 1 ]] ||
6593                 error "$LFS getdirstripe: found $dircnt, not 1"
6594         dircnt=$($LFS getdirstripe --recursive $dir |
6595                 grep -c lmv_stripe_count)
6596         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6597                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6598 }
6599 run_test 56b "check $LFS getdirstripe"
6600
6601 test_56bb() {
6602         verify_yaml_available || skip_env "YAML verification not installed"
6603         local output_file=$DIR/$tfile.out
6604
6605         $LFS getdirstripe -v -D -y $DIR 1> $output_file
6606
6607         cat $output_file
6608         cat $output_file | verify_yaml || error "layout is not valid YAML"
6609 }
6610 run_test 56bb "check $LFS getdirstripe layout is YAML"
6611
6612 test_56c() {
6613         remote_ost_nodsh && skip "remote OST with nodsh"
6614
6615         local ost_idx=0
6616         local ost_name=$(ostname_from_index $ost_idx)
6617         local old_status=$(ost_dev_status $ost_idx)
6618         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6619
6620         [[ -z "$old_status" ]] ||
6621                 skip_env "OST $ost_name is in $old_status status"
6622
6623         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6624         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6625                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6626         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6627                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6628                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6629         fi
6630
6631         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6632                 error "$LFS df -v showing inactive devices"
6633         sleep_maxage
6634
6635         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6636
6637         [[ "$new_status" =~ "D" ]] ||
6638                 error "$ost_name status is '$new_status', missing 'D'"
6639         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6640                 [[ "$new_status" =~ "N" ]] ||
6641                         error "$ost_name status is '$new_status', missing 'N'"
6642         fi
6643         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6644                 [[ "$new_status" =~ "f" ]] ||
6645                         error "$ost_name status is '$new_status', missing 'f'"
6646         fi
6647
6648         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6649         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6650                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6651         [[ -z "$p" ]] && restore_lustre_params < $p || true
6652         sleep_maxage
6653
6654         new_status=$(ost_dev_status $ost_idx)
6655         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6656                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6657         # can't check 'f' as devices may actually be on flash
6658 }
6659 run_test 56c "check 'lfs df' showing device status"
6660
6661 test_56d() {
6662         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6663         local osts=$($LFS df -v $MOUNT | grep -c OST)
6664
6665         $LFS df $MOUNT
6666
6667         (( mdts == MDSCOUNT )) ||
6668                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6669         (( osts == OSTCOUNT )) ||
6670                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6671 }
6672 run_test 56d "'lfs df -v' prints only configured devices"
6673
6674 test_56e() {
6675         err_enoent=2 # No such file or directory
6676         err_eopnotsupp=95 # Operation not supported
6677
6678         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6679         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6680
6681         # Check for handling of path not exists
6682         output=$($LFS df $enoent_mnt 2>&1)
6683         ret=$?
6684
6685         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6686         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6687                 error "expect failure $err_enoent, not $ret"
6688
6689         # Check for handling of non-Lustre FS
6690         output=$($LFS df $notsup_mnt)
6691         ret=$?
6692
6693         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6694         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6695                 error "expect success $err_eopnotsupp, not $ret"
6696
6697         # Check for multiple LustreFS argument
6698         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6699         ret=$?
6700
6701         [[ $output -eq 3 && $ret -eq 0 ]] ||
6702                 error "expect success 3, not $output, rc = $ret"
6703
6704         # Check for correct non-Lustre FS handling among multiple
6705         # LustreFS argument
6706         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6707                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6708         ret=$?
6709
6710         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6711                 error "expect success 2, not $output, rc = $ret"
6712 }
6713 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6714
6715 NUMFILES=3
6716 NUMDIRS=3
6717 setup_56() {
6718         local local_tdir="$1"
6719         local local_numfiles="$2"
6720         local local_numdirs="$3"
6721         local dir_params="$4"
6722         local dir_stripe_params="$5"
6723
6724         if [ ! -d "$local_tdir" ] ; then
6725                 test_mkdir -p $dir_stripe_params $local_tdir
6726                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6727                 for i in $(seq $local_numfiles) ; do
6728                         touch $local_tdir/file$i
6729                 done
6730                 for i in $(seq $local_numdirs) ; do
6731                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6732                         for j in $(seq $local_numfiles) ; do
6733                                 touch $local_tdir/dir$i/file$j
6734                         done
6735                 done
6736         fi
6737 }
6738
6739 setup_56_special() {
6740         local local_tdir=$1
6741         local local_numfiles=$2
6742         local local_numdirs=$3
6743
6744         setup_56 $local_tdir $local_numfiles $local_numdirs
6745
6746         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6747                 for i in $(seq $local_numfiles) ; do
6748                         mknod $local_tdir/loop${i}b b 7 $i
6749                         mknod $local_tdir/null${i}c c 1 3
6750                         ln -s $local_tdir/file1 $local_tdir/link${i}
6751                 done
6752                 for i in $(seq $local_numdirs) ; do
6753                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6754                         mknod $local_tdir/dir$i/null${i}c c 1 3
6755                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6756                 done
6757         fi
6758 }
6759
6760 test_56g() {
6761         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6762         local expected=$(($NUMDIRS + 2))
6763
6764         setup_56 $dir $NUMFILES $NUMDIRS
6765
6766         # test lfs find with -name
6767         for i in $(seq $NUMFILES) ; do
6768                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6769
6770                 [ $nums -eq $expected ] ||
6771                         error "lfs find -name '*$i' $dir wrong: "\
6772                               "found $nums, expected $expected"
6773         done
6774 }
6775 run_test 56g "check lfs find -name"
6776
6777 test_56h() {
6778         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6779         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6780
6781         setup_56 $dir $NUMFILES $NUMDIRS
6782
6783         # test lfs find with ! -name
6784         for i in $(seq $NUMFILES) ; do
6785                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6786
6787                 [ $nums -eq $expected ] ||
6788                         error "lfs find ! -name '*$i' $dir wrong: "\
6789                               "found $nums, expected $expected"
6790         done
6791 }
6792 run_test 56h "check lfs find ! -name"
6793
6794 test_56i() {
6795         local dir=$DIR/$tdir
6796
6797         test_mkdir $dir
6798
6799         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6800         local out=$($cmd)
6801
6802         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6803 }
6804 run_test 56i "check 'lfs find -ost UUID' skips directories"
6805
6806 test_56j() {
6807         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6808
6809         setup_56_special $dir $NUMFILES $NUMDIRS
6810
6811         local expected=$((NUMDIRS + 1))
6812         local cmd="$LFS find -type d $dir"
6813         local nums=$($cmd | wc -l)
6814
6815         [ $nums -eq $expected ] ||
6816                 error "'$cmd' wrong: found $nums, expected $expected"
6817 }
6818 run_test 56j "check lfs find -type d"
6819
6820 test_56k() {
6821         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6822
6823         setup_56_special $dir $NUMFILES $NUMDIRS
6824
6825         local expected=$(((NUMDIRS + 1) * NUMFILES))
6826         local cmd="$LFS find -type f $dir"
6827         local nums=$($cmd | wc -l)
6828
6829         [ $nums -eq $expected ] ||
6830                 error "'$cmd' wrong: found $nums, expected $expected"
6831 }
6832 run_test 56k "check lfs find -type f"
6833
6834 test_56l() {
6835         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6836
6837         setup_56_special $dir $NUMFILES $NUMDIRS
6838
6839         local expected=$((NUMDIRS + NUMFILES))
6840         local cmd="$LFS find -type b $dir"
6841         local nums=$($cmd | wc -l)
6842
6843         [ $nums -eq $expected ] ||
6844                 error "'$cmd' wrong: found $nums, expected $expected"
6845 }
6846 run_test 56l "check lfs find -type b"
6847
6848 test_56m() {
6849         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6850
6851         setup_56_special $dir $NUMFILES $NUMDIRS
6852
6853         local expected=$((NUMDIRS + NUMFILES))
6854         local cmd="$LFS find -type c $dir"
6855         local nums=$($cmd | wc -l)
6856         [ $nums -eq $expected ] ||
6857                 error "'$cmd' wrong: found $nums, expected $expected"
6858 }
6859 run_test 56m "check lfs find -type c"
6860
6861 test_56n() {
6862         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6863         setup_56_special $dir $NUMFILES $NUMDIRS
6864
6865         local expected=$((NUMDIRS + NUMFILES))
6866         local cmd="$LFS find -type l $dir"
6867         local nums=$($cmd | wc -l)
6868
6869         [ $nums -eq $expected ] ||
6870                 error "'$cmd' wrong: found $nums, expected $expected"
6871 }
6872 run_test 56n "check lfs find -type l"
6873
6874 test_56o() {
6875         local dir=$DIR/$tdir
6876
6877         setup_56 $dir $NUMFILES $NUMDIRS
6878         utime $dir/file1 > /dev/null || error "utime (1)"
6879         utime $dir/file2 > /dev/null || error "utime (2)"
6880         utime $dir/dir1 > /dev/null || error "utime (3)"
6881         utime $dir/dir2 > /dev/null || error "utime (4)"
6882         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6883         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6884
6885         local expected=4
6886         local nums=$($LFS find -mtime +0 $dir | wc -l)
6887
6888         [ $nums -eq $expected ] ||
6889                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6890
6891         expected=12
6892         cmd="$LFS find -mtime 0 $dir"
6893         nums=$($cmd | wc -l)
6894         [ $nums -eq $expected ] ||
6895                 error "'$cmd' wrong: found $nums, expected $expected"
6896 }
6897 run_test 56o "check lfs find -mtime for old files"
6898
6899 test_56ob() {
6900         local dir=$DIR/$tdir
6901         local expected=1
6902         local count=0
6903
6904         # just to make sure there is something that won't be found
6905         test_mkdir $dir
6906         touch $dir/$tfile.now
6907
6908         for age in year week day hour min; do
6909                 count=$((count + 1))
6910
6911                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6912                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6913                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6914
6915                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6916                 local nums=$($cmd | wc -l)
6917                 [ $nums -eq $expected ] ||
6918                         error "'$cmd' wrong: found $nums, expected $expected"
6919
6920                 cmd="$LFS find $dir -atime $count${age:0:1}"
6921                 nums=$($cmd | wc -l)
6922                 [ $nums -eq $expected ] ||
6923                         error "'$cmd' wrong: found $nums, expected $expected"
6924         done
6925
6926         sleep 2
6927         cmd="$LFS find $dir -ctime +1s -type f"
6928         nums=$($cmd | wc -l)
6929         (( $nums == $count * 2 + 1)) ||
6930                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6931 }
6932 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6933
6934 test_newerXY_base() {
6935         local x=$1
6936         local y=$2
6937         local dir=$DIR/$tdir
6938         local ref
6939         local negref
6940
6941         if [ $y == "t" ]; then
6942                 if [ $x == "b" ]; then
6943                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6944                 else
6945                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6946                 fi
6947         else
6948                 ref=$DIR/$tfile.newer.$x$y
6949                 touch $ref || error "touch $ref failed"
6950         fi
6951
6952         echo "before = $ref"
6953         sleep 2
6954         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6955         sleep 2
6956         if [ $y == "t" ]; then
6957                 if [ $x == "b" ]; then
6958                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6959                 else
6960                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6961                 fi
6962         else
6963                 negref=$DIR/$tfile.negnewer.$x$y
6964                 touch $negref || error "touch $negref failed"
6965         fi
6966
6967         echo "after = $negref"
6968         local cmd="$LFS find $dir -newer$x$y $ref"
6969         local nums=$(eval $cmd | wc -l)
6970         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6971
6972         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6973                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6974
6975         cmd="$LFS find $dir ! -newer$x$y $negref"
6976         nums=$(eval $cmd | wc -l)
6977         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6978                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6979
6980         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6981         nums=$(eval $cmd | wc -l)
6982         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6983                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6984
6985         rm -rf $DIR/*
6986 }
6987
6988 test_56oc() {
6989         test_newerXY_base "a" "a"
6990         test_newerXY_base "a" "m"
6991         test_newerXY_base "a" "c"
6992         test_newerXY_base "m" "a"
6993         test_newerXY_base "m" "m"
6994         test_newerXY_base "m" "c"
6995         test_newerXY_base "c" "a"
6996         test_newerXY_base "c" "m"
6997         test_newerXY_base "c" "c"
6998
6999         test_newerXY_base "a" "t"
7000         test_newerXY_base "m" "t"
7001         test_newerXY_base "c" "t"
7002
7003         (( $MDS1_VERSION >= $(version_code v2_13_53-145-g186b97e68a) &&
7004            $CLIENT_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
7005                 { echo "btime needs v2_13_53-145-g186b97e68a"; return 0; }
7006
7007         test_newerXY_base "b" "b"
7008         test_newerXY_base "b" "t"
7009 }
7010 run_test 56oc "check lfs find -newerXY work"
7011
7012 test_56od() {
7013         (( $MDS1_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
7014                 skip "btime unsupported on MDS < v2_13_53-145-g186b97e68a"
7015
7016         (( $CLIENT_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
7017                 skip "btime unsupported on clients < v2_13_53-145-g186b97e68a"
7018
7019         local dir=$DIR/$tdir
7020         local ref=$DIR/$tfile.ref
7021         local negref=$DIR/$tfile.negref
7022
7023         mkdir $dir || error "mkdir $dir failed"
7024         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
7025         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
7026         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
7027         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
7028         touch $ref || error "touch $ref failed"
7029         # sleep 3 seconds at least
7030         sleep 3
7031
7032         local before=$(do_facet mds1 date +%s)
7033         local skew=$(($(date +%s) - before + 1))
7034
7035         if (( skew < 0 && skew > -5 )); then
7036                 sleep $((0 - skew + 1))
7037                 skew=0
7038         fi
7039
7040         # Set the dir stripe params to limit files all on MDT0,
7041         # otherwise we need to calc the max clock skew between
7042         # the client and MDTs.
7043         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
7044         sleep 2
7045         touch $negref || error "touch $negref failed"
7046
7047         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
7048         local nums=$($cmd | wc -l)
7049         local expected=$(((NUMFILES + 1) * NUMDIRS))
7050
7051         [ $nums -eq $expected ] ||
7052                 error "'$cmd' wrong: found $nums, expected $expected"
7053
7054         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
7055         nums=$($cmd | wc -l)
7056         expected=$((NUMFILES + 1))
7057         [ $nums -eq $expected ] ||
7058                 error "'$cmd' wrong: found $nums, expected $expected"
7059
7060         [ $skew -lt 0 ] && return
7061
7062         local after=$(do_facet mds1 date +%s)
7063         local age=$((after - before + 1 + skew))
7064
7065         cmd="$LFS find $dir -btime -${age}s -type f"
7066         nums=$($cmd | wc -l)
7067         expected=$(((NUMFILES + 1) * NUMDIRS))
7068
7069         echo "Clock skew between client and server: $skew, age:$age"
7070         [ $nums -eq $expected ] ||
7071                 error "'$cmd' wrong: found $nums, expected $expected"
7072
7073         expected=$(($NUMDIRS + 1))
7074         cmd="$LFS find $dir -btime -${age}s -type d"
7075         nums=$($cmd | wc -l)
7076         [ $nums -eq $expected ] ||
7077                 error "'$cmd' wrong: found $nums, expected $expected"
7078         rm -f $ref $negref || error "Failed to remove $ref $negref"
7079 }
7080 run_test 56od "check lfs find -btime with units"
7081
7082 test_56p() {
7083         [ $RUNAS_ID -eq $UID ] &&
7084                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7085
7086         local dir=$DIR/$tdir
7087
7088         setup_56 $dir $NUMFILES $NUMDIRS
7089         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
7090
7091         local expected=$NUMFILES
7092         local cmd="$LFS find -uid $RUNAS_ID $dir"
7093         local nums=$($cmd | wc -l)
7094
7095         [ $nums -eq $expected ] ||
7096                 error "'$cmd' wrong: found $nums, expected $expected"
7097
7098         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
7099         cmd="$LFS find ! -uid $RUNAS_ID $dir"
7100         nums=$($cmd | wc -l)
7101         [ $nums -eq $expected ] ||
7102                 error "'$cmd' wrong: found $nums, expected $expected"
7103 }
7104 run_test 56p "check lfs find -uid and ! -uid"
7105
7106 test_56q() {
7107         [ $RUNAS_ID -eq $UID ] &&
7108                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7109
7110         local dir=$DIR/$tdir
7111
7112         setup_56 $dir $NUMFILES $NUMDIRS
7113         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
7114
7115         local expected=$NUMFILES
7116         local cmd="$LFS find -gid $RUNAS_GID $dir"
7117         local nums=$($cmd | wc -l)
7118
7119         [ $nums -eq $expected ] ||
7120                 error "'$cmd' wrong: found $nums, expected $expected"
7121
7122         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
7123         cmd="$LFS find ! -gid $RUNAS_GID $dir"
7124         nums=$($cmd | wc -l)
7125         [ $nums -eq $expected ] ||
7126                 error "'$cmd' wrong: found $nums, expected $expected"
7127 }
7128 run_test 56q "check lfs find -gid and ! -gid"
7129
7130 test_56r() {
7131         local dir=$DIR/$tdir
7132
7133         setup_56 $dir $NUMFILES $NUMDIRS
7134
7135         local expected=12
7136         local cmd="$LFS find -size 0 -type f -lazy $dir"
7137         local nums=$($cmd | wc -l)
7138
7139         [ $nums -eq $expected ] ||
7140                 error "'$cmd' wrong: found $nums, expected $expected"
7141         cmd="$LFS find -size 0 -type f $dir"
7142         nums=$($cmd | wc -l)
7143         [ $nums -eq $expected ] ||
7144                 error "'$cmd' wrong: found $nums, expected $expected"
7145
7146         expected=0
7147         cmd="$LFS find ! -size 0 -type f -lazy $dir"
7148         nums=$($cmd | wc -l)
7149         [ $nums -eq $expected ] ||
7150                 error "'$cmd' wrong: found $nums, expected $expected"
7151         cmd="$LFS find ! -size 0 -type f $dir"
7152         nums=$($cmd | wc -l)
7153         [ $nums -eq $expected ] ||
7154                 error "'$cmd' wrong: found $nums, expected $expected"
7155
7156         echo "test" > $dir/$tfile
7157         echo "test2" > $dir/$tfile.2 && sync
7158         expected=1
7159         cmd="$LFS find -size 5c -type f -lazy $dir"
7160         nums=$($cmd | wc -l)
7161         [ $nums -eq $expected ] ||
7162                 error "'$cmd' wrong: found $nums, expected $expected"
7163         cmd="$LFS find -size 5c -type f $dir"
7164         nums=$($cmd | wc -l)
7165         [ $nums -eq $expected ] ||
7166                 error "'$cmd' wrong: found $nums, expected $expected"
7167
7168         expected=1
7169         cmd="$LFS find -size +5c -type f -lazy $dir"
7170         nums=$($cmd | wc -l)
7171         [ $nums -eq $expected ] ||
7172                 error "'$cmd' wrong: found $nums, expected $expected"
7173         cmd="$LFS find -size +5c -type f $dir"
7174         nums=$($cmd | wc -l)
7175         [ $nums -eq $expected ] ||
7176                 error "'$cmd' wrong: found $nums, expected $expected"
7177
7178         expected=2
7179         cmd="$LFS find -size +0 -type f -lazy $dir"
7180         nums=$($cmd | wc -l)
7181         [ $nums -eq $expected ] ||
7182                 error "'$cmd' wrong: found $nums, expected $expected"
7183         cmd="$LFS find -size +0 -type f $dir"
7184         nums=$($cmd | wc -l)
7185         [ $nums -eq $expected ] ||
7186                 error "'$cmd' wrong: found $nums, expected $expected"
7187
7188         expected=2
7189         cmd="$LFS find ! -size -5c -type f -lazy $dir"
7190         nums=$($cmd | wc -l)
7191         [ $nums -eq $expected ] ||
7192                 error "'$cmd' wrong: found $nums, expected $expected"
7193         cmd="$LFS find ! -size -5c -type f $dir"
7194         nums=$($cmd | wc -l)
7195         [ $nums -eq $expected ] ||
7196                 error "'$cmd' wrong: found $nums, expected $expected"
7197
7198         expected=12
7199         cmd="$LFS find -size -5c -type f -lazy $dir"
7200         nums=$($cmd | wc -l)
7201         [ $nums -eq $expected ] ||
7202                 error "'$cmd' wrong: found $nums, expected $expected"
7203         cmd="$LFS find -size -5c -type f $dir"
7204         nums=$($cmd | wc -l)
7205         [ $nums -eq $expected ] ||
7206                 error "'$cmd' wrong: found $nums, expected $expected"
7207 }
7208 run_test 56r "check lfs find -size works"
7209
7210 test_56ra_sub() {
7211         local expected=$1
7212         local glimpses=$2
7213         local cmd="$3"
7214
7215         cancel_lru_locks $OSC
7216
7217         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7218         local nums=$($cmd | wc -l)
7219
7220         [ $nums -eq $expected ] ||
7221                 error "'$cmd' wrong: found $nums, expected $expected"
7222
7223         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7224
7225         if (( rpcs_before + glimpses != rpcs_after )); then
7226                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
7227                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
7228
7229                 if [[ $glimpses == 0 ]]; then
7230                         error "'$cmd' should not send glimpse RPCs to OST"
7231                 else
7232                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
7233                 fi
7234         fi
7235 }
7236
7237 test_56ra() {
7238         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
7239                 skip "MDS < 2.12.58 doesn't return LSOM data"
7240         local dir=$DIR/$tdir
7241         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
7242
7243         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
7244
7245         # statahead_agl may cause extra glimpse which confuses results. LU-13017
7246         $LCTL set_param -n llite.*.statahead_agl=0
7247         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
7248
7249         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7250         # open and close all files to ensure LSOM is updated
7251         cancel_lru_locks $OSC
7252         find $dir -type f | xargs cat > /dev/null
7253
7254         #   expect_found  glimpse_rpcs  command_to_run
7255         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
7256         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
7257         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
7258         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
7259
7260         echo "test" > $dir/$tfile
7261         echo "test2" > $dir/$tfile.2 && sync
7262         cancel_lru_locks $OSC
7263         cat $dir/$tfile $dir/$tfile.2 > /dev/null
7264
7265         test_56ra_sub  1  0 "$LFS find -size 5c -type f -lazy $dir"
7266         test_56ra_sub  1 14 "$LFS find -size 5c -type f $dir"
7267         test_56ra_sub  1  0 "$LFS find -size +5c -type f -lazy $dir"
7268         test_56ra_sub  1 14 "$LFS find -size +5c -type f $dir"
7269
7270         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
7271         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
7272         test_56ra_sub  2  0 "$LFS find ! -size -5c -type f -lazy $dir"
7273         test_56ra_sub  2 14 "$LFS find ! -size -5c -type f $dir"
7274         test_56ra_sub 12  0 "$LFS find -size -5c -type f -lazy $dir"
7275         test_56ra_sub 12 14 "$LFS find -size -5c -type f $dir"
7276 }
7277 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
7278
7279 test_56rb() {
7280         local dir=$DIR/$tdir
7281         local tmp=$TMP/$tfile.log
7282         local mdt_idx;
7283
7284         test_mkdir -p $dir || error "failed to mkdir $dir"
7285         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
7286                 error "failed to setstripe $dir/$tfile"
7287         mdt_idx=$($LFS getdirstripe -i $dir)
7288         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
7289
7290         stack_trap "rm -f $tmp" EXIT
7291         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7292         ! grep -q obd_uuid $tmp ||
7293                 error "failed to find --size +100K --ost 0 $dir"
7294         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7295         ! grep -q obd_uuid $tmp ||
7296                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7297 }
7298 run_test 56rb "check lfs find --size --ost/--mdt works"
7299
7300 test_56rc() {
7301         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7302         local dir=$DIR/$tdir
7303         local found
7304
7305         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7306         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7307         (( $MDSCOUNT > 2 )) &&
7308                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7309         mkdir $dir/$tdir-{1..10}
7310         touch $dir/$tfile-{1..10}
7311
7312         found=$($LFS find $dir --mdt-count 2 | wc -l)
7313         expect=11
7314         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7315
7316         found=$($LFS find $dir -T +1 | wc -l)
7317         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7318         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7319
7320         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7321         expect=11
7322         (( $found == $expect )) || error "found $found all_char, expect $expect"
7323
7324         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7325         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7326         (( $found == $expect )) || error "found $found all_char, expect $expect"
7327 }
7328 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7329
7330 test_56rd() {
7331         local dir=$DIR/$tdir
7332
7333         test_mkdir $dir
7334         rm -f $dir/*
7335
7336         mkfifo $dir/fifo || error "failed to create fifo file"
7337         $LFS find $dir -t p --printf "%p %y %LP\n" ||
7338                 error "should not fail even cannot get projid from pipe file"
7339         found=$($LFS find $dir -t p --printf "%y")
7340         [[ "p" == $found ]] || error "found $found, expect p"
7341
7342         mknod $dir/chardev c 1 5 ||
7343                 error "failed to create character device file"
7344         $LFS find $dir -t c --printf "%p %y %LP\n" ||
7345                 error "should not fail even cannot get projid from chardev file"
7346         found=$($LFS find $dir -t c --printf "%y")
7347         [[ "c" == $found ]] || error "found $found, expect c"
7348
7349         found=$($LFS find $dir ! -type d --printf "%p %y %LP\n" | wc -l)
7350         (( found == 2 )) || error "unable to list all files"
7351 }
7352 run_test 56rd "check lfs find --printf special files"
7353
7354 test_56s() { # LU-611 #LU-9369
7355         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7356
7357         local dir=$DIR/$tdir
7358         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7359
7360         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7361         for i in $(seq $NUMDIRS); do
7362                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7363         done
7364
7365         local expected=$NUMDIRS
7366         local cmd="$LFS find -c $OSTCOUNT $dir"
7367         local nums=$($cmd | wc -l)
7368
7369         [ $nums -eq $expected ] || {
7370                 $LFS getstripe -R $dir
7371                 error "'$cmd' wrong: found $nums, expected $expected"
7372         }
7373
7374         expected=$((NUMDIRS + onestripe))
7375         cmd="$LFS find -stripe-count +0 -type f $dir"
7376         nums=$($cmd | wc -l)
7377         [ $nums -eq $expected ] || {
7378                 $LFS getstripe -R $dir
7379                 error "'$cmd' wrong: found $nums, expected $expected"
7380         }
7381
7382         expected=$onestripe
7383         cmd="$LFS find -stripe-count 1 -type f $dir"
7384         nums=$($cmd | wc -l)
7385         [ $nums -eq $expected ] || {
7386                 $LFS getstripe -R $dir
7387                 error "'$cmd' wrong: found $nums, expected $expected"
7388         }
7389
7390         cmd="$LFS find -stripe-count -2 -type f $dir"
7391         nums=$($cmd | wc -l)
7392         [ $nums -eq $expected ] || {
7393                 $LFS getstripe -R $dir
7394                 error "'$cmd' wrong: found $nums, expected $expected"
7395         }
7396
7397         expected=0
7398         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7399         nums=$($cmd | wc -l)
7400         [ $nums -eq $expected ] || {
7401                 $LFS getstripe -R $dir
7402                 error "'$cmd' wrong: found $nums, expected $expected"
7403         }
7404 }
7405 run_test 56s "check lfs find -stripe-count works"
7406
7407 test_56t() { # LU-611 #LU-9369
7408         local dir=$DIR/$tdir
7409
7410         setup_56 $dir 0 $NUMDIRS
7411         for i in $(seq $NUMDIRS); do
7412                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7413         done
7414
7415         local expected=$NUMDIRS
7416         local cmd="$LFS find -S 8M $dir"
7417         local nums=$($cmd | wc -l)
7418
7419         [ $nums -eq $expected ] || {
7420                 $LFS getstripe -R $dir
7421                 error "'$cmd' wrong: found $nums, expected $expected"
7422         }
7423         rm -rf $dir
7424
7425         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7426
7427         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7428
7429         expected=$(((NUMDIRS + 1) * NUMFILES))
7430         cmd="$LFS find -stripe-size 512k -type f $dir"
7431         nums=$($cmd | wc -l)
7432         [ $nums -eq $expected ] ||
7433                 error "'$cmd' wrong: found $nums, expected $expected"
7434
7435         cmd="$LFS find -stripe-size +320k -type f $dir"
7436         nums=$($cmd | wc -l)
7437         [ $nums -eq $expected ] ||
7438                 error "'$cmd' wrong: found $nums, expected $expected"
7439
7440         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7441         cmd="$LFS find -stripe-size +200k -type f $dir"
7442         nums=$($cmd | wc -l)
7443         [ $nums -eq $expected ] ||
7444                 error "'$cmd' wrong: found $nums, expected $expected"
7445
7446         cmd="$LFS find -stripe-size -640k -type f $dir"
7447         nums=$($cmd | wc -l)
7448         [ $nums -eq $expected ] ||
7449                 error "'$cmd' wrong: found $nums, expected $expected"
7450
7451         expected=4
7452         cmd="$LFS find -stripe-size 256k -type f $dir"
7453         nums=$($cmd | wc -l)
7454         [ $nums -eq $expected ] ||
7455                 error "'$cmd' wrong: found $nums, expected $expected"
7456
7457         cmd="$LFS find -stripe-size -320k -type f $dir"
7458         nums=$($cmd | wc -l)
7459         [ $nums -eq $expected ] ||
7460                 error "'$cmd' wrong: found $nums, expected $expected"
7461
7462         expected=0
7463         cmd="$LFS find -stripe-size 1024k -type f $dir"
7464         nums=$($cmd | wc -l)
7465         [ $nums -eq $expected ] ||
7466                 error "'$cmd' wrong: found $nums, expected $expected"
7467 }
7468 run_test 56t "check lfs find -stripe-size works"
7469
7470 test_56u() { # LU-611
7471         local dir=$DIR/$tdir
7472
7473         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7474
7475         if [[ $OSTCOUNT -gt 1 ]]; then
7476                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7477                 onestripe=4
7478         else
7479                 onestripe=0
7480         fi
7481
7482         local expected=$(((NUMDIRS + 1) * NUMFILES))
7483         local cmd="$LFS find -stripe-index 0 -type f $dir"
7484         local nums=$($cmd | wc -l)
7485
7486         [ $nums -eq $expected ] ||
7487                 error "'$cmd' wrong: found $nums, expected $expected"
7488
7489         expected=$onestripe
7490         cmd="$LFS find -stripe-index 1 -type f $dir"
7491         nums=$($cmd | wc -l)
7492         [ $nums -eq $expected ] ||
7493                 error "'$cmd' wrong: found $nums, expected $expected"
7494
7495         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7496         nums=$($cmd | wc -l)
7497         [ $nums -eq $expected ] ||
7498                 error "'$cmd' wrong: found $nums, expected $expected"
7499
7500         expected=0
7501         # This should produce an error and not return any files
7502         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7503         nums=$($cmd 2>/dev/null | wc -l)
7504         [ $nums -eq $expected ] ||
7505                 error "'$cmd' wrong: found $nums, expected $expected"
7506
7507         if [[ $OSTCOUNT -gt 1 ]]; then
7508                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7509                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7510                 nums=$($cmd | wc -l)
7511                 [ $nums -eq $expected ] ||
7512                         error "'$cmd' wrong: found $nums, expected $expected"
7513         fi
7514 }
7515 run_test 56u "check lfs find -stripe-index works"
7516
7517 test_56v() {
7518         local mdt_idx=0
7519         local dir=$DIR/$tdir
7520
7521         setup_56 $dir $NUMFILES $NUMDIRS
7522
7523         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7524         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7525
7526         for file in $($LFS find -m $UUID $dir); do
7527                 file_midx=$($LFS getstripe -m $file)
7528                 [ $file_midx -eq $mdt_idx ] ||
7529                         error "lfs find -m $UUID != getstripe -m $file_midx"
7530         done
7531 }
7532 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7533
7534 test_56wa() {
7535         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7536         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7537
7538         local dir=$DIR/$tdir
7539
7540         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7541         stack_trap "rm -rf $dir"
7542
7543         local stripe_size=$($LFS getstripe -S -d $dir) ||
7544                 error "$LFS getstripe -S -d $dir failed"
7545         stripe_size=${stripe_size%% *}
7546
7547         local file_size=$((stripe_size * OSTCOUNT))
7548         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7549         local required_space=$((file_num * file_size))
7550         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7551                            head -n1)
7552         (( free_space >= required_space / 1024 )) ||
7553                 skip_env "need $required_space, have $free_space kbytes"
7554
7555         local dd_bs=65536
7556         local dd_count=$((file_size / dd_bs))
7557
7558         # write data into the files
7559         local i
7560         local j
7561         local file
7562
7563         for ((i = 1; i <= NUMFILES; i++ )); do
7564                 file=$dir/file$i
7565                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7566                         error "write data into $file failed"
7567         done
7568         for ((i = 1; i <= NUMDIRS; i++ )); do
7569                 for ((j = 1; j <= NUMFILES; j++ )); do
7570                         file=$dir/dir$i/file$j
7571                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7572                                 error "write data into $file failed"
7573                 done
7574         done
7575
7576         # $LFS_MIGRATE will fail if hard link migration is unsupported
7577         if (( MDS1_VERSION > $(version_code 2.5.55) )); then
7578                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7579                         error "creating links to $dir/dir1/file1 failed"
7580         fi
7581
7582         local expected=-1
7583
7584         (( OSTCOUNT <= 1 )) || expected=$((OSTCOUNT - 1))
7585
7586         # lfs_migrate file
7587         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7588
7589         echo "$cmd"
7590         eval $cmd || error "$cmd failed"
7591
7592         check_stripe_count $dir/file1 $expected
7593
7594         if (( $MDS1_VERSION >= $(version_code 2.6.90) )); then
7595                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7596                 # OST 1 if it is on OST 0. This file is small enough to
7597                 # be on only one stripe.
7598                 file=$dir/migr_1_ost
7599                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7600                         error "write data into $file failed"
7601                 local obdidx=$($LFS getstripe -i $file)
7602                 local oldmd5=$(md5sum $file)
7603                 local newobdidx=0
7604
7605                 (( obdidx != 0 )) || newobdidx=1
7606                 cmd="$LFS migrate -i $newobdidx $file"
7607                 echo $cmd
7608                 eval $cmd || error "$cmd failed"
7609
7610                 local realobdix=$($LFS getstripe -i $file)
7611                 local newmd5=$(md5sum $file)
7612
7613                 (( $newobdidx == $realobdix )) ||
7614                         error "new OST is different (was=$obdidx, wanted=$newobdidx, got=$realobdix)"
7615                 [[ "$oldmd5" == "$newmd5" ]] ||
7616                         error "md5sum differ: $oldmd5, $newmd5"
7617         fi
7618
7619         # lfs_migrate dir
7620         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7621         echo "$cmd"
7622         eval $cmd || error "$cmd failed"
7623
7624         for (( j = 1; j <= NUMFILES; j++ )); do
7625                 check_stripe_count $dir/dir1/file$j $expected
7626         done
7627
7628         # lfs_migrate works with lfs find
7629         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7630              $LFS_MIGRATE -y -c $expected"
7631         echo "$cmd"
7632         eval $cmd || error "$cmd failed"
7633
7634         for (( i = 2; i <= NUMFILES; i++ )); do
7635                 check_stripe_count $dir/file$i $expected
7636         done
7637         for (( i = 2; i <= NUMDIRS; i++ )); do
7638                 for (( j = 1; j <= NUMFILES; j++ )); do
7639                         check_stripe_count $dir/dir$i/file$j $expected
7640                 done
7641         done
7642 }
7643 run_test 56wa "check lfs_migrate -c stripe_count works"
7644
7645 test_56wb() {
7646         local file1=$DIR/$tdir/file1
7647         local create_pool=false
7648         local initial_pool=$($LFS getstripe -p $DIR)
7649         local pool_list=()
7650         local pool=""
7651
7652         echo -n "Creating test dir..."
7653         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7654         echo "done."
7655
7656         echo -n "Creating test file..."
7657         touch $file1 || error "cannot create file"
7658         echo "done."
7659
7660         echo -n "Detecting existing pools..."
7661         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7662
7663         if [ ${#pool_list[@]} -gt 0 ]; then
7664                 echo "${pool_list[@]}"
7665                 for thispool in "${pool_list[@]}"; do
7666                         if [[ -z "$initial_pool" ||
7667                               "$initial_pool" != "$thispool" ]]; then
7668                                 pool="$thispool"
7669                                 echo "Using existing pool '$pool'"
7670                                 break
7671                         fi
7672                 done
7673         else
7674                 echo "none detected."
7675         fi
7676         if [ -z "$pool" ]; then
7677                 pool=${POOL:-testpool}
7678                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7679                 echo -n "Creating pool '$pool'..."
7680                 create_pool=true
7681                 pool_add $pool &> /dev/null ||
7682                         error "pool_add failed"
7683                 echo "done."
7684
7685                 echo -n "Adding target to pool..."
7686                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7687                         error "pool_add_targets failed"
7688                 echo "done."
7689         fi
7690
7691         echo -n "Setting pool using -p option..."
7692         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7693                 error "migrate failed rc = $?"
7694         echo "done."
7695
7696         echo -n "Verifying test file is in pool after migrating..."
7697         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7698                 error "file was not migrated to pool $pool"
7699         echo "done."
7700
7701         echo -n "Removing test file from pool '$pool'..."
7702         # "lfs migrate $file" won't remove the file from the pool
7703         # until some striping information is changed.
7704         $LFS migrate -c 1 $file1 &> /dev/null ||
7705                 error "cannot remove from pool"
7706         [ "$($LFS getstripe -p $file1)" ] &&
7707                 error "pool still set"
7708         echo "done."
7709
7710         echo -n "Setting pool using --pool option..."
7711         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7712                 error "migrate failed rc = $?"
7713         echo "done."
7714
7715         # Clean up
7716         rm -f $file1
7717         if $create_pool; then
7718                 destroy_test_pools 2> /dev/null ||
7719                         error "destroy test pools failed"
7720         fi
7721 }
7722 run_test 56wb "check lfs_migrate pool support"
7723
7724 test_56wc() {
7725         local file1="$DIR/$tdir/$tfile"
7726         local md5
7727         local parent_ssize
7728         local parent_scount
7729         local cur_ssize
7730         local cur_scount
7731         local orig_ssize
7732         local new_scount
7733         local cur_comp
7734
7735         echo -n "Creating test dir..."
7736         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7737         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7738                 error "cannot set stripe by '-S 1M -c 1'"
7739         echo "done"
7740
7741         echo -n "Setting initial stripe for test file..."
7742         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7743                 error "cannot set stripe"
7744         cur_ssize=$($LFS getstripe -S "$file1")
7745         (( cur_ssize == 524288 )) || error "setstripe -S $cur_ssize != 524288"
7746         echo "done."
7747
7748         dd if=/dev/urandom of=$file1 bs=1M count=12 || error "dd $file1 failed"
7749         stack_trap "rm -f $file1"
7750         md5="$(md5sum $file1)"
7751
7752         # File currently set to -S 512K -c 1
7753
7754         # Ensure -c and -S options are rejected when -R is set
7755         echo -n "Verifying incompatible options are detected..."
7756         $LFS_MIGRATE -R -c 1 "$file1" &&
7757                 error "incompatible -R and -c options not detected"
7758         $LFS_MIGRATE -R -S 1M "$file1" &&
7759                 error "incompatible -R and -S options not detected"
7760         $LFS_MIGRATE -R -p pool "$file1" &&
7761                 error "incompatible -R and -p options not detected"
7762         $LFS_MIGRATE -R -E eof -c 1 "$file1" &&
7763                 error "incompatible -R and -E options not detected"
7764         $LFS_MIGRATE -R -A "$file1" &&
7765                 error "incompatible -R and -A options not detected"
7766         $LFS_MIGRATE -A -c 1 "$file1" &&
7767                 error "incompatible -A and -c options not detected"
7768         $LFS_MIGRATE -A -S 1M "$file1" &&
7769                 error "incompatible -A and -S options not detected"
7770         $LFS_MIGRATE -A -p pool "$file1" &&
7771                 error "incompatible -A and -p options not detected"
7772         $LFS_MIGRATE -A -E eof -c 1 "$file1" &&
7773                 error "incompatible -A and -E options not detected"
7774         echo "done."
7775
7776         # Ensure unrecognized options are passed through to 'lfs migrate'
7777         echo -n "Verifying -S option is passed through to lfs migrate..."
7778         $LFS_MIGRATE -y -S 1M "$file1" || error "migration failed"
7779         cur_ssize=$($LFS getstripe -S "$file1")
7780         (( cur_ssize == 1048576 )) || error "migrate -S $cur_ssize != 1048576"
7781         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (1)"
7782         echo "done."
7783
7784         # File currently set to -S 1M -c 1
7785
7786         # Ensure long options are supported
7787         echo -n "Verifying long options supported..."
7788         $LFS_MIGRATE --non-block "$file1" ||
7789                 error "long option without argument not supported"
7790         $LFS_MIGRATE --stripe-size 512K "$file1" ||
7791                 error "long option with argument not supported"
7792         cur_ssize=$($LFS getstripe -S "$file1")
7793         (( cur_ssize == 524288 )) ||
7794                 error "migrate --stripe-size $cur_ssize != 524288"
7795         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (2)"
7796         echo "done."
7797
7798         # File currently set to -S 512K -c 1
7799
7800         if (( OSTCOUNT > 1 )); then
7801                 echo -n "Verifying explicit stripe count can be set..."
7802                 $LFS_MIGRATE -c 2 "$file1" || error "migrate failed"
7803                 cur_scount=$($LFS getstripe -c "$file1")
7804                 (( cur_scount == 2 )) || error "migrate -c $cur_scount != 2"
7805                 [[ "$(md5sum $file1)" == "$md5" ]] ||
7806                         error "file data has changed (3)"
7807                 echo "done."
7808         fi
7809
7810         # File currently set to -S 512K -c 1 or -S 512K -c 2
7811
7812         # Ensure parent striping is used if -R is set, and no stripe
7813         # count or size is specified
7814         echo -n "Setting stripe for parent directory..."
7815         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7816                 error "cannot set stripe '-S 2M -c 1'"
7817         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (4)"
7818         echo "done."
7819
7820         echo -n "Verifying restripe option uses parent stripe settings..."
7821         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7822         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7823         $LFS_MIGRATE -R "$file1" || error "migrate failed"
7824         cur_ssize=$($LFS getstripe -S "$file1")
7825         (( cur_ssize == parent_ssize )) ||
7826                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7827         cur_scount=$($LFS getstripe -c "$file1")
7828         (( cur_scount == parent_scount )) ||
7829                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7830         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (5)"
7831         echo "done."
7832
7833         # File currently set to -S 1M -c 1
7834
7835         # Ensure striping is preserved if -R is not set, and no stripe
7836         # count or size is specified
7837         echo -n "Verifying striping size preserved when not specified..."
7838         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7839         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7840                 error "cannot set stripe on parent directory"
7841         $LFS_MIGRATE "$file1" || error "migrate failed"
7842         cur_ssize=$($LFS getstripe -S "$file1")
7843         (( cur_ssize == orig_ssize )) ||
7844                 error "migrate by default $cur_ssize != $orig_ssize"
7845         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (6)"
7846         echo "done."
7847
7848         # Ensure file name properly detected when final option has no argument
7849         echo -n "Verifying file name properly detected..."
7850         $LFS_MIGRATE "$file1" ||
7851                 error "file name interpreted as option argument"
7852         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (7)"
7853         echo "done."
7854
7855         # Ensure PFL arguments are passed through properly
7856         echo -n "Verifying PFL options passed through..."
7857         new_scount=$(((OSTCOUNT + 1) / 2))
7858         $LFS_MIGRATE -E 1M -c 1 -E 16M -c $new_scount -E eof -c -1 "$file1" ||
7859                 error "migrate PFL arguments failed"
7860         cur_comp=$($LFS getstripe --comp-count $file1)
7861         (( cur_comp == 3 )) || error "component count '$cur_comp' != 3"
7862         cur_scount=$($LFS getstripe --stripe-count $file1)
7863         (( cur_scount == new_scount)) ||
7864                 error "PFL stripe count $cur_scount != $new_scount"
7865         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (8)"
7866         echo "done."
7867 }
7868 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7869
7870 test_56wd() {
7871         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7872
7873         local file1=$DIR/$tdir/$tfile
7874
7875         echo -n "Creating test dir..."
7876         test_mkdir $DIR/$tdir || error "cannot create dir"
7877         echo "done."
7878
7879         echo -n "Creating test file..."
7880         echo "$tfile" > $file1
7881         echo "done."
7882
7883         # Ensure 'lfs migrate' will fail by using a non-existent option,
7884         # and make sure rsync is not called to recover
7885         echo -n "Make sure --no-rsync option works..."
7886         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7887                 grep -q 'refusing to fall back to rsync' ||
7888                 error "rsync was called with --no-rsync set"
7889         echo "done."
7890
7891         # Ensure rsync is called without trying 'lfs migrate' first
7892         echo -n "Make sure --rsync option works..."
7893         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7894                 grep -q 'falling back to rsync' &&
7895                 error "lfs migrate was called with --rsync set"
7896         echo "done."
7897 }
7898 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7899
7900 test_56we() {
7901         local td=$DIR/$tdir
7902         local tf=$td/$tfile
7903
7904         test_mkdir $td || error "cannot create $td"
7905         touch $tf || error "cannot touch $tf"
7906
7907         echo -n "Make sure --non-direct|-D works..."
7908         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7909                 grep -q "lfs migrate --non-direct" ||
7910                 error "--non-direct option cannot work correctly"
7911         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7912                 grep -q "lfs migrate -D" ||
7913                 error "-D option cannot work correctly"
7914         echo "done."
7915 }
7916 run_test 56we "check lfs_migrate --non-direct|-D support"
7917
7918 test_56x() {
7919         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7920         check_swap_layouts_support
7921
7922         local dir=$DIR/$tdir
7923         local ref1=/etc/passwd
7924         local file1=$dir/file1
7925
7926         test_mkdir $dir || error "creating dir $dir"
7927         $LFS setstripe -c 2 $file1
7928         cp $ref1 $file1
7929         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7930         stripe=$($LFS getstripe -c $file1)
7931         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7932         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7933
7934         # clean up
7935         rm -f $file1
7936 }
7937 run_test 56x "lfs migration support"
7938
7939 test_56xa() {
7940         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7941         check_swap_layouts_support
7942
7943         local dir=$DIR/$tdir/$testnum
7944
7945         test_mkdir -p $dir
7946
7947         local ref1=/etc/passwd
7948         local file1=$dir/file1
7949
7950         $LFS setstripe -c 2 $file1
7951         cp $ref1 $file1
7952         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7953
7954         local stripe=$($LFS getstripe -c $file1)
7955
7956         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7957         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7958
7959         # clean up
7960         rm -f $file1
7961 }
7962 run_test 56xa "lfs migration --block support"
7963
7964 check_migrate_links() {
7965         [[ "$1" == "--rsync" ]] && local opts="--rsync -y" && shift
7966         local dir="$1"
7967         local file1="$dir/file1"
7968         local begin="$2"
7969         local count="$3"
7970         local runas="$4"
7971         local total_count=$(($begin + $count - 1))
7972         local symlink_count=10
7973         local uniq_count=10
7974
7975         if [ ! -f "$file1" ]; then
7976                 echo -n "creating initial file..."
7977                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7978                         error "cannot setstripe initial file"
7979                 echo "done"
7980
7981                 echo -n "creating symlinks..."
7982                 for s in $(seq 1 $symlink_count); do
7983                         ln -s "$file1" "$dir/slink$s" ||
7984                                 error "cannot create symlinks"
7985                 done
7986                 echo "done"
7987
7988                 echo -n "creating nonlinked files..."
7989                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7990                         error "cannot create nonlinked files"
7991                 echo "done"
7992         fi
7993
7994         # create hard links
7995         if [ ! -f "$dir/file$total_count" ]; then
7996                 echo -n "creating hard links $begin:$total_count..."
7997                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7998                         /dev/null || error "cannot create hard links"
7999                 echo "done"
8000         fi
8001
8002         echo -n "checking number of hard links listed in xattrs..."
8003         local fid=$($LFS getstripe -F "$file1")
8004         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
8005
8006         echo "${#paths[*]}"
8007         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
8008                         skip "hard link list has unexpected size, skipping test"
8009         fi
8010         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
8011                         error "link names should exceed xattrs size"
8012         fi
8013
8014         echo -n "migrating files..."
8015         local migrate_out=$($runas $LFS_MIGRATE $opts -S '1m' $dir)
8016         local rc=$?
8017         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
8018         echo "done"
8019
8020         # make sure all links have been properly migrated
8021         echo -n "verifying files..."
8022         fid=$($LFS getstripe -F "$file1") ||
8023                 error "cannot get fid for file $file1"
8024         for i in $(seq 2 $total_count); do
8025                 local fid2=$($LFS getstripe -F $dir/file$i)
8026
8027                 [ "$fid2" == "$fid" ] ||
8028                         error "migrated hard link has mismatched FID"
8029         done
8030
8031         # make sure hard links were properly detected, and migration was
8032         # performed only once for the entire link set; nonlinked files should
8033         # also be migrated
8034         local actual=$(grep -c 'done' <<< "$migrate_out")
8035         local expected=$(($uniq_count + 1))
8036
8037         [ "$actual" -eq  "$expected" ] ||
8038                 error "hard links individually migrated ($actual != $expected)"
8039
8040         # make sure the correct number of hard links are present
8041         local hardlinks=$(stat -c '%h' "$file1")
8042
8043         [ $hardlinks -eq $total_count ] ||
8044                 error "num hard links $hardlinks != $total_count"
8045         echo "done"
8046
8047         return 0
8048 }
8049
8050 test_56xb() {
8051         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
8052                 skip "Need MDS version at least 2.10.55"
8053
8054         local dir="$DIR/$tdir"
8055
8056         test_mkdir "$dir" || error "cannot create dir $dir"
8057
8058         echo "testing lfs migrate mode when all links fit within xattrs"
8059         check_migrate_links "$dir" 2 99
8060
8061         echo "testing rsync mode when all links fit within xattrs"
8062         check_migrate_links --rsync "$dir" 2 99
8063
8064         echo "testing lfs migrate mode when all links do not fit within xattrs"
8065         check_migrate_links "$dir" 101 100
8066
8067         echo "testing rsync mode when all links do not fit within xattrs"
8068         check_migrate_links --rsync "$dir" 101 100
8069
8070         chown -R $RUNAS_ID $dir
8071         echo "testing non-root lfs migrate mode when not all links are in xattr"
8072         check_migrate_links "$dir" 101 100 "$RUNAS"
8073
8074         # clean up
8075         rm -rf $dir
8076 }
8077 run_test 56xb "lfs migration hard link support"
8078
8079 test_56xc() {
8080         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8081
8082         local dir="$DIR/$tdir"
8083
8084         test_mkdir "$dir" || error "cannot create dir $dir"
8085
8086         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
8087         echo -n "Setting initial stripe for 20MB test file..."
8088         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
8089                 error "cannot setstripe 20MB file"
8090         echo "done"
8091         echo -n "Sizing 20MB test file..."
8092         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
8093         echo "done"
8094         echo -n "Verifying small file autostripe count is 1..."
8095         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
8096                 error "cannot migrate 20MB file"
8097         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
8098                 error "cannot get stripe for $dir/20mb"
8099         [ $stripe_count -eq 1 ] ||
8100                 error "unexpected stripe count $stripe_count for 20MB file"
8101         rm -f "$dir/20mb"
8102         echo "done"
8103
8104         # Test 2: File is small enough to fit within the available space on
8105         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
8106         # have at least an additional 1KB for each desired stripe for test 3
8107         echo -n "Setting stripe for 1GB test file..."
8108         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
8109         echo "done"
8110         echo -n "Sizing 1GB test file..."
8111         # File size is 1GB + 3KB
8112         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
8113         echo "done"
8114
8115         # need at least 512MB per OST for 1GB file to fit in 2 stripes
8116         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
8117         if (( avail > 524288 * OSTCOUNT )); then
8118                 echo -n "Migrating 1GB file..."
8119                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
8120                         error "cannot migrate 1GB file"
8121                 echo "done"
8122                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
8123                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
8124                         error "cannot getstripe for 1GB file"
8125                 [ $stripe_count -eq 2 ] ||
8126                         error "unexpected stripe count $stripe_count != 2"
8127                 echo "done"
8128         fi
8129
8130         # Test 3: File is too large to fit within the available space on
8131         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
8132         if [ $OSTCOUNT -ge 3 ]; then
8133                 # The required available space is calculated as
8134                 # file size (1GB + 3KB) / OST count (3).
8135                 local kb_per_ost=349526
8136
8137                 echo -n "Migrating 1GB file with limit..."
8138                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
8139                         error "cannot migrate 1GB file with limit"
8140                 echo "done"
8141
8142                 stripe_count=$($LFS getstripe -c "$dir/1gb")
8143                 echo -n "Verifying 1GB autostripe count with limited space..."
8144                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
8145                         error "unexpected stripe count $stripe_count (min 3)"
8146                 echo "done"
8147         fi
8148
8149         # clean up
8150         rm -rf $dir
8151 }
8152 run_test 56xc "lfs migration autostripe"
8153
8154 test_56xd() {
8155         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8156
8157         local dir=$DIR/$tdir
8158         local f_mgrt=$dir/$tfile.mgrt
8159         local f_yaml=$dir/$tfile.yaml
8160         local f_copy=$dir/$tfile.copy
8161         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8162         local layout_copy="-c 2 -S 2M -i 1"
8163         local yamlfile=$dir/yamlfile
8164         local layout_before;
8165         local layout_after;
8166
8167         test_mkdir "$dir" || error "cannot create dir $dir"
8168         stack_trap "rm -rf $dir"
8169         $LFS setstripe $layout_yaml $f_yaml ||
8170                 error "cannot setstripe $f_yaml with layout $layout_yaml"
8171         $LFS getstripe --yaml $f_yaml > $yamlfile
8172         $LFS setstripe $layout_copy $f_copy ||
8173                 error "cannot setstripe $f_copy with layout $layout_copy"
8174         touch $f_mgrt
8175         dd if=/dev/zero of=$f_mgrt bs=1M count=4
8176
8177         # 1. test option --yaml
8178         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
8179                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
8180         layout_before=$(get_layout_param $f_yaml)
8181         layout_after=$(get_layout_param $f_mgrt)
8182         [ "$layout_after" == "$layout_before" ] ||
8183                 error "lfs_migrate --yaml: $layout_after != $layout_before"
8184
8185         # 2. test option --copy
8186         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
8187                 error "cannot migrate $f_mgrt with --copy $f_copy"
8188         layout_before=$(SKIP_INDEX=yes get_layout_param $f_copy)
8189         layout_after=$(SKIP_INDEX=yes get_layout_param $f_mgrt)
8190         [ "$layout_after" == "$layout_before" ] ||
8191                 error "lfs_migrate --copy: $layout_after != $layout_before"
8192 }
8193 run_test 56xd "check lfs_migrate --yaml and --copy support"
8194
8195 test_56xe() {
8196         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8197
8198         local dir=$DIR/$tdir
8199         local f_comp=$dir/$tfile
8200         local layout="-E 1M -S 512K -E 2M -c 2 -E 3M -c 2 -E eof -c $OSTCOUNT"
8201         local layout_before=""
8202         local layout_after=""
8203
8204         test_mkdir "$dir" || error "cannot create dir $dir"
8205         stack_trap "rm -rf $dir"
8206         $LFS setstripe $layout $f_comp ||
8207                 error "cannot setstripe $f_comp with layout $layout"
8208         layout_before=$(SKIP_INDEX=yes get_layout_param $f_comp)
8209         dd if=/dev/zero of=$f_comp bs=1M count=4
8210
8211         # 1. migrate a comp layout file by lfs_migrate
8212         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
8213         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8214         idx_before=$($LFS getstripe $f_comp | awk '$2 == "0:" { print $5 }' |
8215                      tr '\n' ' ')
8216         [ "$layout_before" == "$layout_after" ] ||
8217                 error "lfs_migrate: $layout_before != $layout_after"
8218
8219         # 2. migrate a comp layout file by lfs migrate
8220         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8221         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8222         idx_after=$($LFS getstripe $f_comp | awk '$2 == "0:" { print $5 }' |
8223                      tr '\n' ' ')
8224         [ "$layout_before" == "$layout_after" ] ||
8225                 error "lfs migrate: $layout_before != $layout_after"
8226
8227         # this may not fail every time with a broken lfs migrate, but will fail
8228         # often enough to notice, and will not have false positives very often
8229         [ "$idx_before" != "$idx_after" ] ||
8230                 error "lfs migrate: $idx_before == $idx_after"
8231 }
8232 run_test 56xe "migrate a composite layout file"
8233
8234 test_56xf() {
8235         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8236
8237         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
8238                 skip "Need server version at least 2.13.53"
8239
8240         local dir=$DIR/$tdir
8241         local f_comp=$dir/$tfile
8242         local layout="-E 1M -c1 -E -1 -c2"
8243         local fid_before=""
8244         local fid_after=""
8245
8246         test_mkdir "$dir" || error "cannot create dir $dir"
8247         stack_trap "rm -rf $dir"
8248         $LFS setstripe $layout $f_comp ||
8249                 error "cannot setstripe $f_comp with layout $layout"
8250         fid_before=$($LFS getstripe --fid $f_comp)
8251         dd if=/dev/zero of=$f_comp bs=1M count=4
8252
8253         # 1. migrate a comp layout file to a comp layout
8254         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8255         fid_after=$($LFS getstripe --fid $f_comp)
8256         [ "$fid_before" == "$fid_after" ] ||
8257                 error "comp-to-comp migrate: $fid_before != $fid_after"
8258
8259         # 2. migrate a comp layout file to a plain layout
8260         $LFS migrate -c2 $f_comp ||
8261                 error "cannot migrate $f_comp by lfs migrate"
8262         fid_after=$($LFS getstripe --fid $f_comp)
8263         [ "$fid_before" == "$fid_after" ] ||
8264                 error "comp-to-plain migrate: $fid_before != $fid_after"
8265
8266         # 3. migrate a plain layout file to a comp layout
8267         $LFS migrate $layout $f_comp ||
8268                 error "cannot migrate $f_comp by lfs migrate"
8269         fid_after=$($LFS getstripe --fid $f_comp)
8270         [ "$fid_before" == "$fid_after" ] ||
8271                 error "plain-to-comp migrate: $fid_before != $fid_after"
8272 }
8273 run_test 56xf "FID is not lost during migration of a composite layout file"
8274
8275 check_file_ost_range() {
8276         local file="$1"
8277         shift
8278         local range="$*"
8279         local -a file_range
8280         local idx
8281
8282         file_range=($($LFS getstripe -y "$file" |
8283                 awk '/l_ost_idx:/ { print $NF }'))
8284
8285         if [[ "${#file_range[@]}" = 0 ]]; then
8286                 echo "No osts found for $file"
8287                 return 1
8288         fi
8289
8290         for idx in "${file_range[@]}"; do
8291                 [[ " $range " =~ " $idx " ]] ||
8292                         return 1
8293         done
8294
8295         return 0
8296 }
8297
8298 sub_test_56xg() {
8299         local stripe_opt="$1"
8300         local pool="$2"
8301         shift 2
8302         local pool_ostidx="$(seq $* | tr '\n' ' ')"
8303
8304         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
8305                 error "Fail to migrate $tfile on $pool"
8306         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
8307                 error "$tfile is not in pool $pool"
8308         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
8309                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
8310 }
8311
8312 test_56xg() {
8313         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8314         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
8315         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
8316                 skip "Need MDS version newer than 2.14.52"
8317
8318         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
8319         local -a pool_ranges=("0 0" "1 1" "0 1")
8320
8321         # init pools
8322         for i in "${!pool_names[@]}"; do
8323                 pool_add ${pool_names[$i]} ||
8324                         error "pool_add failed (pool: ${pool_names[$i]})"
8325                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
8326                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
8327         done
8328
8329         # init the file to migrate
8330         $LFS setstripe -c1 -i1 $DIR/$tfile ||
8331                 error "Unable to create $tfile on OST1"
8332         stack_trap "rm -f $DIR/$tfile"
8333         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
8334                 error "Unable to write on $tfile"
8335
8336         echo "1. migrate $tfile on pool ${pool_names[0]}"
8337         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
8338
8339         echo "2. migrate $tfile on pool ${pool_names[2]}"
8340         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
8341
8342         echo "3. migrate $tfile on pool ${pool_names[1]}"
8343         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
8344
8345         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
8346         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
8347         echo
8348
8349         # Clean pools
8350         destroy_test_pools ||
8351                 error "pool_destroy failed"
8352 }
8353 run_test 56xg "lfs migrate pool support"
8354
8355 test_56xh() {
8356         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8357
8358         local size_mb=25
8359         local file1=$DIR/$tfile
8360         local tmp1=$TMP/$tfile.tmp
8361
8362         $LFS setstripe -c 2 $file1
8363
8364         stack_trap "rm -f $file1 $tmp1"
8365         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8366                         error "error creating $tmp1"
8367         ls -lsh $tmp1
8368         cp $tmp1 $file1
8369
8370         local start=$SECONDS
8371
8372         $LFS migrate --stats --stats-interval=1 -W 1M -c 1 $file1 ||
8373                 error "migrate failed rc = $?"
8374
8375         local elapsed=$((SECONDS - start))
8376
8377         # with 1MB/s, elapsed should equal size_mb
8378         (( elapsed >= size_mb * 95 / 100 )) ||
8379                 error "'lfs migrate -W' too fast ($elapsed < 0.95 * $size_mb)?"
8380
8381         (( elapsed <= size_mb * 120 / 100 )) ||
8382                 error_not_in_vm "'lfs migrate -W' slow ($elapsed > 1.2 * $size_mb)"
8383
8384         (( elapsed <= size_mb * 350 / 100 )) ||
8385                 error "'lfs migrate -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8386
8387         stripe=$($LFS getstripe -c $file1)
8388         (( $stripe == 1 )) || error "stripe of $file1 is $stripe != 1"
8389         cmp $file1 $tmp1 || error "content mismatch $file1 differs from $tmp1"
8390
8391         # Clean up file (since it is multiple MB)
8392         rm -f $file1 $tmp1
8393 }
8394 run_test 56xh "lfs migrate bandwidth limitation support"
8395
8396 test_56xi() {
8397         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8398         verify_yaml_available || skip_env "YAML verification not installed"
8399
8400         local size_mb=5
8401         local file1=$DIR/$tfile.1
8402         local file2=$DIR/$tfile.2
8403         local file3=$DIR/$tfile.3
8404         local output_file=$DIR/$tfile.out
8405         local tmp1=$TMP/$tfile.tmp
8406
8407         $LFS setstripe -c 2 $file1
8408         $LFS setstripe -c 2 $file2
8409         $LFS setstripe -c 2 $file3
8410
8411         stack_trap "rm -f $file1 $file2 $file3 $tmp1 $output_file"
8412         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8413                         error "error creating $tmp1"
8414         ls -lsh $tmp1
8415         cp $tmp1 $file1
8416         cp $tmp1 $file2
8417         cp $tmp1 $file3
8418
8419         $LFS migrate --stats --stats-interval=1 \
8420                 -c 1 $file1 $file2 $file3 1> $output_file ||
8421                 error "migrate failed rc = $?"
8422
8423         cat $output_file
8424         cat $output_file | verify_yaml || error "rename_stats is not valid YAML"
8425
8426         # Clean up file (since it is multiple MB)
8427         rm -f $file1 $file2 $file3 $tmp1 $output_file
8428 }
8429 run_test 56xi "lfs migrate stats support"
8430
8431 test_56xj() { # LU-16571 "lfs migrate -b" can cause thread starvation on OSS
8432         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8433
8434         local file=$DIR/$tfile
8435         local linkdir=$DIR/$tdir
8436
8437         test_mkdir $linkdir || error "fail to create $linkdir"
8438         $LFS setstripe -i 0 -c 1 -S1M $file
8439         stack_trap "rm -rf $file $linkdir"
8440         dd if=/dev/urandom of=$file bs=1M count=10 ||
8441                 error "fail to create $file"
8442
8443         # Create file links
8444         local cpts
8445         local threads_max
8446         local nlinks
8447
8448         thread_max=$(do_facet ost1 "$LCTL get_param -n ost.OSS.ost.threads_max")
8449         cpts=$(do_facet ost1 "$LCTL get_param -n cpu_partition_table | wc -l")
8450         (( nlinks = thread_max * 3 / 2 / cpts))
8451
8452         echo "create $nlinks hard links of $file"
8453         createmany -l $file $linkdir/link $nlinks
8454
8455         # Parallel migrates (should not block)
8456         local i
8457         for ((i = 0; i < nlinks; i++)); do
8458                 echo $linkdir/link$i
8459         done | xargs -n1 -P $nlinks $LFS migrate -c2
8460
8461         local stripe_count
8462         stripe_count=$($LFS getstripe -c $file) ||
8463                 error "fail to get stripe count on $file"
8464
8465         ((stripe_count == 2)) ||
8466                 error "fail to migrate $file (stripe_count = $stripe_count)"
8467 }
8468 run_test 56xj "lfs migrate -b should not cause starvation of threads on OSS"
8469
8470 test_56xk() {
8471         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8472
8473         local size_mb=5
8474         local file1=$DIR/$tfile
8475
8476         stack_trap "rm -f $file1"
8477         $LFS setstripe -c 1 $file1
8478         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8479                 error "error creating $file1"
8480         $LFS mirror extend -N $file1 || error "can't mirror"
8481         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8482                 error "can't dd"
8483         $LFS getstripe $file1 | grep stale ||
8484                 error "one component must be stale"
8485
8486         local start=$SECONDS
8487         $LFS mirror resync --stats --stats-interval=1 -W 1M $file1 ||
8488                 error "migrate failed rc = $?"
8489         local elapsed=$((SECONDS - start))
8490         $LFS getstripe $file1 | grep stale &&
8491                 error "all components must be sync"
8492
8493         # with 1MB/s, elapsed should equal size_mb
8494         (( elapsed >= size_mb * 95 / 100 )) ||
8495                 error "'lfs mirror resync -W' too fast ($elapsed < 0.95 * $size_mb)?"
8496
8497         (( elapsed <= size_mb * 120 / 100 )) ||
8498                 error_not_in_vm "'lfs mirror resync -W' slow ($elapsed > 1.2 * $size_mb)"
8499
8500         (( elapsed <= size_mb * 350 / 100 )) ||
8501                 error "'lfs mirror resync -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8502 }
8503 run_test 56xk "lfs mirror resync bandwidth limitation support"
8504
8505 test_56xl() {
8506         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8507         verify_yaml_available || skip_env "YAML verification not installed"
8508
8509         local size_mb=5
8510         local file1=$DIR/$tfile.1
8511         local output_file=$DIR/$tfile.out
8512
8513         stack_trap "rm -f $file1"
8514         $LFS setstripe -c 1 $file1
8515         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8516                 error "error creating $file1"
8517         $LFS mirror extend -N $file1 || error "can't mirror"
8518         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8519                 error "can't dd"
8520         $LFS getstripe $file1 | grep stale ||
8521                 error "one component must be stale"
8522         $LFS getstripe $file1
8523
8524         $LFS mirror resync --stats --stats-interval=1 $file1 >$output_file ||
8525                 error "resync failed rc = $?"
8526         $LFS getstripe $file1 | grep stale &&
8527                 error "all components must be sync"
8528
8529         cat $output_file
8530         cat $output_file | verify_yaml || error "stats is not valid YAML"
8531 }
8532 run_test 56xl "lfs mirror resync stats support"
8533
8534 test_56y() {
8535         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8536                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8537
8538         local res=""
8539         local dir=$DIR/$tdir
8540         local f1=$dir/file1
8541         local f2=$dir/file2
8542
8543         test_mkdir -p $dir || error "creating dir $dir"
8544         touch $f1 || error "creating std file $f1"
8545         $MULTIOP $f2 H2c || error "creating released file $f2"
8546
8547         # a directory can be raid0, so ask only for files
8548         res=$($LFS find $dir -L raid0 -type f | wc -l)
8549         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8550
8551         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8552         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8553
8554         # only files can be released, so no need to force file search
8555         res=$($LFS find $dir -L released)
8556         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8557
8558         res=$($LFS find $dir -type f \! -L released)
8559         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8560 }
8561 run_test 56y "lfs find -L raid0|released"
8562
8563 test_56z() { # LU-4824
8564         # This checks to make sure 'lfs find' continues after errors
8565         # There are two classes of errors that should be caught:
8566         # - If multiple paths are provided, all should be searched even if one
8567         #   errors out
8568         # - If errors are encountered during the search, it should not terminate
8569         #   early
8570         local dir=$DIR/$tdir
8571         local i
8572
8573         test_mkdir $dir
8574         for i in d{0..9}; do
8575                 test_mkdir $dir/$i
8576                 touch $dir/$i/$tfile
8577         done
8578         $LFS find $DIR/non_existent_dir $dir &&
8579                 error "$LFS find did not return an error"
8580         # Make a directory unsearchable. This should NOT be the last entry in
8581         # directory order.  Arbitrarily pick the 6th entry
8582         chmod 700 $($LFS find $dir -type d | sed '6!d')
8583
8584         $RUNAS $LFS find $DIR/non_existent $dir
8585         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8586
8587         # The user should be able to see 10 directories and 9 files
8588         (( count == 19 )) ||
8589                 error "$LFS find found $count != 19 entries after error"
8590 }
8591 run_test 56z "lfs find should continue after an error"
8592
8593 test_56aa() { # LU-5937
8594         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8595
8596         local dir=$DIR/$tdir
8597
8598         mkdir $dir
8599         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8600
8601         createmany -o $dir/striped_dir/${tfile}- 1024
8602         local dirs=$($LFS find --size +8k $dir/)
8603
8604         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8605 }
8606 run_test 56aa "lfs find --size under striped dir"
8607
8608 test_56ab() { # LU-10705
8609         test_mkdir $DIR/$tdir
8610         dd if=/dev/urandom of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8611         dd if=/dev/urandom of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8612         dd if=/dev/urandom of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8613         # Flush writes to ensure valid blocks.  Need to be more thorough for
8614         # ZFS, since blocks are not allocated/returned to client immediately.
8615         sync_all_data
8616         wait_zfs_commit ost1 2
8617         cancel_lru_locks osc
8618         ls -ls $DIR/$tdir
8619
8620         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8621
8622         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8623
8624         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8625         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8626
8627         rm -f $DIR/$tdir/$tfile.[123]
8628 }
8629 run_test 56ab "lfs find --blocks"
8630
8631 # LU-11188
8632 test_56aca() {
8633         local dir="$DIR/$tdir"
8634         local perms=(001 002 003 004 005 006 007
8635                      010 020 030 040 050 060 070
8636                      100 200 300 400 500 600 700
8637                      111 222 333 444 555 666 777)
8638         local perm_minus=(8 8 4 8 4 4 2
8639                           8 8 4 8 4 4 2
8640                           8 8 4 8 4 4 2
8641                           4 4 2 4 2 2 1)
8642         local perm_slash=(8  8 12  8 12 12 14
8643                           8  8 12  8 12 12 14
8644                           8  8 12  8 12 12 14
8645                          16 16 24 16 24 24 28)
8646
8647         test_mkdir "$dir"
8648         for perm in ${perms[*]}; do
8649                 touch "$dir/$tfile.$perm"
8650                 chmod $perm "$dir/$tfile.$perm"
8651         done
8652
8653         for ((i = 0; i < ${#perms[*]}; i++)); do
8654                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8655                 (( $num == 1 )) ||
8656                         error "lfs find -perm ${perms[i]}:"\
8657                               "$num != 1"
8658
8659                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8660                 (( $num == ${perm_minus[i]} )) ||
8661                         error "lfs find -perm -${perms[i]}:"\
8662                               "$num != ${perm_minus[i]}"
8663
8664                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8665                 (( $num == ${perm_slash[i]} )) ||
8666                         error "lfs find -perm /${perms[i]}:"\
8667                               "$num != ${perm_slash[i]}"
8668         done
8669 }
8670 run_test 56aca "check lfs find -perm with octal representation"
8671
8672 test_56acb() {
8673         local dir=$DIR/$tdir
8674         # p is the permission of write and execute for user, group and other
8675         # without the umask. It is used to test +wx.
8676         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8677         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8678         local symbolic=(+t  a+t u+t g+t o+t
8679                         g+s u+s o+s +s o+sr
8680                         o=r,ug+o,u+w
8681                         u+ g+ o+ a+ ugo+
8682                         u- g- o- a- ugo-
8683                         u= g= o= a= ugo=
8684                         o=r,ug+o,u+w u=r,a+u,u+w
8685                         g=r,ugo=g,u+w u+x,+X +X
8686                         u+x,u+X u+X u+x,g+X o+r,+X
8687                         u+x,go+X +wx +rwx)
8688
8689         test_mkdir $dir
8690         for perm in ${perms[*]}; do
8691                 touch "$dir/$tfile.$perm"
8692                 chmod $perm "$dir/$tfile.$perm"
8693         done
8694
8695         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8696                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8697
8698                 (( $num == 1 )) ||
8699                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8700         done
8701 }
8702 run_test 56acb "check lfs find -perm with symbolic representation"
8703
8704 test_56acc() {
8705         local dir=$DIR/$tdir
8706         local tests="17777 787 789 abcd
8707                 ug=uu ug=a ug=gu uo=ou urw
8708                 u+xg+x a=r,u+x,"
8709
8710         test_mkdir $dir
8711         for err in $tests; do
8712                 if $LFS find $dir -perm $err 2>/dev/null; then
8713                         error "lfs find -perm $err: parsing should have failed"
8714                 fi
8715         done
8716 }
8717 run_test 56acc "check parsing error for lfs find -perm"
8718
8719 test_56ba() {
8720         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8721                 skip "Need MDS version at least 2.10.50"
8722
8723         # Create composite files with one component
8724         local dir=$DIR/$tdir
8725
8726         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8727         # Create composite files with three components
8728         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8729         # LU-16904 Create plain layout files
8730         lfs setstripe -c 1 $dir/$tfile-{1..10}
8731
8732         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8733
8734         [[ $nfiles == 10 ]] ||
8735                 error "lfs find -E 1M found $nfiles != 10 files"
8736
8737         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8738         [[ $nfiles == 25 ]] ||
8739                 error "lfs find ! -E 1M found $nfiles != 25 files"
8740
8741         # All files have a component that starts at 0
8742         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8743         [[ $nfiles == 35 ]] ||
8744                 error "lfs find --component-start 0 - $nfiles != 35 files"
8745
8746         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8747         [[ $nfiles == 15 ]] ||
8748                 error "lfs find --component-start 2M - $nfiles != 15 files"
8749
8750         # All files created here have a componenet that does not starts at 2M
8751         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8752         [[ $nfiles == 35 ]] ||
8753                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8754
8755         # Find files with a specified number of components
8756         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8757         [[ $nfiles == 15 ]] ||
8758                 error "lfs find --component-count 3 - $nfiles != 15 files"
8759
8760         # Remember non-composite files have a component count of zero
8761         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8762         [[ $nfiles == 10 ]] ||
8763                 error "lfs find --component-count 0 - $nfiles != 10 files"
8764
8765         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8766         [[ $nfiles == 20 ]] ||
8767                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8768
8769         # All files have a flag called "init"
8770         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8771         [[ $nfiles == 35 ]] ||
8772                 error "lfs find --component-flags init - $nfiles != 35 files"
8773
8774         # Multi-component files will have a component not initialized
8775         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8776         [[ $nfiles == 15 ]] ||
8777                 error "lfs find !--component-flags init - $nfiles != 15 files"
8778
8779         rm -rf $dir
8780
8781 }
8782 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8783
8784 test_56ca() {
8785         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8786                 skip "Need MDS version at least 2.10.57"
8787
8788         local td=$DIR/$tdir
8789         local tf=$td/$tfile
8790         local dir
8791         local nfiles
8792         local cmd
8793         local i
8794         local j
8795
8796         # create mirrored directories and mirrored files
8797         mkdir $td || error "mkdir $td failed"
8798         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8799         createmany -o $tf- 10 || error "create $tf- failed"
8800
8801         for i in $(seq 2); do
8802                 dir=$td/dir$i
8803                 mkdir $dir || error "mkdir $dir failed"
8804                 $LFS mirror create -N$((3 + i)) $dir ||
8805                         error "create mirrored dir $dir failed"
8806                 createmany -o $dir/$tfile- 10 ||
8807                         error "create $dir/$tfile- failed"
8808         done
8809
8810         # change the states of some mirrored files
8811         echo foo > $tf-6
8812         for i in $(seq 2); do
8813                 dir=$td/dir$i
8814                 for j in $(seq 4 9); do
8815                         echo foo > $dir/$tfile-$j
8816                 done
8817         done
8818
8819         # find mirrored files with specific mirror count
8820         cmd="$LFS find --mirror-count 3 --type f $td"
8821         nfiles=$($cmd | wc -l)
8822         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8823
8824         cmd="$LFS find ! --mirror-count 3 --type f $td"
8825         nfiles=$($cmd | wc -l)
8826         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8827
8828         cmd="$LFS find --mirror-count +2 --type f $td"
8829         nfiles=$($cmd | wc -l)
8830         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8831
8832         cmd="$LFS find --mirror-count -6 --type f $td"
8833         nfiles=$($cmd | wc -l)
8834         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8835
8836         # find mirrored files with specific file state
8837         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8838         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8839
8840         cmd="$LFS find --mirror-state=ro --type f $td"
8841         nfiles=$($cmd | wc -l)
8842         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8843
8844         cmd="$LFS find ! --mirror-state=ro --type f $td"
8845         nfiles=$($cmd | wc -l)
8846         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8847
8848         cmd="$LFS find --mirror-state=wp --type f $td"
8849         nfiles=$($cmd | wc -l)
8850         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8851
8852         cmd="$LFS find ! --mirror-state=sp --type f $td"
8853         nfiles=$($cmd | wc -l)
8854         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8855 }
8856 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8857
8858 test_56da() { # LU-14179
8859         local path=$DIR/$tdir
8860
8861         test_mkdir $path
8862         cd $path
8863
8864         local longdir=$(str_repeat 'a' 255)
8865
8866         for i in {1..15}; do
8867                 path=$path/$longdir
8868                 test_mkdir $longdir
8869                 cd $longdir
8870         done
8871
8872         local len=${#path}
8873         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8874
8875         test_mkdir $lastdir
8876         cd $lastdir
8877         # PATH_MAX-1
8878         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8879
8880         # NAME_MAX
8881         touch $(str_repeat 'f' 255)
8882
8883         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8884                 error "lfs find reported an error"
8885
8886         rm -rf $DIR/$tdir
8887 }
8888 run_test 56da "test lfs find with long paths"
8889
8890 test_56ea() { #LU-10378
8891         local path=$DIR/$tdir
8892         local pool=$TESTNAME
8893
8894         # Create ost pool
8895         pool_add $pool || error "pool_add $pool failed"
8896         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8897                 error "adding targets to $pool failed"
8898
8899         # Set default pool on directory before creating file
8900         mkdir $path || error "mkdir $path failed"
8901         $LFS setstripe -p $pool $path ||
8902                 error "set OST pool on $pool failed"
8903         touch $path/$tfile || error "touch $path/$tfile failed"
8904
8905         # Compare basic file attributes from -printf and stat
8906         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G %n")
8907         local attr_stat=$(stat -c "%X %Y %Z %u %g %h" $path/$tfile)
8908
8909         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8910                 error "Attrs from lfs find and stat don't match"
8911
8912         # Compare Lustre attributes from lfs find and lfs getstripe
8913         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8914         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8915         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8916         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8917         local fpool=$($LFS getstripe --pool $path/$tfile)
8918         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8919
8920         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8921                 error "Attrs from lfs find and lfs getstripe don't match"
8922
8923         # Verify behavior for unknown escape/format sequences
8924         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8925
8926         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8927                 error "Escape/format codes don't match"
8928 }
8929 run_test 56ea "test lfs find -printf option"
8930
8931 test_56eb() {
8932         local dir=$DIR/$tdir
8933         local subdir_1=$dir/subdir_1
8934
8935         test_mkdir -p $subdir_1
8936         ln -s subdir_1 $dir/link_1
8937
8938         $LFS getstripe $dir | grep "^$dir/link_1$" -A1 ||
8939                 error "symlink is not followed"
8940
8941         $LFS getstripe --no-follow $dir |
8942                 grep "^$dir/link_1 has no stripe info$" ||
8943                 error "symlink should not have stripe info"
8944
8945         touch $dir/testfile
8946         ln -s testfile $dir/file_link_2
8947
8948         $LFS getstripe $dir | grep "^$dir/file_link_2$" -A1 ||
8949                 error "symlink is not followed"
8950
8951         $LFS getstripe --no-follow $dir |
8952                 grep "^$dir/file_link_2 has no stripe info$" ||
8953                 error "symlink should not have stripe info"
8954 }
8955 run_test 56eb "check lfs getstripe on symlink"
8956
8957 test_56ec() {
8958         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8959         local dir=$DIR/$tdir
8960         local srcfile=$dir/srcfile
8961         local srcyaml=$dir/srcyaml
8962         local destfile=$dir/destfile
8963
8964         test_mkdir -p $dir
8965
8966         $LFS setstripe -i 1 $srcfile
8967         $LFS getstripe --hex-idx --yaml $srcfile > $srcyaml
8968         # if the setstripe yaml parsing fails for any reason, the command can
8969         # randomly assign the correct OST index, leading to an erroneous
8970         # success. but the chance of false success is low enough that a
8971         # regression should still be quickly caught.
8972         $LFS setstripe --yaml=$srcyaml $destfile
8973
8974         local srcindex=$($LFS getstripe -i $srcfile)
8975         local destindex=$($LFS getstripe -i $destfile)
8976
8977         if [[ ! $srcindex -eq $destindex ]]; then
8978                 error "setstripe did not set OST index correctly"
8979         fi
8980 }
8981 run_test 56ec "check lfs getstripe,setstripe --hex --yaml"
8982
8983 test_56eda() {
8984         local dir=$DIR/$tdir
8985         local subdir=$dir/subdir
8986         local file1=$dir/$tfile
8987         local file2=$dir/$tfile\2
8988         local link=$dir/$tfile-link
8989         local nfiles
8990
8991         test_mkdir -p $dir
8992         $LFS setdirstripe -c1 $subdir
8993         touch $file1
8994         touch $file2
8995         ln $file2 $link
8996
8997         nfiles=$($LFS find --links 1 $dir | wc -l)
8998         (( $nfiles == 1 )) ||
8999                 error "lfs find --links expected 1 file, got $nfiles"
9000
9001         nfiles=$($LFS find --type f --links 2 $dir | wc -l)
9002         (( $nfiles == 2 )) ||
9003                 error "lfs find --links expected 2 files, got $nfiles"
9004
9005         nfiles=$($LFS find --type d --links 2 $dir | wc -l)
9006         (( $nfiles == 1 )) ||
9007                 error "lfs find --links expected 1 directory, got $nfiles"
9008 }
9009 run_test 56eda "check lfs find --links"
9010
9011 test_56edb() {
9012         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
9013
9014         local dir=$DIR/$tdir
9015         local stripedir=$dir/stripedir
9016         local nfiles
9017
9018         test_mkdir -p $dir
9019
9020         $LFS setdirstripe -c2 $stripedir
9021
9022         $LFS getdirstripe $stripedir
9023
9024         nfiles=$($LFS find --type d --links 2 $stripedir | wc -l)
9025         (( $nfiles == 1 )) ||
9026                 error "lfs find --links expected 1 directory, got $nfiles"
9027 }
9028 run_test 56edb "check lfs find --links for directory striped on multiple MDTs"
9029
9030 test_56ef() {
9031         local dir=$DIR/$tdir
9032         local dir1=$dir/d1
9033         local dir2=$dir/d2
9034         local nfiles
9035         local err_msg
9036
9037         test_mkdir -p $dir
9038
9039         mkdir $dir1
9040         mkdir $dir2
9041
9042         touch $dir1/f
9043         touch $dir2/f
9044
9045         nfiles=$($LFS find $dir1 $dir2 ! -type d | wc -l)
9046         (( $nfiles == 2 )) ||
9047                 error "(1) lfs find expected 2 files, got $nfiles"
9048
9049         nfiles=$($LFS find $dir1 $dir2 -type f | wc -l)
9050         (( $nfiles == 2 )) ||
9051                 error "(2) lfs find expected 2 files, got $nfiles"
9052
9053         nfiles=$($LFS find -type f $dir1 $dir2 | wc -l)
9054         (( $nfiles == 2 )) ||
9055                 error "(3) lfs find expected 2 files, got $nfiles"
9056
9057         err_msg=$($LFS find $dir1/typo $dir1/f 2>&1 > /dev/null)
9058         [[ $err_msg =~ "No such file or directory" ]] ||
9059                 error "expected standard error message, got: '$err_msg'"
9060 }
9061 run_test 56ef "lfs find with multiple paths"
9062
9063 test_56eg() {
9064         local dir=$DIR/$tdir
9065         local found
9066
9067         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9068
9069         test_mkdir -p $dir
9070
9071         touch $dir/$tfile
9072         ln -s $dir/$tfile $dir/$tfile.symlink
9073         setfattr -n "trusted.test" -v "test_target" $dir/$tfile
9074         setfattr --no-dereference -n "trusted.test" -v "test_link" \
9075                 $dir/$tfile.symlink
9076         setfattr --no-dereference -n "trusted.common" \
9077                 $dir/{$tfile,$tfile.symlink}
9078
9079         found=$($LFS find -xattr "trusted.*=test_target" \
9080                 -xattr "trusted.common" $dir)
9081         [[ "$found" == "$dir/$tfile" ]] || {
9082                 getfattr -d -m trusted.* $dir/$tfile
9083                 error "should have found '$tfile' with xattr 'trusted.test=test_target', got '$found'"
9084         }
9085
9086         found=$($LFS find -xattr "trusted.*=test_link" \
9087                 -xattr "trusted.common" $dir)
9088         [[ "$found" == "$dir/$tfile.symlink" ]] || {
9089                 getfattr --no-dereference -d -m trusted.* $dir/$tfile.symlink
9090                 error "should have found '$tfile.symlink' with xattr 'trusted.test=test_link', got '$found'"
9091         }
9092
9093         rm -f $dir/*
9094
9095         touch $dir/$tfile.1
9096         touch $dir/$tfile.2
9097         setfattr -n "user.test" -v "1" $dir/$tfile.1
9098         setfattr -n "user.test" -v "2" $dir/$tfile.2
9099         setfattr -n "user.test2" -v "common" $dir/$tfile.{1,2}
9100
9101         found=$($LFS find -xattr "user.*=common" -xattr "user.test=1" $dir)
9102         [[ "$found" == "$dir/$tfile.1" ]] || {
9103                 getfattr -d $dir/$tfile.1
9104                 error "should have found '$tfile.1' with xattr user.test=1', got '$found'"
9105         }
9106
9107         found=$($LFS find -xattr "user.*=common" ! -xattr "user.test=1" $dir)
9108         [[ "$found" == "$dir/$tfile.2" ]] || {
9109                 getfattr -d $dir/$tfile.2
9110                 error "should have found '$tfile.2' without xattr 'user.test=1', got '$found'"
9111         }
9112
9113         setfattr -n "user.empty" $dir/$tfile.1
9114         found=$($LFS find -xattr "user.empty" $dir)
9115         [[ "$found" == "$dir/$tfile.1" ]] || {
9116                 getfattr -d $dir/$tfile.1
9117                 error "should have found '$tfile.1' with xattr 'user.empty=', got '$found'"
9118         }
9119
9120         # setfattr command normally does not store terminating null byte
9121         # when writing a string as an xattr value.
9122         #
9123         # In order to test matching a value string that includes a terminating
9124         # null, explicitly encode the string "test\0" with the null terminator.
9125         setfattr -n "user.test" -v "0x7465737400" $dir/$tfile.1
9126         found=$($LFS find -xattr "user.test=test" $dir)
9127         [[ "$found" == "$dir/$tfile.1" ]] || {
9128                 getfattr -d --encoding=hex $dir/$tfile.1
9129                 error "should have found '$tfile.1' with xattr 'user.test=0x7465737400', got '$found'"
9130         }
9131 }
9132 run_test 56eg "lfs find -xattr"
9133
9134 test_57a() {
9135         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9136         # note test will not do anything if MDS is not local
9137         if [ "$mds1_FSTYPE" != ldiskfs ]; then
9138                 skip_env "ldiskfs only test"
9139         fi
9140         remote_mds_nodsh && skip "remote MDS with nodsh"
9141
9142         local MNTDEV="osd*.*MDT*.mntdev"
9143         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
9144         [ -z "$DEV" ] && error "can't access $MNTDEV"
9145         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
9146                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
9147                         error "can't access $DEV"
9148                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
9149                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
9150                 rm $TMP/t57a.dump
9151         done
9152 }
9153 run_test 57a "verify MDS filesystem created with large inodes =="
9154
9155 test_57b() {
9156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9157         if [ "$mds1_FSTYPE" != ldiskfs ]; then
9158                 skip_env "ldiskfs only test"
9159         fi
9160         remote_mds_nodsh && skip "remote MDS with nodsh"
9161
9162         local dir=$DIR/$tdir
9163         local filecount=100
9164         local file1=$dir/f1
9165         local fileN=$dir/f$filecount
9166
9167         rm -rf $dir || error "removing $dir"
9168         test_mkdir -c1 $dir
9169         local mdtidx=$($LFS getstripe -m $dir)
9170         local mdtname=MDT$(printf %04x $mdtidx)
9171         local facet=mds$((mdtidx + 1))
9172
9173         echo "mcreating $filecount files"
9174         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
9175
9176         # verify that files do not have EAs yet
9177         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
9178                 error "$file1 has an EA"
9179         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
9180                 error "$fileN has an EA"
9181
9182         sync
9183         sleep 1
9184         df $dir  #make sure we get new statfs data
9185         local mdsfree=$(do_facet $facet \
9186                         lctl get_param -n osd*.*$mdtname.kbytesfree)
9187         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
9188         local file
9189
9190         echo "opening files to create objects/EAs"
9191         for file in $(seq -f $dir/f%g 1 $filecount); do
9192                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
9193                         error "opening $file"
9194         done
9195
9196         # verify that files have EAs now
9197         $LFS getstripe -y $file1 | grep -q "l_ost_idx" ||
9198                 error "$file1 missing EA"
9199         $LFS getstripe -y $fileN | grep -q "l_ost_idx" ||
9200                 error "$fileN missing EA"
9201
9202         sleep 1  #make sure we get new statfs data
9203         df $dir
9204         local mdsfree2=$(do_facet $facet \
9205                          lctl get_param -n osd*.*$mdtname.kbytesfree)
9206         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
9207
9208         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
9209                 if [ "$mdsfree" != "$mdsfree2" ]; then
9210                         error "MDC before $mdcfree != after $mdcfree2"
9211                 else
9212                         echo "MDC before $mdcfree != after $mdcfree2"
9213                         echo "unable to confirm if MDS has large inodes"
9214                 fi
9215         fi
9216         rm -rf $dir
9217 }
9218 run_test 57b "default LOV EAs are stored inside large inodes ==="
9219
9220 test_58() {
9221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9222         [ -z "$(which wiretest 2>/dev/null)" ] &&
9223                         skip_env "could not find wiretest"
9224
9225         wiretest
9226 }
9227 run_test 58 "verify cross-platform wire constants =============="
9228
9229 test_59() {
9230         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9231
9232         echo "touch 130 files"
9233         createmany -o $DIR/f59- 130
9234         echo "rm 130 files"
9235         unlinkmany $DIR/f59- 130
9236         sync
9237         # wait for commitment of removal
9238         wait_delete_completed
9239 }
9240 run_test 59 "verify cancellation of llog records async ========="
9241
9242 TEST60_HEAD="test_60 run $RANDOM"
9243 test_60a() {
9244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9245         remote_mgs_nodsh && skip "remote MGS with nodsh"
9246         do_facet mgs "! which run-llog.sh &> /dev/null" &&
9247                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
9248                         skip_env "missing subtest run-llog.sh"
9249
9250         log "$TEST60_HEAD - from kernel mode"
9251         do_facet mgs "$LCTL dk > /dev/null"
9252         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
9253         do_facet mgs $LCTL dk > $TMP/$tfile
9254
9255         # LU-6388: test llog_reader
9256         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
9257         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
9258         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
9259                         skip_env "missing llog_reader"
9260         local fstype=$(facet_fstype mgs)
9261         [ $fstype != ldiskfs -a $fstype != zfs ] &&
9262                 skip_env "Only for ldiskfs or zfs type mgs"
9263
9264         local mntpt=$(facet_mntpt mgs)
9265         local mgsdev=$(mgsdevname 1)
9266         local fid_list
9267         local fid
9268         local rec_list
9269         local rec
9270         local rec_type
9271         local obj_file
9272         local path
9273         local seq
9274         local oid
9275         local pass=true
9276
9277         #get fid and record list
9278         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
9279                 tail -n 4))
9280         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
9281                 tail -n 4))
9282         #remount mgs as ldiskfs or zfs type
9283         stop mgs || error "stop mgs failed"
9284         mount_fstype mgs || error "remount mgs failed"
9285         for ((i = 0; i < ${#fid_list[@]}; i++)); do
9286                 fid=${fid_list[i]}
9287                 rec=${rec_list[i]}
9288                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
9289                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
9290                 oid=$((16#$oid))
9291
9292                 case $fstype in
9293                         ldiskfs )
9294                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
9295                         zfs )
9296                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
9297                 esac
9298                 echo "obj_file is $obj_file"
9299                 do_facet mgs $llog_reader $obj_file
9300
9301                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
9302                         awk '{ print $3 }' | sed -e "s/^type=//g")
9303                 if [ $rec_type != $rec ]; then
9304                         echo "FAILED test_60a wrong record type $rec_type," \
9305                               "should be $rec"
9306                         pass=false
9307                         break
9308                 fi
9309
9310                 #check obj path if record type is LLOG_LOGID_MAGIC
9311                 if [ "$rec" == "1064553b" ]; then
9312                         path=$(do_facet mgs $llog_reader $obj_file |
9313                                 grep "path=" | awk '{ print $NF }' |
9314                                 sed -e "s/^path=//g")
9315                         if [ $obj_file != $mntpt/$path ]; then
9316                                 echo "FAILED test_60a wrong obj path" \
9317                                       "$montpt/$path, should be $obj_file"
9318                                 pass=false
9319                                 break
9320                         fi
9321                 fi
9322         done
9323         rm -f $TMP/$tfile
9324         #restart mgs before "error", otherwise it will block the next test
9325         stop mgs || error "stop mgs failed"
9326         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
9327         $pass || error "test failed, see FAILED test_60a messages for specifics"
9328 }
9329 run_test 60a "llog_test run from kernel module and test llog_reader"
9330
9331 test_60b() { # bug 6411
9332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9333
9334         dmesg > $DIR/$tfile
9335         LLOG_COUNT=$(do_facet mgs dmesg |
9336                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
9337                           /llog_[a-z]*.c:[0-9]/ {
9338                                 if (marker)
9339                                         from_marker++
9340                                 from_begin++
9341                           }
9342                           END {
9343                                 if (marker)
9344                                         print from_marker
9345                                 else
9346                                         print from_begin
9347                           }")
9348
9349         [[ $LLOG_COUNT -gt 120 ]] &&
9350                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
9351 }
9352 run_test 60b "limit repeated messages from CERROR/CWARN"
9353
9354 test_60c() {
9355         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9356
9357         echo "create 5000 files"
9358         createmany -o $DIR/f60c- 5000
9359 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
9360         lctl set_param fail_loc=0x80000137
9361         unlinkmany $DIR/f60c- 5000
9362         lctl set_param fail_loc=0
9363 }
9364 run_test 60c "unlink file when mds full"
9365
9366 test_60d() {
9367         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9368
9369         SAVEPRINTK=$(lctl get_param -n printk)
9370         # verify "lctl mark" is even working"
9371         MESSAGE="test message ID $RANDOM $$"
9372         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9373         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
9374
9375         lctl set_param printk=0 || error "set lnet.printk failed"
9376         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
9377         MESSAGE="new test message ID $RANDOM $$"
9378         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
9379         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9380         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
9381
9382         lctl set_param -n printk="$SAVEPRINTK"
9383 }
9384 run_test 60d "test printk console message masking"
9385
9386 test_60e() {
9387         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9388         remote_mds_nodsh && skip "remote MDS with nodsh"
9389
9390         touch $DIR/$tfile
9391 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
9392         do_facet mds1 lctl set_param fail_loc=0x15b
9393         rm $DIR/$tfile
9394 }
9395 run_test 60e "no space while new llog is being created"
9396
9397 test_60f() {
9398         local old_path=$($LCTL get_param -n debug_path)
9399
9400         stack_trap "$LCTL set_param debug_path=$old_path"
9401         stack_trap "rm -f $TMP/$tfile*"
9402         rm -f $TMP/$tfile* 2> /dev/null
9403         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
9404         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
9405         test_mkdir $DIR/$tdir
9406         # retry in case the open is cached and not released
9407         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
9408                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
9409                 sleep 0.1
9410         done
9411         ls $TMP/$tfile*
9412         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
9413 }
9414 run_test 60f "change debug_path works"
9415
9416 test_60g() {
9417         local pid
9418         local i
9419
9420         test_mkdir -c $MDSCOUNT $DIR/$tdir
9421
9422         (
9423                 local index=0
9424                 while true; do
9425                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
9426                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
9427                                 2>/dev/null
9428                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
9429                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
9430                         index=$((index + 1))
9431                 done
9432         ) &
9433
9434         pid=$!
9435
9436         for i in {0..100}; do
9437                 # define OBD_FAIL_OSD_TXN_START    0x19a
9438                 local index=$((i % MDSCOUNT + 1))
9439
9440                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
9441                         > /dev/null
9442                 sleep 0.01
9443         done
9444
9445         kill -9 $pid
9446
9447         for i in $(seq $MDSCOUNT); do
9448                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
9449         done
9450
9451         mkdir $DIR/$tdir/new || error "mkdir failed"
9452         rmdir $DIR/$tdir/new || error "rmdir failed"
9453
9454         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
9455                 -t namespace
9456         for i in $(seq $MDSCOUNT); do
9457                 wait_update_facet mds$i "$LCTL get_param -n \
9458                         mdd.$(facet_svc mds$i).lfsck_namespace |
9459                         awk '/^status/ { print \\\$2 }'" "completed"
9460         done
9461
9462         ls -R $DIR/$tdir
9463         rm -rf $DIR/$tdir || error "rmdir failed"
9464 }
9465 run_test 60g "transaction abort won't cause MDT hung"
9466
9467 test_60h() {
9468         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
9469                 skip "Need MDS version at least 2.12.52"
9470         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
9471
9472         local f
9473
9474         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
9475         #define OBD_FAIL_MDS_STRIPE_FID          0x189
9476         for fail_loc in 0x80000188 0x80000189; do
9477                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
9478                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
9479                         error "mkdir $dir-$fail_loc failed"
9480                 for i in {0..10}; do
9481                         # create may fail on missing stripe
9482                         echo $i > $DIR/$tdir-$fail_loc/$i
9483                 done
9484                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9485                         error "getdirstripe $tdir-$fail_loc failed"
9486                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
9487                         error "migrate $tdir-$fail_loc failed"
9488                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9489                         error "getdirstripe $tdir-$fail_loc failed"
9490                 pushd $DIR/$tdir-$fail_loc
9491                 for f in *; do
9492                         echo $f | cmp $f - || error "$f data mismatch"
9493                 done
9494                 popd
9495                 rm -rf $DIR/$tdir-$fail_loc
9496         done
9497 }
9498 run_test 60h "striped directory with missing stripes can be accessed"
9499
9500 function t60i_load() {
9501         mkdir $DIR/$tdir
9502         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
9503         $LCTL set_param fail_loc=0x131c fail_val=1
9504         for ((i=0; i<5000; i++)); do
9505                 touch $DIR/$tdir/f$i
9506         done
9507 }
9508
9509 test_60i() {
9510         changelog_register || error "changelog_register failed"
9511         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
9512         changelog_users $SINGLEMDS | grep -q $cl_user ||
9513                 error "User $cl_user not found in changelog_users"
9514         changelog_chmask "ALL"
9515         t60i_load &
9516         local PID=$!
9517         for((i=0; i<100; i++)); do
9518                 changelog_dump >/dev/null ||
9519                         error "can't read changelog"
9520         done
9521         kill $PID
9522         wait $PID
9523         changelog_deregister || error "changelog_deregister failed"
9524         $LCTL set_param fail_loc=0
9525 }
9526 run_test 60i "llog: new record vs reader race"
9527
9528 test_60j() {
9529         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
9530                 skip "need MDS version at least 2.15.50"
9531         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9532         remote_mds_nodsh && skip "remote MDS with nodsh"
9533         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
9534
9535         changelog_users $SINGLEMDS | grep "^cl" &&
9536                 skip "active changelog user"
9537
9538         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
9539
9540         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
9541                 skip_env "missing llog_reader"
9542
9543         mkdir_on_mdt0 $DIR/$tdir
9544
9545         local f=$DIR/$tdir/$tfile
9546         local mdt_dev
9547         local tmpfile
9548         local plain
9549
9550         changelog_register || error "cannot register changelog user"
9551
9552         # set changelog_mask to ALL
9553         changelog_chmask "ALL"
9554         changelog_clear
9555
9556         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
9557         unlinkmany ${f}- 100 || error "unlinkmany failed"
9558
9559         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
9560         mdt_dev=$(facet_device $SINGLEMDS)
9561
9562         do_facet $SINGLEMDS sync
9563         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
9564                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
9565                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
9566
9567         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
9568
9569         # if $tmpfile is not on EXT3 filesystem for some reason
9570         [[ ${plain:0:1} == 'O' ]] ||
9571                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
9572
9573         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
9574                 $mdt_dev; stat -c %s $tmpfile")
9575         echo "Truncate llog from $size to $((size - size % 8192))"
9576         size=$((size - size % 8192))
9577         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
9578         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9579                 grep -c 'in bitmap only')
9580         (( $errs > 0 )) || error "llog_reader didn't find lost records"
9581
9582         size=$((size - 9000))
9583         echo "Corrupt llog in the middle at $size"
9584         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
9585                 count=333 conv=notrunc
9586         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9587                 grep -c 'next chunk')
9588         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
9589 }
9590 run_test 60j "llog_reader reports corruptions"
9591
9592 test_61a() {
9593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9594
9595         f="$DIR/f61"
9596         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
9597         cancel_lru_locks osc
9598         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
9599         sync
9600 }
9601 run_test 61a "mmap() writes don't make sync hang ================"
9602
9603 test_61b() {
9604         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
9605 }
9606 run_test 61b "mmap() of unstriped file is successful"
9607
9608 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
9609 # Though this test is irrelevant anymore, it helped to reveal some
9610 # other grant bugs (LU-4482), let's keep it.
9611 test_63a() {   # was test_63
9612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9613
9614         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
9615
9616         for i in `seq 10` ; do
9617                 dd if=/dev/zero of=$DIR/f63 bs=8k &
9618                 sleep 5
9619                 kill $!
9620                 sleep 1
9621         done
9622
9623         rm -f $DIR/f63 || true
9624 }
9625 run_test 63a "Verify oig_wait interruption does not crash ======="
9626
9627 # bug 2248 - async write errors didn't return to application on sync
9628 # bug 3677 - async write errors left page locked
9629 test_63b() {
9630         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9631
9632         debugsave
9633         lctl set_param debug=-1
9634
9635         # ensure we have a grant to do async writes
9636         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
9637         rm $DIR/$tfile
9638
9639         sync    # sync lest earlier test intercept the fail_loc
9640
9641         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9642         lctl set_param fail_loc=0x80000406
9643         $MULTIOP $DIR/$tfile Owy && \
9644                 error "sync didn't return ENOMEM"
9645         sync; sleep 2; sync     # do a real sync this time to flush page
9646         lctl get_param -n llite.*.dump_page_cache | grep locked && \
9647                 error "locked page left in cache after async error" || true
9648         debugrestore
9649 }
9650 run_test 63b "async write errors should be returned to fsync ==="
9651
9652 test_64a () {
9653         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9654
9655         lfs df $DIR
9656         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
9657 }
9658 run_test 64a "verify filter grant calculations (in kernel) ====="
9659
9660 test_64b () {
9661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9662
9663         bash oos.sh $MOUNT || error "oos.sh failed: $?"
9664 }
9665 run_test 64b "check out-of-space detection on client"
9666
9667 test_64c() {
9668         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
9669 }
9670 run_test 64c "verify grant shrink"
9671
9672 import_param() {
9673         local tgt=$1
9674         local param=$2
9675
9676         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
9677 }
9678
9679 # this does exactly what osc_request.c:osc_announce_cached() does in
9680 # order to calculate max amount of grants to ask from server
9681 want_grant() {
9682         local tgt=$1
9683
9684         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
9685         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
9686
9687         ((rpc_in_flight++));
9688         nrpages=$((nrpages * rpc_in_flight))
9689
9690         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
9691
9692         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
9693
9694         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
9695         local undirty=$((nrpages * PAGE_SIZE))
9696
9697         local max_extent_pages
9698         max_extent_pages=$(import_param $tgt grant_max_extent_size)
9699         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
9700         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
9701         local grant_extent_tax
9702         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9703
9704         undirty=$((undirty + nrextents * grant_extent_tax))
9705
9706         echo $undirty
9707 }
9708
9709 # this is size of unit for grant allocation. It should be equal to
9710 # what tgt_grant.c:tgt_grant_chunk() calculates
9711 grant_chunk() {
9712         local tgt=$1
9713         local max_brw_size
9714         local grant_extent_tax
9715
9716         max_brw_size=$(import_param $tgt max_brw_size)
9717
9718         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9719
9720         echo $(((max_brw_size + grant_extent_tax) * 2))
9721 }
9722
9723 test_64d() {
9724         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
9725                 skip "OST < 2.10.55 doesn't limit grants enough"
9726
9727         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9728
9729         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9730                 skip "no grant_param connect flag"
9731
9732         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9733
9734         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9735         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9736
9737
9738         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9739         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9740
9741         $LFS setstripe $DIR/$tfile -i 0 -c 1
9742         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9743         ddpid=$!
9744
9745         while kill -0 $ddpid; do
9746                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9747
9748                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9749                         kill $ddpid
9750                         error "cur_grant $cur_grant > $max_cur_granted"
9751                 fi
9752
9753                 sleep 1
9754         done
9755 }
9756 run_test 64d "check grant limit exceed"
9757
9758 check_grants() {
9759         local tgt=$1
9760         local expected=$2
9761         local msg=$3
9762         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9763
9764         ((cur_grants == expected)) ||
9765                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9766 }
9767
9768 round_up_p2() {
9769         echo $((($1 + $2 - 1) & ~($2 - 1)))
9770 }
9771
9772 test_64e() {
9773         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9774         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9775                 skip "Need OSS version at least 2.11.56"
9776
9777         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9778         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9779         $LCTL set_param debug=+cache
9780
9781         # Remount client to reset grant
9782         remount_client $MOUNT || error "failed to remount client"
9783         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9784
9785         local init_grants=$(import_param $osc_tgt initial_grant)
9786
9787         check_grants $osc_tgt $init_grants "init grants"
9788
9789         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9790         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9791         local gbs=$(import_param $osc_tgt grant_block_size)
9792
9793         # write random number of bytes from max_brw_size / 4 to max_brw_size
9794         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9795         # align for direct io
9796         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9797         # round to grant consumption unit
9798         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9799
9800         local grants=$((wb_round_up + extent_tax))
9801
9802         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9803         stack_trap "rm -f $DIR/$tfile"
9804
9805         # define OBD_FAIL_TGT_NO_GRANT 0x725
9806         # make the server not grant more back
9807         do_facet ost1 $LCTL set_param fail_loc=0x725
9808         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9809
9810         do_facet ost1 $LCTL set_param fail_loc=0
9811
9812         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9813
9814         rm -f $DIR/$tfile || error "rm failed"
9815
9816         # Remount client to reset grant
9817         remount_client $MOUNT || error "failed to remount client"
9818         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9819
9820         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9821
9822         # define OBD_FAIL_TGT_NO_GRANT 0x725
9823         # make the server not grant more back
9824         do_facet ost1 $LCTL set_param fail_loc=0x725
9825         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9826         do_facet ost1 $LCTL set_param fail_loc=0
9827
9828         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9829 }
9830 run_test 64e "check grant consumption (no grant allocation)"
9831
9832 test_64f() {
9833         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9834
9835         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9836         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9837         $LCTL set_param debug=+cache
9838
9839         # Remount client to reset grant
9840         remount_client $MOUNT || error "failed to remount client"
9841         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9842
9843         local init_grants=$(import_param $osc_tgt initial_grant)
9844         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9845         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9846         local gbs=$(import_param $osc_tgt grant_block_size)
9847         local chunk=$(grant_chunk $osc_tgt)
9848
9849         # write random number of bytes from max_brw_size / 4 to max_brw_size
9850         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9851         # align for direct io
9852         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9853         # round to grant consumption unit
9854         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9855
9856         local grants=$((wb_round_up + extent_tax))
9857
9858         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9859         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9860                 error "error writing to $DIR/$tfile"
9861
9862         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9863                 "direct io with grant allocation"
9864
9865         rm -f $DIR/$tfile || error "rm failed"
9866
9867         # Remount client to reset grant
9868         remount_client $MOUNT || error "failed to remount client"
9869         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9870
9871         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9872
9873         # Testing that buffered IO consumes grant on the client
9874
9875         # Delay the RPC on the server so it's guaranteed to not complete even
9876         # if the RPC is sent from the client
9877         #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
9878         $LCTL set_param fail_loc=0x50a fail_val=3
9879         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 conv=notrunc ||
9880                 error "error writing to $DIR/$tfile with buffered IO"
9881
9882         check_grants $osc_tgt $((init_grants - grants)) \
9883                 "buffered io, not write rpc"
9884
9885         # Clear the fail loc and do a sync on the client
9886         $LCTL set_param fail_loc=0 fail_val=0
9887         sync
9888
9889         # RPC is now known to have sent
9890         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9891                 "buffered io, one RPC"
9892 }
9893 run_test 64f "check grant consumption (with grant allocation)"
9894
9895 test_64g() {
9896         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9897                 skip "Need MDS version at least 2.14.56"
9898
9899         local mdts=$(comma_list $(mdts_nodes))
9900
9901         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9902                         tr '\n' ' ')
9903         stack_trap "$LCTL set_param $old"
9904
9905         # generate dirty pages and increase dirty granted on MDT
9906         stack_trap "rm -f $DIR/$tfile-*"
9907         for (( i = 0; i < 10; i++)); do
9908                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9909                         error "can't set stripe"
9910                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9911                         error "can't dd"
9912                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9913                         $LFS getstripe $DIR/$tfile-$i
9914                         error "not DoM file"
9915                 }
9916         done
9917
9918         # flush dirty pages
9919         sync
9920
9921         # wait until grant shrink reset grant dirty on MDTs
9922         for ((i = 0; i < 120; i++)); do
9923                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9924                         awk '{sum=sum+$1} END {print sum}')
9925                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9926                 echo "$grant_dirty grants, $vm_dirty pages"
9927                 (( grant_dirty + vm_dirty == 0 )) && break
9928                 (( i == 3 )) && sync &&
9929                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9930                 sleep 1
9931         done
9932
9933         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9934                 awk '{sum=sum+$1} END {print sum}')
9935         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9936 }
9937 run_test 64g "grant shrink on MDT"
9938
9939 test_64h() {
9940         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9941                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9942
9943         local instance=$($LFS getname -i $DIR)
9944         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9945         local num_exps=$(do_facet ost1 \
9946             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9947         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9948         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9949         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9950
9951         # 10MiB is for file to be written, max_brw_size * 16 *
9952         # num_exps is space reserve so that tgt_grant_shrink() decided
9953         # to not shrink
9954         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9955         (( avail * 1024 < expect )) &&
9956                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9957
9958         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9959         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9960         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9961         $LCTL set_param osc.*OST0000*.grant_shrink=1
9962         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9963
9964         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9965         stack_trap "rm -f $DIR/$tfile"
9966         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9967
9968         # drop cache so that coming read would do rpc
9969         cancel_lru_locks osc
9970
9971         # shrink interval is set to 10, pause for 7 seconds so that
9972         # grant thread did not wake up yet but coming read entered
9973         # shrink mode for rpc (osc_should_shrink_grant())
9974         sleep 7
9975
9976         declare -a cur_grant_bytes
9977         declare -a tot_granted
9978         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9979         tot_granted[0]=$(do_facet ost1 \
9980             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9981
9982         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9983
9984         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9985         tot_granted[1]=$(do_facet ost1 \
9986             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9987
9988         # grant change should be equal on both sides
9989         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9990                 tot_granted[0] - tot_granted[1])) ||
9991                 error "grant change mismatch, "                                \
9992                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9993                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9994 }
9995 run_test 64h "grant shrink on read"
9996
9997 test_64i() {
9998         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9999                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
10000
10001         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10002         remote_ost_nodsh && skip "remote OSTs with nodsh"
10003
10004         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10005         stack_trap "rm -f $DIR/$tfile"
10006
10007         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
10008
10009         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
10010         local instance=$($LFS getname -i $DIR)
10011
10012         local osc_tgt="$FSNAME-OST0000-osc-$instance"
10013         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
10014
10015         # shrink grants and simulate rpc loss
10016         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
10017         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
10018         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
10019
10020         fail ost1
10021
10022         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
10023
10024         local testid=$(echo $TESTNAME | tr '_' ' ')
10025
10026         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
10027                 grep "GRANT, real grant" &&
10028                 error "client has more grants then it owns" || true
10029 }
10030 run_test 64i "shrink on reconnect"
10031
10032 # bug 1414 - set/get directories' stripe info
10033 test_65a() {
10034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10035
10036         # LU-16904 check if the root is set as PFL layout
10037         local numcomp=$($LFS getstripe --component-count $MOUNT)
10038         [ $numcomp -eq 0 ] || skip "Skip test_65a for PFL layout"
10039
10040         test_mkdir $DIR/$tdir
10041         touch $DIR/$tdir/f1
10042         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
10043 }
10044 run_test 65a "directory with no stripe info"
10045
10046 test_65b() {
10047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10048
10049         test_mkdir $DIR/$tdir
10050         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10051
10052         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
10053                                                 error "setstripe"
10054         touch $DIR/$tdir/f2
10055         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
10056 }
10057 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
10058
10059 test_65c() {
10060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10061         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
10062
10063         test_mkdir $DIR/$tdir
10064         local stripesize=$($LFS getstripe -S $DIR/$tdir)
10065
10066         $LFS setstripe -S $((stripesize * 4)) -i 1 \
10067                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
10068         touch $DIR/$tdir/f3
10069         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
10070 }
10071 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
10072
10073 test_65d() {
10074         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10075
10076         test_mkdir $DIR/$tdir
10077         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
10078         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10079
10080         if [[ $STRIPECOUNT -le 0 ]]; then
10081                 sc=1
10082         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
10083                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
10084                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
10085         else
10086                 sc=$(($STRIPECOUNT - 1))
10087         fi
10088         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
10089         touch $DIR/$tdir/f4 $DIR/$tdir/f5
10090         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
10091                 error "lverify failed"
10092 }
10093 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
10094
10095 test_65e() {
10096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10097
10098         # LU-16904 delete layout when root is set as PFL layout
10099         save_layout_restore_at_exit $MOUNT
10100         $LFS setstripe -d $MOUNT || error "setstripe failed"
10101
10102         test_mkdir $DIR/$tdir
10103
10104         $LFS setstripe $DIR/$tdir || error "setstripe"
10105         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
10106                                         error "no stripe info failed"
10107         touch $DIR/$tdir/f6
10108         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
10109 }
10110 run_test 65e "directory setstripe defaults"
10111
10112 test_65f() {
10113         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10114
10115         test_mkdir $DIR/${tdir}f
10116         $RUNAS $LFS setstripe $DIR/${tdir}f &&
10117                 error "setstripe succeeded" || true
10118 }
10119 run_test 65f "dir setstripe permission (should return error) ==="
10120
10121 test_65g() {
10122         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10123
10124         # LU-16904 delete layout when root is set as PFL layout
10125         save_layout_restore_at_exit $MOUNT
10126         $LFS setstripe -d $MOUNT || error "setstripe failed"
10127
10128         test_mkdir $DIR/$tdir
10129         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10130
10131         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
10132                 error "setstripe -S failed"
10133         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
10134         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
10135                 error "delete default stripe failed"
10136 }
10137 run_test 65g "directory setstripe -d"
10138
10139 test_65h() {
10140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10141
10142         test_mkdir $DIR/$tdir
10143         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10144
10145         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
10146                 error "setstripe -S failed"
10147         test_mkdir $DIR/$tdir/dd1
10148         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
10149                 error "stripe info inherit failed"
10150 }
10151 run_test 65h "directory stripe info inherit ===================="
10152
10153 test_65i() {
10154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10155
10156         save_layout_restore_at_exit $MOUNT
10157
10158         # bug6367: set non-default striping on root directory
10159         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
10160
10161         # bug12836: getstripe on -1 default directory striping
10162         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
10163
10164         # bug12836: getstripe -v on -1 default directory striping
10165         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
10166
10167         # bug12836: new find on -1 default directory striping
10168         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
10169 }
10170 run_test 65i "various tests to set root directory striping"
10171
10172 test_65j() { # bug6367
10173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10174
10175         sync; sleep 1
10176
10177         # if we aren't already remounting for each test, do so for this test
10178         if [ "$I_MOUNTED" = "yes" ]; then
10179                 cleanup || error "failed to unmount"
10180                 setup
10181         fi
10182
10183         save_layout_restore_at_exit $MOUNT
10184
10185         $LFS setstripe -d $MOUNT || error "setstripe failed"
10186 }
10187 run_test 65j "set default striping on root directory (bug 6367)="
10188
10189 cleanup_65k() {
10190         rm -rf $DIR/$tdir
10191         wait_delete_completed
10192         do_facet $SINGLEMDS "lctl set_param -n \
10193                 osp.$ost*MDT0000.max_create_count=$max_count"
10194         do_facet $SINGLEMDS "lctl set_param -n \
10195                 osp.$ost*MDT0000.create_count=$count"
10196         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10197         echo $INACTIVE_OSC "is Activate"
10198
10199         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10200 }
10201
10202 test_65k() { # bug11679
10203         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10204         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10205         remote_mds_nodsh && skip "remote MDS with nodsh"
10206
10207         local disable_precreate=true
10208         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
10209                 disable_precreate=false
10210
10211         echo "Check OST status: "
10212         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
10213                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
10214
10215         for OSC in $MDS_OSCS; do
10216                 echo $OSC "is active"
10217                 do_facet $SINGLEMDS lctl --device %$OSC activate
10218         done
10219
10220         for INACTIVE_OSC in $MDS_OSCS; do
10221                 local ost=$(osc_to_ost $INACTIVE_OSC)
10222                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
10223                                lov.*md*.target_obd |
10224                                awk -F: /$ost/'{ print $1 }' | head -n 1)
10225
10226                 mkdir -p $DIR/$tdir
10227                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
10228                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
10229
10230                 echo "Deactivate: " $INACTIVE_OSC
10231                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
10232
10233                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
10234                               osp.$ost*MDT0000.create_count")
10235                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
10236                                   osp.$ost*MDT0000.max_create_count")
10237                 $disable_precreate &&
10238                         do_facet $SINGLEMDS "lctl set_param -n \
10239                                 osp.$ost*MDT0000.max_create_count=0"
10240
10241                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
10242                         [ -f $DIR/$tdir/$idx ] && continue
10243                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
10244                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
10245                                 { cleanup_65k;
10246                                   error "setstripe $idx should succeed"; }
10247                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
10248                 done
10249                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
10250                 rmdir $DIR/$tdir
10251
10252                 do_facet $SINGLEMDS "lctl set_param -n \
10253                         osp.$ost*MDT0000.max_create_count=$max_count"
10254                 do_facet $SINGLEMDS "lctl set_param -n \
10255                         osp.$ost*MDT0000.create_count=$count"
10256                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10257                 echo $INACTIVE_OSC "is Activate"
10258
10259                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10260         done
10261 }
10262 run_test 65k "validate manual striping works properly with deactivated OSCs"
10263
10264 test_65l() { # bug 12836
10265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10266
10267         test_mkdir -p $DIR/$tdir/test_dir
10268         $LFS setstripe -c -1 $DIR/$tdir/test_dir
10269         $LFS find -mtime -1 $DIR/$tdir >/dev/null
10270 }
10271 run_test 65l "lfs find on -1 stripe dir ========================"
10272
10273 test_65m() {
10274         local layout=$(save_layout $MOUNT)
10275         $RUNAS $LFS setstripe -c 2 $MOUNT && {
10276                 restore_layout $MOUNT $layout
10277                 error "setstripe should fail by non-root users"
10278         }
10279         true
10280 }
10281 run_test 65m "normal user can't set filesystem default stripe"
10282
10283 test_65n() {
10284         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
10285         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
10286                 skip "Need MDS version at least 2.12.50"
10287         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
10288
10289         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
10290         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
10291         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
10292
10293         save_layout_restore_at_exit $MOUNT
10294
10295         # new subdirectory under root directory should not inherit
10296         # the default layout from root
10297         # LU-16904 check if the root is set as PFL layout
10298         local numcomp=$($LFS getstripe --component-count $MOUNT)
10299
10300         if [[ $numcomp -eq 0 ]]; then
10301                 local dir1=$MOUNT/$tdir-1
10302                 mkdir $dir1 || error "mkdir $dir1 failed"
10303                 ! getfattr -n trusted.lov $dir1 &> /dev/null ||
10304                         error "$dir1 shouldn't have LOV EA"
10305         fi
10306
10307         # delete the default layout on root directory
10308         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
10309
10310         local dir2=$MOUNT/$tdir-2
10311         mkdir $dir2 || error "mkdir $dir2 failed"
10312         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
10313                 error "$dir2 shouldn't have LOV EA"
10314
10315         # set a new striping pattern on root directory
10316         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10317         local new_def_stripe_size=$((def_stripe_size * 2))
10318         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
10319                 error "set stripe size on $MOUNT failed"
10320
10321         # new file created in $dir2 should inherit the new stripe size from
10322         # the filesystem default
10323         local file2=$dir2/$tfile-2
10324         touch $file2 || error "touch $file2 failed"
10325
10326         local file2_stripe_size=$($LFS getstripe -S $file2)
10327         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
10328         {
10329                 echo "file2_stripe_size: '$file2_stripe_size'"
10330                 echo "new_def_stripe_size: '$new_def_stripe_size'"
10331                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
10332         }
10333
10334         local dir3=$MOUNT/$tdir-3
10335         mkdir $dir3 || error "mkdir $dir3 failed"
10336         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
10337         # the root layout, which is the actual default layout that will be used
10338         # when new files are created in $dir3.
10339         local dir3_layout=$(get_layout_param $dir3)
10340         local root_dir_layout=$(get_layout_param $MOUNT)
10341         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
10342         {
10343                 echo "dir3_layout: '$dir3_layout'"
10344                 echo "root_dir_layout: '$root_dir_layout'"
10345                 error "$dir3 should show the default layout from $MOUNT"
10346         }
10347
10348         # set OST pool on root directory
10349         local pool=$TESTNAME
10350         pool_add $pool || error "add $pool failed"
10351         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10352                 error "add targets to $pool failed"
10353
10354         $LFS setstripe -p $pool $MOUNT ||
10355                 error "set OST pool on $MOUNT failed"
10356
10357         # new file created in $dir3 should inherit the pool from
10358         # the filesystem default
10359         local file3=$dir3/$tfile-3
10360         touch $file3 || error "touch $file3 failed"
10361
10362         local file3_pool=$($LFS getstripe -p $file3)
10363         [[ "$file3_pool" = "$pool" ]] ||
10364                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
10365
10366         local dir4=$MOUNT/$tdir-4
10367         mkdir $dir4 || error "mkdir $dir4 failed"
10368         local dir4_layout=$(get_layout_param $dir4)
10369         root_dir_layout=$(get_layout_param $MOUNT)
10370         echo "$LFS getstripe -d $dir4"
10371         $LFS getstripe -d $dir4
10372         echo "$LFS getstripe -d $MOUNT"
10373         $LFS getstripe -d $MOUNT
10374         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
10375         {
10376                 echo "dir4_layout: '$dir4_layout'"
10377                 echo "root_dir_layout: '$root_dir_layout'"
10378                 error "$dir4 should show the default layout from $MOUNT"
10379         }
10380
10381         # new file created in $dir4 should inherit the pool from
10382         # the filesystem default
10383         local file4=$dir4/$tfile-4
10384         touch $file4 || error "touch $file4 failed"
10385
10386         local file4_pool=$($LFS getstripe -p $file4)
10387         [[ "$file4_pool" = "$pool" ]] ||
10388                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
10389
10390         # new subdirectory under non-root directory should inherit
10391         # the default layout from its parent directory
10392         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
10393                 error "set directory layout on $dir4 failed"
10394
10395         local dir5=$dir4/$tdir-5
10396         mkdir $dir5 || error "mkdir $dir5 failed"
10397
10398         dir4_layout=$(get_layout_param $dir4)
10399         local dir5_layout=$(get_layout_param $dir5)
10400         [[ "$dir4_layout" = "$dir5_layout" ]] ||
10401         {
10402                 echo "dir4_layout: '$dir4_layout'"
10403                 echo "dir5_layout: '$dir5_layout'"
10404                 error "$dir5 should inherit the default layout from $dir4"
10405         }
10406
10407         # though subdir under ROOT doesn't inherit default layout, but
10408         # its sub dir/file should be created with default layout.
10409         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
10410         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
10411                 skip "Need MDS version at least 2.12.59"
10412
10413         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
10414         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
10415         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
10416
10417         if [ $default_lmv_hash == "none" ]; then
10418                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
10419         else
10420                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
10421                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
10422         fi
10423
10424         $LFS setdirstripe -D -c 2 $MOUNT ||
10425                 error "setdirstripe -D -c 2 failed"
10426         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
10427         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
10428         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
10429
10430         # $dir4 layout includes pool
10431         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
10432         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10433                 error "pool lost on setstripe"
10434         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
10435         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10436                 error "pool lost on compound layout setstripe"
10437 }
10438 run_test 65n "don't inherit default layout from root for new subdirectories"
10439
10440 test_65o() {
10441         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
10442                 skip "need MDS version at least 2.14.57"
10443
10444         # set OST pool on root directory
10445         local pool=$TESTNAME
10446
10447         pool_add $pool || error "add $pool failed"
10448         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10449                 error "add targets to $pool failed"
10450
10451         local dir1=$MOUNT/$tdir
10452
10453         mkdir $dir1 || error "mkdir $dir1 failed"
10454
10455         # set a new striping pattern on root directory
10456         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10457
10458         $LFS setstripe -p $pool $dir1 ||
10459                 error "set directory layout on $dir1 failed"
10460
10461         # $dir1 layout includes pool
10462         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
10463         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10464                 error "pool lost on setstripe"
10465         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
10466         $LFS getstripe $dir1
10467         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10468                 error "pool lost on compound layout setstripe"
10469
10470         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
10471                 error "setdirstripe failed on sub-dir with inherited pool"
10472         $LFS getstripe $dir1/dir2
10473         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
10474                 error "pool lost on compound layout setdirstripe"
10475
10476         $LFS setstripe -E -1 -c 1 $dir1
10477         $LFS getstripe -d $dir1
10478         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10479                 error "pool lost on setstripe"
10480 }
10481 run_test 65o "pool inheritance for mdt component"
10482
10483 test_65p () { # LU-16152
10484         local src_dir=$DIR/$tdir/src_dir
10485         local dst_dir=$DIR/$tdir/dst_dir
10486         local yaml_file=$DIR/$tdir/layout.yaml
10487         local border
10488
10489         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10490                 skip "Need at least version 2.15.51"
10491
10492         test_mkdir -p $src_dir
10493         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
10494                 error "failed to setstripe"
10495         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
10496                 error "failed to getstripe"
10497
10498         test_mkdir -p $dst_dir
10499         $LFS setstripe --yaml $yaml_file $dst_dir ||
10500                 error "failed to setstripe with yaml file"
10501         border=$($LFS getstripe -d $dst_dir |
10502                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
10503                 error "failed to getstripe"
10504
10505         # 2048M is 0x80000000, or 2147483648
10506         (( $border == 2147483648 )) ||
10507                 error "failed to handle huge number in yaml layout"
10508 }
10509 run_test 65p "setstripe with yaml file and huge number"
10510
10511 test_65q () { # LU-16194
10512         local src_dir=$DIR/$tdir/src_dir
10513
10514         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) &&
10515         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
10516                 skip "Need at least version 2.15.51"
10517
10518         test_mkdir -p $src_dir
10519         # 8E is 0x8000 0000 0000 0000, which is negative as s64
10520         $LFS setstripe -E 8E -c 4 -E EOF -c 8 $src_dir &&
10521                 error "should fail if extent start/end >=8E"
10522
10523         # EOF should work as before
10524         $LFS setstripe -E 8M -c 4 -E EOF -c 8 $src_dir ||
10525                 error "failed to setstripe normally"
10526 }
10527 run_test 65q "setstripe with >=8E offset should fail"
10528
10529 # bug 2543 - update blocks count on client
10530 test_66() {
10531         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10532
10533         local COUNT=${COUNT:-8}
10534         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
10535         sync; sync_all_data; sync; sync_all_data
10536         cancel_lru_locks osc
10537         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
10538         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
10539 }
10540 run_test 66 "update inode blocks count on client ==============="
10541
10542 meminfo() {
10543         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
10544 }
10545
10546 swap_used() {
10547         swapon -s | awk '($1 == "'$1'") { print $4 }'
10548 }
10549
10550 # bug5265, obdfilter oa2dentry return -ENOENT
10551 # #define OBD_FAIL_SRV_ENOENT 0x217
10552 test_69() {
10553         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10554         remote_ost_nodsh && skip "remote OST with nodsh"
10555
10556         f="$DIR/$tfile"
10557         $LFS setstripe -c 1 -i 0 $f
10558         stack_trap "rm -f $f ${f}.2"
10559
10560         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
10561
10562         do_facet ost1 lctl set_param fail_loc=0x217
10563         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
10564         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
10565
10566         do_facet ost1 lctl set_param fail_loc=0
10567         $DIRECTIO write $f 0 2 || error "write error"
10568
10569         cancel_lru_locks osc
10570         $DIRECTIO read $f 0 1 || error "read error"
10571
10572         do_facet ost1 lctl set_param fail_loc=0x217
10573         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
10574
10575         do_facet ost1 lctl set_param fail_loc=0
10576 }
10577 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
10578
10579 test_70a() {
10580         # Perform a really simple test of health write and health check
10581         (( $OST1_VERSION >= $(version_code 2.15.59) )) ||
10582                 skip "OSTs < 2.15.59 doesn't have enable_health_write"
10583
10584         local orig_value="$(do_facet ost1 $LCTL get_param -n enable_health_write)"
10585
10586         stack_trap "do_facet ost1 $LCTL set_param enable_health_write $orig_value"
10587
10588         # Test with health write off
10589         do_facet ost1 $LCTL set_param enable_health_write off ||
10590                 error "can't set enable_health_write off"
10591         do_facet ost1 $LCTL get_param enable_health_write ||
10592                 error "can't get enable_health_write"
10593
10594         [[ "$(do_facet ost1 $LCTL get_param health_check)" =~ "healthy" ]] ||
10595                 error "not healthy (1)"
10596
10597         # Test with health write on
10598         do_facet ost1 $LCTL set_param enable_health_write on ||
10599                 error "can't set enable_health_write on"
10600         do_facet ost1 $LCTL get_param enable_health_write ||
10601                 error "can't get enable_health_write"
10602
10603         [[ "$(do_facet ost1 $LCTL get_param health_check)" =~ "healthy" ]] ||
10604                 error "not healthy (2)"
10605 }
10606 run_test 70a "verify health_check, health_write don't explode (on OST)"
10607
10608 test_71() {
10609         test_mkdir $DIR/$tdir
10610         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
10611         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
10612 }
10613 run_test 71 "Running dbench on lustre (don't segment fault) ===="
10614
10615 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
10616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10617         [ "$RUNAS_ID" = "$UID" ] &&
10618                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10619         # Check that testing environment is properly set up. Skip if not
10620         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
10621                 skip_env "User $RUNAS_ID does not exist - skipping"
10622
10623         touch $DIR/$tfile
10624         chmod 777 $DIR/$tfile
10625         chmod ug+s $DIR/$tfile
10626         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
10627                 error "$RUNAS dd $DIR/$tfile failed"
10628         # See if we are still setuid/sgid
10629         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10630                 error "S/gid is not dropped on write"
10631         # Now test that MDS is updated too
10632         cancel_lru_locks mdc
10633         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10634                 error "S/gid is not dropped on MDS"
10635         rm -f $DIR/$tfile
10636 }
10637 run_test 72a "Test that remove suid works properly (bug5695) ===="
10638
10639 test_72b() { # bug 24226 -- keep mode setting when size is not changing
10640         local perm
10641
10642         [ "$RUNAS_ID" = "$UID" ] &&
10643                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10644         [ "$RUNAS_ID" -eq 0 ] &&
10645                 skip_env "RUNAS_ID = 0 -- skipping"
10646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10647         # Check that testing environment is properly set up. Skip if not
10648         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
10649                 skip_env "User $RUNAS_ID does not exist - skipping"
10650
10651         touch $DIR/${tfile}-f{g,u}
10652         test_mkdir $DIR/${tfile}-dg
10653         test_mkdir $DIR/${tfile}-du
10654         chmod 770 $DIR/${tfile}-{f,d}{g,u}
10655         chmod g+s $DIR/${tfile}-{f,d}g
10656         chmod u+s $DIR/${tfile}-{f,d}u
10657         for perm in 777 2777 4777; do
10658                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
10659                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
10660                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
10661                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
10662         done
10663         true
10664 }
10665 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
10666
10667 # bug 3462 - multiple simultaneous MDC requests
10668 test_73() {
10669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10670
10671         test_mkdir $DIR/d73-1
10672         test_mkdir $DIR/d73-2
10673         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
10674         pid1=$!
10675
10676         lctl set_param fail_loc=0x80000129
10677         $MULTIOP $DIR/d73-1/f73-2 Oc &
10678         sleep 1
10679         lctl set_param fail_loc=0
10680
10681         $MULTIOP $DIR/d73-2/f73-3 Oc &
10682         pid3=$!
10683
10684         kill -USR1 $pid1
10685         wait $pid1 || return 1
10686
10687         sleep 25
10688
10689         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
10690         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
10691         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
10692
10693         rm -rf $DIR/d73-*
10694 }
10695 run_test 73 "multiple MDC requests (should not deadlock)"
10696
10697 test_74a() { # bug 6149, 6184
10698         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10699
10700         touch $DIR/f74a
10701         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10702         #
10703         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10704         # will spin in a tight reconnection loop
10705         $LCTL set_param fail_loc=0x8000030e
10706         # get any lock that won't be difficult - lookup works.
10707         ls $DIR/f74a
10708         $LCTL set_param fail_loc=0
10709         rm -f $DIR/f74a
10710         true
10711 }
10712 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
10713
10714 test_74b() { # bug 13310
10715         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10716
10717         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10718         #
10719         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10720         # will spin in a tight reconnection loop
10721         $LCTL set_param fail_loc=0x8000030e
10722         # get a "difficult" lock
10723         touch $DIR/f74b
10724         $LCTL set_param fail_loc=0
10725         rm -f $DIR/f74b
10726         true
10727 }
10728 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
10729
10730 test_74c() {
10731         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10732
10733         #define OBD_FAIL_LDLM_NEW_LOCK
10734         $LCTL set_param fail_loc=0x319
10735         touch $DIR/$tfile && error "touch successful"
10736         $LCTL set_param fail_loc=0
10737         true
10738 }
10739 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
10740
10741 slab_lic=/sys/kernel/slab/lustre_inode_cache
10742 num_objects() {
10743         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
10744         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
10745                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
10746 }
10747
10748 test_76a() { # Now for b=20433, added originally in b=1443
10749         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10750
10751         cancel_lru_locks osc
10752         # there may be some slab objects cached per core
10753         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10754         local before=$(num_objects)
10755         local count=$((512 * cpus))
10756         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10757         local margin=$((count / 10))
10758         if [[ -f $slab_lic/aliases ]]; then
10759                 local aliases=$(cat $slab_lic/aliases)
10760                 (( aliases > 0 )) && margin=$((margin * aliases))
10761         fi
10762
10763         echo "before slab objects: $before"
10764         for i in $(seq $count); do
10765                 touch $DIR/$tfile
10766                 rm -f $DIR/$tfile
10767         done
10768         cancel_lru_locks osc
10769         local after=$(num_objects)
10770         echo "created: $count, after slab objects: $after"
10771         # shared slab counts are not very accurate, allow significant margin
10772         # the main goal is that the cache growth is not permanently > $count
10773         while (( after > before + margin )); do
10774                 sleep 1
10775                 after=$(num_objects)
10776                 wait=$((wait + 1))
10777                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10778                 if (( wait > 60 )); then
10779                         error "inode slab grew from $before+$margin to $after"
10780                 fi
10781         done
10782 }
10783 run_test 76a "confirm clients recycle inodes properly ===="
10784
10785 test_76b() {
10786         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10787         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10788
10789         local count=512
10790         local before=$(num_objects)
10791
10792         for i in $(seq $count); do
10793                 mkdir $DIR/$tdir
10794                 rmdir $DIR/$tdir
10795         done
10796
10797         local after=$(num_objects)
10798         local wait=0
10799
10800         while (( after > before )); do
10801                 sleep 1
10802                 after=$(num_objects)
10803                 wait=$((wait + 1))
10804                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10805                 if (( wait > 60 )); then
10806                         error "inode slab grew from $before to $after"
10807                 fi
10808         done
10809
10810         echo "slab objects before: $before, after: $after"
10811 }
10812 run_test 76b "confirm clients recycle directory inodes properly ===="
10813
10814 export ORIG_CSUM=""
10815 set_checksums()
10816 {
10817         # Note: in sptlrpc modes which enable its own bulk checksum, the
10818         # original crc32_le bulk checksum will be automatically disabled,
10819         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10820         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10821         # In this case set_checksums() will not be no-op, because sptlrpc
10822         # bulk checksum will be enabled all through the test.
10823
10824         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10825         lctl set_param -n osc.*.checksums $1
10826         return 0
10827 }
10828
10829 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10830                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10831 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10832                              tr -d [] | head -n1)}
10833 set_checksum_type()
10834 {
10835         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10836         rc=$?
10837         log "set checksum type to $1, rc = $rc"
10838         return $rc
10839 }
10840
10841 get_osc_checksum_type()
10842 {
10843         # arugment 1: OST name, like OST0000
10844         ost=$1
10845         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10846                         sed 's/.*\[\(.*\)\].*/\1/g')
10847         rc=$?
10848         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10849         echo $checksum_type
10850 }
10851
10852 F77_TMP=$TMP/f77-temp
10853 F77SZ=8
10854 setup_f77() {
10855         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10856                 error "error writing to $F77_TMP"
10857 }
10858
10859 test_77a() { # bug 10889
10860         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10861         $GSS && skip_env "could not run with gss"
10862
10863         [ ! -f $F77_TMP ] && setup_f77
10864         set_checksums 1
10865         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10866         set_checksums 0
10867         rm -f $DIR/$tfile
10868 }
10869 run_test 77a "normal checksum read/write operation"
10870
10871 test_77b() { # bug 10889
10872         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10873         $GSS && skip_env "could not run with gss"
10874
10875         [ ! -f $F77_TMP ] && setup_f77
10876         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10877         $LCTL set_param fail_loc=0x80000409
10878         set_checksums 1
10879
10880         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10881                 error "dd error: $?"
10882         $LCTL set_param fail_loc=0
10883
10884         for algo in $CKSUM_TYPES; do
10885                 cancel_lru_locks osc
10886                 set_checksum_type $algo
10887                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10888                 $LCTL set_param fail_loc=0x80000408
10889                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10890                 $LCTL set_param fail_loc=0
10891         done
10892         set_checksums 0
10893         set_checksum_type $ORIG_CSUM_TYPE
10894         rm -f $DIR/$tfile
10895 }
10896 run_test 77b "checksum error on client write, read"
10897
10898 cleanup_77c() {
10899         trap 0
10900         set_checksums 0
10901         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10902         $check_ost &&
10903                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10904         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10905         $check_ost && [ -n "$ost_file_prefix" ] &&
10906                 do_facet ost1 rm -f ${ost_file_prefix}\*
10907 }
10908
10909 test_77c() {
10910         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10911         $GSS && skip_env "could not run with gss"
10912         remote_ost_nodsh && skip "remote OST with nodsh"
10913
10914         local bad1
10915         local osc_file_prefix
10916         local osc_file
10917         local check_ost=false
10918         local ost_file_prefix
10919         local ost_file
10920         local orig_cksum
10921         local dump_cksum
10922         local fid
10923
10924         # ensure corruption will occur on first OSS/OST
10925         $LFS setstripe -i 0 $DIR/$tfile
10926
10927         [ ! -f $F77_TMP ] && setup_f77
10928         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10929                 error "dd write error: $?"
10930         fid=$($LFS path2fid $DIR/$tfile)
10931
10932         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10933         then
10934                 check_ost=true
10935                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10936                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10937         else
10938                 echo "OSS do not support bulk pages dump upon error"
10939         fi
10940
10941         osc_file_prefix=$($LCTL get_param -n debug_path)
10942         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10943
10944         trap cleanup_77c EXIT
10945
10946         set_checksums 1
10947         # enable bulk pages dump upon error on Client
10948         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10949         # enable bulk pages dump upon error on OSS
10950         $check_ost &&
10951                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10952
10953         # flush Client cache to allow next read to reach OSS
10954         cancel_lru_locks osc
10955
10956         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10957         $LCTL set_param fail_loc=0x80000408
10958         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10959         $LCTL set_param fail_loc=0
10960
10961         rm -f $DIR/$tfile
10962
10963         # check cksum dump on Client
10964         osc_file=$(ls ${osc_file_prefix}*)
10965         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10966         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10967         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10968         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10969         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10970                      cksum)
10971         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10972         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10973                 error "dump content does not match on Client"
10974
10975         $check_ost || skip "No need to check cksum dump on OSS"
10976
10977         # check cksum dump on OSS
10978         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10979         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10980         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10981         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10982         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10983                 error "dump content does not match on OSS"
10984
10985         cleanup_77c
10986 }
10987 run_test 77c "checksum error on client read with debug"
10988
10989 test_77d() { # bug 10889
10990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10991         $GSS && skip_env "could not run with gss"
10992
10993         stack_trap "rm -f $DIR/$tfile"
10994         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10995         $LCTL set_param fail_loc=0x80000409
10996         set_checksums 1
10997         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10998                 error "direct write: rc=$?"
10999         $LCTL set_param fail_loc=0
11000         set_checksums 0
11001
11002         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
11003         $LCTL set_param fail_loc=0x80000408
11004         set_checksums 1
11005         cancel_lru_locks osc
11006         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
11007                 error "direct read: rc=$?"
11008         $LCTL set_param fail_loc=0
11009         set_checksums 0
11010 }
11011 run_test 77d "checksum error on OST direct write, read"
11012
11013 test_77f() { # bug 10889
11014         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11015         $GSS && skip_env "could not run with gss"
11016
11017         set_checksums 1
11018         stack_trap "rm -f $DIR/$tfile"
11019         for algo in $CKSUM_TYPES; do
11020                 cancel_lru_locks osc
11021                 set_checksum_type $algo
11022                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
11023                 $LCTL set_param fail_loc=0x409
11024                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
11025                         error "direct write succeeded"
11026                 $LCTL set_param fail_loc=0
11027         done
11028         set_checksum_type $ORIG_CSUM_TYPE
11029         set_checksums 0
11030 }
11031 run_test 77f "repeat checksum error on write (expect error)"
11032
11033 test_77g() { # bug 10889
11034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11035         $GSS && skip_env "could not run with gss"
11036         remote_ost_nodsh && skip "remote OST with nodsh"
11037
11038         [ ! -f $F77_TMP ] && setup_f77
11039
11040         local file=$DIR/$tfile
11041         stack_trap "rm -f $file" EXIT
11042
11043         $LFS setstripe -c 1 -i 0 $file
11044         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
11045         do_facet ost1 lctl set_param fail_loc=0x8000021a
11046         set_checksums 1
11047         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
11048                 error "write error: rc=$?"
11049         do_facet ost1 lctl set_param fail_loc=0
11050         set_checksums 0
11051
11052         cancel_lru_locks osc
11053         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
11054         do_facet ost1 lctl set_param fail_loc=0x8000021b
11055         set_checksums 1
11056         cmp $F77_TMP $file || error "file compare failed"
11057         do_facet ost1 lctl set_param fail_loc=0
11058         set_checksums 0
11059 }
11060 run_test 77g "checksum error on OST write, read"
11061
11062 test_77k() { # LU-10906
11063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11064         $GSS && skip_env "could not run with gss"
11065
11066         local cksum_param="osc.$FSNAME*.checksums"
11067         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
11068         local checksum
11069         local i
11070
11071         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
11072         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
11073         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
11074
11075         for i in 0 1; do
11076                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
11077                         error "failed to set checksum=$i on MGS"
11078                 wait_update $HOSTNAME "$get_checksum" $i
11079                 #remount
11080                 echo "remount client, checksum should be $i"
11081                 remount_client $MOUNT || error "failed to remount client"
11082                 checksum=$(eval $get_checksum)
11083                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
11084         done
11085         # remove persistent param to avoid races with checksum mountopt below
11086         do_facet mgs $LCTL set_param -P -d $cksum_param ||
11087                 error "failed to delete checksum on MGS"
11088
11089         for opt in "checksum" "nochecksum"; do
11090                 #remount with mount option
11091                 echo "remount client with option $opt, checksum should be $i"
11092                 umount_client $MOUNT || error "failed to umount client"
11093                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
11094                         error "failed to mount client with option '$opt'"
11095                 checksum=$(eval $get_checksum)
11096                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
11097                 i=$((i - 1))
11098         done
11099
11100         remount_client $MOUNT || error "failed to remount client"
11101 }
11102 run_test 77k "enable/disable checksum correctly"
11103
11104 test_77l() {
11105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11106         $GSS && skip_env "could not run with gss"
11107
11108         set_checksums 1
11109         stack_trap "set_checksums $ORIG_CSUM" EXIT
11110         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
11111         local old
11112
11113         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
11114         $LCTL set_param osc.*.idle_timeout=10
11115         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
11116
11117         set_checksum_type invalid && error "unexpected success of invalid checksum type"
11118
11119         $LFS setstripe -c 1 -i 0 $DIR/$tfile
11120         for algo in $CKSUM_TYPES; do
11121                 set_checksum_type $algo || error "fail to set checksum type $algo"
11122                 osc_algo=$(get_osc_checksum_type OST0000)
11123                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
11124
11125                 # no locks, no reqs to let the connection idle
11126                 cancel_lru_locks osc
11127                 lru_resize_disable osc
11128                 wait_osc_import_state client ost1 IDLE
11129
11130                 # ensure ost1 is connected
11131                 stat $DIR/$tfile >/dev/null || error "can't stat"
11132                 wait_osc_import_state client ost1 FULL
11133
11134                 osc_algo=$(get_osc_checksum_type OST0000)
11135                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
11136         done
11137         return 0
11138 }
11139 run_test 77l "preferred checksum type is remembered after reconnected"
11140
11141 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
11142 rm -f $F77_TMP
11143 unset F77_TMP
11144
11145 test_77m() {
11146         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
11147                 skip "Need at least version 2.14.52"
11148         local param=checksum_speed
11149
11150         $LCTL get_param $param || error "reading $param failed"
11151
11152         csum_speeds=$($LCTL get_param -n $param)
11153
11154         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
11155                 error "known checksum types are missing"
11156 }
11157 run_test 77m "Verify checksum_speed is correctly read"
11158
11159 check_filefrag_77n() {
11160         local nr_ext=0
11161         local starts=()
11162         local ends=()
11163
11164         while read extidx a b start end rest; do
11165                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
11166                         nr_ext=$(( $nr_ext + 1 ))
11167                         starts+=( ${start%..} )
11168                         ends+=( ${end%:} )
11169                 fi
11170         done < <( filefrag -sv $1 )
11171
11172         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
11173         return 1
11174 }
11175
11176 test_77n() {
11177         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
11178
11179         touch $DIR/$tfile
11180         $TRUNCATE $DIR/$tfile 0
11181         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
11182         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
11183         check_filefrag_77n $DIR/$tfile ||
11184                 skip "$tfile blocks not contiguous around hole"
11185
11186         set_checksums 1
11187         stack_trap "set_checksums $ORIG_CSUM" EXIT
11188         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
11189         stack_trap "rm -f $DIR/$tfile"
11190
11191         for algo in $CKSUM_TYPES; do
11192                 if [[ "$algo" =~ ^t10 ]]; then
11193                         set_checksum_type $algo ||
11194                                 error "fail to set checksum type $algo"
11195                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
11196                                 error "fail to read $tfile with $algo"
11197                 fi
11198         done
11199         rm -f $DIR/$tfile
11200         return 0
11201 }
11202 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
11203
11204 test_77o() {
11205         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
11206                 skip "Need MDS version at least 2.14.55"
11207         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
11208                 skip "Need OST version at least 2.14.55"
11209         local ofd=obdfilter
11210         local mdt=mdt
11211
11212         # print OST checksum_type
11213         echo "$ofd.$FSNAME-*.checksum_type:"
11214         do_nodes $(comma_list $(osts_nodes)) \
11215                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
11216
11217         # print MDT checksum_type
11218         echo "$mdt.$FSNAME-*.checksum_type:"
11219         do_nodes $(comma_list $(mdts_nodes)) \
11220                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
11221
11222         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
11223                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
11224
11225         (( $o_count == $OSTCOUNT )) ||
11226                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
11227
11228         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
11229                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
11230
11231         (( $m_count == $MDSCOUNT )) ||
11232                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
11233 }
11234 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
11235
11236 cleanup_test_78() {
11237         trap 0
11238         rm -f $DIR/$tfile
11239 }
11240
11241 test_78() { # bug 10901
11242         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11243         remote_ost || skip_env "local OST"
11244
11245         NSEQ=5
11246         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
11247         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
11248         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
11249         echo "MemTotal: $MEMTOTAL"
11250
11251         # reserve 256MB of memory for the kernel and other running processes,
11252         # and then take 1/2 of the remaining memory for the read/write buffers.
11253         if [ $MEMTOTAL -gt 512 ] ;then
11254                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
11255         else
11256                 # for those poor memory-starved high-end clusters...
11257                 MEMTOTAL=$((MEMTOTAL / 2))
11258         fi
11259         echo "Mem to use for directio: $MEMTOTAL"
11260
11261         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
11262         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
11263         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
11264         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
11265                 head -n1)
11266         echo "Smallest OST: $SMALLESTOST"
11267         [[ $SMALLESTOST -lt 10240 ]] &&
11268                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
11269
11270         trap cleanup_test_78 EXIT
11271
11272         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
11273                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
11274
11275         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
11276         echo "File size: $F78SIZE"
11277         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
11278         for i in $(seq 1 $NSEQ); do
11279                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
11280                 echo directIO rdwr round $i of $NSEQ
11281                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
11282         done
11283
11284         cleanup_test_78
11285 }
11286 run_test 78 "handle large O_DIRECT writes correctly ============"
11287
11288 test_79() { # bug 12743
11289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11290
11291         wait_delete_completed
11292
11293         BKTOTAL=$(calc_osc_kbytes kbytestotal)
11294         BKFREE=$(calc_osc_kbytes kbytesfree)
11295         BKAVAIL=$(calc_osc_kbytes kbytesavail)
11296
11297         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
11298         DFTOTAL=`echo $STRING | cut -d, -f1`
11299         DFUSED=`echo $STRING  | cut -d, -f2`
11300         DFAVAIL=`echo $STRING | cut -d, -f3`
11301         DFFREE=$(($DFTOTAL - $DFUSED))
11302
11303         ALLOWANCE=$((64 * $OSTCOUNT))
11304
11305         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
11306            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
11307                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
11308         fi
11309         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
11310            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
11311                 error "df free($DFFREE) mismatch OST free($BKFREE)"
11312         fi
11313         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
11314            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
11315                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
11316         fi
11317 }
11318 run_test 79 "df report consistency check ======================="
11319
11320 test_80() { # bug 10718
11321         remote_ost_nodsh && skip "remote OST with nodsh"
11322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11323
11324         # relax strong synchronous semantics for slow backends like ZFS
11325         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
11326                 local soc="obdfilter.*.sync_lock_cancel"
11327                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11328
11329                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
11330                 if [ -z "$save" ]; then
11331                         soc="obdfilter.*.sync_on_lock_cancel"
11332                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11333                 fi
11334
11335                 if [ "$save" != "never" ]; then
11336                         local hosts=$(comma_list $(osts_nodes))
11337
11338                         do_nodes $hosts $LCTL set_param $soc=never
11339                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
11340                 fi
11341         fi
11342
11343         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
11344         sync; sleep 1; sync
11345         local before=$(date +%s)
11346         cancel_lru_locks osc
11347         local after=$(date +%s)
11348         local diff=$((after - before))
11349         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
11350
11351         rm -f $DIR/$tfile
11352 }
11353 run_test 80 "Page eviction is equally fast at high offsets too"
11354
11355 test_81a() { # LU-456
11356         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11357         remote_ost_nodsh && skip "remote OST with nodsh"
11358
11359         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11360         # MUST OR with the CFS_FAIL_ONCE (0x80000000)
11361         do_facet ost1 lctl set_param fail_loc=0x80000228
11362
11363         # write should trigger a retry and success
11364         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11365         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11366         RC=$?
11367         if [ $RC -ne 0 ] ; then
11368                 error "write should success, but failed for $RC"
11369         fi
11370 }
11371 run_test 81a "OST should retry write when get -ENOSPC ==============="
11372
11373 test_81b() { # LU-456
11374         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11375         remote_ost_nodsh && skip "remote OST with nodsh"
11376
11377         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11378         # Don't OR with the CFS_FAIL_ONCE (0x80000000)
11379         do_facet ost1 lctl set_param fail_loc=0x228
11380
11381         # write should retry several times and return -ENOSPC finally
11382         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11383         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11384         RC=$?
11385         ENOSPC=28
11386         if [ $RC -ne $ENOSPC ] ; then
11387                 error "dd should fail for -ENOSPC, but succeed."
11388         fi
11389 }
11390 run_test 81b "OST should return -ENOSPC when retry still fails ======="
11391
11392 test_99() {
11393         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
11394
11395         test_mkdir $DIR/$tdir.cvsroot
11396         chown $RUNAS_ID $DIR/$tdir.cvsroot
11397
11398         cd $TMP
11399         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
11400
11401         cd /etc/init.d
11402         # some versions of cvs import exit(1) when asked to import links or
11403         # files they can't read.  ignore those files.
11404         local toignore=$(find . -type l -printf '-I %f\n' -o \
11405                          ! -perm /4 -printf '-I %f\n')
11406         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
11407                 $tdir.reposname vtag rtag
11408
11409         cd $DIR
11410         test_mkdir $DIR/$tdir.reposname
11411         chown $RUNAS_ID $DIR/$tdir.reposname
11412         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
11413
11414         cd $DIR/$tdir.reposname
11415         $RUNAS touch foo99
11416         $RUNAS cvs add -m 'addmsg' foo99
11417         $RUNAS cvs update
11418         $RUNAS cvs commit -m 'nomsg' foo99
11419         rm -fr $DIR/$tdir.cvsroot
11420 }
11421 run_test 99 "cvs strange file/directory operations"
11422
11423 test_100() {
11424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11425         [[ "$NETTYPE" =~ tcp ]] ||
11426                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
11427         [[ -n "$(type -p ss)" ]] || skip_env "ss not available"
11428         remote_ost_nodsh && skip "remote OST with nodsh"
11429         remote_mds_nodsh && skip "remote MDS with nodsh"
11430         remote_servers || skip "useless for local single node setup"
11431
11432         ss -tna | ( rc=1; while read STATE SND RCV LOCAL REMOTE STAT; do
11433                 [[ "${REMOTE/*:/}" == "$ACCEPTOR_PORT" ]] || continue
11434
11435                 rc=0
11436                 if (( ${LOCAL/*:/} >= 1024 )); then
11437                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
11438                         ss -tna
11439                         error "local: ${LOCAL/*:/} > 1024 remote: ${REMOTE/*:/}"
11440                 fi
11441         done
11442         (( $rc == 0 )) || error "privileged port not found" )
11443 }
11444 run_test 100 "check local port using privileged port"
11445
11446 function get_named_value()
11447 {
11448     local tag=$1
11449
11450     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
11451 }
11452
11453 test_101a() {
11454         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11455
11456         local s
11457         local discard
11458         local nreads=10000
11459         local cache_limit=32
11460
11461         $LCTL set_param -n osc.*-osc*.rpc_stats=0
11462         $LCTL set_param -n llite.*.read_ahead_stats=0
11463         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
11464                               awk '/^max_cached_mb/ { print $2 }')
11465         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
11466         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
11467
11468         #
11469         # randomly read 10000 of 64K chunks from file 3x 32MB in size
11470         #
11471         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
11472         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
11473
11474         discard=0
11475         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
11476                    get_named_value 'read.but.discarded'); do
11477                         discard=$(($discard + $s))
11478         done
11479
11480         $LCTL get_param osc.*-osc*.rpc_stats
11481         $LCTL get_param llite.*.read_ahead_stats
11482
11483         # Discard is generally zero, but sometimes a few random reads line up
11484         # and trigger larger readahead, which is wasted & leads to discards.
11485         if [[ $(($discard)) -gt $nreads ]]; then
11486                 error "too many ($discard) discarded pages"
11487         fi
11488         rm -f $DIR/$tfile || true
11489 }
11490 run_test 101a "check read-ahead for random reads"
11491
11492 setup_test101bc() {
11493         test_mkdir $DIR/$tdir
11494         local ssize=$1
11495         local FILE_LENGTH=$2
11496         STRIPE_OFFSET=0
11497
11498         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
11499
11500         local list=$(comma_list $(osts_nodes))
11501         set_osd_param $list '' read_cache_enable 0
11502         set_osd_param $list '' writethrough_cache_enable 0
11503
11504         trap cleanup_test101bc EXIT
11505         # prepare the read-ahead file
11506         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
11507
11508         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
11509                                 count=$FILE_SIZE_MB 2> /dev/null
11510
11511 }
11512
11513 cleanup_test101bc() {
11514         trap 0
11515         rm -rf $DIR/$tdir
11516         rm -f $DIR/$tfile
11517
11518         local list=$(comma_list $(osts_nodes))
11519         set_osd_param $list '' read_cache_enable 1
11520         set_osd_param $list '' writethrough_cache_enable 1
11521 }
11522
11523 ra_check_101() {
11524         local read_size=$1
11525         local stripe_size=$2
11526         local stride_length=$((stripe_size / read_size))
11527         local stride_width=$((stride_length * OSTCOUNT))
11528         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
11529                                 (stride_width - stride_length) ))
11530         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
11531                   get_named_value 'read.but.discarded' | calc_sum)
11532
11533         if [[ $discard -gt $discard_limit ]]; then
11534                 $LCTL get_param llite.*.read_ahead_stats
11535                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
11536         else
11537                 echo "Read-ahead success for size ${read_size}"
11538         fi
11539 }
11540
11541 test_101b() {
11542         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11543         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11544
11545         local STRIPE_SIZE=1048576
11546         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
11547
11548         if [ $SLOW == "yes" ]; then
11549                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
11550         else
11551                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
11552         fi
11553
11554         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
11555
11556         # prepare the read-ahead file
11557         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11558         cancel_lru_locks osc
11559         for BIDX in 2 4 8 16 32 64 128 256
11560         do
11561                 local BSIZE=$((BIDX*4096))
11562                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
11563                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
11564                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
11565                 $LCTL set_param -n llite.*.read_ahead_stats=0
11566                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
11567                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
11568                 cancel_lru_locks osc
11569                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
11570         done
11571         cleanup_test101bc
11572         true
11573 }
11574 run_test 101b "check stride-io mode read-ahead ================="
11575
11576 test_101c() {
11577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11578
11579         local STRIPE_SIZE=1048576
11580         local FILE_LENGTH=$((STRIPE_SIZE*100))
11581         local nreads=10000
11582         local rsize=65536
11583         local osc_rpc_stats
11584
11585         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11586
11587         cancel_lru_locks osc
11588         $LCTL set_param osc.*.rpc_stats=0
11589         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
11590         $LCTL get_param osc.*.rpc_stats
11591         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
11592                 local stats=$($LCTL get_param -n $osc_rpc_stats)
11593                 local lines=$(echo "$stats" | awk 'END {print NR;}')
11594                 local size
11595
11596                 if [ $lines -le 20 ]; then
11597                         echo "continue debug"
11598                         continue
11599                 fi
11600                 for size in 1 2 4 8; do
11601                         local rpc=$(echo "$stats" |
11602                                     awk '($1 == "'$size':") {print $2; exit; }')
11603                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
11604                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
11605                 done
11606                 echo "$osc_rpc_stats check passed!"
11607         done
11608         cleanup_test101bc
11609         true
11610 }
11611 run_test 101c "check stripe_size aligned read-ahead"
11612
11613 test_101d() {
11614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11615
11616         local file=$DIR/$tfile
11617         local sz_MB=${FILESIZE_101d:-80}
11618         local ra_MB=${READAHEAD_MB:-40}
11619
11620         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
11621         [ $free_MB -lt $sz_MB ] &&
11622                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
11623
11624         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
11625         $LFS setstripe -c -1 $file || error "setstripe failed"
11626
11627         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
11628         echo Cancel LRU locks on lustre client to flush the client cache
11629         cancel_lru_locks osc
11630
11631         echo Disable read-ahead
11632         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11633         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11634         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
11635         $LCTL get_param -n llite.*.max_read_ahead_mb
11636
11637         echo "Reading the test file $file with read-ahead disabled"
11638         local sz_KB=$((sz_MB * 1024 / 4))
11639         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
11640         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
11641         # 83886080 bytes (84 MB, 80 MiB) copied, 16 s, 5.2 MB/s
11642         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11643                       sed -e '/records/d' -e 's/.* \([0-9][0-9\.]*\) *s.*/\1/')
11644
11645         echo "Cancel LRU locks on lustre client to flush the client cache"
11646         cancel_lru_locks osc
11647         echo Enable read-ahead with ${ra_MB}MB
11648         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
11649
11650         echo "Reading the test file $file with read-ahead enabled"
11651         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11652                       sed -e '/records/d' -e 's/.* \([0-9][0-9\.]*\) *s.*/\1/')
11653
11654         echo "read-ahead disabled time read '$raOFF'"
11655         echo "read-ahead enabled time read '$raON'"
11656
11657         rm -f $file
11658         wait_delete_completed
11659
11660         # use awk for this check instead of bash because it handles decimals
11661         awk "{ exit !($raOFF < 0.5 || $raOFF > $raON) }" <<<"ignore_me" ||
11662                 error "readahead ${raON}s > no-readahead ${raOFF}s (${sz_MB}M)"
11663 }
11664 run_test 101d "file read with and without read-ahead enabled"
11665
11666 test_101e() {
11667         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11668
11669         local file=$DIR/$tfile
11670         local size_KB=500  #KB
11671         local count=100
11672         local bsize=1024
11673
11674         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
11675         local need_KB=$((count * size_KB))
11676         [[ $free_KB -le $need_KB ]] &&
11677                 skip_env "Need free space $need_KB, have $free_KB"
11678
11679         echo "Creating $count ${size_KB}K test files"
11680         for ((i = 0; i < $count; i++)); do
11681                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
11682         done
11683
11684         echo "Cancel LRU locks on lustre client to flush the client cache"
11685         cancel_lru_locks $OSC
11686
11687         echo "Reset readahead stats"
11688         $LCTL set_param -n llite.*.read_ahead_stats=0
11689
11690         for ((i = 0; i < $count; i++)); do
11691                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
11692         done
11693
11694         $LCTL get_param llite.*.max_cached_mb
11695         $LCTL get_param llite.*.read_ahead_stats
11696         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11697                      get_named_value 'misses' | calc_sum)
11698
11699         for ((i = 0; i < $count; i++)); do
11700                 rm -rf $file.$i 2>/dev/null
11701         done
11702
11703         #10000 means 20% reads are missing in readahead
11704         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
11705 }
11706 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
11707
11708 test_101f() {
11709         which iozone || skip_env "no iozone installed"
11710
11711         local old_debug=$($LCTL get_param debug)
11712         old_debug=${old_debug#*=}
11713         $LCTL set_param debug="reada mmap"
11714
11715         # create a test file
11716         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
11717
11718         echo Cancel LRU locks on lustre client to flush the client cache
11719         cancel_lru_locks osc
11720
11721         echo Reset readahead stats
11722         $LCTL set_param -n llite.*.read_ahead_stats=0
11723
11724         echo mmap read the file with small block size
11725         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
11726                 > /dev/null 2>&1
11727
11728         echo checking missing pages
11729         $LCTL get_param llite.*.read_ahead_stats
11730         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11731                         get_named_value 'misses' | calc_sum)
11732
11733         $LCTL set_param debug="$old_debug"
11734         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
11735         rm -f $DIR/$tfile
11736 }
11737 run_test 101f "check mmap read performance"
11738
11739 test_101g_brw_size_test() {
11740         local mb=$1
11741         local pages=$((mb * 1048576 / PAGE_SIZE))
11742         local file=$DIR/$tfile
11743
11744         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11745                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11746         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11747                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11748                         return 2
11749         done
11750
11751         stack_trap "rm -f $file" EXIT
11752         $LCTL set_param -n osc.*.rpc_stats=0
11753
11754         # 10 RPCs should be enough for the test
11755         local count=10
11756         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11757                 { error "dd write ${mb} MB blocks failed"; return 3; }
11758         cancel_lru_locks osc
11759         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11760                 { error "dd write ${mb} MB blocks failed"; return 4; }
11761
11762         # calculate number of full-sized read and write RPCs
11763         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11764                 sed -n '/pages per rpc/,/^$/p' |
11765                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11766                 END { print reads,writes }'))
11767         # allow one extra full-sized read RPC for async readahead
11768         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11769                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11770         [[ ${rpcs[1]} == $count ]] ||
11771                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11772 }
11773
11774 test_101g() {
11775         remote_ost_nodsh && skip "remote OST with nodsh"
11776
11777         local rpcs
11778         local osts=$(get_facets OST)
11779         local list=$(comma_list $(osts_nodes))
11780         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11781         local brw_size="obdfilter.*.brw_size"
11782
11783         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11784
11785         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11786
11787         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11788                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11789                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11790            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11791                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11792                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11793
11794                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11795                         suffix="M"
11796
11797                 if [[ $orig_mb -lt 16 ]]; then
11798                         save_lustre_params $osts "$brw_size" > $p
11799                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11800                                 error "set 16MB RPC size failed"
11801
11802                         echo "remount client to enable new RPC size"
11803                         remount_client $MOUNT || error "remount_client failed"
11804                 fi
11805
11806                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11807                 # should be able to set brw_size=12, but no rpc_stats for that
11808                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11809         fi
11810
11811         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11812
11813         if [[ $orig_mb -lt 16 ]]; then
11814                 restore_lustre_params < $p
11815                 remount_client $MOUNT || error "remount_client restore failed"
11816         fi
11817
11818         rm -f $p $DIR/$tfile
11819 }
11820 run_test 101g "Big bulk(4/16 MiB) readahead"
11821
11822 test_101h() {
11823         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11824
11825         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11826                 error "dd 70M file failed"
11827         echo Cancel LRU locks on lustre client to flush the client cache
11828         cancel_lru_locks osc
11829
11830         echo "Reset readahead stats"
11831         $LCTL set_param -n llite.*.read_ahead_stats 0
11832
11833         echo "Read 10M of data but cross 64M bundary"
11834         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11835         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11836                      get_named_value 'misses' | calc_sum)
11837         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11838         rm -f $p $DIR/$tfile
11839 }
11840 run_test 101h "Readahead should cover current read window"
11841
11842 test_101i() {
11843         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11844                 error "dd 10M file failed"
11845
11846         local max_per_file_mb=$($LCTL get_param -n \
11847                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11848         cancel_lru_locks osc
11849         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11850         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11851                 error "set max_read_ahead_per_file_mb to 1 failed"
11852
11853         echo "Reset readahead stats"
11854         $LCTL set_param llite.*.read_ahead_stats=0
11855
11856         dd if=$DIR/$tfile of=/dev/null bs=2M
11857
11858         $LCTL get_param llite.*.read_ahead_stats
11859         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11860                      awk '/misses/ { print $2 }')
11861         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11862         rm -f $DIR/$tfile
11863 }
11864 run_test 101i "allow current readahead to exceed reservation"
11865
11866 test_101j() {
11867         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11868                 error "setstripe $DIR/$tfile failed"
11869         local file_size=$((1048576 * 16))
11870         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11871         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11872
11873         echo Disable read-ahead
11874         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11875
11876         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11877         for blk in $PAGE_SIZE 1048576 $file_size; do
11878                 cancel_lru_locks osc
11879                 echo "Reset readahead stats"
11880                 $LCTL set_param -n llite.*.read_ahead_stats=0
11881                 local count=$(($file_size / $blk))
11882                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11883                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11884                              get_named_value 'failed.to.fast.read' | calc_sum)
11885                 $LCTL get_param -n llite.*.read_ahead_stats
11886                 [ $miss -eq $count ] || error "expected $count got $miss"
11887         done
11888
11889         rm -f $p $DIR/$tfile
11890 }
11891 run_test 101j "A complete read block should be submitted when no RA"
11892
11893 test_readahead_base() {
11894         local file=$DIR/$tfile
11895         local size=$1
11896         local iosz
11897         local ramax
11898         local ranum
11899
11900         $LCTL set_param -n llite.*.read_ahead_stats=0
11901         # The first page is not accounted into readahead
11902         ramax=$(((size + PAGE_SIZE - 1) / PAGE_SIZE - 1))
11903         iosz=$(((size + 1048575) / 1048576 * 1048576))
11904         echo "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11905
11906         $LCTL mark  "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11907         fallocate -l $size $file || error "failed to fallocate $file"
11908         cancel_lru_locks osc
11909         $MULTIOP $file or${iosz}c || error "failed to read $file"
11910         $LCTL get_param -n llite.*.read_ahead_stats
11911         ranum=$($LCTL get_param -n llite.*.read_ahead_stats |
11912                 awk '/readahead.pages/ { print $7 }' | calc_sum)
11913         (( $ranum <= $ramax )) ||
11914                 error "read-ahead pages is $ranum more than $ramax"
11915         rm -rf $file || error "failed to remove $file"
11916 }
11917
11918 test_101m()
11919 {
11920         local file=$DIR/$tfile
11921         local ramax
11922         local ranum
11923         local size
11924         local iosz
11925
11926         check_set_fallocate_or_skip
11927         stack_trap "rm -f $file" EXIT
11928
11929         test_readahead_base 4096
11930
11931         # file size: 16K = 16384
11932         test_readahead_base 16384
11933         test_readahead_base 16385
11934         test_readahead_base 16383
11935
11936         # file size: 1M + 1 = 1048576 + 1
11937         test_readahead_base 1048577
11938         # file size: 1M + 16K
11939         test_readahead_base $((1048576 + 16384))
11940
11941         # file size: stripe_size * (stripe_count - 1) + 16K
11942         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11943         test_readahead_base $((1048576 * (OSTCOUNT - 1) + 16384))
11944         # file size: stripe_size * stripe_count + 16K
11945         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11946         test_readahead_base $((1048576 * OSTCOUNT + 16384))
11947         # file size: 2 * stripe_size * stripe_count + 16K
11948         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11949         test_readahead_base $((2 * 1048576 * OSTCOUNT + 16384))
11950 }
11951 run_test 101m "read ahead for small file and last stripe of the file"
11952
11953 setup_test102() {
11954         test_mkdir $DIR/$tdir
11955         chown $RUNAS_ID $DIR/$tdir
11956         STRIPE_SIZE=65536
11957         STRIPE_OFFSET=1
11958         STRIPE_COUNT=$OSTCOUNT
11959         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11960
11961         trap cleanup_test102 EXIT
11962         cd $DIR
11963         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11964         cd $DIR/$tdir
11965         for num in 1 2 3 4; do
11966                 for count in $(seq 1 $STRIPE_COUNT); do
11967                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11968                                 local size=`expr $STRIPE_SIZE \* $num`
11969                                 local file=file"$num-$idx-$count"
11970                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11971                         done
11972                 done
11973         done
11974
11975         cd $DIR
11976         $1 tar cf $TMP/f102.tar $tdir --xattrs
11977 }
11978
11979 cleanup_test102() {
11980         trap 0
11981         rm -f $TMP/f102.tar
11982         rm -rf $DIR/d0.sanity/d102
11983 }
11984
11985 test_102a() {
11986         [ "$UID" != 0 ] && skip "must run as root"
11987         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11988                 skip_env "must have user_xattr"
11989
11990         [ -z "$(which setfattr 2>/dev/null)" ] &&
11991                 skip_env "could not find setfattr"
11992
11993         local testfile=$DIR/$tfile
11994
11995         touch $testfile
11996         echo "set/get xattr..."
11997         setfattr -n trusted.name1 -v value1 $testfile ||
11998                 error "setfattr -n trusted.name1=value1 $testfile failed"
11999         getfattr -n trusted.name1 $testfile 2> /dev/null |
12000           grep "trusted.name1=.value1" ||
12001                 error "$testfile missing trusted.name1=value1"
12002
12003         setfattr -n user.author1 -v author1 $testfile ||
12004                 error "setfattr -n user.author1=author1 $testfile failed"
12005         getfattr -n user.author1 $testfile 2> /dev/null |
12006           grep "user.author1=.author1" ||
12007                 error "$testfile missing trusted.author1=author1"
12008
12009         echo "listxattr..."
12010         setfattr -n trusted.name2 -v value2 $testfile ||
12011                 error "$testfile unable to set trusted.name2"
12012         setfattr -n trusted.name3 -v value3 $testfile ||
12013                 error "$testfile unable to set trusted.name3"
12014         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
12015             grep "trusted.name" | wc -l) -eq 3 ] ||
12016                 error "$testfile missing 3 trusted.name xattrs"
12017
12018         setfattr -n user.author2 -v author2 $testfile ||
12019                 error "$testfile unable to set user.author2"
12020         setfattr -n user.author3 -v author3 $testfile ||
12021                 error "$testfile unable to set user.author3"
12022         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
12023             grep "user.author" | wc -l) -eq 3 ] ||
12024                 error "$testfile missing 3 user.author xattrs"
12025
12026         echo "remove xattr..."
12027         setfattr -x trusted.name1 $testfile ||
12028                 error "$testfile error deleting trusted.name1"
12029         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
12030                 error "$testfile did not delete trusted.name1 xattr"
12031
12032         setfattr -x user.author1 $testfile ||
12033                 error "$testfile error deleting user.author1"
12034         echo "set lustre special xattr ..."
12035         $LFS setstripe -c1 $testfile
12036         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
12037                 awk -F "=" '/trusted.lov/ { print $2 }' )
12038         setfattr -n "trusted.lov" -v $lovea $testfile ||
12039                 error "$testfile doesn't ignore setting trusted.lov again"
12040         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
12041                 error "$testfile allow setting invalid trusted.lov"
12042         rm -f $testfile
12043 }
12044 run_test 102a "user xattr test =================================="
12045
12046 check_102b_layout() {
12047         local layout="$*"
12048         local testfile=$DIR/$tfile
12049
12050         echo "test layout '$layout'"
12051         $LFS setstripe $layout $testfile || error "setstripe failed"
12052         $LFS getstripe -y $testfile
12053
12054         echo "get/set/list trusted.lov xattr ..." # b=10930
12055         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
12056         [[ "$value" =~ "trusted.lov" ]] ||
12057                 error "can't get trusted.lov from $testfile"
12058         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
12059                 error "getstripe failed"
12060
12061         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
12062
12063         value=$(cut -d= -f2 <<<$value)
12064         # LU-13168: truncated xattr should fail if short lov_user_md header
12065         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
12066                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
12067         for len in $lens; do
12068                 echo "setfattr $len $testfile.2"
12069                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
12070                         [ $len -lt 66 ] && error "short xattr len=$len worked"
12071         done
12072         local stripe_size=$($LFS getstripe -S $testfile.2)
12073         local stripe_count=$($LFS getstripe -c $testfile.2)
12074         [[ $stripe_size -eq 65536 ]] ||
12075                 error "stripe size $stripe_size != 65536"
12076         [[ $stripe_count -eq $stripe_count_orig ]] ||
12077                 error "stripe count $stripe_count != $stripe_count_orig"
12078         rm $testfile $testfile.2
12079 }
12080
12081 test_102b() {
12082         [ -z "$(which setfattr 2>/dev/null)" ] &&
12083                 skip_env "could not find setfattr"
12084         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12085
12086         # check plain layout
12087         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
12088
12089         # and also check composite layout
12090         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
12091
12092 }
12093 run_test 102b "getfattr/setfattr for trusted.lov EAs"
12094
12095 test_102c() {
12096         [ -z "$(which setfattr 2>/dev/null)" ] &&
12097                 skip_env "could not find setfattr"
12098         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12099
12100         # b10930: get/set/list lustre.lov xattr
12101         echo "get/set/list lustre.lov xattr ..."
12102         test_mkdir $DIR/$tdir
12103         chown $RUNAS_ID $DIR/$tdir
12104         local testfile=$DIR/$tdir/$tfile
12105         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
12106                 error "setstripe failed"
12107         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
12108                 error "getstripe failed"
12109         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
12110         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
12111
12112         local testfile2=${testfile}2
12113         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
12114                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
12115
12116         $RUNAS $MCREATE $testfile2
12117         $RUNAS setfattr -n lustre.lov -v $value $testfile2
12118         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
12119         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
12120         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
12121         [ $stripe_count -eq $STRIPECOUNT ] ||
12122                 error "stripe count $stripe_count != $STRIPECOUNT"
12123 }
12124 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
12125
12126 compare_stripe_info1() {
12127         local stripe_index_all_zero=true
12128
12129         for num in 1 2 3 4; do
12130                 for count in $(seq 1 $STRIPE_COUNT); do
12131                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
12132                                 local size=$((STRIPE_SIZE * num))
12133                                 local file=file"$num-$offset-$count"
12134                                 stripe_size=$($LFS getstripe -S $PWD/$file)
12135                                 [[ $stripe_size -ne $size ]] &&
12136                                     error "$file: size $stripe_size != $size"
12137                                 stripe_count=$($LFS getstripe -c $PWD/$file)
12138                                 # allow fewer stripes to be created, ORI-601
12139                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
12140                                     error "$file: count $stripe_count != $count"
12141                                 stripe_index=$($LFS getstripe -i $PWD/$file)
12142                                 [[ $stripe_index -ne 0 ]] &&
12143                                         stripe_index_all_zero=false
12144                         done
12145                 done
12146         done
12147         $stripe_index_all_zero &&
12148                 error "all files are being extracted starting from OST index 0"
12149         return 0
12150 }
12151
12152 have_xattrs_include() {
12153         tar --help | grep -q xattrs-include &&
12154                 echo --xattrs-include="lustre.*"
12155 }
12156
12157 test_102d() {
12158         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12159         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12160
12161         XINC=$(have_xattrs_include)
12162         setup_test102
12163         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
12164         cd $DIR/$tdir/$tdir
12165         compare_stripe_info1
12166 }
12167 run_test 102d "tar restore stripe info from tarfile,not keep osts"
12168
12169 test_102f() {
12170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12171         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12172
12173         XINC=$(have_xattrs_include)
12174         setup_test102
12175         test_mkdir $DIR/$tdir.restore
12176         cd $DIR
12177         tar cf - --xattrs $tdir | tar xf - \
12178                 -C $DIR/$tdir.restore --xattrs $XINC
12179         cd $DIR/$tdir.restore/$tdir
12180         compare_stripe_info1
12181 }
12182 run_test 102f "tar copy files, not keep osts"
12183
12184 grow_xattr() {
12185         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
12186                 skip "must have user_xattr"
12187         [ -z "$(which setfattr 2>/dev/null)" ] &&
12188                 skip_env "could not find setfattr"
12189         [ -z "$(which getfattr 2>/dev/null)" ] &&
12190                 skip_env "could not find getfattr"
12191
12192         local xsize=${1:-1024}  # in bytes
12193         local file=$DIR/$tfile
12194         local value="$(generate_string $xsize)"
12195         local xbig=trusted.big
12196         local toobig=$2
12197
12198         touch $file
12199         log "save $xbig on $file"
12200         if [ -z "$toobig" ]
12201         then
12202                 setfattr -n $xbig -v $value $file ||
12203                         error "saving $xbig on $file failed"
12204         else
12205                 setfattr -n $xbig -v $value $file &&
12206                         error "saving $xbig on $file succeeded"
12207                 return 0
12208         fi
12209
12210         local orig=$(get_xattr_value $xbig $file)
12211         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
12212
12213         local xsml=trusted.sml
12214         log "save $xsml on $file"
12215         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
12216
12217         local new=$(get_xattr_value $xbig $file)
12218         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
12219
12220         log "grow $xsml on $file"
12221         setfattr -n $xsml -v "$value" $file ||
12222                 error "growing $xsml on $file failed"
12223
12224         new=$(get_xattr_value $xbig $file)
12225         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
12226         log "$xbig still valid after growing $xsml"
12227
12228         rm -f $file
12229 }
12230
12231 test_102h() { # bug 15777
12232         grow_xattr 1024
12233 }
12234 run_test 102h "grow xattr from inside inode to external block"
12235
12236 test_102ha() {
12237         large_xattr_enabled || skip_env "ea_inode feature disabled"
12238
12239         echo "setting xattr of max xattr size: $(max_xattr_size)"
12240         grow_xattr $(max_xattr_size)
12241
12242         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
12243         echo "This should fail:"
12244         grow_xattr $(($(max_xattr_size) + 10)) 1
12245 }
12246 run_test 102ha "grow xattr from inside inode to external inode"
12247
12248 test_102i() { # bug 17038
12249         [ -z "$(which getfattr 2>/dev/null)" ] &&
12250                 skip "could not find getfattr"
12251
12252         touch $DIR/$tfile
12253         ln -s $DIR/$tfile $DIR/${tfile}link
12254         getfattr -n trusted.lov $DIR/$tfile ||
12255                 error "lgetxattr on $DIR/$tfile failed"
12256         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
12257                 grep -i "no such attr" ||
12258                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
12259         rm -f $DIR/$tfile $DIR/${tfile}link
12260 }
12261 run_test 102i "lgetxattr test on symbolic link ============"
12262
12263 test_102j() {
12264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12265         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12266
12267         XINC=$(have_xattrs_include)
12268         setup_test102 "$RUNAS"
12269         chown $RUNAS_ID $DIR/$tdir
12270         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
12271         cd $DIR/$tdir/$tdir
12272         compare_stripe_info1 "$RUNAS"
12273 }
12274 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
12275
12276 test_102k() {
12277         [ -z "$(which setfattr 2>/dev/null)" ] &&
12278                 skip "could not find setfattr"
12279
12280         touch $DIR/$tfile
12281         # b22187 just check that does not crash for regular file.
12282         setfattr -n trusted.lov $DIR/$tfile
12283         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
12284         local test_kdir=$DIR/$tdir
12285         test_mkdir $test_kdir
12286         local default_size=$($LFS getstripe -S $test_kdir)
12287         local default_count=$($LFS getstripe -c $test_kdir)
12288         local default_offset=$($LFS getstripe -i $test_kdir)
12289         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
12290                 error 'dir setstripe failed'
12291         setfattr -n trusted.lov $test_kdir
12292         local stripe_size=$($LFS getstripe -S $test_kdir)
12293         local stripe_count=$($LFS getstripe -c $test_kdir)
12294         local stripe_offset=$($LFS getstripe -i $test_kdir)
12295         [ $stripe_size -eq $default_size ] ||
12296                 error "stripe size $stripe_size != $default_size"
12297         [ $stripe_count -eq $default_count ] ||
12298                 error "stripe count $stripe_count != $default_count"
12299         [ $stripe_offset -eq $default_offset ] ||
12300                 error "stripe offset $stripe_offset != $default_offset"
12301         rm -rf $DIR/$tfile $test_kdir
12302 }
12303 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
12304
12305 test_102l() {
12306         [ -z "$(which getfattr 2>/dev/null)" ] &&
12307                 skip "could not find getfattr"
12308
12309         # LU-532 trusted. xattr is invisible to non-root
12310         local testfile=$DIR/$tfile
12311
12312         touch $testfile
12313
12314         echo "listxattr as user..."
12315         chown $RUNAS_ID $testfile
12316         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
12317             grep -q "trusted" &&
12318                 error "$testfile trusted xattrs are user visible"
12319
12320         return 0;
12321 }
12322 run_test 102l "listxattr size test =================================="
12323
12324 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
12325         local path=$DIR/$tfile
12326         touch $path
12327
12328         listxattr_size_check $path || error "listattr_size_check $path failed"
12329 }
12330 run_test 102m "Ensure listxattr fails on small bufffer ========"
12331
12332 cleanup_test102
12333
12334 getxattr() { # getxattr path name
12335         # Return the base64 encoding of the value of xattr name on path.
12336         local path=$1
12337         local name=$2
12338
12339         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
12340         # file: $path
12341         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12342         #
12343         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12344
12345         getfattr --absolute-names --encoding=base64 --name=$name $path |
12346                 awk -F= -v name=$name '$1 == name {
12347                         print substr($0, index($0, "=") + 1);
12348         }'
12349 }
12350
12351 test_102n() { # LU-4101 mdt: protect internal xattrs
12352         [ -z "$(which setfattr 2>/dev/null)" ] &&
12353                 skip "could not find setfattr"
12354         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
12355         then
12356                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
12357         fi
12358
12359         local file0=$DIR/$tfile.0
12360         local file1=$DIR/$tfile.1
12361         local xattr0=$TMP/$tfile.0
12362         local xattr1=$TMP/$tfile.1
12363         local namelist="lov lma lmv link fid version som hsm"
12364         local name
12365         local value
12366
12367         rm -rf $file0 $file1 $xattr0 $xattr1
12368         touch $file0 $file1
12369
12370         # Get 'before' xattrs of $file1.
12371         getfattr --absolute-names --dump --match=- $file1 > $xattr0
12372
12373         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
12374                 namelist+=" lfsck_namespace"
12375         for name in $namelist; do
12376                 # Try to copy xattr from $file0 to $file1.
12377                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12378
12379                 setfattr --name=trusted.$name --value="$value" $file1 ||
12380                         error "setxattr 'trusted.$name' failed"
12381
12382                 # Try to set a garbage xattr.
12383                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12384
12385                 if [[ x$name == "xlov" ]]; then
12386                         setfattr --name=trusted.lov --value="$value" $file1 &&
12387                         error "setxattr invalid 'trusted.lov' success"
12388                 else
12389                         setfattr --name=trusted.$name --value="$value" $file1 ||
12390                                 error "setxattr invalid 'trusted.$name' failed"
12391                 fi
12392
12393                 # Try to remove the xattr from $file1. We don't care if this
12394                 # appears to succeed or fail, we just don't want there to be
12395                 # any changes or crashes.
12396                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12397         done
12398
12399         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
12400         then
12401                 name="lfsck_ns"
12402                 # Try to copy xattr from $file0 to $file1.
12403                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12404
12405                 setfattr --name=trusted.$name --value="$value" $file1 ||
12406                         error "setxattr 'trusted.$name' failed"
12407
12408                 # Try to set a garbage xattr.
12409                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12410
12411                 setfattr --name=trusted.$name --value="$value" $file1 ||
12412                         error "setxattr 'trusted.$name' failed"
12413
12414                 # Try to remove the xattr from $file1. We don't care if this
12415                 # appears to succeed or fail, we just don't want there to be
12416                 # any changes or crashes.
12417                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12418         fi
12419
12420         # Get 'after' xattrs of file1.
12421         getfattr --absolute-names --dump --match=- $file1 > $xattr1
12422
12423         if ! diff $xattr0 $xattr1; then
12424                 error "before and after xattrs of '$file1' differ"
12425         fi
12426
12427         rm -rf $file0 $file1 $xattr0 $xattr1
12428
12429         return 0
12430 }
12431 run_test 102n "silently ignore setxattr on internal trusted xattrs"
12432
12433 test_102p() { # LU-4703 setxattr did not check ownership
12434         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
12435                 skip "MDS needs to be at least 2.5.56"
12436
12437         local testfile=$DIR/$tfile
12438
12439         touch $testfile
12440
12441         echo "setfacl as user..."
12442         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
12443         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
12444
12445         echo "setfattr as user..."
12446         setfacl -m "u:$RUNAS_ID:---" $testfile
12447         $RUNAS setfattr -x system.posix_acl_access $testfile
12448         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
12449 }
12450 run_test 102p "check setxattr(2) correctly fails without permission"
12451
12452 test_102q() {
12453         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
12454                 skip "MDS needs to be at least 2.6.92"
12455
12456         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
12457 }
12458 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
12459
12460 test_102r() {
12461         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
12462                 skip "MDS needs to be at least 2.6.93"
12463
12464         touch $DIR/$tfile || error "touch"
12465         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
12466         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
12467         rm $DIR/$tfile || error "rm"
12468
12469         #normal directory
12470         mkdir -p $DIR/$tdir || error "mkdir"
12471         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12472         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12473         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12474                 error "$testfile error deleting user.author1"
12475         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12476                 grep "user.$(basename $tdir)" &&
12477                 error "$tdir did not delete user.$(basename $tdir)"
12478         rmdir $DIR/$tdir || error "rmdir"
12479
12480         #striped directory
12481         test_mkdir $DIR/$tdir
12482         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12483         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12484         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12485                 error "$testfile error deleting user.author1"
12486         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12487                 grep "user.$(basename $tdir)" &&
12488                 error "$tdir did not delete user.$(basename $tdir)"
12489         rmdir $DIR/$tdir || error "rm striped dir"
12490 }
12491 run_test 102r "set EAs with empty values"
12492
12493 test_102s() {
12494         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12495                 skip "MDS needs to be at least 2.11.52"
12496
12497         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12498
12499         save_lustre_params client "llite.*.xattr_cache" > $save
12500
12501         for cache in 0 1; do
12502                 lctl set_param llite.*.xattr_cache=$cache
12503
12504                 rm -f $DIR/$tfile
12505                 touch $DIR/$tfile || error "touch"
12506                 for prefix in lustre security system trusted user; do
12507                         # Note getxattr() may fail with 'Operation not
12508                         # supported' or 'No such attribute' depending
12509                         # on prefix and cache.
12510                         getfattr -n $prefix.n102s $DIR/$tfile &&
12511                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
12512                 done
12513         done
12514
12515         restore_lustre_params < $save
12516 }
12517 run_test 102s "getting nonexistent xattrs should fail"
12518
12519 test_102t() {
12520         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12521                 skip "MDS needs to be at least 2.11.52"
12522
12523         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12524
12525         save_lustre_params client "llite.*.xattr_cache" > $save
12526
12527         for cache in 0 1; do
12528                 lctl set_param llite.*.xattr_cache=$cache
12529
12530                 for buf_size in 0 256; do
12531                         rm -f $DIR/$tfile
12532                         touch $DIR/$tfile || error "touch"
12533                         setfattr -n user.multiop $DIR/$tfile
12534                         $MULTIOP $DIR/$tfile oa$buf_size ||
12535                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
12536                 done
12537         done
12538
12539         restore_lustre_params < $save
12540 }
12541 run_test 102t "zero length xattr values handled correctly"
12542
12543 run_acl_subtest()
12544 {
12545         local test=$LUSTRE/tests/acl/$1.test
12546         local tmp=$(mktemp -t $1-XXXXXX).test
12547         local bin=$2
12548         local dmn=$3
12549         local grp=$4
12550         local nbd=$5
12551         export LANG=C
12552
12553
12554         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
12555         local sedgroups="-e s/:users/:$grp/g"
12556         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
12557
12558         sed $sedusers $sedgroups < $test > $tmp
12559         stack_trap "rm -f $tmp"
12560         [[ -s $tmp ]] || error "sed failed to create test script"
12561
12562         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
12563         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
12564 }
12565
12566 test_103a() {
12567         [ "$UID" != 0 ] && skip "must run as root"
12568         $GSS && skip_env "could not run under gss"
12569         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
12570                 skip_env "must have acl enabled"
12571         which setfacl || skip_env "could not find setfacl"
12572         remote_mds_nodsh && skip "remote MDS with nodsh"
12573
12574         local mdts=$(comma_list $(mdts_nodes))
12575         local saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
12576
12577         [[ -z "$saved" ]] || do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE
12578         stack_trap "[[ -z \"$saved\" ]] || \
12579                     do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$saved" EXIT
12580
12581         ACLBIN=${ACLBIN:-"bin"}
12582         ACLDMN=${ACLDMN:-"daemon"}
12583         ACLGRP=${ACLGRP:-"users"}
12584         ACLNBD=${ACLNBD:-"nobody"}
12585
12586         if ! id $ACLBIN ||
12587            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
12588                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
12589                 ACLBIN=$USER0
12590                 if ! id $ACLBIN ; then
12591                         cat /etc/passwd
12592                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
12593                 fi
12594         fi
12595         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
12596            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
12597                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
12598                 ACLDMN=$USER1
12599                 if ! id $ACLDMN ; then
12600                         cat /etc/passwd
12601                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
12602                 fi
12603         fi
12604         if ! getent group $ACLGRP; then
12605                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
12606                 ACLGRP="$TSTUSR"
12607                 if ! getent group $ACLGRP; then
12608                         echo "cannot find group '$ACLGRP', adding it"
12609                         cat /etc/group
12610                         add_group 60000 $ACLGRP
12611                 fi
12612         fi
12613
12614         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
12615         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
12616         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12617
12618         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12619                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
12620                 ACLGRP="$TSTUSR"
12621                 if ! getent group $ACLGRP; then
12622                         echo "cannot find group '$ACLGRP', adding it"
12623                         cat /etc/group
12624                         add_group 60000 $ACLGRP
12625                 fi
12626                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12627                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12628                         cat /etc/group
12629                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
12630                 fi
12631         fi
12632
12633         gpasswd -a $ACLDMN $ACLBIN ||
12634                 error "setting client group failed"             # LU-5641
12635         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
12636                 error "setting MDS group failed"                # LU-5641
12637
12638         declare -a identity_old
12639
12640         for ((num = 1; num <= $MDSCOUNT; num++)); do
12641                 switch_identity $num true || identity_old[$num]=$?
12642         done
12643
12644         SAVE_UMASK=$(umask)
12645         umask 0022
12646         mkdir -p $DIR/$tdir
12647         cd $DIR/$tdir
12648
12649         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
12650         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
12651         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
12652         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
12653         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
12654         # CentOS7- uses nobody=99, while newer distros use nobody=65534
12655         if ! id -u $ACLNBD ||
12656            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
12657                 ACLNBD="nfsnobody"
12658                 if ! id -u $ACLNBD; then
12659                         ACLNBD=""
12660                 fi
12661         fi
12662         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
12663                 add_group $(id -u $ACLNBD) $ACLNBD
12664                 if ! getent group $ACLNBD; then
12665                         ACLNBD=""
12666                 fi
12667         fi
12668         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
12669            [[ -n "$ACLNBD" ]] && which setfattr; then
12670                 run_acl_subtest permissions_xattr \
12671                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
12672         elif [[ -z "$ACLNBD" ]]; then
12673                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
12674         else
12675                 echo "skip 'permission_xattr' test - missing setfattr command"
12676         fi
12677         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
12678
12679         # inheritance test got from HP
12680         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
12681         chmod +x make-tree || error "chmod +x failed"
12682         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
12683         rm -f make-tree
12684
12685         echo "LU-974 ignore umask when acl is enabled..."
12686         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
12687         if [ $MDSCOUNT -ge 2 ]; then
12688                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
12689         fi
12690
12691         echo "LU-2561 newly created file is same size as directory..."
12692         if [ "$mds1_FSTYPE" != "zfs" ]; then
12693                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
12694         else
12695                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
12696         fi
12697
12698         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
12699
12700         cd $SAVE_PWD
12701         umask $SAVE_UMASK
12702
12703         for ((num = 1; num <= $MDSCOUNT; num++)); do
12704                 if [[ "${identity_old[$num]}" == 1 ]]; then
12705                         switch_identity $num false || identity_old[$num]=$?
12706                 fi
12707         done
12708 }
12709 run_test 103a "acl test"
12710
12711 test_103b() {
12712         declare -a pids
12713         local U
12714
12715         stack_trap "rm -f $DIR/$tfile.*"
12716         for U in {0..511}; do
12717                 {
12718                 local O=$(printf "%04o" $U)
12719
12720                 umask $(printf "%04o" $((511 ^ $O)))
12721                 $LFS setstripe -c 1 $DIR/$tfile.s$O
12722                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
12723
12724                 (( $S == ($O & 0666) )) ||
12725                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
12726
12727                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
12728                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
12729                 (( $S == ($O & 0666) )) ||
12730                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
12731
12732                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
12733                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
12734                 (( $S == ($O & 0666) )) ||
12735                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
12736                 rm -f $DIR/$tfile.[smp]$0
12737                 } &
12738                 local pid=$!
12739
12740                 # limit the concurrently running threads to 64. LU-11878
12741                 local idx=$((U % 64))
12742                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
12743                 pids[idx]=$pid
12744         done
12745         wait
12746 }
12747 run_test 103b "umask lfs setstripe"
12748
12749 test_103c() {
12750         mkdir -p $DIR/$tdir
12751         cp -rp $DIR/$tdir $DIR/$tdir.bak
12752
12753         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
12754                 error "$DIR/$tdir shouldn't contain default ACL"
12755         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
12756                 error "$DIR/$tdir.bak shouldn't contain default ACL"
12757         true
12758 }
12759 run_test 103c "'cp -rp' won't set empty acl"
12760
12761 test_103e() {
12762         local numacl
12763         local fileacl
12764         local saved_debug=$($LCTL get_param -n debug)
12765
12766         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
12767                 skip "MDS needs to be at least 2.14.52"
12768
12769         large_xattr_enabled || skip_env "ea_inode feature disabled"
12770
12771         mkdir -p $DIR/$tdir
12772         # add big LOV EA to cause reply buffer overflow earlier
12773         $LFS setstripe -C 1000 $DIR/$tdir
12774         lctl set_param mdc.*-mdc*.stats=clear
12775
12776         $LCTL set_param debug=0
12777         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
12778         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
12779
12780         # add a large number of default ACLs (expect 8000+ for 2.13+)
12781         for U in {2..7000}; do
12782                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
12783                         error "Able to add just $U default ACLs"
12784         done
12785         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
12786         echo "$numacl default ACLs created"
12787
12788         stat $DIR/$tdir || error "Cannot stat directory"
12789         # check file creation
12790         touch $DIR/$tdir/$tfile ||
12791                 error "failed to create $tfile with $numacl default ACLs"
12792         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
12793         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12794         echo "$fileacl ACLs were inherited"
12795         (( $fileacl == $numacl )) ||
12796                 error "Not all default ACLs were inherited: $numacl != $fileacl"
12797         # check that new ACLs creation adds new ACLs to inherited ACLs
12798         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
12799                 error "Cannot set new ACL"
12800         numacl=$((numacl + 1))
12801         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12802         (( $fileacl == $numacl )) ||
12803                 error "failed to add new ACL: $fileacl != $numacl as expected"
12804         # adds more ACLs to a file to reach their maximum at 8000+
12805         numacl=0
12806         for U in {20000..25000}; do
12807                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12808                 numacl=$((numacl + 1))
12809         done
12810         echo "Added $numacl more ACLs to the file"
12811         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12812         echo "Total $fileacl ACLs in file"
12813         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12814         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12815         rmdir $DIR/$tdir || error "Cannot remove directory"
12816 }
12817 run_test 103e "inheritance of big amount of default ACLs"
12818
12819 test_103f() {
12820         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12821                 skip "MDS needs to be at least 2.14.51"
12822
12823         large_xattr_enabled || skip_env "ea_inode feature disabled"
12824
12825         # enable changelog to consume more internal MDD buffers
12826         changelog_register
12827
12828         mkdir -p $DIR/$tdir
12829         # add big LOV EA
12830         $LFS setstripe -C 1000 $DIR/$tdir
12831         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12832         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12833         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12834         rmdir $DIR/$tdir || error "Cannot remove directory"
12835 }
12836 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12837
12838 test_104a() {
12839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12840
12841         touch $DIR/$tfile
12842         lfs df || error "lfs df failed"
12843         lfs df -ih || error "lfs df -ih failed"
12844         lfs df -h $DIR || error "lfs df -h $DIR failed"
12845         lfs df -i $DIR || error "lfs df -i $DIR failed"
12846         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12847         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12848
12849         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12850         lctl --device %$OSC deactivate
12851         lfs df || error "lfs df with deactivated OSC failed"
12852         lctl --device %$OSC activate
12853         # wait the osc back to normal
12854         wait_osc_import_ready client ost
12855
12856         lfs df || error "lfs df with reactivated OSC failed"
12857         rm -f $DIR/$tfile
12858 }
12859 run_test 104a "lfs df [-ih] [path] test ========================="
12860
12861 test_104b() {
12862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12863         [ $RUNAS_ID -eq $UID ] &&
12864                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12865
12866         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12867                         grep "Permission denied" | wc -l)))
12868         if [ $denied_cnt -ne 0 ]; then
12869                 error "lfs check servers test failed"
12870         fi
12871 }
12872 run_test 104b "$RUNAS lfs check servers test ===================="
12873
12874 #
12875 # Verify $1 is within range of $2.
12876 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12877 # $1 is <= 2% of $2. Else Fail.
12878 #
12879 value_in_range() {
12880         # Strip all units (M, G, T)
12881         actual=$(echo $1 | tr -d A-Z)
12882         expect=$(echo $2 | tr -d A-Z)
12883
12884         expect_lo=$(($expect * 98 / 100)) # 2% below
12885         expect_hi=$(($expect * 102 / 100)) # 2% above
12886
12887         # permit 2% drift above and below
12888         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12889 }
12890
12891 test_104c() {
12892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12893         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12894
12895         local ost_param="osd-zfs.$FSNAME-OST0000."
12896         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12897         local ofacets=$(get_facets OST)
12898         local mfacets=$(get_facets MDS)
12899         local saved_ost_blocks=
12900         local saved_mdt_blocks=
12901
12902         echo "Before recordsize change"
12903         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12904         df=($(df -h | grep "$MOUNT"$))
12905
12906         # For checking.
12907         echo "lfs output : ${lfs_df[*]}"
12908         echo "df  output : ${df[*]}"
12909
12910         for facet in ${ofacets//,/ }; do
12911                 if [ -z $saved_ost_blocks ]; then
12912                         saved_ost_blocks=$(do_facet $facet \
12913                                 lctl get_param -n $ost_param.blocksize)
12914                         echo "OST Blocksize: $saved_ost_blocks"
12915                 fi
12916                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12917                 do_facet $facet zfs set recordsize=32768 $ost
12918         done
12919
12920         # BS too small. Sufficient for functional testing.
12921         for facet in ${mfacets//,/ }; do
12922                 if [ -z $saved_mdt_blocks ]; then
12923                         saved_mdt_blocks=$(do_facet $facet \
12924                                 lctl get_param -n $mdt_param.blocksize)
12925                         echo "MDT Blocksize: $saved_mdt_blocks"
12926                 fi
12927                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12928                 do_facet $facet zfs set recordsize=32768 $mdt
12929         done
12930
12931         # Give new values chance to reflect change
12932         sleep 2
12933
12934         echo "After recordsize change"
12935         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12936         df_after=($(df -h | grep "$MOUNT"$))
12937
12938         # For checking.
12939         echo "lfs output : ${lfs_df_after[*]}"
12940         echo "df  output : ${df_after[*]}"
12941
12942         # Verify lfs df
12943         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12944                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12945         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12946                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12947         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12948                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12949
12950         # Verify df
12951         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12952                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12953         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12954                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12955         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12956                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12957
12958         # Restore MDT recordize back to original
12959         for facet in ${mfacets//,/ }; do
12960                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12961                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12962         done
12963
12964         # Restore OST recordize back to original
12965         for facet in ${ofacets//,/ }; do
12966                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12967                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12968         done
12969
12970         return 0
12971 }
12972 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12973
12974 test_104d() {
12975         (( $RUNAS_ID != $UID )) ||
12976                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12977
12978         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12979                 skip "lustre version doesn't support lctl dl with non-root"
12980
12981         # debugfs only allows root users to access files, so the
12982         # previous move of the "devices" file to debugfs broke
12983         # "lctl dl" for non-root users. The LU-9680 Netlink
12984         # interface again allows non-root users to list devices.
12985         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12986                 error "lctl dl doesn't work for non root"
12987
12988         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12989         [ "$ost_count" -eq $OSTCOUNT ]  ||
12990                 error "lctl dl reports wrong number of OST devices"
12991
12992         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12993         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12994                 error "lctl dl reports wrong number of MDT devices"
12995 }
12996 run_test 104d "$RUNAS lctl dl test"
12997
12998 test_105a() {
12999         # doesn't work on 2.4 kernels
13000         touch $DIR/$tfile
13001         if $(flock_is_enabled); then
13002                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
13003         else
13004                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
13005         fi
13006         rm -f $DIR/$tfile
13007 }
13008 run_test 105a "flock when mounted without -o flock test ========"
13009
13010 test_105b() {
13011         touch $DIR/$tfile
13012         if $(flock_is_enabled); then
13013                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
13014         else
13015                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
13016         fi
13017         rm -f $DIR/$tfile
13018 }
13019 run_test 105b "fcntl when mounted without -o flock test ========"
13020
13021 test_105c() {
13022         touch $DIR/$tfile
13023         if $(flock_is_enabled); then
13024                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
13025         else
13026                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
13027         fi
13028         rm -f $DIR/$tfile
13029 }
13030 run_test 105c "lockf when mounted without -o flock test"
13031
13032 test_105d() { # bug 15924
13033         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13034
13035         test_mkdir $DIR/$tdir
13036         flock_is_enabled || skip_env "mount w/o flock enabled"
13037         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
13038         $LCTL set_param fail_loc=0x80000315
13039         flocks_test 2 $DIR/$tdir
13040 }
13041 run_test 105d "flock race (should not freeze) ========"
13042
13043 test_105e() { # bug 22660 && 22040
13044         flock_is_enabled || skip_env "mount w/o flock enabled"
13045
13046         touch $DIR/$tfile
13047         flocks_test 3 $DIR/$tfile
13048 }
13049 run_test 105e "Two conflicting flocks from same process"
13050
13051 wait_end() {
13052         echo $*
13053         while :; do
13054                 [ -f $TMP/${tfile}_sTOP ] && return
13055                 sleep 1
13056         done
13057 }
13058
13059 test_105f() {
13060         flock_is_enabled || skip_env "mount w/o flock enabled"
13061
13062         local pmax=$(ulimit -u)
13063         local i=0
13064         touch $DIR/$tfile
13065         [ $pmax -gt 20 ] && pmax=20
13066         for((i=0; i <= $pmax; i++)) {
13067                 wait_end "R4000, 5000" | flocks_test 6 $DIR/$tfile &
13068         }
13069         for((i=0; i <= 10; i++)) {
13070                 local locks=$(do_facet $SINGLEMDS $LCTL get_param -n \
13071                         ldlm.namespaces.mdt-${FSNAME}-MDT0000*.lock_count)
13072                 [ $locks -ge $pmax ] && break
13073                 [ $i -eq 10 ] && error "The locks cannot be added after 10 secs"
13074                 sleep 1
13075         }
13076         touch $TMP/${tfile}_sTOP
13077         wait
13078         rm -r $DIR/$tfile $TMP/${tfile}_sTOP
13079 }
13080 run_test 105f "Enqueue same range flocks"
13081
13082 test_106() { #bug 10921
13083         test_mkdir $DIR/$tdir
13084         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
13085         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
13086 }
13087 run_test 106 "attempt exec of dir followed by chown of that dir"
13088
13089 test_107() {
13090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13091
13092         CDIR=`pwd`
13093         local file=core
13094
13095         cd $DIR
13096         rm -f $file
13097
13098         local save_pattern=$(sysctl -n kernel.core_pattern)
13099         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
13100         sysctl -w kernel.core_pattern=$file
13101         sysctl -w kernel.core_uses_pid=0
13102
13103         ulimit -c unlimited
13104         sleep 60 &
13105         SLEEPPID=$!
13106
13107         sleep 1
13108
13109         kill -s 11 $SLEEPPID
13110         wait $SLEEPPID
13111         if [ -e $file ]; then
13112                 size=`stat -c%s $file`
13113                 [ $size -eq 0 ] && error "Fail to create core file $file"
13114         else
13115                 error "Fail to create core file $file"
13116         fi
13117         rm -f $file
13118         sysctl -w kernel.core_pattern=$save_pattern
13119         sysctl -w kernel.core_uses_pid=$save_uses_pid
13120         cd $CDIR
13121 }
13122 run_test 107 "Coredump on SIG"
13123
13124 test_110() {
13125         test_mkdir $DIR/$tdir
13126         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
13127         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
13128                 error "mkdir with 256 char should fail, but did not"
13129         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
13130                 error "create with 255 char failed"
13131         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
13132                 error "create with 256 char should fail, but did not"
13133
13134         ls -l $DIR/$tdir
13135         rm -rf $DIR/$tdir
13136 }
13137 run_test 110 "filename length checking"
13138
13139 test_116a() { # was previously test_116()
13140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13141         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13142         remote_mds_nodsh && skip "remote MDS with nodsh"
13143
13144         echo -n "Free space priority "
13145         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
13146                 head -n1
13147         declare -a AVAIL
13148         free_min_max
13149
13150         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
13151         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
13152         stack_trap simple_cleanup_common
13153
13154         # Check if we need to generate uneven OSTs
13155         test_mkdir -p $DIR/$tdir/OST${MINI}
13156         local FILL=$((MINV / 4))
13157         local DIFF=$((MAXV - MINV))
13158         local DIFF2=$((DIFF * 100 / MINV))
13159
13160         local threshold=$(do_facet $SINGLEMDS \
13161                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
13162         threshold=${threshold%%%}
13163         echo -n "Check for uneven OSTs: "
13164         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
13165
13166         if [[ $DIFF2 -gt $threshold ]]; then
13167                 echo "ok"
13168                 echo "Don't need to fill OST$MINI"
13169         else
13170                 # generate uneven OSTs. Write 2% over the QOS threshold value
13171                 echo "no"
13172                 DIFF=$((threshold - DIFF2 + 2))
13173                 DIFF2=$((MINV * DIFF / 100))
13174                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
13175                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
13176                         error "setstripe failed"
13177                 DIFF=$((DIFF2 / 2048))
13178                 i=0
13179                 while [ $i -lt $DIFF ]; do
13180                         i=$((i + 1))
13181                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
13182                                 bs=2M count=1 2>/dev/null
13183                         echo -n .
13184                 done
13185                 echo .
13186                 sync
13187                 sleep_maxage
13188                 free_min_max
13189         fi
13190
13191         DIFF=$((MAXV - MINV))
13192         DIFF2=$((DIFF * 100 / MINV))
13193         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
13194         if [ $DIFF2 -gt $threshold ]; then
13195                 echo "ok"
13196         else
13197                 skip "QOS imbalance criteria not met"
13198         fi
13199
13200         MINI1=$MINI
13201         MINV1=$MINV
13202         MAXI1=$MAXI
13203         MAXV1=$MAXV
13204
13205         # now fill using QOS
13206         $LFS setstripe -c 1 $DIR/$tdir
13207         FILL=$((FILL / 200))
13208         if [ $FILL -gt 600 ]; then
13209                 FILL=600
13210         fi
13211         echo "writing $FILL files to QOS-assigned OSTs"
13212         i=0
13213         while [ $i -lt $FILL ]; do
13214                 i=$((i + 1))
13215                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
13216                         count=1 2>/dev/null
13217                 echo -n .
13218         done
13219         echo "wrote $i 200k files"
13220         sync
13221         sleep_maxage
13222
13223         echo "Note: free space may not be updated, so measurements might be off"
13224         free_min_max
13225         DIFF2=$((MAXV - MINV))
13226         echo "free space delta: orig $DIFF final $DIFF2"
13227         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
13228         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
13229         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
13230         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
13231         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
13232         if [[ $DIFF -gt 0 ]]; then
13233                 FILL=$((DIFF2 * 100 / DIFF - 100))
13234                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
13235         fi
13236
13237         # Figure out which files were written where
13238         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
13239                awk '/'$MINI1': / {print $2; exit}')
13240         echo $UUID
13241         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
13242         echo "$MINC files created on smaller OST $MINI1"
13243         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
13244                awk '/'$MAXI1': / {print $2; exit}')
13245         echo $UUID
13246         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
13247         echo "$MAXC files created on larger OST $MAXI1"
13248         if [[ $MINC -gt 0 ]]; then
13249                 FILL=$((MAXC * 100 / MINC - 100))
13250                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
13251         fi
13252         [[ $MAXC -gt $MINC ]] ||
13253                 error_ignore LU-9 "stripe QOS didn't balance free space"
13254 }
13255 run_test 116a "stripe QOS: free space balance ==================="
13256
13257 test_116b() { # LU-2093
13258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13259         remote_mds_nodsh && skip "remote MDS with nodsh"
13260
13261 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
13262         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
13263                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
13264         [ -z "$old_rr" ] && skip "no QOS"
13265         do_facet $SINGLEMDS lctl set_param \
13266                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
13267         mkdir -p $DIR/$tdir
13268         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
13269         createmany -o $DIR/$tdir/f- 20 || error "can't create"
13270         do_facet $SINGLEMDS lctl set_param fail_loc=0
13271         rm -rf $DIR/$tdir
13272         do_facet $SINGLEMDS lctl set_param \
13273                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
13274 }
13275 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
13276
13277 test_117() # bug 10891
13278 {
13279         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13280
13281         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
13282         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
13283         lctl set_param fail_loc=0x21e
13284         > $DIR/$tfile || error "truncate failed"
13285         lctl set_param fail_loc=0
13286         echo "Truncate succeeded."
13287         rm -f $DIR/$tfile
13288 }
13289 run_test 117 "verify osd extend =========="
13290
13291 NO_SLOW_RESENDCOUNT=4
13292 export OLD_RESENDCOUNT=""
13293 set_resend_count () {
13294         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
13295         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
13296         lctl set_param -n $PROC_RESENDCOUNT $1
13297         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
13298 }
13299
13300 # for reduce test_118* time (b=14842)
13301 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13302
13303 # Reset async IO behavior after error case
13304 reset_async() {
13305         FILE=$DIR/reset_async
13306
13307         # Ensure all OSCs are cleared
13308         $LFS setstripe -c -1 $FILE
13309         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
13310         sync
13311         rm $FILE
13312 }
13313
13314 test_118a() #bug 11710
13315 {
13316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13317
13318         reset_async
13319
13320         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13321         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13322         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13323
13324         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13325                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13326                 return 1;
13327         fi
13328         rm -f $DIR/$tfile
13329 }
13330 run_test 118a "verify O_SYNC works =========="
13331
13332 test_118b()
13333 {
13334         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13335         remote_ost_nodsh && skip "remote OST with nodsh"
13336
13337         reset_async
13338
13339         #define OBD_FAIL_SRV_ENOENT 0x217
13340         set_nodes_failloc "$(osts_nodes)" 0x217
13341         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13342         RC=$?
13343         set_nodes_failloc "$(osts_nodes)" 0
13344         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13345         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13346                     grep -c writeback)
13347
13348         if [[ $RC -eq 0 ]]; then
13349                 error "Must return error due to dropped pages, rc=$RC"
13350                 return 1;
13351         fi
13352
13353         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13354                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13355                 return 1;
13356         fi
13357
13358         echo "Dirty pages not leaked on ENOENT"
13359
13360         # Due to the above error the OSC will issue all RPCs syncronously
13361         # until a subsequent RPC completes successfully without error.
13362         $MULTIOP $DIR/$tfile Ow4096yc
13363         rm -f $DIR/$tfile
13364
13365         return 0
13366 }
13367 run_test 118b "Reclaim dirty pages on fatal error =========="
13368
13369 test_118c()
13370 {
13371         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13372
13373         # for 118c, restore the original resend count, LU-1940
13374         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
13375                                 set_resend_count $OLD_RESENDCOUNT
13376         remote_ost_nodsh && skip "remote OST with nodsh"
13377
13378         reset_async
13379
13380         #define OBD_FAIL_OST_EROFS               0x216
13381         set_nodes_failloc "$(osts_nodes)" 0x216
13382
13383         # multiop should block due to fsync until pages are written
13384         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13385         MULTIPID=$!
13386         sleep 1
13387
13388         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13389                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13390         fi
13391
13392         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13393                     grep -c writeback)
13394         if [[ $WRITEBACK -eq 0 ]]; then
13395                 error "No page in writeback, writeback=$WRITEBACK"
13396         fi
13397
13398         set_nodes_failloc "$(osts_nodes)" 0
13399         wait $MULTIPID
13400         RC=$?
13401         if [[ $RC -ne 0 ]]; then
13402                 error "Multiop fsync failed, rc=$RC"
13403         fi
13404
13405         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13406         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13407                     grep -c writeback)
13408         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13409                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13410         fi
13411
13412         rm -f $DIR/$tfile
13413         echo "Dirty pages flushed via fsync on EROFS"
13414         return 0
13415 }
13416 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
13417
13418 # continue to use small resend count to reduce test_118* time (b=14842)
13419 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13420
13421 test_118d()
13422 {
13423         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13424         remote_ost_nodsh && skip "remote OST with nodsh"
13425
13426         reset_async
13427
13428         #define OBD_FAIL_OST_BRW_PAUSE_BULK
13429         set_nodes_failloc "$(osts_nodes)" 0x214
13430         # multiop should block due to fsync until pages are written
13431         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13432         MULTIPID=$!
13433         sleep 1
13434
13435         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13436                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13437         fi
13438
13439         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13440                     grep -c writeback)
13441         if [[ $WRITEBACK -eq 0 ]]; then
13442                 error "No page in writeback, writeback=$WRITEBACK"
13443         fi
13444
13445         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
13446         set_nodes_failloc "$(osts_nodes)" 0
13447
13448         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13449         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13450                     grep -c writeback)
13451         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13452                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13453         fi
13454
13455         rm -f $DIR/$tfile
13456         echo "Dirty pages gaurenteed flushed via fsync"
13457         return 0
13458 }
13459 run_test 118d "Fsync validation inject a delay of the bulk =========="
13460
13461 test_118f() {
13462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13463
13464         reset_async
13465
13466         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
13467         lctl set_param fail_loc=0x8000040a
13468
13469         # Should simulate EINVAL error which is fatal
13470         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13471         RC=$?
13472         if [[ $RC -eq 0 ]]; then
13473                 error "Must return error due to dropped pages, rc=$RC"
13474         fi
13475
13476         lctl set_param fail_loc=0x0
13477
13478         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13479         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13480         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13481                     grep -c writeback)
13482         if [[ $LOCKED -ne 0 ]]; then
13483                 error "Locked pages remain in cache, locked=$LOCKED"
13484         fi
13485
13486         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13487                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13488         fi
13489
13490         rm -f $DIR/$tfile
13491         echo "No pages locked after fsync"
13492
13493         reset_async
13494         return 0
13495 }
13496 run_test 118f "Simulate unrecoverable OSC side error =========="
13497
13498 test_118g() {
13499         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13500
13501         reset_async
13502
13503         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
13504         lctl set_param fail_loc=0x406
13505
13506         # simulate local -ENOMEM
13507         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13508         RC=$?
13509
13510         lctl set_param fail_loc=0
13511         if [[ $RC -eq 0 ]]; then
13512                 error "Must return error due to dropped pages, rc=$RC"
13513         fi
13514
13515         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13516         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13517         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13518                         grep -c writeback)
13519         if [[ $LOCKED -ne 0 ]]; then
13520                 error "Locked pages remain in cache, locked=$LOCKED"
13521         fi
13522
13523         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13524                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13525         fi
13526
13527         rm -f $DIR/$tfile
13528         echo "No pages locked after fsync"
13529
13530         reset_async
13531         return 0
13532 }
13533 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
13534
13535 test_118h() {
13536         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13537         remote_ost_nodsh && skip "remote OST with nodsh"
13538
13539         reset_async
13540
13541         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13542         set_nodes_failloc "$(osts_nodes)" 0x20e
13543         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13544         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13545         RC=$?
13546
13547         set_nodes_failloc "$(osts_nodes)" 0
13548         if [[ $RC -eq 0 ]]; then
13549                 error "Must return error due to dropped pages, rc=$RC"
13550         fi
13551
13552         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13553         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13554         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13555                     grep -c writeback)
13556         if [[ $LOCKED -ne 0 ]]; then
13557                 error "Locked pages remain in cache, locked=$LOCKED"
13558         fi
13559
13560         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13561                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13562         fi
13563
13564         rm -f $DIR/$tfile
13565         echo "No pages locked after fsync"
13566
13567         return 0
13568 }
13569 run_test 118h "Verify timeout in handling recoverables errors  =========="
13570
13571 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13572
13573 test_118i() {
13574         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13575         remote_ost_nodsh && skip "remote OST with nodsh"
13576
13577         reset_async
13578
13579         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13580         set_nodes_failloc "$(osts_nodes)" 0x20e
13581
13582         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13583         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13584         PID=$!
13585         sleep 5
13586         set_nodes_failloc "$(osts_nodes)" 0
13587
13588         wait $PID
13589         RC=$?
13590         if [[ $RC -ne 0 ]]; then
13591                 error "got error, but should be not, rc=$RC"
13592         fi
13593
13594         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13595         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13596         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13597         if [[ $LOCKED -ne 0 ]]; then
13598                 error "Locked pages remain in cache, locked=$LOCKED"
13599         fi
13600
13601         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13602                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13603         fi
13604
13605         rm -f $DIR/$tfile
13606         echo "No pages locked after fsync"
13607
13608         return 0
13609 }
13610 run_test 118i "Fix error before timeout in recoverable error  =========="
13611
13612 [ "$SLOW" = "no" ] && set_resend_count 4
13613
13614 test_118j() {
13615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13616         remote_ost_nodsh && skip "remote OST with nodsh"
13617
13618         reset_async
13619
13620         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
13621         set_nodes_failloc "$(osts_nodes)" 0x220
13622
13623         # return -EIO from OST
13624         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13625         RC=$?
13626         set_nodes_failloc "$(osts_nodes)" 0x0
13627         if [[ $RC -eq 0 ]]; then
13628                 error "Must return error due to dropped pages, rc=$RC"
13629         fi
13630
13631         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13632         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13633         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13634         if [[ $LOCKED -ne 0 ]]; then
13635                 error "Locked pages remain in cache, locked=$LOCKED"
13636         fi
13637
13638         # in recoverable error on OST we want resend and stay until it finished
13639         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13640                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13641         fi
13642
13643         rm -f $DIR/$tfile
13644         echo "No pages locked after fsync"
13645
13646         return 0
13647 }
13648 run_test 118j "Simulate unrecoverable OST side error =========="
13649
13650 test_118k()
13651 {
13652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13653         remote_ost_nodsh && skip "remote OSTs with nodsh"
13654
13655         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13656         set_nodes_failloc "$(osts_nodes)" 0x20e
13657         test_mkdir $DIR/$tdir
13658
13659         for ((i=0;i<10;i++)); do
13660                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
13661                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
13662                 SLEEPPID=$!
13663                 sleep 0.500s
13664                 kill $SLEEPPID
13665                 wait $SLEEPPID
13666         done
13667
13668         set_nodes_failloc "$(osts_nodes)" 0
13669         rm -rf $DIR/$tdir
13670 }
13671 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
13672
13673 test_118l() # LU-646
13674 {
13675         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13676
13677         test_mkdir $DIR/$tdir
13678         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
13679         rm -rf $DIR/$tdir
13680 }
13681 run_test 118l "fsync dir"
13682
13683 test_118m() # LU-3066
13684 {
13685         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13686
13687         test_mkdir $DIR/$tdir
13688         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
13689         rm -rf $DIR/$tdir
13690 }
13691 run_test 118m "fdatasync dir ========="
13692
13693 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13694
13695 test_118n()
13696 {
13697         local begin
13698         local end
13699
13700         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13701         remote_ost_nodsh && skip "remote OSTs with nodsh"
13702
13703         # Sleep to avoid a cached response.
13704         #define OBD_STATFS_CACHE_SECONDS 1
13705         sleep 2
13706
13707         # Inject a 10 second delay in the OST_STATFS handler.
13708         #define OBD_FAIL_OST_STATFS_DELAY 0x242
13709         set_nodes_failloc "$(osts_nodes)" 0x242
13710
13711         begin=$SECONDS
13712         stat --file-system $MOUNT > /dev/null
13713         end=$SECONDS
13714
13715         set_nodes_failloc "$(osts_nodes)" 0
13716
13717         if ((end - begin > 20)); then
13718             error "statfs took $((end - begin)) seconds, expected 10"
13719         fi
13720 }
13721 run_test 118n "statfs() sends OST_STATFS requests in parallel"
13722
13723 test_119a() # bug 11737
13724 {
13725         BSIZE=$((512 * 1024))
13726         directio write $DIR/$tfile 0 1 $BSIZE
13727         # We ask to read two blocks, which is more than a file size.
13728         # directio will indicate an error when requested and actual
13729         # sizes aren't equeal (a normal situation in this case) and
13730         # print actual read amount.
13731         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
13732         if [ "$NOB" != "$BSIZE" ]; then
13733                 error "read $NOB bytes instead of $BSIZE"
13734         fi
13735         rm -f $DIR/$tfile
13736 }
13737 run_test 119a "Short directIO read must return actual read amount"
13738
13739 test_119b() # bug 11737
13740 {
13741         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13742
13743         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
13744         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
13745         sync
13746         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
13747                 error "direct read failed"
13748         rm -f $DIR/$tfile
13749 }
13750 run_test 119b "Sparse directIO read must return actual read amount"
13751
13752 test_119c() # bug 13099
13753 {
13754         BSIZE=1048576
13755         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
13756         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
13757         rm -f $DIR/$tfile
13758 }
13759 run_test 119c "Testing for direct read hitting hole"
13760
13761 # Note: test 119d was removed, skipping 119d for new tests to avoid polluting
13762 # Maloo test history
13763
13764 test_119e()
13765 {
13766         (( $MDS1_VERSION >= $(version_code 2.15.58) )) ||
13767                 skip "Need server version at least 2.15.58"
13768         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13769
13770         local stripe_size=$((1024 * 1024)) #1 MiB
13771         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13772         local file_size=$((25 * stripe_size))
13773         local bsizes
13774
13775         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13776         stack_trap "rm -f $DIR/$tfile*"
13777
13778         # Just a bit bigger than the largest size in the test set below
13779         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13780                 error "buffered i/o to create file failed"
13781
13782         # trivial test of unaligned DIO
13783         dd if=$DIR/$tfile.1 bs=4095 of=$DIR/$tfile.2 count=4 \
13784                 iflag=direct oflag=direct ||
13785                 error "trivial unaligned dio failed"
13786
13787         # Test of disabling unaligned DIO support
13788         $LCTL set_param llite.*.unaligned_dio=0
13789         stack_trap "$LCTL set_param llite.*.unaligned_dio=1"
13790         echo "testing disabling unaligned DIO - 'invalid argument' expected:"
13791         dd if=$DIR/$tfile.1 bs=1024 of=$DIR/$tfile.2 count=4 \
13792                 iflag=direct oflag=direct &&
13793                 error "unaligned dio succeeded when disabled"
13794         $LCTL set_param llite.*.unaligned_dio=1
13795
13796         # Clean up before next part of test
13797         rm -f $DIR/$tfile.2
13798
13799         if zfs_or_rotational; then
13800                 # DIO on ZFS can take up to 2 seconds per IO
13801                 # rotational is better, but still slow.
13802                 # Limit testing on those media to larger sizes
13803                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13804                         $((stripe_size + 1024))"
13805         else
13806                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13807                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13808                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13809                         $((stripe_size - 1)) $stripe_size \
13810                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13811                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13812         fi
13813
13814         for bs in $bsizes; do
13815                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13816                 echo "Read/write with DIO at size $bs"
13817                 # Read and write with DIO from source to dest
13818                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 \
13819                         iflag=direct oflag=direct ||
13820                         error "dio failed"
13821
13822                 ls -la $DIR/$tfile.1 $DIR/$tfile.2
13823                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13824                         error "size incorrect, file copy read/write bsize: $bs"
13825                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13826                         error "files differ, bsize $bs"
13827                 rm -f $DIR/$tfile.2
13828         done
13829 }
13830 run_test 119e "Basic tests of dio read and write at various sizes"
13831
13832 test_119f()
13833 {
13834         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13835
13836         local stripe_size=$((1024 * 1024)) #1 MiB
13837         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13838         local file_size=$((25 * stripe_size))
13839         local bsizes
13840
13841         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13842         stack_trap "rm -f $DIR/$tfile*"
13843
13844         # Just a bit bigger than the largest size in the test set below
13845         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13846                 error "buffered i/o to create file failed"
13847
13848         if zfs_or_rotational; then
13849                 # DIO on ZFS can take up to 2 seconds per IO
13850                 # rotational is better, but still slow.
13851                 # Limit testing on those media to larger sizes
13852                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13853                         $((stripe_size + 1024))"
13854         else
13855                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13856                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13857                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13858                         $((stripe_size - 1)) $stripe_size \
13859                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13860                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13861         fi
13862
13863         for bs in $bsizes; do
13864                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13865                 # Read and write with DIO from source to dest in two
13866                 # threads - should give correct copy of file
13867
13868                 echo "bs: $bs"
13869                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13870                         oflag=direct conv=notrunc &
13871                 pid_dio1=$!
13872                 # Note block size is different here for a more interesting race
13873                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
13874                         iflag=direct oflag=direct conv=notrunc &
13875                 pid_dio2=$!
13876                 wait $pid_dio1
13877                 rc1=$?
13878                 wait $pid_dio2
13879                 rc2=$?
13880                 if (( rc1 != 0 )); then
13881                         error "dio copy 1 w/bsize $bs failed: $rc1"
13882                 fi
13883                 if (( rc2 != 0 )); then
13884                         error "dio copy 2 w/bsize $bs failed: $rc2"
13885                 fi
13886
13887
13888                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13889                         error "size incorrect, file copy read/write bsize: $bs"
13890                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13891                         error "files differ, bsize $bs"
13892                 rm -f $DIR/$tfile.2
13893         done
13894 }
13895 run_test 119f "dio vs dio race"
13896
13897 test_119g()
13898 {
13899         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13900
13901         local stripe_size=$((1024 * 1024)) #1 MiB
13902         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13903         local file_size=$((25 * stripe_size))
13904         local bsizes
13905
13906         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13907         stack_trap "rm -f $DIR/$tfile*"
13908
13909         # Just a bit bigger than the largest size in the test set below
13910         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13911                 error "buffered i/o to create file failed"
13912
13913         if zfs_or_rotational; then
13914                 # DIO on ZFS can take up to 2 seconds per IO
13915                 # rotational is better, but still slow.
13916                 # Limit testing on those media to larger sizes
13917                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13918                         $((stripe_size + 1024))"
13919         else
13920                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13921                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13922                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13923                         $((stripe_size - 1)) $stripe_size \
13924                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13925                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13926         fi
13927
13928         for bs in $bsizes; do
13929                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13930                 echo "bs: $bs"
13931                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13932                         oflag=direct conv=notrunc &
13933                 pid_dio1=$!
13934                 # Buffered I/O with similar but not the same block size
13935                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 &
13936                 pid_bio2=$!
13937                 wait $pid_dio1
13938                 rc1=$?
13939                 wait $pid_bio2
13940                 rc2=$?
13941                 if (( rc1 != 0 )); then
13942                         error "dio copy 1 w/bsize $bs failed: $rc1"
13943                 fi
13944                 if (( rc2 != 0 )); then
13945                         error "buffered copy 2 w/bsize $bs failed: $rc2"
13946                 fi
13947
13948                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13949                         error "size incorrect"
13950                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13951                         error "files differ, bsize $bs"
13952                 rm -f $DIR/$tfile.2
13953         done
13954 }
13955 run_test 119g "dio vs buffered I/O race"
13956
13957 test_119h()
13958 {
13959         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13960
13961         local stripe_size=$((1024 * 1024)) #1 MiB
13962         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13963         local file_size=$((25 * stripe_size))
13964         local bsizes
13965
13966         stack_trap "rm -f $DIR/$tfile.*"
13967
13968         if zfs_or_rotational; then
13969                 # DIO on ZFS can take up to 2 seconds per IO
13970                 # rotational is better, but still slow.
13971                 # Limit testing on those media to larger sizes
13972                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13973                         $((stripe_size + 1024))"
13974         else
13975                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13976                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13977                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13978                         $((stripe_size - 1)) $stripe_size \
13979                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13980                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13981         fi
13982
13983         for bs in $bsizes; do
13984                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13985                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13986                 echo "unaligned writes of blocksize: $bs"
13987                 # Write a file with unaligned DIO and regular DIO, and compare
13988                 # them
13989                 # with 'u', multiop randomly unaligns the io from the buffer
13990                 $MULTIOP $DIR/$tfile.1 \
13991                 oO_CREAT:O_RDWR:O_DIRECT:wu${bs}wu${bs}wu${bs}wu${bs}wu${bs} ||
13992                         error "multiop memory unaligned write failed, $bs"
13993                 $MULTIOP $DIR/$tfile.2 \
13994                 oO_CREAT:O_RDWR:O_DIRECT:w${bs}w${bs}w${bs}w${bs}w${bs} ||
13995                         error "multiop memory aligned write failed, $bs"
13996
13997                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13998                         error "files differ, bsize $bs"
13999                 rm -f $DIR/$tfile.*
14000         done
14001
14002         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
14003         dd if=/dev/zero bs=$((stripe_size * 5)) of=$DIR/$tfile.1 count=5 ||
14004                 error "dd to create source file for read failed"
14005
14006         # Just a few quick tests to make sure unaligned DIO reads don't crash
14007         for bs in $bsizes; do
14008
14009                 echo "unaligned reads of blocksize: $bs"
14010                 # with 'u', multiop randomly unaligns the io from the buffer
14011                 $MULTIOP $DIR/$tfile.1 \
14012                 oO_CREAT:O_RDWR:O_DIRECT:ru${bs}ru${bs}ru${bs}ru${bs}ru${bs} ||
14013                         error "multiop memory unaligned read failed, $bs"
14014
14015         done
14016         rm -f $DIR/$tfile*
14017 }
14018 run_test 119h "basic tests of memory unaligned dio"
14019
14020 # aiocp with the '-a' option makes testing memory unaligned aio trivial
14021 test_119i()
14022 {
14023         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14024         which aiocp || skip_env "no aiocp installed"
14025
14026         local stripe_size=$((1024 * 1024)) #1 MiB
14027         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
14028         local file_size=$((25 * stripe_size))
14029         local bsizes
14030
14031         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
14032         stack_trap "rm -f $DIR/$tfile.*"
14033
14034         # Just a bit bigger than the largest size in the test set below
14035         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
14036                 error "buffered i/o to create file failed"
14037
14038         if zfs_or_rotational; then
14039                 # DIO on ZFS can take up to 2 seconds per IO
14040                 # rotational is better, but still slow.
14041                 # Limit testing on those media to larger sizes
14042                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
14043                         $((stripe_size + 1024))"
14044         else
14045                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
14046                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
14047                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
14048                         $((stripe_size - 1)) $stripe_size \
14049                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
14050                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
14051         fi
14052
14053         # Do page aligned and NOT page aligned AIO
14054         for align in 8 512 $((PAGE_SIZE)); do
14055         # Deliberately includes a few aligned sizes
14056         for bs in $bsizes; do
14057                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
14058
14059                 echo "bs: $bs, align: $align, file_size $file_size"
14060                 aiocp -a $align -b $bs -s $file_size -f O_DIRECT \
14061                         $DIR/$tfile.1 $DIR/$tfile.2 ||
14062                         error "unaligned aio failed, bs: $bs, align: $align"
14063
14064                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
14065                         error "size incorrect"
14066                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
14067                         error "files differ"
14068                 rm -f $DIR/$tfile.2
14069         done
14070         done
14071 }
14072 run_test 119i "test unaligned aio at varying sizes"
14073
14074 test_119j()
14075 {
14076         (( $LINUX_VERSION_CODE > $(version_code 4.5.0) )) ||
14077                 skip "needs kernel > 4.5.0 for ki_flags support"
14078
14079         local rpcs
14080         dd if=/dev/urandom of=$DIR/$tfile bs=8 count=1 || error "(0) dd failed"
14081         sync
14082         $LCTL set_param -n osc.*.rpc_stats=0
14083         # Read from page cache, does not generate an rpc
14084         dd if=$DIR/$tfile of=/dev/null bs=8 count=1 || error "(1) dd failed"
14085         $LCTL get_param osc.*.rpc_stats
14086         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
14087                 sed -n '/pages per rpc/,/^$/p' |
14088                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
14089                 END { print reads,writes }'))
14090         [[ ${rpcs[0]} == 0 ]] ||
14091                 error "(3) ${rpcs[0]} != 0 read RPCs"
14092
14093         # Test hybrid IO read
14094         # Force next BIO as DIO
14095         # This forces an RPC to the server
14096         #define OBD_FAIL_LLITE_FORCE_BIO_AS_DIO 0x1429
14097         $LCTL set_param fail_loc=0x1429
14098         dd if=$DIR/$tfile of=/dev/null bs=8 count=1 || error "(4) dd failed"
14099         $LCTL get_param osc.*.rpc_stats
14100         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
14101                 sed -n '/pages per rpc/,/^$/p' |
14102                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
14103                 END { print reads,writes }'))
14104         [[ ${rpcs[0]} == 1 ]] ||
14105                 error "(5) ${rpcs[0]} != 1 read RPCs"
14106
14107         # Test hybrid IO write
14108         #define OBD_FAIL_LLITE_FORCE_BIO_AS_DIO 0x1429
14109         $LCTL set_param fail_loc=0x1429
14110         #NB: We do not check for 0 write RPCs in the BIO case because that
14111         # would make the test racey vs cache flushing
14112         # but the DIO case is guaranteed to generate 1 write RPC
14113         dd if=/dev/zero of=$DIR/$tfile bs=8 count=1 || error "(6) dd failed"
14114         $LCTL get_param osc.*.rpc_stats
14115         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
14116                 sed -n '/pages per rpc/,/^$/p' |
14117                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
14118                 END { print reads,writes }'))
14119         [[ ${rpcs[1]} == 1 ]] ||
14120                 error "(7) ${rpcs[0]} != 1 read RPCs"
14121 }
14122 run_test 119j "basic tests of hybrid IO switching"
14123
14124 test_120a() {
14125         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14126         remote_mds_nodsh && skip "remote MDS with nodsh"
14127         test_mkdir -i0 -c1 $DIR/$tdir
14128         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14129                 skip_env "no early lock cancel on server"
14130
14131         lru_resize_disable mdc
14132         lru_resize_disable osc
14133         cancel_lru_locks mdc
14134         # asynchronous object destroy at MDT could cause bl ast to client
14135         cancel_lru_locks osc
14136
14137         stat $DIR/$tdir > /dev/null
14138         can1=$(do_facet mds1 \
14139                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14140                awk '/ldlm_cancel/ {print $2}')
14141         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14142                awk '/ldlm_bl_callback/ {print $2}')
14143         test_mkdir -i0 -c1 $DIR/$tdir/d1
14144         can2=$(do_facet mds1 \
14145                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14146                awk '/ldlm_cancel/ {print $2}')
14147         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14148                awk '/ldlm_bl_callback/ {print $2}')
14149         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14150         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14151         lru_resize_enable mdc
14152         lru_resize_enable osc
14153 }
14154 run_test 120a "Early Lock Cancel: mkdir test"
14155
14156 test_120b() {
14157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14158         remote_mds_nodsh && skip "remote MDS with nodsh"
14159         test_mkdir $DIR/$tdir
14160         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14161                 skip_env "no early lock cancel on server"
14162
14163         lru_resize_disable mdc
14164         lru_resize_disable osc
14165         cancel_lru_locks mdc
14166         stat $DIR/$tdir > /dev/null
14167         can1=$(do_facet $SINGLEMDS \
14168                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14169                awk '/ldlm_cancel/ {print $2}')
14170         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14171                awk '/ldlm_bl_callback/ {print $2}')
14172         touch $DIR/$tdir/f1
14173         can2=$(do_facet $SINGLEMDS \
14174                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14175                awk '/ldlm_cancel/ {print $2}')
14176         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14177                awk '/ldlm_bl_callback/ {print $2}')
14178         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14179         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14180         lru_resize_enable mdc
14181         lru_resize_enable osc
14182 }
14183 run_test 120b "Early Lock Cancel: create test"
14184
14185 test_120c() {
14186         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14187         remote_mds_nodsh && skip "remote MDS with nodsh"
14188         test_mkdir -i0 -c1 $DIR/$tdir
14189         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14190                 skip "no early lock cancel on server"
14191
14192         lru_resize_disable mdc
14193         lru_resize_disable osc
14194         test_mkdir -i0 -c1 $DIR/$tdir/d1
14195         test_mkdir -i0 -c1 $DIR/$tdir/d2
14196         touch $DIR/$tdir/d1/f1
14197         cancel_lru_locks mdc
14198         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
14199         can1=$(do_facet mds1 \
14200                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14201                awk '/ldlm_cancel/ {print $2}')
14202         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14203                awk '/ldlm_bl_callback/ {print $2}')
14204         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
14205         can2=$(do_facet mds1 \
14206                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14207                awk '/ldlm_cancel/ {print $2}')
14208         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14209                awk '/ldlm_bl_callback/ {print $2}')
14210         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14211         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14212         lru_resize_enable mdc
14213         lru_resize_enable osc
14214 }
14215 run_test 120c "Early Lock Cancel: link test"
14216
14217 test_120d() {
14218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14219         remote_mds_nodsh && skip "remote MDS with nodsh"
14220         test_mkdir -i0 -c1 $DIR/$tdir
14221         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14222                 skip_env "no early lock cancel on server"
14223
14224         lru_resize_disable mdc
14225         lru_resize_disable osc
14226         touch $DIR/$tdir
14227         cancel_lru_locks mdc
14228         stat $DIR/$tdir > /dev/null
14229         can1=$(do_facet mds1 \
14230                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14231                awk '/ldlm_cancel/ {print $2}')
14232         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14233                awk '/ldlm_bl_callback/ {print $2}')
14234         chmod a+x $DIR/$tdir
14235         can2=$(do_facet mds1 \
14236                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14237                awk '/ldlm_cancel/ {print $2}')
14238         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14239                awk '/ldlm_bl_callback/ {print $2}')
14240         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14241         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14242         lru_resize_enable mdc
14243         lru_resize_enable osc
14244 }
14245 run_test 120d "Early Lock Cancel: setattr test"
14246
14247 test_120e() {
14248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14249         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14250                 skip_env "no early lock cancel on server"
14251         remote_mds_nodsh && skip "remote MDS with nodsh"
14252
14253         local dlmtrace_set=false
14254
14255         test_mkdir -i0 -c1 $DIR/$tdir
14256         lru_resize_disable mdc
14257         lru_resize_disable osc
14258         ! $LCTL get_param debug | grep -q dlmtrace &&
14259                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
14260         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
14261         cancel_lru_locks mdc
14262         cancel_lru_locks osc
14263         dd if=$DIR/$tdir/f1 of=/dev/null
14264         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
14265         # XXX client can not do early lock cancel of OST lock
14266         # during unlink (LU-4206), so cancel osc lock now.
14267         sleep 2
14268         cancel_lru_locks osc
14269         can1=$(do_facet mds1 \
14270                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14271                awk '/ldlm_cancel/ {print $2}')
14272         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14273                awk '/ldlm_bl_callback/ {print $2}')
14274         unlink $DIR/$tdir/f1
14275         sleep 5
14276         can2=$(do_facet mds1 \
14277                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14278                awk '/ldlm_cancel/ {print $2}')
14279         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14280                awk '/ldlm_bl_callback/ {print $2}')
14281         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
14282                 $LCTL dk $TMP/cancel.debug.txt
14283         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
14284                 $LCTL dk $TMP/blocking.debug.txt
14285         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
14286         lru_resize_enable mdc
14287         lru_resize_enable osc
14288 }
14289 run_test 120e "Early Lock Cancel: unlink test"
14290
14291 test_120f() {
14292         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14293         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14294                 skip_env "no early lock cancel on server"
14295         remote_mds_nodsh && skip "remote MDS with nodsh"
14296
14297         test_mkdir -i0 -c1 $DIR/$tdir
14298         lru_resize_disable mdc
14299         lru_resize_disable osc
14300         test_mkdir -i0 -c1 $DIR/$tdir/d1
14301         test_mkdir -i0 -c1 $DIR/$tdir/d2
14302         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
14303         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
14304         cancel_lru_locks mdc
14305         cancel_lru_locks osc
14306         dd if=$DIR/$tdir/d1/f1 of=/dev/null
14307         dd if=$DIR/$tdir/d2/f2 of=/dev/null
14308         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
14309         # XXX client can not do early lock cancel of OST lock
14310         # during rename (LU-4206), so cancel osc lock now.
14311         sleep 2
14312         cancel_lru_locks osc
14313         can1=$(do_facet mds1 \
14314                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14315                awk '/ldlm_cancel/ {print $2}')
14316         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14317                awk '/ldlm_bl_callback/ {print $2}')
14318         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
14319         sleep 5
14320         can2=$(do_facet mds1 \
14321                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14322                awk '/ldlm_cancel/ {print $2}')
14323         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14324                awk '/ldlm_bl_callback/ {print $2}')
14325         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14326         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14327         lru_resize_enable mdc
14328         lru_resize_enable osc
14329 }
14330 run_test 120f "Early Lock Cancel: rename test"
14331
14332 test_120g() {
14333         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14334         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14335                 skip_env "no early lock cancel on server"
14336         remote_mds_nodsh && skip "remote MDS with nodsh"
14337
14338         lru_resize_disable mdc
14339         lru_resize_disable osc
14340         count=10000
14341         echo create $count files
14342         test_mkdir $DIR/$tdir
14343         cancel_lru_locks mdc
14344         cancel_lru_locks osc
14345         t0=$(date +%s)
14346
14347         can0=$(do_facet $SINGLEMDS \
14348                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14349                awk '/ldlm_cancel/ {print $2}')
14350         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14351                awk '/ldlm_bl_callback/ {print $2}')
14352         createmany -o $DIR/$tdir/f $count
14353         sync
14354         can1=$(do_facet $SINGLEMDS \
14355                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14356                awk '/ldlm_cancel/ {print $2}')
14357         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14358                awk '/ldlm_bl_callback/ {print $2}')
14359         t1=$(date +%s)
14360         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
14361         echo rm $count files
14362         rm -r $DIR/$tdir
14363         sync
14364         can2=$(do_facet $SINGLEMDS \
14365                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14366                awk '/ldlm_cancel/ {print $2}')
14367         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14368                awk '/ldlm_bl_callback/ {print $2}')
14369         t2=$(date +%s)
14370         echo total: $count removes in $((t2-t1))
14371         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
14372         sleep 2
14373         # wait for commitment of removal
14374         lru_resize_enable mdc
14375         lru_resize_enable osc
14376 }
14377 run_test 120g "Early Lock Cancel: performance test"
14378
14379 test_121() { #bug #10589
14380         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14381
14382         rm -rf $DIR/$tfile
14383         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
14384 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
14385         lctl set_param fail_loc=0x310
14386         cancel_lru_locks osc > /dev/null
14387         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
14388         lctl set_param fail_loc=0
14389         [[ $reads -eq $writes ]] ||
14390                 error "read $reads blocks, must be $writes blocks"
14391 }
14392 run_test 121 "read cancel race ========="
14393
14394 test_123a_base() { # was test 123, statahead(bug 11401)
14395         local lsx="$1"
14396
14397         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
14398
14399         SLOWOK=0
14400         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
14401                 log "testing UP system. Performance may be lower than expected."
14402                 SLOWOK=1
14403         fi
14404         running_in_vm && SLOWOK=1
14405
14406         $LCTL set_param mdc.*.batch_stats=0
14407
14408         rm -rf $DIR/$tdir
14409         test_mkdir $DIR/$tdir
14410         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
14411         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
14412         MULT=10
14413         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
14414                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
14415
14416                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
14417                 lctl set_param -n llite.*.statahead_max 0
14418                 lctl get_param llite.*.statahead_max
14419                 cancel_lru_locks mdc
14420                 cancel_lru_locks osc
14421                 stime=$(date +%s)
14422                 time $lsx $DIR/$tdir | wc -l
14423                 etime=$(date +%s)
14424                 delta=$((etime - stime))
14425                 log "$lsx $i files without statahead: $delta sec"
14426                 lctl set_param llite.*.statahead_max=$max
14427
14428                 swrong=$(lctl get_param -n llite.*.statahead_stats |
14429                          awk '/statahead.wrong:/ { print $NF }')
14430                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
14431                 cancel_lru_locks mdc
14432                 cancel_lru_locks osc
14433                 stime=$(date +%s)
14434                 time $lsx $DIR/$tdir | wc -l
14435                 etime=$(date +%s)
14436                 delta_sa=$((etime - stime))
14437                 log "$lsx $i files with statahead: $delta_sa sec"
14438                 lctl get_param -n llite.*.statahead_stats
14439                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
14440                          awk '/statahead.wrong:/ { print $NF }')
14441
14442                 [[ $swrong -lt $ewrong ]] &&
14443                         log "statahead was stopped, maybe too many locks held!"
14444                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
14445
14446                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
14447                         max=$(lctl get_param -n llite.*.statahead_max |
14448                                 head -n 1)
14449                         lctl set_param -n llite.*.statahead_max 0
14450                         lctl get_param llite.*.statahead_max
14451                         cancel_lru_locks mdc
14452                         cancel_lru_locks osc
14453                         stime=$(date +%s)
14454                         time $lsx $DIR/$tdir | wc -l
14455                         etime=$(date +%s)
14456                         delta=$((etime - stime))
14457                         log "$lsx $i files again without statahead: $delta sec"
14458                         lctl set_param llite.*.statahead_max=$max
14459                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
14460                                 if [ $SLOWOK -eq 0 ]; then
14461                                         error "$lsx $i files is slower with statahead!"
14462                                 else
14463                                         log "$lsx $i files is slower with statahead!"
14464                                 fi
14465                                 break
14466                         fi
14467                 fi
14468
14469                 [ $delta -gt 20 ] && break
14470                 [ $delta -gt 8 ] && MULT=$((50 / delta))
14471                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
14472         done
14473         log "$lsx done"
14474
14475         stime=$(date +%s)
14476         rm -r $DIR/$tdir
14477         sync
14478         etime=$(date +%s)
14479         delta=$((etime - stime))
14480         log "rm -r $DIR/$tdir/: $delta seconds"
14481         log "rm done"
14482         lctl get_param -n llite.*.statahead_stats
14483         $LCTL get_param mdc.*.batch_stats
14484 }
14485
14486 test_123aa() {
14487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14488
14489         test_123a_base "ls -l"
14490 }
14491 run_test 123aa "verify statahead work"
14492
14493 test_123ab() {
14494         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14495
14496         statx_supported || skip_env "Test must be statx() syscall supported"
14497
14498         test_123a_base "$STATX -l"
14499 }
14500 run_test 123ab "verify statahead work by using statx"
14501
14502 test_123ac() {
14503         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14504
14505         statx_supported || skip_env "Test must be statx() syscall supported"
14506
14507         local rpcs_before
14508         local rpcs_after
14509         local agl_before
14510         local agl_after
14511
14512         cancel_lru_locks $OSC
14513         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14514         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
14515                      awk '/agl.total:/ { print $NF }')
14516         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
14517         test_123a_base "$STATX --cached=always -D"
14518         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
14519                     awk '/agl.total:/ { print $NF }')
14520         [ $agl_before -eq $agl_after ] ||
14521                 error "Should not trigger AGL thread - $agl_before:$agl_after"
14522         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14523         [ $rpcs_after -eq $rpcs_before ] ||
14524                 error "$STATX should not send glimpse RPCs to $OSC"
14525 }
14526 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
14527
14528 test_batch_statahead() {
14529         local max=$1
14530         local batch_max=$2
14531         local num=10000
14532         local batch_rpcs
14533         local unbatch_rpcs
14534         local hit_total
14535
14536         echo -e "\nbatching: statahead_max=$max statahead_batch_max=$batch_max"
14537         $LCTL set_param mdc.*.batch_stats=0
14538         $LCTL set_param llite.*.statahead_max=$max
14539         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14540         # Verify that batched statahead is faster than one without statahead
14541         test_123a_base "ls -l"
14542
14543         stack_trap "rm -rf $DIR/$tdir" EXIT
14544         mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
14545         createmany -o $DIR/$tdir/$tfile $num || error "failed to create files"
14546
14547         # unbatched statahead
14548         $LCTL set_param llite.*.statahead_batch_max=0
14549         $LCTL set_param llite.*.statahead_stats=clear
14550         $LCTL set_param mdc.*.stats=clear
14551         cancel_lru_locks mdc
14552         cancel_lru_locks osc
14553         time ls -l $DIR/$tdir | wc -l
14554         unbatch_rpcs=$(calc_stats mdc.*.stats ldlm_ibits_enqueue)
14555         wait_update_facet client "pgrep ll_sa" "" 35 ||
14556                 error "ll_sa thread is still running"
14557         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14558                     awk '/hit.total:/ { print $NF }')
14559         # hit ratio should be larger than 75% (7500).
14560         (( $hit_total > 7500 )) ||
14561                 error "unbatched statahead hit count ($hit_total) is too low"
14562
14563         # batched statahead
14564         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14565         $LCTL set_param llite.*.statahead_stats=clear
14566         $LCTL set_param mdc.*.batch_stats=clear
14567         $LCTL set_param mdc.*.stats=clear
14568         cancel_lru_locks mdc
14569         cancel_lru_locks osc
14570         time ls -l $DIR/$tdir | wc -l
14571         batch_rpcs=$(calc_stats mdc.*.stats mds_batch)
14572         # wait for statahead thread to quit and update statahead stats
14573         wait_update_facet client "pgrep ll_sa" "" 35 ||
14574                 error "ll_sa thread is still running"
14575         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14576                     awk '/hit.total:/ { print $NF }')
14577         # hit ratio should be larger than 75% (7500).
14578         (( $hit_total > 7500 )) ||
14579                 error "batched statahead hit count ($hit_total) is too low"
14580
14581         echo "unbatched RPCs: $unbatch_rpcs, batched RPCs: $batch_rpcs"
14582         (( $unbatch_rpcs > $batch_rpcs )) ||
14583                 error "batched statahead does not reduce RPC count"
14584         $LCTL get_param mdc.*.batch_stats
14585 }
14586
14587 test_123ad() {
14588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14589
14590         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
14591                 skip "Need server version at least 2.15.53"
14592
14593         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14594                 skip "Server does not support batch RPC"
14595
14596         local max
14597         local batch_max
14598
14599         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14600         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14601
14602         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14603         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14604
14605         test_batch_statahead 32 32
14606         test_batch_statahead 2048 256
14607 }
14608 run_test 123ad "Verify batching statahead works correctly"
14609
14610 test_123b () { # statahead(bug 15027)
14611         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14612
14613         test_mkdir $DIR/$tdir
14614         createmany -o $DIR/$tdir/$tfile-%d 1000
14615
14616         cancel_lru_locks mdc
14617         cancel_lru_locks osc
14618
14619 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
14620         lctl set_param fail_loc=0x80000803
14621         ls -lR $DIR/$tdir > /dev/null
14622         log "ls done"
14623         lctl set_param fail_loc=0x0
14624         lctl get_param -n llite.*.statahead_stats
14625         rm -r $DIR/$tdir
14626         sync
14627
14628 }
14629 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
14630
14631 test_123c() {
14632         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
14633
14634         test_mkdir -i 0 -c 1 $DIR/$tdir.0
14635         test_mkdir -i 1 -c 1 $DIR/$tdir.1
14636         touch $DIR/$tdir.1/{1..3}
14637         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
14638
14639         remount_client $MOUNT
14640
14641         $MULTIOP $DIR/$tdir.0 Q
14642
14643         # let statahead to complete
14644         ls -l $DIR/$tdir.0 > /dev/null
14645
14646         testid=$(echo $TESTNAME | tr '_' ' ')
14647         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
14648                 error "statahead warning" || true
14649 }
14650 run_test 123c "Can not initialize inode warning on DNE statahead"
14651
14652 test_123d() {
14653         local num=100
14654         local swrong
14655         local ewrong
14656
14657         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
14658         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
14659                 error "setdirstripe $DIR/$tdir failed"
14660         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
14661         remount_client $MOUNT
14662         $LCTL get_param llite.*.statahead_max
14663         $LCTL set_param llite.*.statahead_stats=0 ||
14664                 error "clear statahead_stats failed"
14665         swrong=$(lctl get_param -n llite.*.statahead_stats |
14666                  awk '/statahead.wrong:/ { print $NF }')
14667         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
14668         # wait for statahead thread finished to update hit/miss stats.
14669         sleep 1
14670         $LCTL get_param -n llite.*.statahead_stats
14671         ewrong=$(lctl get_param -n llite.*.statahead_stats |
14672                  awk '/statahead.wrong:/ { print $NF }')
14673         (( $swrong == $ewrong )) ||
14674                 log "statahead was stopped, maybe too many locks held!"
14675 }
14676 run_test 123d "Statahead on striped directories works correctly"
14677
14678 test_123e() {
14679         local max
14680         local batch_max
14681         local dir=$DIR/$tdir
14682
14683         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14684                 skip "Server does not support batch RPC"
14685
14686         mkdir $dir || error "mkdir $dir failed"
14687         $LFS setstripe -C 32 $dir || error "setstripe $dir failed"
14688         stack_trap "rm -rf $dir"
14689
14690         touch $dir/$tfile.{0..1000} || error "touch 1000 files failed"
14691
14692         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14693         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14694         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14695         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14696
14697         $LCTL set_param llite.*.statahead_max=2048
14698         $LCTL set_param llite.*.statahead_batch_max=1024
14699
14700         ls -l $dir
14701         $LCTL get_param mdc.*.batch_stats
14702         $LCTL get_param llite.*.statahead_*
14703 }
14704 run_test 123e "statahead with large wide striping"
14705
14706 test_123f() {
14707         local max
14708         local batch_max
14709         local dir=$DIR/$tdir
14710
14711         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14712                 skip "Server does not support batch RPC"
14713
14714         mkdir $dir || error "mkdir $dir failed"
14715         $LFS setstripe -C 1000 $dir || error "setstripe $dir failed"
14716         stack_trap "rm -rf $dir"
14717
14718         touch $dir/$tfile.{0..200} || error "touch 200 files failed"
14719
14720         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14721         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14722
14723         $LCTL set_param llite.*.statahead_max=64
14724         $LCTL set_param llite.*.statahead_batch_max=64
14725
14726         ls -l $dir
14727         lctl get_param mdc.*.batch_stats
14728         lctl get_param llite.*.statahead_*
14729
14730         $LCTL set_param llite.*.statahead_max=$max
14731         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14732 }
14733 run_test 123f "Retry mechanism with large wide striping files"
14734
14735 test_123g() {
14736         local dir=$DIR/$tdir
14737         local num=1000
14738
14739         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14740                 skip "Server does not support batch RPC"
14741
14742         mkdir $dir || error "failed to mkdir $dir"
14743         createmany -o $dir/$tfile $num || error "failed creatmany files"
14744         cancel_lru_locks mdc
14745         cancel_lru_locks osc
14746
14747         $LCTL set_param llite.*.statahead_stats=clear
14748         $LCTL set_param mdc.*.batch_stats=clear
14749         aheadmany -c stat -s 0 -e $num -b $tfile -d $dir ||
14750                 error "aheadmany $dir with $tfile failed"
14751         wait_update_facet client "pgrep ll_sa" "" 35 ||
14752                 error "ll_sa thread is still running"
14753         $LCTL get_param -n llite.*.statahead_stats
14754         $LCTL get_param -n mdc.*.batch_stats
14755
14756         local count
14757
14758         count=$($LCTL get_param -n llite.*.statahead_stats |
14759                 awk '/hit.total:/ {print $2}')
14760         echo "Hit total: $count"
14761         # Hit ratio should be >= 75%
14762         (( $count > num * 75 / 100 )) ||
14763                 error "hit total $count is be > 75% of $num"
14764 }
14765 run_test 123g "Test for stat-ahead advise"
14766
14767 test_123h_base() {
14768         local dir=$DIR/$tdir
14769         local cmd="touch $dir/$tfile.{$1}"
14770         local fcnt=$2
14771
14772         stack_trap "rm -rf $dir"
14773         mkdir -p $dir || error "failed to mkdir $dir"
14774         eval $cmd
14775
14776         cancel_lru_locks mdc
14777         $LCTL set_param llite.*.statahead_stats=clear
14778         $LCTL set_param mdc.*.batch_stats=0
14779         $LCTL set_param llite.*.statahead_max=1024
14780         $LCTL set_param llite.*.statahead_batch_max=1024
14781         lctl get_param -n llite.*.statahead_stats
14782         du -a $dir > /dev/null
14783         echo "Wait statahead thread (ll_sa_xxx) to exit..."
14784         wait_update_facet client "pgrep ll_sa" "" 35 ||
14785                 error "ll_sa statahead thread does not quit in 35s"
14786         $LCTL get_param -n llite.*.statahead_stats
14787         $LCTL get_param -n mdc.*.batch_stats
14788
14789         local count=$($LCTL get_param -n llite.*.statahead_stats |
14790                         awk '/fname.total:/ {print $2}')
14791
14792         [ $count == 1 ] || error "File name pattern statahead not trigger"
14793         count=$($LCTL get_param -n llite.*.statahead_stats |
14794                 awk '/hit.total:/ {print $2}')
14795         # Hit ratio should be >= 75%
14796         (( $count > fcnt * 75 / 100 )) ||
14797                 error "hit total is too low: $count"
14798         rm -rf $dir || error "rm -rf $dir failed"
14799 }
14800
14801 test_123h() {
14802         local max
14803         local batch_max
14804         local enabled
14805
14806         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14807                 skip "Server does not support batch RPC"
14808
14809         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14810         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14811         enabled=$($LCTL get_param -n llite.*.enable_statahead_fname | head -n 1)
14812         stack_trap "$LCTL set_param llite.*.statahead_max=$max"
14813         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max"
14814         stack_trap "$LCTL set_param llite.*.enable_statahead_fname=$enabled"
14815
14816         $LCTL set_param llite.*.enable_statahead_fname=1
14817
14818         echo "Scan a directory with number regularized fname"
14819         test_123h_base "0..10000" 10000
14820
14821         echo "Scan a directory with zeroed padding number regularized fname"
14822         test_123h_base "000000..010000" 10000
14823 }
14824 run_test 123h "Verify statahead work with the fname pattern via du"
14825
14826 test_123i_base() {
14827         local fmt=$1
14828         local iocmd=$2
14829         local dir=$DIR/$tdir
14830         local cmd="createmany -m $fmt"
14831
14832         echo "Command:"
14833         echo "- $cmd"
14834         echo "- $iocmd"
14835         stack_trap "unlinkmany $fmt"
14836         mkdir -p $dir || error "failed to mkdir $dir"
14837         eval $cmd
14838
14839         cancel_lru_locks mdc
14840         $LCTL set_param llite.*.statahead_stats=clear
14841         $LCTL set_param mdc.*.batch_stats=0
14842
14843         echo "statahead_stats (Pre):"
14844         lctl get_param -n llite.*.statahead_stats
14845         eval $iocmd || error "$iocmd failed"
14846         echo "statahead_stats (Post):"
14847         $LCTL get_param -n llite.*.statahead_stats
14848         $LCTL get_param -n mdc.*.batch_stats
14849
14850         echo "Wait the statahead thread (ll_sa_xxx) to exit ..."
14851         wait_update_facet client "pgrep ll_sa" "" 35 ||
14852                 error "ll_sa statahead thread does not quit in 35s"
14853         $LCTL get_param -n llite.*.statahead_stats
14854         $LCTL get_param -n mdc.*.batch_stats
14855
14856         local count=$($LCTL get_param -n llite.*.statahead_stats |
14857                         awk '/fname.total:/ {print $2}')
14858
14859         [ $count == 1 ] || error "File name pattern statahead not trigger"
14860         count=$($LCTL get_param -n llite.*.statahead_stats |
14861                 awk '/hit.total:/ {print $2}')
14862         # Hit ratio should be >= 75%
14863         (( $count > 750 )) || error "hit total is too low: $count"
14864 }
14865
14866 test_123i() {
14867         local dir=$DIR/$tdir
14868         local cnt=1000
14869         local max
14870         local batch_max
14871         local enabled
14872         local min
14873
14874         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14875                 skip "Server does not support batch RPC"
14876
14877         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14878         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14879         min=$($LCTL get_param -n llite.*.statahead_min | head -n 1)
14880         enabled=$($LCTL get_param -n llite.*.enable_statahead_fname | head -n 1)
14881         stack_trap "$LCTL set_param llite.*.statahead_max=$max"
14882         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max"
14883         stack_trap "$LCTL set_param llite.*.statahead_min=$min"
14884         stack_trap "$LCTL set_param llite.*.enable_statahead_fname=$enabled"
14885         $LCTL set_param llite.*.statahead_max=1024
14886         $LCTL set_param llite.*.statahead_batch_max=32
14887         $LCTL set_param llite.*.statahead_min=64
14888         $LCTL set_param llite.*.enable_statahead_fname=1
14889
14890         test_123i_base "$dir/$tfile.%06d $cnt" "ls $dir/* > /dev/null"
14891         test_123i_base "$dir/$tfile $cnt" \
14892                 "aheadmany -c stat -N -s 0 -e $cnt -b $tfile -d $dir"
14893 }
14894 run_test 123i "Verify statahead work with the fname indexing pattern"
14895
14896 test_124a() {
14897         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14898         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14899                 skip_env "no lru resize on server"
14900
14901         local NR=2000
14902
14903         test_mkdir $DIR/$tdir
14904
14905         log "create $NR files at $DIR/$tdir"
14906         createmany -o $DIR/$tdir/f $NR ||
14907                 error "failed to create $NR files in $DIR/$tdir"
14908
14909         cancel_lru_locks mdc
14910         ls -l $DIR/$tdir > /dev/null
14911
14912         local NSDIR=""
14913         local LRU_SIZE=0
14914         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
14915                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
14916                 LRU_SIZE=$($LCTL get_param -n $PARAM)
14917                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
14918                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
14919                         log "NSDIR=$NSDIR"
14920                         log "NS=$(basename $NSDIR)"
14921                         break
14922                 fi
14923         done
14924
14925         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
14926                 skip "Not enough cached locks created!"
14927         fi
14928         log "LRU=$LRU_SIZE"
14929
14930         local SLEEP=30
14931
14932         # We know that lru resize allows one client to hold $LIMIT locks
14933         # for 10h. After that locks begin to be killed by client.
14934         local MAX_HRS=10
14935         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
14936         log "LIMIT=$LIMIT"
14937         if [ $LIMIT -lt $LRU_SIZE ]; then
14938                 skip "Limit is too small $LIMIT"
14939         fi
14940
14941         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
14942         # killing locks. Some time was spent for creating locks. This means
14943         # that up to the moment of sleep finish we must have killed some of
14944         # them (10-100 locks). This depends on how fast ther were created.
14945         # Many of them were touched in almost the same moment and thus will
14946         # be killed in groups.
14947         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
14948
14949         # Use $LRU_SIZE_B here to take into account real number of locks
14950         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
14951         local LRU_SIZE_B=$LRU_SIZE
14952         log "LVF=$LVF"
14953         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
14954         log "OLD_LVF=$OLD_LVF"
14955         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
14956
14957         # Let's make sure that we really have some margin. Client checks
14958         # cached locks every 10 sec.
14959         SLEEP=$((SLEEP+20))
14960         log "Sleep ${SLEEP} sec"
14961         local SEC=0
14962         while ((SEC<$SLEEP)); do
14963                 echo -n "..."
14964                 sleep 5
14965                 SEC=$((SEC+5))
14966                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
14967                 echo -n "$LRU_SIZE"
14968         done
14969         echo ""
14970         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
14971         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
14972
14973         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
14974                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
14975                 unlinkmany $DIR/$tdir/f $NR
14976                 return
14977         }
14978
14979         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
14980         log "unlink $NR files at $DIR/$tdir"
14981         unlinkmany $DIR/$tdir/f $NR
14982 }
14983 run_test 124a "lru resize ======================================="
14984
14985 get_max_pool_limit()
14986 {
14987         local limit=$($LCTL get_param \
14988                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
14989         local max=0
14990         for l in $limit; do
14991                 if [[ $l -gt $max ]]; then
14992                         max=$l
14993                 fi
14994         done
14995         echo $max
14996 }
14997
14998 test_124b() {
14999         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15000         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
15001                 skip_env "no lru resize on server"
15002
15003         LIMIT=$(get_max_pool_limit)
15004
15005         NR=$(($(default_lru_size)*20))
15006         if [[ $NR -gt $LIMIT ]]; then
15007                 log "Limit lock number by $LIMIT locks"
15008                 NR=$LIMIT
15009         fi
15010
15011         IFree=$(mdsrate_inodes_available)
15012         if [ $IFree -lt $NR ]; then
15013                 log "Limit lock number by $IFree inodes"
15014                 NR=$IFree
15015         fi
15016
15017         lru_resize_disable mdc
15018         test_mkdir -p $DIR/$tdir/disable_lru_resize
15019
15020         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
15021         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
15022         cancel_lru_locks mdc
15023         stime=`date +%s`
15024         PID=""
15025         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
15026         PID="$PID $!"
15027         sleep 2
15028         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
15029         PID="$PID $!"
15030         sleep 2
15031         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
15032         PID="$PID $!"
15033         wait $PID
15034         etime=`date +%s`
15035         nolruresize_delta=$((etime-stime))
15036         log "ls -la time: $nolruresize_delta seconds"
15037         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
15038         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
15039
15040         lru_resize_enable mdc
15041         test_mkdir -p $DIR/$tdir/enable_lru_resize
15042
15043         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
15044         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
15045         cancel_lru_locks mdc
15046         stime=`date +%s`
15047         PID=""
15048         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
15049         PID="$PID $!"
15050         sleep 2
15051         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
15052         PID="$PID $!"
15053         sleep 2
15054         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
15055         PID="$PID $!"
15056         wait $PID
15057         etime=`date +%s`
15058         lruresize_delta=$((etime-stime))
15059         log "ls -la time: $lruresize_delta seconds"
15060         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
15061
15062         if [ $lruresize_delta -gt $nolruresize_delta ]; then
15063                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
15064         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
15065                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
15066         else
15067                 log "lru resize performs the same with no lru resize"
15068         fi
15069         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
15070 }
15071 run_test 124b "lru resize (performance test) ======================="
15072
15073 test_124c() {
15074         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15075         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
15076                 skip_env "no lru resize on server"
15077
15078         # cache ununsed locks on client
15079         local nr=100
15080         cancel_lru_locks mdc
15081         test_mkdir $DIR/$tdir
15082         createmany -o $DIR/$tdir/f $nr ||
15083                 error "failed to create $nr files in $DIR/$tdir"
15084         ls -l $DIR/$tdir > /dev/null
15085
15086         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15087         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15088         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
15089         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
15090         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
15091
15092         # set lru_max_age to 1 sec
15093         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
15094         echo "sleep $((recalc_p * 2)) seconds..."
15095         sleep $((recalc_p * 2))
15096
15097         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
15098         # restore lru_max_age
15099         $LCTL set_param -n $nsdir.lru_max_age $max_age
15100         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
15101         unlinkmany $DIR/$tdir/f $nr
15102 }
15103 run_test 124c "LRUR cancel very aged locks"
15104
15105 test_124d() {
15106         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15107         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
15108                 skip_env "no lru resize on server"
15109
15110         # cache ununsed locks on client
15111         local nr=100
15112
15113         lru_resize_disable mdc
15114         stack_trap "lru_resize_enable mdc" EXIT
15115
15116         cancel_lru_locks mdc
15117
15118         # asynchronous object destroy at MDT could cause bl ast to client
15119         test_mkdir $DIR/$tdir
15120         createmany -o $DIR/$tdir/f $nr ||
15121                 error "failed to create $nr files in $DIR/$tdir"
15122         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
15123
15124         ls -l $DIR/$tdir > /dev/null
15125
15126         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15127         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15128         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
15129         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
15130
15131         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
15132
15133         # set lru_max_age to 1 sec
15134         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
15135         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
15136
15137         echo "sleep $((recalc_p * 2)) seconds..."
15138         sleep $((recalc_p * 2))
15139
15140         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
15141
15142         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
15143 }
15144 run_test 124d "cancel very aged locks if lru-resize disabled"
15145
15146 test_125() { # 13358
15147         $LCTL get_param -n llite.*.client_type | grep -q local ||
15148                 skip "must run as local client"
15149         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
15150                 skip_env "must have acl enabled"
15151         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15152         id $USER0 || skip_env "missing user $USER0"
15153
15154         test_mkdir $DIR/$tdir
15155         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
15156         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
15157                 error "setfacl $DIR/$tdir failed"
15158         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
15159 }
15160 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
15161
15162 test_126() { # bug 12829/13455
15163         $GSS && skip_env "must run as gss disabled"
15164         $LCTL get_param -n llite.*.client_type | grep -q local ||
15165                 skip "must run as local client"
15166         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
15167
15168         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
15169         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
15170         rm -f $DIR/$tfile
15171         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
15172 }
15173 run_test 126 "check that the fsgid provided by the client is taken into account"
15174
15175 test_127a() { # bug 15521
15176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15177         local name count samp unit min max sum sumsq
15178         local tmpfile=$TMP/$tfile.tmp
15179
15180         # enable stats header if it is disabled
15181         $LCTL set_param enable_stats_header=1
15182
15183         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
15184         echo "stats before reset"
15185         stack_trap "rm -f $tmpfile"
15186         local now=$(date +%s)
15187
15188         $LCTL get_param osc.*.stats | tee $tmpfile
15189
15190         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
15191         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
15192         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
15193         local uptime=$(awk '{ print $1 }' /proc/uptime)
15194
15195         # snapshot_time should match POSIX epoch time, allow some delta for VMs
15196         (( ${snapshot_time%\.*} >= $now - 5 &&
15197            ${snapshot_time%\.*} <= $now + 5 )) ||
15198                 error "snapshot_time=$snapshot_time != now=$now"
15199         # elapsed _should_ be from mount, but at least less than uptime
15200         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
15201                 error "elapsed=$elapsed > uptime=$uptime"
15202         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
15203            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
15204                 error "elapsed=$elapsed != $snapshot_time - $start_time"
15205
15206         $LCTL set_param osc.*.stats=0
15207         local reset=$(date +%s)
15208         local fsize=$((2048 * 1024))
15209
15210         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
15211         cancel_lru_locks osc
15212         dd if=$DIR/$tfile of=/dev/null bs=$fsize
15213
15214         now=$(date +%s)
15215         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
15216         while read name count samp unit min max sum sumsq; do
15217                 [[ "$samp" == "samples" ]] || continue
15218
15219                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
15220                 [ ! $min ] && error "Missing min value for $name proc entry"
15221                 eval $name=$count || error "Wrong proc format"
15222
15223                 case $name in
15224                 read_bytes|write_bytes)
15225                         [[ "$unit" =~ "bytes" ]] ||
15226                                 error "unit is not 'bytes': $unit"
15227                         (( $min >= 4096 )) || error "min is too small: $min"
15228                         (( $min <= $fsize )) || error "min is too big: $min"
15229                         (( $max >= 4096 )) || error "max is too small: $max"
15230                         (( $max <= $fsize )) || error "max is too big: $max"
15231                         (( $sum == $fsize )) || error "sum is wrong: $sum"
15232                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
15233                                 error "sumsquare is too small: $sumsq"
15234                         (( $sumsq <= $fsize * $fsize )) ||
15235                                 error "sumsquare is too big: $sumsq"
15236                         ;;
15237                 ost_read|ost_write)
15238                         [[ "$unit" =~ "usec" ]] ||
15239                                 error "unit is not 'usec': $unit"
15240                         ;;
15241                 *)      ;;
15242                 esac
15243         done < $tmpfile
15244
15245         #check that we actually got some stats
15246         [ "$read_bytes" ] || error "Missing read_bytes stats"
15247         [ "$write_bytes" ] || error "Missing write_bytes stats"
15248         [ "$read_bytes" != 0 ] || error "no read done"
15249         [ "$write_bytes" != 0 ] || error "no write done"
15250
15251         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
15252         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
15253         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
15254
15255         # snapshot_time should match POSIX epoch time, allow some delta for VMs
15256         (( ${snapshot_time%\.*} >= $now - 5 &&
15257            ${snapshot_time%\.*} <= $now + 5 )) ||
15258                 error "reset snapshot_time=$snapshot_time != now=$now"
15259         # elapsed should be from time of stats reset
15260         (( ${elapsed%\.*} >= $now - $reset - 2 &&
15261            ${elapsed%\.*} <= $now - $reset + 2 )) ||
15262                 error "reset elapsed=$elapsed > $now - $reset"
15263         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
15264            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
15265                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
15266 }
15267 run_test 127a "verify the client stats are sane"
15268
15269 test_127b() { # bug LU-333
15270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15271         local name count samp unit min max sum sumsq
15272
15273         echo "stats before reset"
15274         $LCTL get_param llite.*.stats
15275         $LCTL set_param llite.*.stats=0
15276
15277         # perform 2 reads and writes so MAX is different from SUM.
15278         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
15279         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
15280         cancel_lru_locks osc
15281         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
15282         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
15283
15284         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
15285         stack_trap "rm -f $TMP/$tfile.tmp"
15286         while read name count samp unit min max sum sumsq; do
15287                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
15288                 eval $name=$count || error "Wrong proc format"
15289
15290                 case $name in
15291                 read_bytes|write_bytes)
15292                         [[ "$unit" =~ "bytes" ]] ||
15293                                 error "unit is not 'bytes': $unit"
15294                         (( $count == 2 )) || error "count is not 2: $count"
15295                         (( $min == $PAGE_SIZE )) ||
15296                                 error "min is not $PAGE_SIZE: $min"
15297                         (( $max == $PAGE_SIZE )) ||
15298                                 error "max is not $PAGE_SIZE: $max"
15299                         (( $sum == $PAGE_SIZE * 2 )) ||
15300                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
15301                         ;;
15302                 read|write)
15303                         [[ "$unit" =~ "usec" ]] ||
15304                                 error "unit is not 'usec': $unit"
15305                         ;;
15306                 *)      ;;
15307                 esac
15308         done < $TMP/$tfile.tmp
15309
15310         #check that we actually got some stats
15311         [ "$read_bytes" ] || error "Missing read_bytes stats"
15312         [ "$write_bytes" ] || error "Missing write_bytes stats"
15313         [ "$read_bytes" != 0 ] || error "no read done"
15314         [ "$write_bytes" != 0 ] || error "no write done"
15315 }
15316 run_test 127b "verify the llite client stats are sane"
15317
15318 test_127c() { # LU-12394
15319         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
15320         local size
15321         local bsize
15322         local reads
15323         local writes
15324         local count
15325
15326         $LCTL set_param llite.*.extents_stats=1
15327         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
15328
15329         # Use two stripes so there is enough space in default config
15330         $LFS setstripe -c 2 $DIR/$tfile
15331
15332         # Extent stats start at 0-4K and go in power of two buckets
15333         # LL_HIST_START = 12 --> 2^12 = 4K
15334         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
15335         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
15336         # small configs
15337         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
15338                 do
15339                 # Write and read, 2x each, second time at a non-zero offset
15340                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
15341                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
15342                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
15343                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
15344                 rm -f $DIR/$tfile
15345         done
15346
15347         $LCTL get_param llite.*.extents_stats
15348
15349         count=2
15350         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
15351                 do
15352                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
15353                                 grep -m 1 $bsize)
15354                 reads=$(echo $bucket | awk '{print $5}')
15355                 writes=$(echo $bucket | awk '{print $9}')
15356                 [ "$reads" -eq $count ] ||
15357                         error "$reads reads in < $bsize bucket, expect $count"
15358                 [ "$writes" -eq $count ] ||
15359                         error "$writes writes in < $bsize bucket, expect $count"
15360         done
15361
15362         # Test mmap write and read
15363         $LCTL set_param llite.*.extents_stats=c
15364         size=512
15365         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
15366         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
15367         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
15368
15369         $LCTL get_param llite.*.extents_stats
15370
15371         count=$(((size*1024) / PAGE_SIZE))
15372
15373         bsize=$((2 * PAGE_SIZE / 1024))K
15374
15375         bucket=$($LCTL get_param -n llite.*.extents_stats |
15376                         grep -m 1 $bsize)
15377         reads=$(echo $bucket | awk '{print $5}')
15378         writes=$(echo $bucket | awk '{print $9}')
15379         # mmap writes fault in the page first, creating an additonal read
15380         [ "$reads" -eq $((2 * count)) ] ||
15381                 error "$reads reads in < $bsize bucket, expect $count"
15382         [ "$writes" -eq $count ] ||
15383                 error "$writes writes in < $bsize bucket, expect $count"
15384 }
15385 run_test 127c "test llite extent stats with regular & mmap i/o"
15386
15387 test_128() { # bug 15212
15388         touch $DIR/$tfile
15389         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
15390                 find $DIR/$tfile
15391                 find $DIR/$tfile
15392         EOF
15393
15394         result=$(grep error $TMP/$tfile.log)
15395         rm -f $DIR/$tfile $TMP/$tfile.log
15396         [ -z "$result" ] ||
15397                 error "consecutive find's under interactive lfs failed"
15398 }
15399 run_test 128 "interactive lfs for 2 consecutive find's"
15400
15401 set_dir_limits () {
15402         local mntdev
15403         local canondev
15404         local node
15405
15406         local ldproc=/proc/fs/ldiskfs
15407         local facets=$(get_facets MDS)
15408
15409         for facet in ${facets//,/ }; do
15410                 canondev=$(ldiskfs_canon \
15411                            *.$(convert_facet2label $facet).mntdev $facet)
15412                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
15413                         ldproc=/sys/fs/ldiskfs
15414                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
15415                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
15416         done
15417 }
15418
15419 check_mds_dmesg() {
15420         local facets=$(get_facets MDS)
15421         for facet in ${facets//,/ }; do
15422                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
15423         done
15424         return 1
15425 }
15426
15427 test_129() {
15428         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15429         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
15430                 skip "Need MDS version with at least 2.5.56"
15431         if [ "$mds1_FSTYPE" != ldiskfs ]; then
15432                 skip_env "ldiskfs only test"
15433         fi
15434         remote_mds_nodsh && skip "remote MDS with nodsh"
15435
15436         local ENOSPC=28
15437         local has_warning=false
15438
15439         rm -rf $DIR/$tdir
15440         mkdir -p $DIR/$tdir
15441
15442         # block size of mds1
15443         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
15444         set_dir_limits $maxsize $((maxsize * 6 / 8))
15445         stack_trap "set_dir_limits 0 0"
15446         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
15447         local dirsize=$(stat -c%s "$DIR/$tdir")
15448         local nfiles=0
15449         while (( $dirsize <= $maxsize )); do
15450                 $MCREATE $DIR/$tdir/file_base_$nfiles
15451                 rc=$?
15452                 # check two errors:
15453                 # ENOSPC for ext4 max_dir_size, which has been used since
15454                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
15455                 if (( rc == ENOSPC )); then
15456                         set_dir_limits 0 0
15457                         echo "rc=$rc returned as expected after $nfiles files"
15458
15459                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
15460                                 error "create failed w/o dir size limit"
15461
15462                         # messages may be rate limited if test is run repeatedly
15463                         check_mds_dmesg '"is approaching max"' ||
15464                                 echo "warning message should be output"
15465                         check_mds_dmesg '"has reached max"' ||
15466                                 echo "reached message should be output"
15467
15468                         dirsize=$(stat -c%s "$DIR/$tdir")
15469
15470                         [[ $dirsize -ge $maxsize ]] && return 0
15471                         error "dirsize $dirsize < $maxsize after $nfiles files"
15472                 elif (( rc != 0 )); then
15473                         break
15474                 fi
15475                 nfiles=$((nfiles + 1))
15476                 dirsize=$(stat -c%s "$DIR/$tdir")
15477         done
15478
15479         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
15480 }
15481 run_test 129 "test directory size limit ========================"
15482
15483 OLDIFS="$IFS"
15484 cleanup_130() {
15485         trap 0
15486         IFS="$OLDIFS"
15487         rm -f $DIR/$tfile
15488 }
15489
15490 test_130a() {
15491         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
15492         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
15493
15494         trap cleanup_130 EXIT RETURN
15495
15496         local fm_file=$DIR/$tfile
15497         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
15498         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
15499                 error "dd failed for $fm_file"
15500
15501         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
15502         filefrag -ves $fm_file
15503         local rc=$?
15504         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15505                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15506         (( $rc == 0 )) || error "filefrag $fm_file failed"
15507
15508         filefrag_op=$(filefrag -ve -k $fm_file |
15509                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15510         local lun=$($LFS getstripe -i $fm_file)
15511
15512         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
15513         IFS=$'\n'
15514         local tot_len=0
15515         for line in $filefrag_op; do
15516                 local frag_lun=$(echo $line | cut -d: -f5)
15517                 local ext_len=$(echo $line | cut -d: -f4)
15518
15519                 if (( $frag_lun != $lun )); then
15520                         error "FIEMAP on 1-stripe file($fm_file) failed"
15521                         return
15522                 fi
15523                 (( tot_len += ext_len ))
15524         done
15525
15526         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
15527                 error "FIEMAP on 1-stripe file($fm_file) failed"
15528                 return
15529         fi
15530
15531         echo "FIEMAP on single striped file succeeded"
15532 }
15533 run_test 130a "FIEMAP (1-stripe file)"
15534
15535 test_130b() {
15536         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15537
15538         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15539         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15540         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15541                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15542
15543         trap cleanup_130 EXIT RETURN
15544
15545         local fm_file=$DIR/$tfile
15546         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15547                 error "setstripe on $fm_file"
15548
15549         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
15550                 error "dd failed on $fm_file"
15551
15552         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15553         filefrag_op=$(filefrag -ve -k $fm_file |
15554                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15555
15556         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15557                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15558
15559         IFS=$'\n'
15560         local tot_len=0
15561         local num_luns=1
15562
15563         for line in $filefrag_op; do
15564                 local frag_lun=$(echo $line | cut -d: -f5 |
15565                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15566                 local ext_len=$(echo $line | cut -d: -f4)
15567                 if (( $frag_lun != $last_lun )); then
15568                         if (( tot_len != 1024 )); then
15569                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15570                                 return
15571                         else
15572                                 (( num_luns += 1 ))
15573                                 tot_len=0
15574                         fi
15575                 fi
15576                 (( tot_len += ext_len ))
15577                 last_lun=$frag_lun
15578         done
15579         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
15580                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15581                 return
15582         fi
15583
15584         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
15585 }
15586 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
15587
15588 test_130c() {
15589         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15590
15591         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15592         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15593         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15594                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15595
15596         trap cleanup_130 EXIT RETURN
15597
15598         local fm_file=$DIR/$tfile
15599         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
15600
15601         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
15602                 error "dd failed on $fm_file"
15603
15604         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15605         filefrag_op=$(filefrag -ve -k $fm_file |
15606                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15607
15608         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15609                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15610
15611         IFS=$'\n'
15612         local tot_len=0
15613         local num_luns=1
15614         for line in $filefrag_op; do
15615                 local frag_lun=$(echo $line | cut -d: -f5 |
15616                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15617                 local ext_len=$(echo $line | cut -d: -f4)
15618                 if (( $frag_lun != $last_lun )); then
15619                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
15620                         if (( logical != 512 )); then
15621                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
15622                                 return
15623                         fi
15624                         if (( tot_len != 512 )); then
15625                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15626                                 return
15627                         else
15628                                 (( num_luns += 1 ))
15629                                 tot_len=0
15630                         fi
15631                 fi
15632                 (( tot_len += ext_len ))
15633                 last_lun=$frag_lun
15634         done
15635         if (( num_luns != 2 || tot_len != 512 )); then
15636                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15637                 return
15638         fi
15639
15640         echo "FIEMAP on 2-stripe file with hole succeeded"
15641 }
15642 run_test 130c "FIEMAP (2-stripe file with hole)"
15643
15644 test_130d() {
15645         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
15646
15647         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15648         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15649         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15650                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15651
15652         trap cleanup_130 EXIT RETURN
15653
15654         local fm_file=$DIR/$tfile
15655         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15656                         error "setstripe on $fm_file"
15657
15658         local actual_stripe_count=$($LFS getstripe -c $fm_file)
15659         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
15660                 error "dd failed on $fm_file"
15661
15662         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15663         filefrag_op=$(filefrag -ve -k $fm_file |
15664                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15665
15666         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15667                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15668
15669         IFS=$'\n'
15670         local tot_len=0
15671         local num_luns=1
15672         for line in $filefrag_op; do
15673                 local frag_lun=$(echo $line | cut -d: -f5 |
15674                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15675                 local ext_len=$(echo $line | cut -d: -f4)
15676                 if (( $frag_lun != $last_lun )); then
15677                         if (( tot_len != 1024 )); then
15678                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15679                                 return
15680                         else
15681                                 (( num_luns += 1 ))
15682                                 local tot_len=0
15683                         fi
15684                 fi
15685                 (( tot_len += ext_len ))
15686                 last_lun=$frag_lun
15687         done
15688         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
15689                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15690                 return
15691         fi
15692
15693         echo "FIEMAP on N-stripe file succeeded"
15694 }
15695 run_test 130d "FIEMAP (N-stripe file)"
15696
15697 test_130e() {
15698         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15699
15700         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15701         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15702         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15703                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15704
15705         trap cleanup_130 EXIT RETURN
15706
15707         local fm_file=$DIR/$tfile
15708         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
15709         stack_trap "rm -f $fm_file"
15710
15711         local num_blks=512
15712         local expected_len=$(( (num_blks / 2) * 64 ))
15713         for ((i = 0; i < $num_blks; i++)); do
15714                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
15715                         conv=notrunc > /dev/null 2>&1
15716         done
15717
15718         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15719         filefrag_op=$(filefrag -ve -k $fm_file |
15720                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15721
15722         local last_lun=$(echo $filefrag_op | cut -d: -f5)
15723
15724         IFS=$'\n'
15725         local tot_len=0
15726         local num_luns=1
15727         for line in $filefrag_op; do
15728                 local frag_lun=$(echo $line | cut -d: -f5)
15729                 local ext_len=$(echo $line | cut -d: -f4)
15730                 if (( $frag_lun != $last_lun )); then
15731                         if (( tot_len != $expected_len )); then
15732                                 error "OST$last_lun $tot_len != $expected_len"
15733                         else
15734                                 (( num_luns += 1 ))
15735                                 tot_len=0
15736                         fi
15737                 fi
15738                 (( tot_len += ext_len ))
15739                 last_lun=$frag_lun
15740         done
15741         if (( num_luns != 2 || tot_len != $expected_len )); then
15742                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
15743         fi
15744
15745         echo "FIEMAP with continuation calls succeeded"
15746 }
15747 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
15748
15749 test_130f() {
15750         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15751         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15752         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15753                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15754
15755         local fm_file=$DIR/$tfile
15756         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
15757                 error "multiop create with lov_delay_create on $fm_file"
15758
15759         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15760         filefrag_extents=$(filefrag -vek $fm_file |
15761                            awk '/extents? found/ { print $2 }')
15762         if (( $filefrag_extents != 0 )); then
15763                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
15764         fi
15765
15766         rm -f $fm_file
15767 }
15768 run_test 130f "FIEMAP (unstriped file)"
15769
15770 test_130g() {
15771         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
15772                 skip "Need MDS version with at least 2.12.53 for overstriping"
15773         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15774         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15775         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15776                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15777
15778         local file=$DIR/$tfile
15779         local nr=$((OSTCOUNT * 100))
15780
15781         $LFS setstripe -C $nr -S1M $file ||
15782                 error "failed to setstripe -C $nr $file"
15783
15784         stack_trap "rm -f $file"
15785         dd if=/dev/zero of=$file count=$nr bs=1M
15786         sync
15787         nr=$($LFS getstripe -c $file)
15788
15789         local extents=$(filefrag -v $file |
15790                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
15791
15792         echo "filefrag list $extents extents in file with stripecount $nr"
15793         if (( extents < nr )); then
15794                 $LFS getstripe $file
15795                 filefrag -v $file
15796                 error "filefrag printed $extents < $nr extents"
15797         fi
15798 }
15799 run_test 130g "FIEMAP (overstripe file)"
15800
15801 # Test for writev/readv
15802 test_131a() {
15803         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
15804                 error "writev test failed"
15805         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
15806                 error "readv failed"
15807         rm -f $DIR/$tfile
15808 }
15809 run_test 131a "test iov's crossing stripe boundary for writev/readv"
15810
15811 test_131b() {
15812         local fsize=$((524288 + 1048576 + 1572864))
15813         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
15814                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15815                         error "append writev test failed"
15816
15817         ((fsize += 1572864 + 1048576))
15818         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
15819                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15820                         error "append writev test failed"
15821         rm -f $DIR/$tfile
15822 }
15823 run_test 131b "test append writev"
15824
15825 test_131c() {
15826         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
15827         error "NOT PASS"
15828 }
15829 run_test 131c "test read/write on file w/o objects"
15830
15831 test_131d() {
15832         rwv -f $DIR/$tfile -w -n 1 1572864
15833         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
15834         if [ "$NOB" != 1572864 ]; then
15835                 error "Short read filed: read $NOB bytes instead of 1572864"
15836         fi
15837         rm -f $DIR/$tfile
15838 }
15839 run_test 131d "test short read"
15840
15841 test_131e() {
15842         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
15843         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
15844         error "read hitting hole failed"
15845         rm -f $DIR/$tfile
15846 }
15847 run_test 131e "test read hitting hole"
15848
15849 check_stats() {
15850         local facet=$1
15851         local op=$2
15852         local want=${3:-0}
15853         local res
15854
15855         # open             11 samples [usecs] 468 4793 13658 35791898
15856         case $facet in
15857         mds*) res=($(do_facet $facet \
15858                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
15859                  ;;
15860         ost*) res=($(do_facet $facet \
15861                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
15862                  ;;
15863         *) error "Wrong facet '$facet'" ;;
15864         esac
15865         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
15866         # if $want is zero, it means any stat increment is ok.
15867         if (( $want > 0 )); then
15868                 local count=${res[1]}
15869
15870                 if (( $count != $want )); then
15871                         if [[ $facet =~ "mds" ]]; then
15872                                 do_nodes $(comma_list $(mdts_nodes)) \
15873                                         $LCTL get_param mdt.*.md_stats
15874                         else
15875                                 do_nodes $(comma_list $(osts-nodes)) \
15876                                         $LCTL get_param obdfilter.*.stats
15877                         fi
15878                         error "The $op counter on $facet is $count, not $want"
15879                 fi
15880         fi
15881 }
15882
15883 test_133a() {
15884         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15885         remote_ost_nodsh && skip "remote OST with nodsh"
15886         remote_mds_nodsh && skip "remote MDS with nodsh"
15887         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15888                 skip_env "MDS doesn't support rename stats"
15889
15890         local testdir=$DIR/${tdir}/stats_testdir
15891
15892         mkdir_on_mdt0 $DIR/${tdir}
15893
15894         # clear stats.
15895         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15896         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15897
15898         # verify mdt stats first.
15899         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15900         check_stats $SINGLEMDS "mkdir" 1
15901
15902         # clear "open" from "lfs mkdir" above
15903         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15904         touch ${testdir}/${tfile} || error "touch failed"
15905         check_stats $SINGLEMDS "open" 1
15906         check_stats $SINGLEMDS "close" 1
15907         (( $MDS1_VERSION >= $(version_code 2.15.62) )) && {
15908                 # open should match close
15909                 ls -lR ${testdir}
15910                 check_stats $SINGLEMDS "open" 2
15911                 check_stats $SINGLEMDS "close" 2
15912         }
15913         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
15914                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
15915                 check_stats $SINGLEMDS "mknod" 2
15916         }
15917         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
15918         check_stats $SINGLEMDS "unlink" 1
15919         rm -f ${testdir}/${tfile} || error "file remove failed"
15920         check_stats $SINGLEMDS "unlink" 2
15921
15922         # remove working dir and check mdt stats again.
15923         rmdir ${testdir} || error "rmdir failed"
15924         check_stats $SINGLEMDS "rmdir" 1
15925
15926         local testdir1=$DIR/${tdir}/stats_testdir1
15927         mkdir_on_mdt0 ${testdir}
15928         mkdir_on_mdt0 ${testdir1}
15929         touch ${testdir1}/test1
15930         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
15931         check_stats $SINGLEMDS "crossdir_rename" 1
15932
15933         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
15934         check_stats $SINGLEMDS "samedir_rename" 1
15935
15936         rm -rf $DIR/${tdir}
15937 }
15938 run_test 133a "Verifying MDT stats ========================================"
15939
15940 test_133b() {
15941         local res
15942
15943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15944         remote_ost_nodsh && skip "remote OST with nodsh"
15945         remote_mds_nodsh && skip "remote MDS with nodsh"
15946
15947         local testdir=$DIR/${tdir}/stats_testdir
15948
15949         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15950         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15951         touch ${testdir}/${tfile} || error "touch failed"
15952         cancel_lru_locks mdc
15953
15954         # clear stats.
15955         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15956         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15957
15958         # extra mdt stats verification.
15959         chmod 444 ${testdir}/${tfile} || error "chmod failed"
15960         check_stats $SINGLEMDS "setattr" 1
15961         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15962         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
15963         then            # LU-1740
15964                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
15965                 check_stats $SINGLEMDS "getattr" 1
15966         fi
15967         rm -rf $DIR/${tdir}
15968
15969         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
15970         # so the check below is not reliable
15971         [ $MDSCOUNT -eq 1 ] || return 0
15972
15973         # Sleep to avoid a cached response.
15974         #define OBD_STATFS_CACHE_SECONDS 1
15975         sleep 2
15976         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15977         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15978         $LFS df || error "lfs failed"
15979         check_stats $SINGLEMDS "statfs" 1
15980
15981         # check aggregated statfs (LU-10018)
15982         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
15983                 return 0
15984         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
15985                 return 0
15986         sleep 2
15987         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15988         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15989         df $DIR
15990         check_stats $SINGLEMDS "statfs" 1
15991
15992         # We want to check that the client didn't send OST_STATFS to
15993         # ost1 but the MDT also uses OST_STATFS for precreate. So some
15994         # extra care is needed here.
15995         if remote_mds; then
15996                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
15997                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
15998
15999                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
16000                 [ "$res" ] && error "OST got STATFS"
16001         fi
16002
16003         return 0
16004 }
16005 run_test 133b "Verifying extra MDT stats =================================="
16006
16007 test_133c() {
16008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16009         remote_ost_nodsh && skip "remote OST with nodsh"
16010         remote_mds_nodsh && skip "remote MDS with nodsh"
16011
16012         local testdir=$DIR/$tdir/stats_testdir
16013
16014         test_mkdir -p $testdir
16015
16016         # verify obdfilter stats.
16017         $LFS setstripe -c 1 -i 0 $testdir/$tfile
16018         sync
16019         cancel_lru_locks osc
16020         wait_delete_completed
16021
16022         # clear stats.
16023         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
16024         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
16025
16026         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
16027                 error "dd failed"
16028         sync
16029         cancel_lru_locks osc
16030         check_stats ost1 "write" 1
16031
16032         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
16033         check_stats ost1 "read" 1
16034
16035         > $testdir/$tfile || error "truncate failed"
16036         check_stats ost1 "punch" 1
16037
16038         rm -f $testdir/$tfile || error "file remove failed"
16039         wait_delete_completed
16040         check_stats ost1 "destroy" 1
16041
16042         rm -rf $DIR/$tdir
16043 }
16044 run_test 133c "Verifying OST stats ========================================"
16045
16046 order_2() {
16047         local value=$1
16048         local orig=$value
16049         local order=1
16050
16051         while [ $value -ge 2 ]; do
16052                 order=$((order*2))
16053                 value=$((value/2))
16054         done
16055
16056         if [ $orig -gt $order ]; then
16057                 order=$((order*2))
16058         fi
16059         echo $order
16060 }
16061
16062 size_in_KMGT() {
16063     local value=$1
16064     local size=('K' 'M' 'G' 'T');
16065     local i=0
16066     local size_string=$value
16067
16068     while [ $value -ge 1024 ]; do
16069         if [ $i -gt 3 ]; then
16070             #T is the biggest unit we get here, if that is bigger,
16071             #just return XXXT
16072             size_string=${value}T
16073             break
16074         fi
16075         value=$((value >> 10))
16076         if [ $value -lt 1024 ]; then
16077             size_string=${value}${size[$i]}
16078             break
16079         fi
16080         i=$((i + 1))
16081     done
16082
16083     echo $size_string
16084 }
16085
16086 get_rename_size() {
16087         local size=$1
16088         local context=${2:-.}
16089         local sample=$(do_facet $SINGLEMDS $LCTL \
16090                 get_param mdt.$FSNAME-MDT0000.rename_stats |
16091                 grep -A1 $context |
16092                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
16093         echo $sample
16094 }
16095
16096 test_133d() {
16097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16098         remote_ost_nodsh && skip "remote OST with nodsh"
16099         remote_mds_nodsh && skip "remote MDS with nodsh"
16100         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
16101                 skip_env "MDS doesn't support rename stats"
16102
16103         local testdir1=$DIR/${tdir}/stats_testdir1
16104         local testdir2=$DIR/${tdir}/stats_testdir2
16105         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
16106
16107         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
16108
16109         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
16110         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
16111
16112         createmany -o $testdir1/test 512 || error "createmany failed"
16113
16114         # check samedir rename size
16115         mv ${testdir1}/test0 ${testdir1}/test_0
16116
16117         local testdir1_size=$(ls -l $DIR/${tdir} |
16118                 awk '/stats_testdir1/ {print $5}')
16119         local testdir2_size=$(ls -l $DIR/${tdir} |
16120                 awk '/stats_testdir2/ {print $5}')
16121
16122         testdir1_size=$(order_2 $testdir1_size)
16123         testdir2_size=$(order_2 $testdir2_size)
16124
16125         testdir1_size=$(size_in_KMGT $testdir1_size)
16126         testdir2_size=$(size_in_KMGT $testdir2_size)
16127
16128         echo "source rename dir size: ${testdir1_size}"
16129         echo "target rename dir size: ${testdir2_size}"
16130
16131         local cmd="do_facet $SINGLEMDS $LCTL "
16132         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
16133
16134         eval $cmd || error "$cmd failed"
16135         local samedir=$($cmd | grep 'same_dir')
16136         local same_sample=$(get_rename_size $testdir1_size)
16137         [ -z "$samedir" ] && error "samedir_rename_size count error"
16138         [[ $same_sample -eq 1 ]] ||
16139                 error "samedir_rename_size error $same_sample"
16140         echo "Check same dir rename stats success"
16141
16142         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
16143
16144         # check crossdir rename size
16145         mv ${testdir1}/test_0 ${testdir2}/test_0
16146
16147         testdir1_size=$(ls -l $DIR/${tdir} |
16148                 awk '/stats_testdir1/ {print $5}')
16149         testdir2_size=$(ls -l $DIR/${tdir} |
16150                 awk '/stats_testdir2/ {print $5}')
16151
16152         testdir1_size=$(order_2 $testdir1_size)
16153         testdir2_size=$(order_2 $testdir2_size)
16154
16155         testdir1_size=$(size_in_KMGT $testdir1_size)
16156         testdir2_size=$(size_in_KMGT $testdir2_size)
16157
16158         echo "source rename dir size: ${testdir1_size}"
16159         echo "target rename dir size: ${testdir2_size}"
16160
16161         eval $cmd || error "$cmd failed"
16162         local crossdir=$($cmd | grep 'crossdir')
16163         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
16164         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
16165         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
16166         [[ $src_sample -eq 1 ]] ||
16167                 error "crossdir_rename_size error $src_sample"
16168         [[ $tgt_sample -eq 1 ]] ||
16169                 error "crossdir_rename_size error $tgt_sample"
16170         echo "Check cross dir rename stats success"
16171         rm -rf $DIR/${tdir}
16172 }
16173 run_test 133d "Verifying rename_stats ========================================"
16174
16175 test_133e() {
16176         remote_mds_nodsh && skip "remote MDS with nodsh"
16177         remote_ost_nodsh && skip "remote OST with nodsh"
16178         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16179
16180         local testdir=$DIR/${tdir}/stats_testdir
16181         local ctr f0 f1 bs=32768 count=42 sum
16182
16183         mkdir -p ${testdir} || error "mkdir failed"
16184
16185         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
16186
16187         for ctr in {write,read}_bytes; do
16188                 sync
16189                 cancel_lru_locks osc
16190
16191                 do_facet ost1 $LCTL set_param -n \
16192                         "obdfilter.*.exports.clear=clear"
16193
16194                 if [ $ctr = write_bytes ]; then
16195                         f0=/dev/zero
16196                         f1=${testdir}/${tfile}
16197                 else
16198                         f0=${testdir}/${tfile}
16199                         f1=/dev/null
16200                 fi
16201
16202                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
16203                         error "dd failed"
16204                 sync
16205                 cancel_lru_locks osc
16206
16207                 sum=$(do_facet ost1 $LCTL get_param \
16208                         "obdfilter.*.exports.*.stats" |
16209                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
16210                                 $1 == ctr { sum += $7 }
16211                                 END { printf("%0.0f", sum) }')
16212
16213                 if ((sum != bs * count)); then
16214                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
16215                 fi
16216         done
16217
16218         rm -rf $DIR/${tdir}
16219 }
16220 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
16221
16222 test_133f() {
16223         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
16224                 skip "too old lustre for get_param -R ($facet_ver)"
16225
16226         # verifying readability.
16227         $LCTL get_param -R '*' &> /dev/null
16228
16229         # Verifing writability with badarea_io.
16230         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
16231         local skipped_params='force_lbug|changelog_mask|daemon_file'
16232         $LCTL list_param -FR '*' | grep '=' | tr -d = |
16233                 egrep -v "$skipped_params" |
16234                 xargs -n 1 find $proc_dirs -name |
16235                 xargs -n 1 badarea_io ||
16236                 error "client badarea_io failed"
16237
16238         # remount the FS in case writes/reads /proc break the FS
16239         cleanup || error "failed to unmount"
16240         setup || error "failed to setup"
16241 }
16242 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
16243
16244 test_133g() {
16245         remote_mds_nodsh && skip "remote MDS with nodsh"
16246         remote_ost_nodsh && skip "remote OST with nodsh"
16247
16248         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
16249         local proc_dirs_str=$(eval echo $proc_dirs)
16250         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
16251         local facet
16252         for facet in mds1 ost1; do
16253                 local facet_ver=$(lustre_version_code $facet)
16254                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
16255                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
16256                 else
16257                         log "$facet: too old lustre for get_param -R"
16258                 fi
16259                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
16260                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
16261                                 tr -d = | egrep -v $skipped_params |
16262                                 xargs -n 1 find $proc_dirs_str -name |
16263                                 xargs -n 1 badarea_io" ||
16264                                         error "$facet badarea_io failed"
16265                 else
16266                         skip_noexit "$facet: too old lustre for get_param -R"
16267                 fi
16268         done
16269
16270         # remount the FS in case writes/reads /proc break the FS
16271         cleanup || error "failed to unmount"
16272         setup || error "failed to setup"
16273 }
16274 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
16275
16276 test_133h() {
16277         remote_mds_nodsh && skip "remote MDS with nodsh"
16278         remote_ost_nodsh && skip "remote OST with nodsh"
16279         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
16280                 skip "Need MDS version at least 2.9.54"
16281
16282         local facet
16283         for facet in client mds1 ost1; do
16284                 # Get the list of files that are missing the terminating newline
16285                 local plist=$(do_facet $facet
16286                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
16287                 local ent
16288                 for ent in $plist; do
16289                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
16290                                 awk -v FS='\v' -v RS='\v\v' \
16291                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
16292                                         print FILENAME}'" 2>/dev/null)
16293                         [ -z $missing ] || {
16294                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
16295                                 error "file does not end with newline: $facet-$ent"
16296                         }
16297                 done
16298         done
16299 }
16300 run_test 133h "Proc files should end with newlines"
16301
16302 test_134a() {
16303         remote_mds_nodsh && skip "remote MDS with nodsh"
16304         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
16305                 skip "Need MDS version at least 2.7.54"
16306
16307         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
16308         cancel_lru_locks mdc
16309
16310         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
16311         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
16312         [ $unused -eq 0 ] || error "$unused locks are not cleared"
16313
16314         local nr=1000
16315         createmany -o $DIR/$tdir/f $nr ||
16316                 error "failed to create $nr files in $DIR/$tdir"
16317         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
16318
16319         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
16320         do_facet mds1 $LCTL set_param fail_loc=0x327
16321         do_facet mds1 $LCTL set_param fail_val=500
16322         touch $DIR/$tdir/m
16323
16324         echo "sleep 10 seconds ..."
16325         sleep 10
16326         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
16327
16328         do_facet mds1 $LCTL set_param fail_loc=0
16329         do_facet mds1 $LCTL set_param fail_val=0
16330         [ $lck_cnt -lt $unused ] ||
16331                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
16332
16333         rm $DIR/$tdir/m
16334         unlinkmany $DIR/$tdir/f $nr
16335 }
16336 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
16337
16338 test_134b() {
16339         remote_mds_nodsh && skip "remote MDS with nodsh"
16340         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
16341                 skip "Need MDS version at least 2.7.54"
16342
16343         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
16344         cancel_lru_locks mdc
16345
16346         local low_wm=$(do_facet mds1 $LCTL get_param -n \
16347                         ldlm.lock_reclaim_threshold_mb)
16348         # disable reclaim temporarily
16349         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
16350
16351         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
16352         do_facet mds1 $LCTL set_param fail_loc=0x328
16353         do_facet mds1 $LCTL set_param fail_val=500
16354
16355         $LCTL set_param debug=+trace
16356
16357         local nr=600
16358         createmany -o $DIR/$tdir/f $nr &
16359         local create_pid=$!
16360
16361         echo "Sleep $TIMEOUT seconds ..."
16362         sleep $TIMEOUT
16363         if ! ps -p $create_pid  > /dev/null 2>&1; then
16364                 do_facet mds1 $LCTL set_param fail_loc=0
16365                 do_facet mds1 $LCTL set_param fail_val=0
16366                 do_facet mds1 $LCTL set_param \
16367                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
16368                 error "createmany finished incorrectly!"
16369         fi
16370         do_facet mds1 $LCTL set_param fail_loc=0
16371         do_facet mds1 $LCTL set_param fail_val=0
16372         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
16373         wait $create_pid || return 1
16374
16375         unlinkmany $DIR/$tdir/f $nr
16376 }
16377 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
16378
16379 test_135() {
16380         remote_mds_nodsh && skip "remote MDS with nodsh"
16381         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
16382                 skip "Need MDS version at least 2.13.50"
16383         local fname
16384
16385         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
16386
16387 #define OBD_FAIL_PLAIN_RECORDS 0x1319
16388         #set only one record at plain llog
16389         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
16390
16391         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
16392
16393         #fill already existed plain llog each 64767
16394         #wrapping whole catalog
16395         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
16396
16397         createmany -o $DIR/$tdir/$tfile_ 64700
16398         for (( i = 0; i < 64700; i = i + 2 ))
16399         do
16400                 rm $DIR/$tdir/$tfile_$i &
16401                 rm $DIR/$tdir/$tfile_$((i + 1)) &
16402                 local pid=$!
16403                 wait $pid
16404         done
16405
16406         #waiting osp synchronization
16407         wait_delete_completed
16408 }
16409 run_test 135 "Race catalog processing"
16410
16411 test_136() {
16412         remote_mds_nodsh && skip "remote MDS with nodsh"
16413         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
16414                 skip "Need MDS version at least 2.13.50"
16415         local fname
16416
16417         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
16418         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
16419         #set only one record at plain llog
16420 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
16421         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
16422
16423         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
16424
16425         #fill already existed 2 plain llogs each 64767
16426         #wrapping whole catalog
16427         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
16428         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
16429         wait_delete_completed
16430
16431         createmany -o $DIR/$tdir/$tfile_ 10
16432         sleep 25
16433
16434         do_facet $SINGLEMDS $LCTL set_param fail_val=3
16435         for (( i = 0; i < 10; i = i + 3 ))
16436         do
16437                 rm $DIR/$tdir/$tfile_$i &
16438                 rm $DIR/$tdir/$tfile_$((i + 1)) &
16439                 local pid=$!
16440                 wait $pid
16441                 sleep 7
16442                 rm $DIR/$tdir/$tfile_$((i + 2)) &
16443         done
16444
16445         #waiting osp synchronization
16446         wait_delete_completed
16447 }
16448 run_test 136 "Race catalog processing 2"
16449
16450 test_140() { #bug-17379
16451         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16452
16453         test_mkdir $DIR/$tdir
16454         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
16455         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
16456
16457         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
16458         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
16459         local i=0
16460         while i=$((i + 1)); do
16461                 test_mkdir $i
16462                 cd $i || error "Changing to $i"
16463                 ln -s ../stat stat || error "Creating stat symlink"
16464                 # Read the symlink until ELOOP present,
16465                 # not LBUGing the system is considered success,
16466                 # we didn't overrun the stack.
16467                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
16468                 if [ $ret -ne 0 ]; then
16469                         if [ $ret -eq 40 ]; then
16470                                 break  # -ELOOP
16471                         else
16472                                 error "Open stat symlink"
16473                                         return
16474                         fi
16475                 fi
16476         done
16477         i=$((i - 1))
16478         echo "The symlink depth = $i"
16479         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
16480                 error "Invalid symlink depth"
16481
16482         # Test recursive symlink
16483         ln -s symlink_self symlink_self
16484         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
16485         echo "open symlink_self returns $ret"
16486         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
16487 }
16488 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
16489
16490 test_150a() {
16491         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16492
16493         local TF="$TMP/$tfile"
16494
16495         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16496         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16497         cp $TF $DIR/$tfile
16498         cancel_lru_locks $OSC
16499         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
16500         remount_client $MOUNT
16501         df -P $MOUNT
16502         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
16503
16504         $TRUNCATE $TF 6000
16505         $TRUNCATE $DIR/$tfile 6000
16506         cancel_lru_locks $OSC
16507         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
16508
16509         echo "12345" >>$TF
16510         echo "12345" >>$DIR/$tfile
16511         cancel_lru_locks $OSC
16512         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
16513
16514         echo "12345" >>$TF
16515         echo "12345" >>$DIR/$tfile
16516         cancel_lru_locks $OSC
16517         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
16518 }
16519 run_test 150a "truncate/append tests"
16520
16521 test_150b() {
16522         check_set_fallocate_or_skip
16523         local out
16524
16525         touch $DIR/$tfile
16526         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16527         out=$(check_fallocate $DIR/$tfile 2>&1) ||
16528                 skip_eopnotsupp "$out|check_fallocate failed"
16529 }
16530 run_test 150b "Verify fallocate (prealloc) functionality"
16531
16532 test_150bb() {
16533         check_set_fallocate_or_skip
16534
16535         touch $DIR/$tfile
16536         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16537         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
16538         > $DIR/$tfile
16539         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
16540         # precomputed md5sum for 20MB of zeroes
16541         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
16542         local sum=($(md5sum $DIR/$tfile))
16543
16544         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
16545
16546         check_set_fallocate 1
16547
16548         > $DIR/$tfile
16549         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
16550         sum=($(md5sum $DIR/$tfile))
16551
16552         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
16553 }
16554 run_test 150bb "Verify fallocate modes both zero space"
16555
16556 test_150c() {
16557         check_set_fallocate_or_skip
16558         local striping="-c2"
16559
16560         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16561         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
16562         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
16563         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
16564         local want=$((OSTCOUNT * 1048576))
16565
16566         # Must allocate all requested space, not more than 5% extra
16567         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16568                 error "bytes $bytes is not $want"
16569
16570         rm -f $DIR/$tfile
16571
16572         echo "verify fallocate on PFL file"
16573
16574         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
16575
16576         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
16577                 error "Create $DIR/$tfile failed"
16578         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
16579         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
16580         want=$((512 * 1048576))
16581
16582         # Must allocate all requested space, not more than 5% extra
16583         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16584                 error "bytes $bytes is not $want"
16585 }
16586 run_test 150c "Verify fallocate Size and Blocks"
16587
16588 test_150d() {
16589         check_set_fallocate_or_skip
16590         local striping="-c2"
16591
16592         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
16593
16594         stack_trap "rm -f $DIR/$tdir; wait_delete_completed"
16595         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
16596                 error "setstripe failed"
16597         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
16598         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
16599         local want=$((OSTCOUNT * 1048576))
16600
16601         # Must allocate all requested space, not more than 5% extra
16602         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16603                 error "bytes $bytes is not $want"
16604 }
16605 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
16606
16607 test_150e() {
16608         check_set_fallocate_or_skip
16609
16610         echo "df before:"
16611         $LFS df
16612         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16613         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16614                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16615
16616         # Find OST with Minimum Size
16617         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16618                        sort -un | head -1)
16619
16620         # Get 100MB per OST of the available space to reduce run time
16621         # else 60% of the available space if we are running SLOW tests
16622         if [ $SLOW == "no" ]; then
16623                 local space=$((1024 * 100 * OSTCOUNT))
16624         else
16625                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
16626         fi
16627
16628         fallocate -l${space}k $DIR/$tfile ||
16629                 error "fallocate ${space}k $DIR/$tfile failed"
16630         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
16631
16632         # get size immediately after fallocate. This should be correctly
16633         # updated
16634         local size=$(stat -c '%s' $DIR/$tfile)
16635         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
16636
16637         # Sleep for a while for statfs to get updated. And not pull from cache.
16638         sleep 2
16639
16640         echo "df after fallocate:"
16641         $LFS df
16642
16643         (( size / 1024 == space )) || error "size $size != requested $space"
16644         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
16645                 error "used $used < space $space"
16646
16647         rm $DIR/$tfile || error "rm failed"
16648         sync
16649         wait_delete_completed
16650
16651         echo "df after unlink:"
16652         $LFS df
16653 }
16654 run_test 150e "Verify 60% of available OST space consumed by fallocate"
16655
16656 test_150f() {
16657         local size
16658         local blocks
16659         local want_size_before=20480 # in bytes
16660         local want_blocks_before=40 # 512 sized blocks
16661         local want_blocks_after=24  # 512 sized blocks
16662         local length=$(((want_blocks_before - want_blocks_after) * 512))
16663
16664         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16665                 skip "need at least 2.14.0 for fallocate punch"
16666
16667         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16668                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16669         fi
16670
16671         check_set_fallocate_or_skip
16672         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16673
16674         [[ "x$DOM" == "xyes" ]] &&
16675                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
16676
16677         echo "Verify fallocate punch: Range within the file range"
16678         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16679                 error "dd failed for bs 4096 and count 5"
16680
16681         # Call fallocate with punch range which is within the file range
16682         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
16683                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
16684         # client must see changes immediately after fallocate
16685         size=$(stat -c '%s' $DIR/$tfile)
16686         blocks=$(stat -c '%b' $DIR/$tfile)
16687
16688         # Verify punch worked.
16689         (( blocks == want_blocks_after )) ||
16690                 error "punch failed: blocks $blocks != $want_blocks_after"
16691
16692         (( size == want_size_before )) ||
16693                 error "punch failed: size $size != $want_size_before"
16694
16695         # Verify there is hole in file
16696         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
16697         # precomputed md5sum
16698         local expect="4a9a834a2db02452929c0a348273b4aa"
16699
16700         cksum=($(md5sum $DIR/$tfile))
16701         [[ "${cksum[0]}" == "$expect" ]] ||
16702                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16703
16704         # Start second sub-case for fallocate punch.
16705         echo "Verify fallocate punch: Range overlapping and less than blocksize"
16706         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16707                 error "dd failed for bs 4096 and count 5"
16708
16709         # Punch range less than block size will have no change in block count
16710         want_blocks_after=40  # 512 sized blocks
16711
16712         # Punch overlaps two blocks and less than blocksize
16713         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
16714                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
16715         size=$(stat -c '%s' $DIR/$tfile)
16716         blocks=$(stat -c '%b' $DIR/$tfile)
16717
16718         # Verify punch worked.
16719         (( blocks == want_blocks_after )) ||
16720                 error "punch failed: blocks $blocks != $want_blocks_after"
16721
16722         (( size == want_size_before )) ||
16723                 error "punch failed: size $size != $want_size_before"
16724
16725         # Verify if range is really zero'ed out. We expect Zeros.
16726         # precomputed md5sum
16727         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
16728         cksum=($(md5sum $DIR/$tfile))
16729         [[ "${cksum[0]}" == "$expect" ]] ||
16730                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16731 }
16732 run_test 150f "Verify fallocate punch functionality"
16733
16734 test_150g() {
16735         local space
16736         local size
16737         local blocks
16738         local blocks_after
16739         local size_after
16740         local BS=4096 # Block size in bytes
16741
16742         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16743                 skip "need at least 2.14.0 for fallocate punch"
16744
16745         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16746                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16747         fi
16748
16749         check_set_fallocate_or_skip
16750         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16751
16752         if [[ "x$DOM" == "xyes" ]]; then
16753                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
16754                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
16755         else
16756                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16757                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16758         fi
16759
16760         # Get 100MB per OST of the available space to reduce run time
16761         # else 60% of the available space if we are running SLOW tests
16762         if [ $SLOW == "no" ]; then
16763                 space=$((1024 * 100 * OSTCOUNT))
16764         else
16765                 # Find OST with Minimum Size
16766                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16767                         sort -un | head -1)
16768                 echo "min size OST: $space"
16769                 space=$(((space * 60)/100 * OSTCOUNT))
16770         fi
16771         # space in 1k units, round to 4k blocks
16772         local blkcount=$((space * 1024 / $BS))
16773
16774         echo "Verify fallocate punch: Very large Range"
16775         fallocate -l${space}k $DIR/$tfile ||
16776                 error "fallocate ${space}k $DIR/$tfile failed"
16777         # write 1M at the end, start and in the middle
16778         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
16779                 error "dd failed: bs $BS count 256"
16780         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
16781                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
16782         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
16783                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
16784
16785         # Gather stats.
16786         size=$(stat -c '%s' $DIR/$tfile)
16787
16788         # gather punch length.
16789         local punch_size=$((size - (BS * 2)))
16790
16791         echo "punch_size = $punch_size"
16792         echo "size - punch_size: $((size - punch_size))"
16793         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
16794
16795         # Call fallocate to punch all except 2 blocks. We leave the
16796         # first and the last block
16797         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
16798         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
16799                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
16800
16801         size_after=$(stat -c '%s' $DIR/$tfile)
16802         blocks_after=$(stat -c '%b' $DIR/$tfile)
16803
16804         # Verify punch worked.
16805         # Size should be kept
16806         (( size == size_after )) ||
16807                 error "punch failed: size $size != $size_after"
16808
16809         # two 4k data blocks to remain plus possible 1 extra extent block
16810         (( blocks_after <= ((BS / 512) * 3) )) ||
16811                 error "too many blocks remains: $blocks_after"
16812
16813         # Verify that file has hole between the first and the last blocks
16814         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
16815         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
16816
16817         echo "Hole at [$hole_start, $hole_end)"
16818         (( hole_start == BS )) ||
16819                 error "no hole at offset $BS after punch"
16820
16821         (( hole_end == BS + punch_size )) ||
16822                 error "data at offset $hole_end < $((BS + punch_size))"
16823 }
16824 run_test 150g "Verify fallocate punch on large range"
16825
16826 test_150h() {
16827         local file=$DIR/$tfile
16828         local size
16829
16830         check_set_fallocate_or_skip
16831         statx_supported || skip_env "Test must be statx() syscall supported"
16832
16833         # fallocate() does not update the size information on the MDT
16834         fallocate -l 16K $file || error "failed to fallocate $file"
16835         cancel_lru_locks $OSC
16836         # STATX with cached-always mode will not send glimpse RPCs to OST,
16837         # it uses the caching attrs on the client side as much as possible.
16838         size=$($STATX --cached=always -c %s $file)
16839         [ $size == 16384 ] ||
16840                 error "size after fallocate() is $size, expected 16384"
16841 }
16842 run_test 150h "Verify extend fallocate updates the file size"
16843
16844 #LU-2902 roc_hit was not able to read all values from lproc
16845 function roc_hit_init() {
16846         local list=$(comma_list $(osts_nodes))
16847         local dir=$DIR/$tdir-check
16848         local file=$dir/$tfile
16849         local BEFORE
16850         local AFTER
16851         local idx
16852
16853         test_mkdir $dir
16854         #use setstripe to do a write to every ost
16855         for i in $(seq 0 $((OSTCOUNT-1))); do
16856                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
16857                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
16858                 idx=$(printf %04x $i)
16859                 BEFORE=$(get_osd_param $list *OST*$idx stats |
16860                         awk '$1 == "cache_access" {sum += $7}
16861                                 END { printf("%0.0f", sum) }')
16862
16863                 cancel_lru_locks osc
16864                 cat $file >/dev/null
16865
16866                 AFTER=$(get_osd_param $list *OST*$idx stats |
16867                         awk '$1 == "cache_access" {sum += $7}
16868                                 END { printf("%0.0f", sum) }')
16869
16870                 echo BEFORE:$BEFORE AFTER:$AFTER
16871                 if ! let "AFTER - BEFORE == 4"; then
16872                         rm -rf $dir
16873                         error "roc_hit is not safe to use"
16874                 fi
16875                 rm $file
16876         done
16877
16878         rm -rf $dir
16879 }
16880
16881 function roc_hit() {
16882         local list=$(comma_list $(osts_nodes))
16883         echo $(get_osd_param $list '' stats |
16884                 awk '$1 == "cache_hit" {sum += $7}
16885                         END { printf("%0.0f", sum) }')
16886 }
16887
16888 function set_cache() {
16889         local on=1
16890
16891         if [ "$2" == "off" ]; then
16892                 on=0;
16893         fi
16894         local list=$(comma_list $(osts_nodes))
16895         set_osd_param $list '' $1_cache_enable $on
16896
16897         cancel_lru_locks osc
16898 }
16899
16900 test_151() {
16901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16902         remote_ost_nodsh && skip "remote OST with nodsh"
16903         (( CLIENT_VERSION == OST1_VERSION )) ||
16904                 skip "LU-13081: no interop testing for OSS cache"
16905
16906         local CPAGES=3
16907         local list=$(comma_list $(osts_nodes))
16908
16909         # check whether obdfilter is cache capable at all
16910         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
16911                 skip "not cache-capable obdfilter"
16912         fi
16913
16914         # check cache is enabled on all obdfilters
16915         if get_osd_param $list '' read_cache_enable | grep 0; then
16916                 skip "oss cache is disabled"
16917         fi
16918
16919         set_osd_param $list '' writethrough_cache_enable 1
16920
16921         # check write cache is enabled on all obdfilters
16922         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
16923                 skip "oss write cache is NOT enabled"
16924         fi
16925
16926         roc_hit_init
16927
16928         #define OBD_FAIL_OBD_NO_LRU  0x609
16929         do_nodes $list $LCTL set_param fail_loc=0x609
16930
16931         # pages should be in the case right after write
16932         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
16933                 error "dd failed"
16934
16935         local BEFORE=$(roc_hit)
16936         cancel_lru_locks osc
16937         cat $DIR/$tfile >/dev/null
16938         local AFTER=$(roc_hit)
16939
16940         do_nodes $list $LCTL set_param fail_loc=0
16941
16942         if ! let "AFTER - BEFORE == CPAGES"; then
16943                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
16944         fi
16945
16946         cancel_lru_locks osc
16947         # invalidates OST cache
16948         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
16949         set_osd_param $list '' read_cache_enable 0
16950         cat $DIR/$tfile >/dev/null
16951
16952         # now data shouldn't be found in the cache
16953         BEFORE=$(roc_hit)
16954         cancel_lru_locks osc
16955         cat $DIR/$tfile >/dev/null
16956         AFTER=$(roc_hit)
16957         if let "AFTER - BEFORE != 0"; then
16958                 error "IN CACHE: before: $BEFORE, after: $AFTER"
16959         fi
16960
16961         set_osd_param $list '' read_cache_enable 1
16962         rm -f $DIR/$tfile
16963 }
16964 run_test 151 "test cache on oss and controls ==============================="
16965
16966 test_152() {
16967         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16968
16969         local TF="$TMP/$tfile"
16970
16971         # simulate ENOMEM during write
16972 #define OBD_FAIL_OST_NOMEM      0x226
16973         lctl set_param fail_loc=0x80000226
16974         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16975         cp $TF $DIR/$tfile
16976         sync || error "sync failed"
16977         lctl set_param fail_loc=0
16978
16979         # discard client's cache
16980         cancel_lru_locks osc
16981
16982         # simulate ENOMEM during read
16983         lctl set_param fail_loc=0x80000226
16984         cmp $TF $DIR/$tfile || error "cmp failed"
16985         lctl set_param fail_loc=0
16986
16987         rm -f $TF
16988 }
16989 run_test 152 "test read/write with enomem ============================"
16990
16991 test_153() {
16992         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
16993 }
16994 run_test 153 "test if fdatasync does not crash ======================="
16995
16996 dot_lustre_fid_permission_check() {
16997         local fid=$1
16998         local ffid=$MOUNT/.lustre/fid/$fid
16999         local test_dir=$2
17000
17001         echo "stat fid $fid"
17002         stat $ffid || error "stat $ffid failed."
17003         echo "touch fid $fid"
17004         touch $ffid || error "touch $ffid failed."
17005         echo "write to fid $fid"
17006         cat /etc/hosts > $ffid || error "write $ffid failed."
17007         echo "read fid $fid"
17008         diff /etc/hosts $ffid || error "read $ffid failed."
17009         echo "append write to fid $fid"
17010         cat /etc/hosts >> $ffid || error "append write $ffid failed."
17011         echo "rename fid $fid"
17012         mv $ffid $test_dir/$tfile.1 &&
17013                 error "rename $ffid to $tfile.1 should fail."
17014         touch $test_dir/$tfile.1
17015         mv $test_dir/$tfile.1 $ffid &&
17016                 error "rename $tfile.1 to $ffid should fail."
17017         rm -f $test_dir/$tfile.1
17018         echo "truncate fid $fid"
17019         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
17020         echo "link fid $fid"
17021         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
17022         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
17023                 id $USER0 || skip_env "missing user $USER0"
17024                 echo "setfacl fid $fid"
17025                 setfacl -R -m u:$USER0:rwx $ffid ||
17026                         error "setfacl $ffid failed"
17027                 echo "getfacl fid $fid"
17028                 getfacl $ffid || error "getfacl $ffid failed."
17029         fi
17030         echo "unlink fid $fid"
17031         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
17032         echo "mknod fid $fid"
17033         mknod $ffid c 1 3 && error "mknod $ffid should fail."
17034
17035         fid=[0xf00000400:0x1:0x0]
17036         ffid=$MOUNT/.lustre/fid/$fid
17037
17038         echo "stat non-exist fid $fid"
17039         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
17040         echo "write to non-exist fid $fid"
17041         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
17042         echo "link new fid $fid"
17043         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
17044
17045         mkdir -p $test_dir/$tdir
17046         touch $test_dir/$tdir/$tfile
17047         fid=$($LFS path2fid $test_dir/$tdir)
17048         rc=$?
17049         [ $rc -ne 0 ] &&
17050                 error "error: could not get fid for $test_dir/$dir/$tfile."
17051
17052         ffid=$MOUNT/.lustre/fid/$fid
17053
17054         echo "ls $fid"
17055         ls $ffid || error "ls $ffid failed."
17056         echo "touch $fid/$tfile.1"
17057         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
17058
17059         echo "touch $MOUNT/.lustre/fid/$tfile"
17060         touch $MOUNT/.lustre/fid/$tfile && \
17061                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
17062
17063         echo "setxattr to $MOUNT/.lustre/fid"
17064         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
17065
17066         echo "listxattr for $MOUNT/.lustre/fid"
17067         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
17068
17069         echo "delxattr from $MOUNT/.lustre/fid"
17070         setfattr -x trusted.name1 $MOUNT/.lustre/fid
17071
17072         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
17073         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
17074                 error "touch invalid fid should fail."
17075
17076         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
17077         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
17078                 error "touch non-normal fid should fail."
17079
17080         echo "rename $tdir to $MOUNT/.lustre/fid"
17081         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
17082                 error "rename to $MOUNT/.lustre/fid should fail."
17083
17084         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
17085         then            # LU-3547
17086                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
17087                 local new_obf_mode=777
17088
17089                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
17090                 chmod $new_obf_mode $DIR/.lustre/fid ||
17091                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
17092
17093                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
17094                 [ $obf_mode -eq $new_obf_mode ] ||
17095                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
17096
17097                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
17098                 chmod $old_obf_mode $DIR/.lustre/fid ||
17099                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
17100         fi
17101
17102         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
17103         fid=$($LFS path2fid $test_dir/$tfile-2)
17104
17105         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
17106         then # LU-5424
17107                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
17108                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
17109                         error "create lov data thru .lustre failed"
17110         fi
17111         echo "cp /etc/passwd $test_dir/$tfile-2"
17112         cp /etc/passwd $test_dir/$tfile-2 ||
17113                 error "copy to $test_dir/$tfile-2 failed."
17114         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
17115         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
17116                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
17117
17118         rm -rf $test_dir/tfile.lnk
17119         rm -rf $test_dir/$tfile-2
17120 }
17121
17122 test_154A() {
17123         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
17124                 skip "Need MDS version at least 2.4.1"
17125
17126         local tf=$DIR/$tfile
17127         touch $tf
17128
17129         local fid=$($LFS path2fid $tf)
17130         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
17131
17132         # check that we get the same pathname back
17133         local rootpath
17134         local found
17135         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
17136                 echo "$rootpath $fid"
17137                 found=$($LFS fid2path $rootpath "$fid")
17138                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
17139                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
17140         done
17141
17142         # check wrong root path format
17143         rootpath=$MOUNT"_wrong"
17144         found=$($LFS fid2path $rootpath "$fid")
17145         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
17146 }
17147 run_test 154A "lfs path2fid and fid2path basic checks"
17148
17149 test_154B() {
17150         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
17151                 skip "Need MDS version at least 2.4.1"
17152
17153         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
17154         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
17155         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
17156         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
17157
17158         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
17159         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
17160
17161         # check that we get the same pathname
17162         echo "PFID: $PFID, name: $name"
17163         local FOUND=$($LFS fid2path $MOUNT "$PFID")
17164         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
17165         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
17166                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
17167
17168         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
17169 }
17170 run_test 154B "verify the ll_decode_linkea tool"
17171
17172 test_154a() {
17173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17174         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17175         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
17176                 skip "Need MDS version at least 2.2.51"
17177         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
17178
17179         cp /etc/hosts $DIR/$tfile
17180
17181         fid=$($LFS path2fid $DIR/$tfile)
17182         rc=$?
17183         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
17184
17185         dot_lustre_fid_permission_check "$fid" $DIR ||
17186                 error "dot lustre permission check $fid failed"
17187
17188         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
17189
17190         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
17191
17192         touch $MOUNT/.lustre/file &&
17193                 error "creation is not allowed under .lustre"
17194
17195         mkdir $MOUNT/.lustre/dir &&
17196                 error "mkdir is not allowed under .lustre"
17197
17198         rm -rf $DIR/$tfile
17199 }
17200 run_test 154a "Open-by-FID"
17201
17202 test_154b() {
17203         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17204         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17205         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17206         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
17207                 skip "Need MDS version at least 2.2.51"
17208
17209         local remote_dir=$DIR/$tdir/remote_dir
17210         local MDTIDX=1
17211         local rc=0
17212
17213         mkdir -p $DIR/$tdir
17214         $LFS mkdir -i $MDTIDX $remote_dir ||
17215                 error "create remote directory failed"
17216
17217         cp /etc/hosts $remote_dir/$tfile
17218
17219         fid=$($LFS path2fid $remote_dir/$tfile)
17220         rc=$?
17221         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
17222
17223         dot_lustre_fid_permission_check "$fid" $remote_dir ||
17224                 error "dot lustre permission check $fid failed"
17225         rm -rf $DIR/$tdir
17226 }
17227 run_test 154b "Open-by-FID for remote directory"
17228
17229 test_154c() {
17230         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
17231                 skip "Need MDS version at least 2.4.1"
17232
17233         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
17234         local FID1=$($LFS path2fid $DIR/$tfile.1)
17235         local FID2=$($LFS path2fid $DIR/$tfile.2)
17236         local FID3=$($LFS path2fid $DIR/$tfile.3)
17237
17238         local N=1
17239         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
17240                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
17241                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
17242                 local want=FID$N
17243                 [ "$FID" = "${!want}" ] ||
17244                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
17245                 N=$((N + 1))
17246         done
17247
17248         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
17249         do
17250                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
17251                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
17252                 N=$((N + 1))
17253         done
17254 }
17255 run_test 154c "lfs path2fid and fid2path multiple arguments"
17256
17257 test_154d() {
17258         remote_mds_nodsh && skip "remote MDS with nodsh"
17259         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
17260                 skip "Need MDS version at least 2.5.53"
17261
17262         if remote_mds; then
17263                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
17264         else
17265                 nid="0@lo"
17266         fi
17267         local proc_ofile="mdt.*.exports.'$nid'.open_files"
17268         local fd
17269         local cmd
17270
17271         rm -f $DIR/$tfile
17272         touch $DIR/$tfile
17273
17274         local fid=$($LFS path2fid $DIR/$tfile)
17275         # Open the file
17276         fd=$(free_fd)
17277         cmd="exec $fd<$DIR/$tfile"
17278         eval $cmd
17279         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
17280         echo "$fid_list" | grep "$fid"
17281         rc=$?
17282
17283         cmd="exec $fd>/dev/null"
17284         eval $cmd
17285         if [ $rc -ne 0 ]; then
17286                 error "FID $fid not found in open files list $fid_list"
17287         fi
17288 }
17289 run_test 154d "Verify open file fid"
17290
17291 test_154e()
17292 {
17293         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
17294                 skip "Need MDS version at least 2.6.50"
17295
17296         if ls -a $MOUNT | grep -q '^\.lustre$'; then
17297                 error ".lustre returned by readdir"
17298         fi
17299 }
17300 run_test 154e ".lustre is not returned by readdir"
17301
17302 test_154f() {
17303         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17304
17305         # create parent directory on a single MDT to avoid cross-MDT hardlinks
17306         mkdir_on_mdt0 $DIR/$tdir
17307         # test dirs inherit from its stripe
17308         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
17309         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
17310         cp /etc/hosts $DIR/$tdir/foo1/$tfile
17311         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
17312         touch $DIR/f
17313
17314         # get fid of parents
17315         local FID0=$($LFS path2fid $DIR/$tdir)
17316         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
17317         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
17318         local FID3=$($LFS path2fid $DIR)
17319
17320         # check that path2fid --parents returns expected <parent_fid>/name
17321         # 1) test for a directory (single parent)
17322         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
17323         [ "$parent" == "$FID0/foo1" ] ||
17324                 error "expected parent: $FID0/foo1, got: $parent"
17325
17326         # 2) test for a file with nlink > 1 (multiple parents)
17327         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
17328         echo "$parent" | grep -F "$FID1/$tfile" ||
17329                 error "$FID1/$tfile not returned in parent list"
17330         echo "$parent" | grep -F "$FID2/link" ||
17331                 error "$FID2/link not returned in parent list"
17332
17333         # 3) get parent by fid
17334         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
17335         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17336         echo "$parent" | grep -F "$FID1/$tfile" ||
17337                 error "$FID1/$tfile not returned in parent list (by fid)"
17338         echo "$parent" | grep -F "$FID2/link" ||
17339                 error "$FID2/link not returned in parent list (by fid)"
17340
17341         # 4) test for entry in root directory
17342         parent=$($LFS path2fid --parents $DIR/f)
17343         echo "$parent" | grep -F "$FID3/f" ||
17344                 error "$FID3/f not returned in parent list"
17345
17346         # 5) test it on root directory
17347         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
17348                 error "$MOUNT should not have parents"
17349
17350         # enable xattr caching and check that linkea is correctly updated
17351         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
17352         save_lustre_params client "llite.*.xattr_cache" > $save
17353         lctl set_param llite.*.xattr_cache 1
17354
17355         # 6.1) linkea update on rename
17356         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
17357
17358         # get parents by fid
17359         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17360         # foo1 should no longer be returned in parent list
17361         echo "$parent" | grep -F "$FID1" &&
17362                 error "$FID1 should no longer be in parent list"
17363         # the new path should appear
17364         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
17365                 error "$FID2/$tfile.moved is not in parent list"
17366
17367         # 6.2) linkea update on unlink
17368         rm -f $DIR/$tdir/foo2/link
17369         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17370         # foo2/link should no longer be returned in parent list
17371         echo "$parent" | grep -F "$FID2/link" &&
17372                 error "$FID2/link should no longer be in parent list"
17373         true
17374
17375         rm -f $DIR/f
17376         restore_lustre_params < $save
17377         rm -f $save
17378 }
17379 run_test 154f "get parent fids by reading link ea"
17380
17381 test_154g()
17382 {
17383         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
17384            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
17385                 skip "Need MDS version at least 2.6.92"
17386
17387         mkdir_on_mdt0 $DIR/$tdir
17388         llapi_fid_test -d $DIR/$tdir
17389 }
17390 run_test 154g "various llapi FID tests"
17391
17392 test_154h()
17393 {
17394         (( $CLIENT_VERSION >= $(version_code 2.15.55.1) )) ||
17395                 skip "Need client at least version 2.15.55.1"
17396
17397         # Create an empty file
17398         touch $DIR/$tfile
17399
17400         # Get FID (interactive mode) and save under $TMP/$tfile.log
17401         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
17402                 path2fid $DIR/$tfile
17403         EOF
17404
17405         fid=$(cat $TMP/$tfile.log)
17406         # $fid should not be empty
17407         [[ ! -z $fid ]] || error "FID is empty"
17408         $LFS rmfid $DIR "$fid" || error "rmfid failed for $fid"
17409 }
17410 run_test 154h "Verify interactive path2fid"
17411
17412 test_155_small_load() {
17413     local temp=$TMP/$tfile
17414     local file=$DIR/$tfile
17415
17416     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
17417         error "dd of=$temp bs=6096 count=1 failed"
17418     cp $temp $file
17419     cancel_lru_locks $OSC
17420     cmp $temp $file || error "$temp $file differ"
17421
17422     $TRUNCATE $temp 6000
17423     $TRUNCATE $file 6000
17424     cmp $temp $file || error "$temp $file differ (truncate1)"
17425
17426     echo "12345" >>$temp
17427     echo "12345" >>$file
17428     cmp $temp $file || error "$temp $file differ (append1)"
17429
17430     echo "12345" >>$temp
17431     echo "12345" >>$file
17432     cmp $temp $file || error "$temp $file differ (append2)"
17433
17434     rm -f $temp $file
17435     true
17436 }
17437
17438 test_155_big_load() {
17439         remote_ost_nodsh && skip "remote OST with nodsh"
17440
17441         local temp=$TMP/$tfile
17442         local file=$DIR/$tfile
17443
17444         free_min_max
17445         local cache_size=$(do_facet ost$((MAXI+1)) \
17446                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
17447
17448         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
17449         # pre-set value
17450         if [ -z "$cache_size" ]; then
17451                 cache_size=256
17452         fi
17453         local large_file_size=$((cache_size * 2))
17454
17455         echo "OSS cache size: $cache_size KB"
17456         echo "Large file size: $large_file_size KB"
17457
17458         [ $MAXV -le $large_file_size ] &&
17459                 skip_env "max available OST size needs > $large_file_size KB"
17460
17461         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
17462
17463         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
17464                 error "dd of=$temp bs=$large_file_size count=1k failed"
17465         cp $temp $file
17466         ls -lh $temp $file
17467         cancel_lru_locks osc
17468         cmp $temp $file || error "$temp $file differ"
17469
17470         rm -f $temp $file
17471         true
17472 }
17473
17474 save_writethrough() {
17475         local facets=$(get_facets OST)
17476
17477         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
17478 }
17479
17480 test_155a() {
17481         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17482
17483         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17484
17485         save_writethrough $p
17486
17487         set_cache read on
17488         set_cache writethrough on
17489         test_155_small_load
17490         restore_lustre_params < $p
17491         rm -f $p
17492 }
17493 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
17494
17495 test_155b() {
17496         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17497
17498         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17499
17500         save_writethrough $p
17501
17502         set_cache read on
17503         set_cache writethrough off
17504         test_155_small_load
17505         restore_lustre_params < $p
17506         rm -f $p
17507 }
17508 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
17509
17510 test_155c() {
17511         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17512
17513         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17514
17515         save_writethrough $p
17516
17517         set_cache read off
17518         set_cache writethrough on
17519         test_155_small_load
17520         restore_lustre_params < $p
17521         rm -f $p
17522 }
17523 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
17524
17525 test_155d() {
17526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17527
17528         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17529
17530         save_writethrough $p
17531
17532         set_cache read off
17533         set_cache writethrough off
17534         test_155_small_load
17535         restore_lustre_params < $p
17536         rm -f $p
17537 }
17538 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
17539
17540 test_155e() {
17541         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17542
17543         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17544
17545         save_writethrough $p
17546
17547         set_cache read on
17548         set_cache writethrough on
17549         test_155_big_load
17550         restore_lustre_params < $p
17551         rm -f $p
17552 }
17553 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
17554
17555 test_155f() {
17556         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17557
17558         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17559
17560         save_writethrough $p
17561
17562         set_cache read on
17563         set_cache writethrough off
17564         test_155_big_load
17565         restore_lustre_params < $p
17566         rm -f $p
17567 }
17568 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
17569
17570 test_155g() {
17571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17572
17573         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17574
17575         save_writethrough $p
17576
17577         set_cache read off
17578         set_cache writethrough on
17579         test_155_big_load
17580         restore_lustre_params < $p
17581         rm -f $p
17582 }
17583 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
17584
17585 test_155h() {
17586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17587
17588         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17589
17590         save_writethrough $p
17591
17592         set_cache read off
17593         set_cache writethrough off
17594         test_155_big_load
17595         restore_lustre_params < $p
17596         rm -f $p
17597 }
17598 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
17599
17600 test_156() {
17601         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17602         remote_ost_nodsh && skip "remote OST with nodsh"
17603         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
17604                 skip "stats not implemented on old servers"
17605         [ "$ost1_FSTYPE" = "zfs" ] &&
17606                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
17607         (( CLIENT_VERSION == OST1_VERSION )) ||
17608                 skip "LU-13081: no interop testing for OSS cache"
17609
17610         local CPAGES=3
17611         local BEFORE
17612         local AFTER
17613         local file="$DIR/$tfile"
17614         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17615
17616         save_writethrough $p
17617         roc_hit_init
17618
17619         log "Turn on read and write cache"
17620         set_cache read on
17621         set_cache writethrough on
17622
17623         log "Write data and read it back."
17624         log "Read should be satisfied from the cache."
17625         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17626         BEFORE=$(roc_hit)
17627         cancel_lru_locks osc
17628         cat $file >/dev/null
17629         AFTER=$(roc_hit)
17630         if ! let "AFTER - BEFORE == CPAGES"; then
17631                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
17632         else
17633                 log "cache hits: before: $BEFORE, after: $AFTER"
17634         fi
17635
17636         log "Read again; it should be satisfied from the cache."
17637         BEFORE=$AFTER
17638         cancel_lru_locks osc
17639         cat $file >/dev/null
17640         AFTER=$(roc_hit)
17641         if ! let "AFTER - BEFORE == CPAGES"; then
17642                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
17643         else
17644                 log "cache hits:: before: $BEFORE, after: $AFTER"
17645         fi
17646
17647         log "Turn off the read cache and turn on the write cache"
17648         set_cache read off
17649         set_cache writethrough on
17650
17651         log "Read again; it should be satisfied from the cache."
17652         BEFORE=$(roc_hit)
17653         cancel_lru_locks osc
17654         cat $file >/dev/null
17655         AFTER=$(roc_hit)
17656         if ! let "AFTER - BEFORE == CPAGES"; then
17657                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
17658         else
17659                 log "cache hits:: before: $BEFORE, after: $AFTER"
17660         fi
17661
17662         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17663                 # > 2.12.56 uses pagecache if cached
17664                 log "Read again; it should not be satisfied from the cache."
17665                 BEFORE=$AFTER
17666                 cancel_lru_locks osc
17667                 cat $file >/dev/null
17668                 AFTER=$(roc_hit)
17669                 if ! let "AFTER - BEFORE == 0"; then
17670                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
17671                 else
17672                         log "cache hits:: before: $BEFORE, after: $AFTER"
17673                 fi
17674         fi
17675
17676         log "Write data and read it back."
17677         log "Read should be satisfied from the cache."
17678         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17679         BEFORE=$(roc_hit)
17680         cancel_lru_locks osc
17681         cat $file >/dev/null
17682         AFTER=$(roc_hit)
17683         if ! let "AFTER - BEFORE == CPAGES"; then
17684                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
17685         else
17686                 log "cache hits:: before: $BEFORE, after: $AFTER"
17687         fi
17688
17689         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17690                 # > 2.12.56 uses pagecache if cached
17691                 log "Read again; it should not be satisfied from the cache."
17692                 BEFORE=$AFTER
17693                 cancel_lru_locks osc
17694                 cat $file >/dev/null
17695                 AFTER=$(roc_hit)
17696                 if ! let "AFTER - BEFORE == 0"; then
17697                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
17698                 else
17699                         log "cache hits:: before: $BEFORE, after: $AFTER"
17700                 fi
17701         fi
17702
17703         log "Turn off read and write cache"
17704         set_cache read off
17705         set_cache writethrough off
17706
17707         log "Write data and read it back"
17708         log "It should not be satisfied from the cache."
17709         rm -f $file
17710         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17711         cancel_lru_locks osc
17712         BEFORE=$(roc_hit)
17713         cat $file >/dev/null
17714         AFTER=$(roc_hit)
17715         if ! let "AFTER - BEFORE == 0"; then
17716                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
17717         else
17718                 log "cache hits:: before: $BEFORE, after: $AFTER"
17719         fi
17720
17721         log "Turn on the read cache and turn off the write cache"
17722         set_cache read on
17723         set_cache writethrough off
17724
17725         log "Write data and read it back"
17726         log "It should not be satisfied from the cache."
17727         rm -f $file
17728         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17729         BEFORE=$(roc_hit)
17730         cancel_lru_locks osc
17731         cat $file >/dev/null
17732         AFTER=$(roc_hit)
17733         if ! let "AFTER - BEFORE == 0"; then
17734                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
17735         else
17736                 log "cache hits:: before: $BEFORE, after: $AFTER"
17737         fi
17738
17739         log "Read again; it should be satisfied from the cache."
17740         BEFORE=$(roc_hit)
17741         cancel_lru_locks osc
17742         cat $file >/dev/null
17743         AFTER=$(roc_hit)
17744         if ! let "AFTER - BEFORE == CPAGES"; then
17745                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
17746         else
17747                 log "cache hits:: before: $BEFORE, after: $AFTER"
17748         fi
17749
17750         restore_lustre_params < $p
17751         rm -f $p $file
17752 }
17753 run_test 156 "Verification of tunables"
17754
17755 test_160a() {
17756         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17757         remote_mds_nodsh && skip "remote MDS with nodsh"
17758         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17759                 skip "Need MDS version at least 2.2.0"
17760
17761         changelog_register || error "changelog_register failed"
17762         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17763         changelog_users $SINGLEMDS | grep -q $cl_user ||
17764                 error "User $cl_user not found in changelog_users"
17765
17766         mkdir_on_mdt0 $DIR/$tdir
17767
17768         # change something
17769         test_mkdir -p $DIR/$tdir/pics/2008/zachy
17770         changelog_clear 0 || error "changelog_clear failed"
17771         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
17772         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
17773         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17774         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17775         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17776         rm $DIR/$tdir/pics/desktop.jpg
17777
17778         echo "verifying changelog mask"
17779         changelog_chmask "-MKDIR"
17780         changelog_chmask "-CLOSE"
17781
17782         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
17783         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
17784
17785         changelog_chmask "+MKDIR"
17786         changelog_chmask "+CLOSE"
17787
17788         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
17789         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
17790
17791         MKDIRS=$(changelog_dump | grep -c "MKDIR")
17792         CLOSES=$(changelog_dump | grep -c "CLOSE")
17793         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
17794         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
17795
17796         # verify contents
17797         echo "verifying target fid"
17798         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
17799         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
17800         [ "$fidc" == "$fidf" ] ||
17801                 error "changelog '$tfile' fid $fidc != file fid $fidf"
17802         echo "verifying parent fid"
17803         # The FID returned from the Changelog may be the directory shard on
17804         # a different MDT, and not the FID returned by path2fid on the parent.
17805         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
17806         # since this is what will matter when recreating this file in the tree.
17807         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
17808         local pathp=$($LFS fid2path $MOUNT "$fidp")
17809         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
17810                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
17811
17812         echo "getting records for $cl_user"
17813         changelog_users $SINGLEMDS
17814         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
17815         local nclr=3
17816         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
17817                 error "changelog_clear failed"
17818         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
17819         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
17820         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
17821                 error "user index expect $user_rec1 + $nclr != $user_rec2"
17822
17823         local min0_rec=$(changelog_users $SINGLEMDS |
17824                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
17825         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
17826                           awk '{ print $1; exit; }')
17827
17828         changelog_dump | tail -n 5
17829         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
17830         [ $first_rec == $((min0_rec + 1)) ] ||
17831                 error "first index should be $min0_rec + 1 not $first_rec"
17832
17833         # LU-3446 changelog index reset on MDT restart
17834         local cur_rec1=$(changelog_users $SINGLEMDS |
17835                          awk '/^current.index:/ { print $NF }')
17836         changelog_clear 0 ||
17837                 error "clear all changelog records for $cl_user failed"
17838         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
17839         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
17840                 error "Fail to start $SINGLEMDS"
17841         local cur_rec2=$(changelog_users $SINGLEMDS |
17842                          awk '/^current.index:/ { print $NF }')
17843         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
17844         [ $cur_rec1 == $cur_rec2 ] ||
17845                 error "current index should be $cur_rec1 not $cur_rec2"
17846
17847         echo "verifying users from this test are deregistered"
17848         changelog_deregister || error "changelog_deregister failed"
17849         changelog_users $SINGLEMDS | grep -q $cl_user &&
17850                 error "User '$cl_user' still in changelog_users"
17851
17852         # lctl get_param -n mdd.*.changelog_users
17853         # current_index: 144
17854         # ID    index (idle seconds)
17855         # cl3   144   (2) mask=<list>
17856         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
17857                 # this is the normal case where all users were deregistered
17858                 # make sure no new records are added when no users are present
17859                 local last_rec1=$(changelog_users $SINGLEMDS |
17860                                   awk '/^current.index:/ { print $NF }')
17861                 touch $DIR/$tdir/chloe
17862                 local last_rec2=$(changelog_users $SINGLEMDS |
17863                                   awk '/^current.index:/ { print $NF }')
17864                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
17865                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
17866         else
17867                 # any changelog users must be leftovers from a previous test
17868                 changelog_users $SINGLEMDS
17869                 echo "other changelog users; can't verify off"
17870         fi
17871 }
17872 run_test 160a "changelog sanity"
17873
17874 test_160b() { # LU-3587
17875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17876         remote_mds_nodsh && skip "remote MDS with nodsh"
17877         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17878                 skip "Need MDS version at least 2.2.0"
17879
17880         changelog_register || error "changelog_register failed"
17881         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17882         changelog_users $SINGLEMDS | grep -q $cl_user ||
17883                 error "User '$cl_user' not found in changelog_users"
17884
17885         local longname1=$(str_repeat a 255)
17886         local longname2=$(str_repeat b 255)
17887
17888         cd $DIR
17889         echo "creating very long named file"
17890         touch $longname1 || error "create of '$longname1' failed"
17891         echo "renaming very long named file"
17892         mv $longname1 $longname2
17893
17894         changelog_dump | grep RENME | tail -n 5
17895         rm -f $longname2
17896 }
17897 run_test 160b "Verify that very long rename doesn't crash in changelog"
17898
17899 test_160c() {
17900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17901         remote_mds_nodsh && skip "remote MDS with nodsh"
17902
17903         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
17904                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
17905                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
17906                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
17907
17908         local rc=0
17909
17910         # Registration step
17911         changelog_register || error "changelog_register failed"
17912
17913         rm -rf $DIR/$tdir
17914         mkdir -p $DIR/$tdir
17915         $MCREATE $DIR/$tdir/foo_160c
17916         changelog_chmask "-TRUNC"
17917         $TRUNCATE $DIR/$tdir/foo_160c 200
17918         changelog_chmask "+TRUNC"
17919         $TRUNCATE $DIR/$tdir/foo_160c 199
17920         changelog_dump | tail -n 5
17921         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
17922         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
17923 }
17924 run_test 160c "verify that changelog log catch the truncate event"
17925
17926 test_160d() {
17927         remote_mds_nodsh && skip "remote MDS with nodsh"
17928         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17930         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
17931                 skip "Need MDS version at least 2.7.60"
17932
17933         # Registration step
17934         changelog_register || error "changelog_register failed"
17935
17936         mkdir -p $DIR/$tdir/migrate_dir
17937         changelog_clear 0 || error "changelog_clear failed"
17938
17939         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
17940         changelog_dump | tail -n 5
17941         local migrates=$(changelog_dump | grep -c "MIGRT")
17942         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
17943 }
17944 run_test 160d "verify that changelog log catch the migrate event"
17945
17946 test_160e() {
17947         remote_mds_nodsh && skip "remote MDS with nodsh"
17948
17949         # Create a user
17950         changelog_register || error "changelog_register failed"
17951
17952         local MDT0=$(facet_svc $SINGLEMDS)
17953         local rc
17954
17955         # No user (expect fail)
17956         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
17957         rc=$?
17958         if [ $rc -eq 0 ]; then
17959                 error "Should fail without user"
17960         elif [ $rc -ne 4 ]; then
17961                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
17962         fi
17963
17964         # Delete a future user (expect fail)
17965         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
17966         rc=$?
17967         if [ $rc -eq 0 ]; then
17968                 error "Deleted non-existant user cl77"
17969         elif [ $rc -ne 2 ]; then
17970                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
17971         fi
17972
17973         # Clear to a bad index (1 billion should be safe)
17974         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
17975         rc=$?
17976
17977         if [ $rc -eq 0 ]; then
17978                 error "Successfully cleared to invalid CL index"
17979         elif [ $rc -ne 22 ]; then
17980                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
17981         fi
17982 }
17983 run_test 160e "changelog negative testing (should return errors)"
17984
17985 test_160f() {
17986         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17987         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17988                 skip "Need MDS version at least 2.10.56"
17989
17990         local mdts=$(comma_list $(mdts_nodes))
17991
17992         # Create a user
17993         changelog_register || error "first changelog_register failed"
17994         changelog_register || error "second changelog_register failed"
17995         local cl_users
17996         declare -A cl_user1
17997         declare -A cl_user2
17998         local user_rec1
17999         local user_rec2
18000         local i
18001
18002         # generate some changelog records to accumulate on each MDT
18003         # use all_char because created files should be evenly distributed
18004         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18005                 error "test_mkdir $tdir failed"
18006         log "$(date +%s): creating first files"
18007         for ((i = 0; i < MDSCOUNT * 2; i++)); do
18008                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
18009                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
18010         done
18011
18012         # check changelogs have been generated
18013         local start=$SECONDS
18014         local idle_time=$((MDSCOUNT * 5 + 5))
18015         local nbcl=$(changelog_dump | wc -l)
18016         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18017
18018         for param in "changelog_max_idle_time=$idle_time" \
18019                      "changelog_gc=1" \
18020                      "changelog_min_gc_interval=2" \
18021                      "changelog_min_free_cat_entries=3"; do
18022                 local MDT0=$(facet_svc $SINGLEMDS)
18023                 local var="${param%=*}"
18024                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18025
18026                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18027                 do_nodes $mdts $LCTL set_param mdd.*.$param
18028         done
18029
18030         # force cl_user2 to be idle (1st part), but also cancel the
18031         # cl_user1 records so that it is not evicted later in the test.
18032         local sleep1=$((idle_time / 2))
18033         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
18034         sleep $sleep1
18035
18036         # simulate changelog catalog almost full
18037         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
18038         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
18039
18040         for i in $(seq $MDSCOUNT); do
18041                 cl_users=(${CL_USERS[mds$i]})
18042                 cl_user1[mds$i]="${cl_users[0]}"
18043                 cl_user2[mds$i]="${cl_users[1]}"
18044
18045                 [ -n "${cl_user1[mds$i]}" ] ||
18046                         error "mds$i: no user registered"
18047                 [ -n "${cl_user2[mds$i]}" ] ||
18048                         error "mds$i: only ${cl_user2[mds$i]} is registered"
18049
18050                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18051                 [ -n "$user_rec1" ] ||
18052                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18053                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
18054                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18055                 [ -n "$user_rec2" ] ||
18056                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18057                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
18058                      "$user_rec1 + 2 == $user_rec2"
18059                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
18060                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
18061                               "$user_rec1 + 2, but is $user_rec2"
18062                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
18063                 [ -n "$user_rec2" ] ||
18064                         error "mds$i: User ${cl_user2[mds$i]} not registered"
18065                 [ $user_rec1 == $user_rec2 ] ||
18066                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
18067                               "$user_rec1, but is $user_rec2"
18068         done
18069
18070         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
18071         local sleep2=$((idle_time - (SECONDS - start) + 1))
18072         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
18073         sleep $sleep2
18074
18075         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
18076         # cl_user1 should be OK because it recently processed records.
18077         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
18078         for ((i = 0; i < MDSCOUNT * 2; i++)); do
18079                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
18080                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
18081         done
18082
18083         # ensure gc thread is done
18084         for i in $(mdts_nodes); do
18085                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
18086                         error "$i: GC-thread not done"
18087         done
18088
18089         local first_rec
18090         for (( i = 1; i <= MDSCOUNT; i++ )); do
18091                 # check cl_user1 still registered
18092                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
18093                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18094                 # check cl_user2 unregistered
18095                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
18096                         error "mds$i: User ${cl_user2[mds$i]} still registered"
18097
18098                 # check changelogs are present and starting at $user_rec1 + 1
18099                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18100                 [ -n "$user_rec1" ] ||
18101                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18102                 first_rec=$($LFS changelog $(facet_svc mds$i) |
18103                             awk '{ print $1; exit; }')
18104
18105                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
18106                 [ $((user_rec1 + 1)) == $first_rec ] ||
18107                         error "mds$i: rec $first_rec != $user_rec1 + 1"
18108         done
18109 }
18110 run_test 160f "changelog garbage collect (timestamped users)"
18111
18112 test_160g() {
18113         remote_mds_nodsh && skip "remote MDS with nodsh"
18114         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
18115                 skip "Need MDS version at least 2.14.55"
18116
18117         local mdts=$(comma_list $(mdts_nodes))
18118
18119         # Create a user
18120         changelog_register || error "first changelog_register failed"
18121         changelog_register || error "second changelog_register failed"
18122         local cl_users
18123         declare -A cl_user1
18124         declare -A cl_user2
18125         local user_rec1
18126         local user_rec2
18127         local i
18128
18129         # generate some changelog records to accumulate on each MDT
18130         # use all_char because created files should be evenly distributed
18131         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18132                 error "test_mkdir $tdir failed"
18133         for ((i = 0; i < MDSCOUNT; i++)); do
18134                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18135                         error "create $DIR/$tdir/d$i.1 failed"
18136         done
18137
18138         # check changelogs have been generated
18139         local nbcl=$(changelog_dump | wc -l)
18140         (( $nbcl > 0 )) || error "no changelogs found"
18141
18142         # reduce the max_idle_indexes value to make sure we exceed it
18143         for param in "changelog_max_idle_indexes=2" \
18144                      "changelog_gc=1" \
18145                      "changelog_min_gc_interval=2"; do
18146                 local MDT0=$(facet_svc $SINGLEMDS)
18147                 local var="${param%=*}"
18148                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18149
18150                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18151                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
18152                         error "unable to set mdd.*.$param"
18153         done
18154
18155         local start=$SECONDS
18156         for i in $(seq $MDSCOUNT); do
18157                 cl_users=(${CL_USERS[mds$i]})
18158                 cl_user1[mds$i]="${cl_users[0]}"
18159                 cl_user2[mds$i]="${cl_users[1]}"
18160
18161                 [ -n "${cl_user1[mds$i]}" ] ||
18162                         error "mds$i: user1 is not registered"
18163                 [ -n "${cl_user2[mds$i]}" ] ||
18164                         error "mds$i: only ${cl_user1[mds$i]} is registered"
18165
18166                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18167                 [ -n "$user_rec1" ] ||
18168                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
18169                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
18170                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18171                 [ -n "$user_rec2" ] ||
18172                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
18173                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
18174                      "$user_rec1 + 2 == $user_rec2"
18175                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
18176                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
18177                               "expected $user_rec1 + 2, but is $user_rec2"
18178                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
18179                 [ -n "$user_rec2" ] ||
18180                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
18181                 [ $user_rec1 == $user_rec2 ] ||
18182                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
18183                               "expected $user_rec1, but is $user_rec2"
18184         done
18185
18186         # ensure we are past the previous changelog_min_gc_interval set above
18187         local sleep2=$((start + 2 - SECONDS))
18188         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18189         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
18190         # cl_user1 should be OK because it recently processed records.
18191         for ((i = 0; i < MDSCOUNT; i++)); do
18192                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
18193                         error "create $DIR/$tdir/d$i.3 failed"
18194         done
18195
18196         # ensure gc thread is done
18197         for i in $(mdts_nodes); do
18198                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
18199                         error "$i: GC-thread not done"
18200         done
18201
18202         local first_rec
18203         for (( i = 1; i <= MDSCOUNT; i++ )); do
18204                 # check cl_user1 still registered
18205                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
18206                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
18207                 # check cl_user2 unregistered
18208                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
18209                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
18210
18211                 # check changelogs are present and starting at $user_rec1 + 1
18212                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18213                 [ -n "$user_rec1" ] ||
18214                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
18215                 first_rec=$($LFS changelog $(facet_svc mds$i) |
18216                             awk '{ print $1; exit; }')
18217
18218                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
18219                 [ $((user_rec1 + 1)) == $first_rec ] ||
18220                         error "mds$i: rec $first_rec != $user_rec1 + 1"
18221         done
18222 }
18223 run_test 160g "changelog garbage collect on idle records"
18224
18225 test_160h() {
18226         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18227         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
18228                 skip "Need MDS version at least 2.10.56"
18229
18230         local mdts=$(comma_list $(mdts_nodes))
18231
18232         # Create a user
18233         changelog_register || error "first changelog_register failed"
18234         changelog_register || error "second changelog_register failed"
18235         local cl_users
18236         declare -A cl_user1
18237         declare -A cl_user2
18238         local user_rec1
18239         local user_rec2
18240         local i
18241
18242         # generate some changelog records to accumulate on each MDT
18243         # use all_char because created files should be evenly distributed
18244         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18245                 error "test_mkdir $tdir failed"
18246         for ((i = 0; i < MDSCOUNT; i++)); do
18247                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18248                         error "create $DIR/$tdir/d$i.1 failed"
18249         done
18250
18251         # check changelogs have been generated
18252         local nbcl=$(changelog_dump | wc -l)
18253         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18254
18255         for param in "changelog_max_idle_time=10" \
18256                      "changelog_gc=1" \
18257                      "changelog_min_gc_interval=2"; do
18258                 local MDT0=$(facet_svc $SINGLEMDS)
18259                 local var="${param%=*}"
18260                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18261
18262                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18263                 do_nodes $mdts $LCTL set_param mdd.*.$param
18264         done
18265
18266         # force cl_user2 to be idle (1st part)
18267         sleep 9
18268
18269         for i in $(seq $MDSCOUNT); do
18270                 cl_users=(${CL_USERS[mds$i]})
18271                 cl_user1[mds$i]="${cl_users[0]}"
18272                 cl_user2[mds$i]="${cl_users[1]}"
18273
18274                 [ -n "${cl_user1[mds$i]}" ] ||
18275                         error "mds$i: no user registered"
18276                 [ -n "${cl_user2[mds$i]}" ] ||
18277                         error "mds$i: only ${cl_user2[mds$i]} is registered"
18278
18279                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18280                 [ -n "$user_rec1" ] ||
18281                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18282                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
18283                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18284                 [ -n "$user_rec2" ] ||
18285                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18286                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
18287                      "$user_rec1 + 2 == $user_rec2"
18288                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
18289                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
18290                               "$user_rec1 + 2, but is $user_rec2"
18291                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
18292                 [ -n "$user_rec2" ] ||
18293                         error "mds$i: User ${cl_user2[mds$i]} not registered"
18294                 [ $user_rec1 == $user_rec2 ] ||
18295                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
18296                               "$user_rec1, but is $user_rec2"
18297         done
18298
18299         # force cl_user2 to be idle (2nd part) and to reach
18300         # changelog_max_idle_time
18301         sleep 2
18302
18303         # force each GC-thread start and block then
18304         # one per MDT/MDD, set fail_val accordingly
18305         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
18306         do_nodes $mdts $LCTL set_param fail_loc=0x1316
18307
18308         # generate more changelogs to trigger fail_loc
18309         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
18310                 error "create $DIR/$tdir/${tfile}bis failed"
18311
18312         # stop MDT to stop GC-thread, should be done in back-ground as it will
18313         # block waiting for the thread to be released and exit
18314         declare -A stop_pids
18315         for i in $(seq $MDSCOUNT); do
18316                 stop mds$i &
18317                 stop_pids[mds$i]=$!
18318         done
18319
18320         for i in $(mdts_nodes); do
18321                 local facet
18322                 local nb=0
18323                 local facets=$(facets_up_on_host $i)
18324
18325                 for facet in ${facets//,/ }; do
18326                         if [[ $facet == mds* ]]; then
18327                                 nb=$((nb + 1))
18328                         fi
18329                 done
18330                 # ensure each MDS's gc threads are still present and all in "R"
18331                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
18332                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
18333                         error "$i: expected $nb GC-thread"
18334                 wait_update $i \
18335                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
18336                         "R" 20 ||
18337                         error "$i: GC-thread not found in R-state"
18338                 # check umounts of each MDT on MDS have reached kthread_stop()
18339                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
18340                         error "$i: expected $nb umount"
18341                 wait_update $i \
18342                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
18343                         error "$i: umount not found in D-state"
18344         done
18345
18346         # release all GC-threads
18347         do_nodes $mdts $LCTL set_param fail_loc=0
18348
18349         # wait for MDT stop to complete
18350         for i in $(seq $MDSCOUNT); do
18351                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
18352         done
18353
18354         # XXX
18355         # may try to check if any orphan changelog records are present
18356         # via ldiskfs/zfs and llog_reader...
18357
18358         # re-start/mount MDTs
18359         for i in $(seq $MDSCOUNT); do
18360                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
18361                         error "Fail to start mds$i"
18362         done
18363
18364         local first_rec
18365         for i in $(seq $MDSCOUNT); do
18366                 # check cl_user1 still registered
18367                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
18368                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18369                 # check cl_user2 unregistered
18370                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
18371                         error "mds$i: User ${cl_user2[mds$i]} still registered"
18372
18373                 # check changelogs are present and starting at $user_rec1 + 1
18374                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18375                 [ -n "$user_rec1" ] ||
18376                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18377                 first_rec=$($LFS changelog $(facet_svc mds$i) |
18378                             awk '{ print $1; exit; }')
18379
18380                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
18381                 [ $((user_rec1 + 1)) == $first_rec ] ||
18382                         error "mds$i: first index should be $user_rec1 + 1, " \
18383                               "but is $first_rec"
18384         done
18385 }
18386 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
18387               "during mount"
18388
18389 test_160i() {
18390
18391         local mdts=$(comma_list $(mdts_nodes))
18392
18393         changelog_register || error "first changelog_register failed"
18394
18395         # generate some changelog records to accumulate on each MDT
18396         # use all_char because created files should be evenly distributed
18397         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18398                 error "test_mkdir $tdir failed"
18399         for ((i = 0; i < MDSCOUNT; i++)); do
18400                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18401                         error "create $DIR/$tdir/d$i.1 failed"
18402         done
18403
18404         # check changelogs have been generated
18405         local nbcl=$(changelog_dump | wc -l)
18406         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18407
18408         # simulate race between register and unregister
18409         # XXX as fail_loc is set per-MDS, with DNE configs the race
18410         # simulation will only occur for one MDT per MDS and for the
18411         # others the normal race scenario will take place
18412         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
18413         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
18414         do_nodes $mdts $LCTL set_param fail_val=1
18415
18416         # unregister 1st user
18417         changelog_deregister &
18418         local pid1=$!
18419         # wait some time for deregister work to reach race rdv
18420         sleep 2
18421         # register 2nd user
18422         changelog_register || error "2nd user register failed"
18423
18424         wait $pid1 || error "1st user deregister failed"
18425
18426         local i
18427         local last_rec
18428         declare -A LAST_REC
18429         for i in $(seq $MDSCOUNT); do
18430                 if changelog_users mds$i | grep "^cl"; then
18431                         # make sure new records are added with one user present
18432                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
18433                                           awk '/^current.index:/ { print $NF }')
18434                 else
18435                         error "mds$i has no user registered"
18436                 fi
18437         done
18438
18439         # generate more changelog records to accumulate on each MDT
18440         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
18441                 error "create $DIR/$tdir/${tfile}bis failed"
18442
18443         for i in $(seq $MDSCOUNT); do
18444                 last_rec=$(changelog_users $SINGLEMDS |
18445                            awk '/^current.index:/ { print $NF }')
18446                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
18447                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
18448                         error "changelogs are off on mds$i"
18449         done
18450 }
18451 run_test 160i "changelog user register/unregister race"
18452
18453 test_160j() {
18454         remote_mds_nodsh && skip "remote MDS with nodsh"
18455         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
18456                 skip "Need MDS version at least 2.12.56"
18457
18458         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
18459         stack_trap "umount $MOUNT2" EXIT
18460
18461         changelog_register || error "first changelog_register failed"
18462         stack_trap "changelog_deregister" EXIT
18463
18464         # generate some changelog
18465         # use all_char because created files should be evenly distributed
18466         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18467                 error "mkdir $tdir failed"
18468         for ((i = 0; i < MDSCOUNT; i++)); do
18469                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18470                         error "create $DIR/$tdir/d$i.1 failed"
18471         done
18472
18473         # open the changelog device
18474         exec 3>/dev/changelog-$FSNAME-MDT0000
18475         stack_trap "exec 3>&-" EXIT
18476         exec 4</dev/changelog-$FSNAME-MDT0000
18477         stack_trap "exec 4<&-" EXIT
18478
18479         # umount the first lustre mount
18480         umount $MOUNT
18481         stack_trap "mount_client $MOUNT" EXIT
18482
18483         # read changelog, which may or may not fail, but should not crash
18484         cat <&4 >/dev/null
18485
18486         # clear changelog
18487         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18488         changelog_users $SINGLEMDS | grep -q $cl_user ||
18489                 error "User $cl_user not found in changelog_users"
18490
18491         printf 'clear:'$cl_user':0' >&3
18492 }
18493 run_test 160j "client can be umounted while its chanangelog is being used"
18494
18495 test_160k() {
18496         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18497         remote_mds_nodsh && skip "remote MDS with nodsh"
18498
18499         mkdir -p $DIR/$tdir/1/1
18500
18501         changelog_register || error "changelog_register failed"
18502         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18503
18504         changelog_users $SINGLEMDS | grep -q $cl_user ||
18505                 error "User '$cl_user' not found in changelog_users"
18506 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
18507         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
18508         rmdir $DIR/$tdir/1/1 & sleep 1
18509         mkdir $DIR/$tdir/2
18510         touch $DIR/$tdir/2/2
18511         rm -rf $DIR/$tdir/2
18512
18513         wait
18514         sleep 4
18515
18516         changelog_dump | grep rmdir || error "rmdir not recorded"
18517 }
18518 run_test 160k "Verify that changelog records are not lost"
18519
18520 # Verifies that a file passed as a parameter has recently had an operation
18521 # performed on it that has generated an MTIME changelog which contains the
18522 # correct parent FID. As files might reside on a different MDT from the
18523 # parent directory in DNE configurations, the FIDs are translated to paths
18524 # before being compared, which should be identical
18525 compare_mtime_changelog() {
18526         local file="${1}"
18527         local mdtidx
18528         local mtime
18529         local cl_fid
18530         local pdir
18531         local dir
18532
18533         mdtidx=$($LFS getstripe --mdt-index $file)
18534         mdtidx=$(printf "%04x" $mdtidx)
18535
18536         # Obtain the parent FID from the MTIME changelog
18537         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
18538         [ -z "$mtime" ] && error "MTIME changelog not recorded"
18539
18540         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
18541         [ -z "$cl_fid" ] && error "parent FID not present"
18542
18543         # Verify that the path for the parent FID is the same as the path for
18544         # the test directory
18545         pdir=$($LFS fid2path $MOUNT "$cl_fid")
18546
18547         dir=$(dirname $1)
18548
18549         [[ "${pdir%/}" == "$dir" ]] ||
18550                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
18551 }
18552
18553 test_160l() {
18554         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18555
18556         remote_mds_nodsh && skip "remote MDS with nodsh"
18557         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
18558                 skip "Need MDS version at least 2.13.55"
18559
18560         local cl_user
18561
18562         changelog_register || error "changelog_register failed"
18563         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18564
18565         changelog_users $SINGLEMDS | grep -q $cl_user ||
18566                 error "User '$cl_user' not found in changelog_users"
18567
18568         # Clear some types so that MTIME changelogs are generated
18569         changelog_chmask "-CREAT"
18570         changelog_chmask "-CLOSE"
18571
18572         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
18573
18574         # Test CL_MTIME during setattr
18575         touch $DIR/$tdir/$tfile
18576         compare_mtime_changelog $DIR/$tdir/$tfile
18577
18578         # Test CL_MTIME during close
18579         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
18580         compare_mtime_changelog $DIR/$tdir/${tfile}_2
18581 }
18582 run_test 160l "Verify that MTIME changelog records contain the parent FID"
18583
18584 test_160m() {
18585         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18586         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18587                 skip "Need MDS version at least 2.14.51"
18588         local cl_users
18589         local cl_user1
18590         local cl_user2
18591         local pid1
18592
18593         # Create a user
18594         changelog_register || error "first changelog_register failed"
18595         changelog_register || error "second changelog_register failed"
18596
18597         cl_users=(${CL_USERS[mds1]})
18598         cl_user1="${cl_users[0]}"
18599         cl_user2="${cl_users[1]}"
18600         # generate some changelog records to accumulate on MDT0
18601         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18602         createmany -m $DIR/$tdir/$tfile 50 ||
18603                 error "create $DIR/$tdir/$tfile failed"
18604         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18605         rm -f $DIR/$tdir
18606
18607         # check changelogs have been generated
18608         local nbcl=$(changelog_dump | wc -l)
18609         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18610
18611 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
18612         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
18613
18614         __changelog_clear mds1 $cl_user1 +10
18615         __changelog_clear mds1 $cl_user2 0 &
18616         pid1=$!
18617         sleep 2
18618         __changelog_clear mds1 $cl_user1 0 ||
18619                 error "fail to cancel record for $cl_user1"
18620         wait $pid1
18621         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
18622 }
18623 run_test 160m "Changelog clear race"
18624
18625 test_160n() {
18626         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18627         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18628                 skip "Need MDS version at least 2.14.51"
18629         local cl_users
18630         local cl_user1
18631         local cl_user2
18632         local pid1
18633         local first_rec
18634         local last_rec=0
18635
18636         # Create a user
18637         changelog_register || error "first changelog_register failed"
18638
18639         cl_users=(${CL_USERS[mds1]})
18640         cl_user1="${cl_users[0]}"
18641
18642         # generate some changelog records to accumulate on MDT0
18643         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18644         first_rec=$(changelog_users $SINGLEMDS |
18645                         awk '/^current.index:/ { print $NF }')
18646         while (( last_rec < (( first_rec + 65000)) )); do
18647                 createmany -m $DIR/$tdir/$tfile 10000 ||
18648                         error "create $DIR/$tdir/$tfile failed"
18649
18650                 for i in $(seq 0 10000); do
18651                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
18652                                 > /dev/null
18653                 done
18654
18655                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
18656                         error "unlinkmany failed unlink"
18657                 last_rec=$(changelog_users $SINGLEMDS |
18658                         awk '/^current.index:/ { print $NF }')
18659                 echo last record $last_rec
18660                 (( last_rec == 0 )) && error "no changelog found"
18661         done
18662
18663 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
18664         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
18665
18666         __changelog_clear mds1 $cl_user1 0 &
18667         pid1=$!
18668         sleep 2
18669         __changelog_clear mds1 $cl_user1 0 ||
18670                 error "fail to cancel record for $cl_user1"
18671         wait $pid1
18672         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
18673 }
18674 run_test 160n "Changelog destroy race"
18675
18676 test_160o() {
18677         local mdt="$(facet_svc $SINGLEMDS)"
18678
18679         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18680         remote_mds_nodsh && skip "remote MDS with nodsh"
18681         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
18682                 skip "Need MDS version at least 2.14.52"
18683
18684         changelog_register --user test_160o -m unlnk+close+open ||
18685                 error "changelog_register failed"
18686
18687         do_facet $SINGLEMDS $LCTL --device $mdt \
18688                                 changelog_register -u "Tt3_-#" &&
18689                 error "bad symbols in name should fail"
18690
18691         do_facet $SINGLEMDS $LCTL --device $mdt \
18692                                 changelog_register -u test_160o &&
18693                 error "the same name registration should fail"
18694
18695         do_facet $SINGLEMDS $LCTL --device $mdt \
18696                         changelog_register -u test_160toolongname &&
18697                 error "too long name registration should fail"
18698
18699         changelog_chmask "MARK+HSM"
18700         lctl get_param mdd.*.changelog*mask
18701         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18702         changelog_users $SINGLEMDS | grep -q $cl_user ||
18703                 error "User $cl_user not found in changelog_users"
18704         #verify username
18705         echo $cl_user | grep -q test_160o ||
18706                 error "User $cl_user has no specific name 'test160o'"
18707
18708         # change something
18709         changelog_clear 0 || error "changelog_clear failed"
18710         # generate some changelog records to accumulate on MDT0
18711         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18712         touch $DIR/$tdir/$tfile                 # open 1
18713
18714         OPENS=$(changelog_dump | grep -c "OPEN")
18715         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
18716
18717         # must be no MKDIR it wasn't set as user mask
18718         MKDIR=$(changelog_dump | grep -c "MKDIR")
18719         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
18720
18721         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
18722                                 mdd.$mdt.changelog_current_mask -n)
18723         # register maskless user
18724         changelog_register || error "changelog_register failed"
18725         # effective mask should be not changed because it is not minimal
18726         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18727                                 mdd.$mdt.changelog_current_mask -n)
18728         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
18729         # set server mask to minimal value
18730         changelog_chmask "MARK"
18731         # check effective mask again, should be treated as DEFMASK now
18732         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18733                                 mdd.$mdt.changelog_current_mask -n)
18734         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18735
18736         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
18737                 # set server mask back to some value
18738                 changelog_chmask "CLOSE,UNLNK"
18739                 # check effective mask again, should not remain as DEFMASK
18740                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
18741                                 mdd.$mdt.changelog_current_mask -n)
18742                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
18743         fi
18744
18745         do_facet $SINGLEMDS $LCTL --device $mdt \
18746                                 changelog_deregister -u test_160o ||
18747                 error "cannot deregister by name"
18748 }
18749 run_test 160o "changelog user name and mask"
18750
18751 test_160p() {
18752         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18753         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18754                 skip "Need MDS version at least 2.14.51"
18755         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
18756         local cl_users
18757         local cl_user1
18758         local entry_count
18759
18760         # Create a user
18761         changelog_register || error "first changelog_register failed"
18762
18763         cl_users=(${CL_USERS[mds1]})
18764         cl_user1="${cl_users[0]}"
18765
18766         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18767         createmany -m $DIR/$tdir/$tfile 50 ||
18768                 error "create $DIR/$tdir/$tfile failed"
18769         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18770         rm -rf $DIR/$tdir
18771
18772         # check changelogs have been generated
18773         entry_count=$(changelog_dump | wc -l)
18774         ((entry_count != 0)) || error "no changelog entries found"
18775
18776         # remove changelog_users and check that orphan entries are removed
18777         stop mds1
18778         local dev=$(mdsdevname 1)
18779         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
18780         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
18781         entry_count=$(changelog_dump | wc -l)
18782         ((entry_count == 0)) ||
18783                 error "found $entry_count changelog entries, expected none"
18784 }
18785 run_test 160p "Changelog orphan cleanup with no users"
18786
18787 test_160q() {
18788         local mdt="$(facet_svc $SINGLEMDS)"
18789         local clu
18790
18791         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18792         remote_mds_nodsh && skip "remote MDS with nodsh"
18793         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
18794                 skip "Need MDS version at least 2.14.54"
18795
18796         # set server mask to minimal value like server init does
18797         changelog_chmask "MARK"
18798         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
18799                 error "changelog_register failed"
18800         # check effective mask again, should be treated as DEFMASK now
18801         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18802                                 mdd.$mdt.changelog_current_mask -n)
18803         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
18804                 error "changelog_deregister failed"
18805         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18806 }
18807 run_test 160q "changelog effective mask is DEFMASK if not set"
18808
18809 test_160s() {
18810         remote_mds_nodsh && skip "remote MDS with nodsh"
18811         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
18812                 skip "Need MDS version at least 2.14.55"
18813
18814         local mdts=$(comma_list $(mdts_nodes))
18815
18816         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
18817         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
18818                                        fail_val=$((24 * 3600 * 10))
18819
18820         # Create a user which is 10 days old
18821         changelog_register || error "first changelog_register failed"
18822         local cl_users
18823         declare -A cl_user1
18824         local i
18825
18826         # generate some changelog records to accumulate on each MDT
18827         # use all_char because created files should be evenly distributed
18828         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18829                 error "test_mkdir $tdir failed"
18830         for ((i = 0; i < MDSCOUNT; i++)); do
18831                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18832                         error "create $DIR/$tdir/d$i.1 failed"
18833         done
18834
18835         # check changelogs have been generated
18836         local nbcl=$(changelog_dump | wc -l)
18837         (( nbcl > 0 )) || error "no changelogs found"
18838
18839         # reduce the max_idle_indexes value to make sure we exceed it
18840         for param in "changelog_max_idle_indexes=2097446912" \
18841                      "changelog_max_idle_time=2592000" \
18842                      "changelog_gc=1" \
18843                      "changelog_min_gc_interval=2"; do
18844                 local MDT0=$(facet_svc $SINGLEMDS)
18845                 local var="${param%=*}"
18846                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18847
18848                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18849                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
18850                         error "unable to set mdd.*.$param"
18851         done
18852
18853         local start=$SECONDS
18854         for i in $(seq $MDSCOUNT); do
18855                 cl_users=(${CL_USERS[mds$i]})
18856                 cl_user1[mds$i]="${cl_users[0]}"
18857
18858                 [[ -n "${cl_user1[mds$i]}" ]] ||
18859                         error "mds$i: no user registered"
18860         done
18861
18862         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
18863         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
18864
18865         # ensure we are past the previous changelog_min_gc_interval set above
18866         local sleep2=$((start + 2 - SECONDS))
18867         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18868
18869         # Generate one more changelog to trigger GC
18870         for ((i = 0; i < MDSCOUNT; i++)); do
18871                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
18872                         error "create $DIR/$tdir/d$i.3 failed"
18873         done
18874
18875         # ensure gc thread is done
18876         for node in $(mdts_nodes); do
18877                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
18878                         error "$node: GC-thread not done"
18879         done
18880
18881         do_nodes $mdts $LCTL set_param fail_loc=0
18882
18883         for (( i = 1; i <= MDSCOUNT; i++ )); do
18884                 # check cl_user1 is purged
18885                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
18886                         error "mds$i: User ${cl_user1[mds$i]} is registered"
18887         done
18888         return 0
18889 }
18890 run_test 160s "changelog garbage collect on idle records * time"
18891
18892 test_160t() {
18893         remote_mds_nodsh && skip "remote MDS with nodsh"
18894         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
18895                 skip "Need MDS version at least 2.15.50"
18896
18897         local MDT0=$(facet_svc $SINGLEMDS)
18898         local cl_users
18899         local cl_user1
18900         local cl_user2
18901         local start
18902
18903         changelog_register --user user1 -m all ||
18904                 error "user1 failed to register"
18905
18906         mkdir_on_mdt0 $DIR/$tdir
18907         # create default overstripe to maximize changelog size
18908         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
18909         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
18910         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18911
18912         # user2 consumes less records so less space
18913         changelog_register --user user2 || error "user2 failed to register"
18914         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
18915         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18916
18917         # check changelogs have been generated
18918         local nbcl=$(changelog_dump | wc -l)
18919         (( nbcl > 0 )) || error "no changelogs found"
18920
18921         # reduce the changelog_min_gc_interval to force check
18922         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
18923                 local var="${param%=*}"
18924                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18925
18926                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
18927                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
18928                         error "unable to set mdd.*.$param"
18929         done
18930
18931         start=$SECONDS
18932         cl_users=(${CL_USERS[mds1]})
18933         cl_user1="${cl_users[0]}"
18934         cl_user2="${cl_users[1]}"
18935
18936         [[ -n $cl_user1 ]] ||
18937                 error "mds1: user #1 isn't registered"
18938         [[ -n $cl_user2 ]] ||
18939                 error "mds1: user #2 isn't registered"
18940
18941         # ensure we are past the previous changelog_min_gc_interval set above
18942         local sleep2=$((start + 2 - SECONDS))
18943         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18944
18945         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
18946         do_facet mds1 $LCTL set_param fail_loc=0x018c \
18947                         fail_val=$(((llog_size1 + llog_size2) / 2))
18948
18949         # Generate more changelog to trigger GC
18950         createmany -o $DIR/$tdir/u3_ 4 ||
18951                 error "create failed for more files"
18952
18953         # ensure gc thread is done
18954         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
18955                 error "mds1: GC-thread not done"
18956
18957         do_facet mds1 $LCTL set_param fail_loc=0
18958
18959         # check cl_user1 is purged
18960         changelog_users mds1 | grep -q "$cl_user1" &&
18961                 error "User $cl_user1 is registered"
18962         # check cl_user2 is not purged
18963         changelog_users mds1 | grep -q "$cl_user2" ||
18964                 error "User $cl_user2 is not registered"
18965 }
18966 run_test 160t "changelog garbage collect on lack of space"
18967
18968 test_160u() { # LU-17400
18969         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18970         remote_mds_nodsh && skip "remote MDS with nodsh"
18971         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
18972                 skip "Need MDS version at least 2.2.0"
18973
18974         cd $DIR || error "cd $DIR failed"
18975
18976         # ensure changelog has a clean view if tests are run multiple times
18977         [ -d rename ] && rm -rf rename
18978
18979         changelog_register || error "changelog_register failed"
18980         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18981
18982         changelog_users $SINGLEMDS | grep -q $cl_user ||
18983                 error "User '$cl_user' not found in changelog_users"
18984
18985         local longname1=$(str_repeat a 255)
18986
18987         echo "creating simple directory tree"
18988         mkdir -p rename/a || error "create of simple directory tree failed"
18989         echo "creating rename/hw file"
18990         echo "hello world" > rename/hw || error "create of rename/hw failed"
18991         echo "creating very long named file"
18992         touch rename/$longname1 || error "create of 'rename/$longname1' failed"
18993         echo "move rename/hw to rename/a/a.hw"
18994         mv rename/hw rename/a/a.hw || error "mv failed"
18995
18996         RENME=($(changelog_dump | grep "RENME"))
18997         #declare -p RENME # for debugging captured value with indexes
18998
18999         [[ "${RENME[11]}" == "a.hw" && "${RENME[14]}" == "hw" ]] ||
19000                 error "changelog rename record type name/sname error"
19001 }
19002 run_test 160u "changelog rename record type name and sname strings are correct"
19003
19004 test_161a() {
19005         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19006
19007         test_mkdir -c1 $DIR/$tdir
19008         cp /etc/hosts $DIR/$tdir/$tfile
19009         test_mkdir -c1 $DIR/$tdir/foo1
19010         test_mkdir -c1 $DIR/$tdir/foo2
19011         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
19012         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
19013         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
19014         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
19015         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
19016         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
19017                 $LFS fid2path $DIR $FID
19018                 error "bad link ea"
19019         fi
19020         # middle
19021         rm $DIR/$tdir/foo2/zachary
19022         # last
19023         rm $DIR/$tdir/foo2/thor
19024         # first
19025         rm $DIR/$tdir/$tfile
19026         # rename
19027         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
19028         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
19029                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
19030         rm $DIR/$tdir/foo2/maggie
19031
19032         # overflow the EA
19033         local longname=$tfile.avg_len_is_thirty_two_
19034         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
19035                 error_noexit 'failed to unlink many hardlinks'" EXIT
19036         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
19037                 error "failed to hardlink many files"
19038         links=$($LFS fid2path $DIR $FID | wc -l)
19039         echo -n "${links}/1000 links in link EA"
19040         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
19041 }
19042 run_test 161a "link ea sanity"
19043
19044 test_161b() {
19045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19046         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
19047
19048         local MDTIDX=1
19049         local remote_dir=$DIR/$tdir/remote_dir
19050
19051         mkdir -p $DIR/$tdir
19052         $LFS mkdir -i $MDTIDX $remote_dir ||
19053                 error "create remote directory failed"
19054
19055         cp /etc/hosts $remote_dir/$tfile
19056         mkdir -p $remote_dir/foo1
19057         mkdir -p $remote_dir/foo2
19058         ln $remote_dir/$tfile $remote_dir/foo1/sofia
19059         ln $remote_dir/$tfile $remote_dir/foo2/zachary
19060         ln $remote_dir/$tfile $remote_dir/foo1/luna
19061         ln $remote_dir/$tfile $remote_dir/foo2/thor
19062
19063         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
19064                      tr -d ']')
19065         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
19066                 $LFS fid2path $DIR $FID
19067                 error "bad link ea"
19068         fi
19069         # middle
19070         rm $remote_dir/foo2/zachary
19071         # last
19072         rm $remote_dir/foo2/thor
19073         # first
19074         rm $remote_dir/$tfile
19075         # rename
19076         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
19077         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
19078         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
19079                 $LFS fid2path $DIR $FID
19080                 error "bad link rename"
19081         fi
19082         rm $remote_dir/foo2/maggie
19083
19084         # overflow the EA
19085         local longname=filename_avg_len_is_thirty_two_
19086         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
19087                 error "failed to hardlink many files"
19088         links=$($LFS fid2path $DIR $FID | wc -l)
19089         echo -n "${links}/1000 links in link EA"
19090         [[ ${links} -gt 60 ]] ||
19091                 error "expected at least 60 links in link EA"
19092         unlinkmany $remote_dir/foo2/$longname 1000 ||
19093         error "failed to unlink many hardlinks"
19094 }
19095 run_test 161b "link ea sanity under remote directory"
19096
19097 test_161c() {
19098         remote_mds_nodsh && skip "remote MDS with nodsh"
19099         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19100         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
19101                 skip "Need MDS version at least 2.1.5"
19102
19103         # define CLF_RENAME_LAST 0x0001
19104         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
19105         changelog_register || error "changelog_register failed"
19106
19107         rm -rf $DIR/$tdir
19108         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
19109         touch $DIR/$tdir/foo_161c
19110         touch $DIR/$tdir/bar_161c
19111         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
19112         changelog_dump | grep RENME | tail -n 5
19113         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
19114         changelog_clear 0 || error "changelog_clear failed"
19115         if [ x$flags != "x0x1" ]; then
19116                 error "flag $flags is not 0x1"
19117         fi
19118
19119         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
19120         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
19121         touch $DIR/$tdir/foo_161c
19122         touch $DIR/$tdir/bar_161c
19123         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
19124         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
19125         changelog_dump | grep RENME | tail -n 5
19126         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
19127         changelog_clear 0 || error "changelog_clear failed"
19128         if [ x$flags != "x0x0" ]; then
19129                 error "flag $flags is not 0x0"
19130         fi
19131         echo "rename overwrite a target having nlink > 1," \
19132                 "changelog record has flags of $flags"
19133
19134         # rename doesn't overwrite a target (changelog flag 0x0)
19135         touch $DIR/$tdir/foo_161c
19136         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
19137         changelog_dump | grep RENME | tail -n 5
19138         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
19139         changelog_clear 0 || error "changelog_clear failed"
19140         if [ x$flags != "x0x0" ]; then
19141                 error "flag $flags is not 0x0"
19142         fi
19143         echo "rename doesn't overwrite a target," \
19144                 "changelog record has flags of $flags"
19145
19146         # define CLF_UNLINK_LAST 0x0001
19147         # unlink a file having nlink = 1 (changelog flag 0x1)
19148         rm -f $DIR/$tdir/foo2_161c
19149         changelog_dump | grep UNLNK | tail -n 5
19150         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
19151         changelog_clear 0 || error "changelog_clear failed"
19152         if [ x$flags != "x0x1" ]; then
19153                 error "flag $flags is not 0x1"
19154         fi
19155         echo "unlink a file having nlink = 1," \
19156                 "changelog record has flags of $flags"
19157
19158         # unlink a file having nlink > 1 (changelog flag 0x0)
19159         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
19160         rm -f $DIR/$tdir/foobar_161c
19161         changelog_dump | grep UNLNK | tail -n 5
19162         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
19163         changelog_clear 0 || error "changelog_clear failed"
19164         if [ x$flags != "x0x0" ]; then
19165                 error "flag $flags is not 0x0"
19166         fi
19167         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
19168 }
19169 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
19170
19171 test_161d() {
19172         remote_mds_nodsh && skip "remote MDS with nodsh"
19173         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
19174
19175         local pid
19176         local fid
19177
19178         changelog_register || error "changelog_register failed"
19179
19180         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
19181         # interfer with $MOUNT/.lustre/fid/ access
19182         mkdir $DIR/$tdir
19183         [[ $? -eq 0 ]] || error "mkdir failed"
19184
19185         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | CFS_FAIL_ONCE
19186         $LCTL set_param fail_loc=0x8000140c
19187         # 5s pause
19188         $LCTL set_param fail_val=5
19189
19190         # create file
19191         echo foofoo > $DIR/$tdir/$tfile &
19192         pid=$!
19193
19194         # wait for create to be delayed
19195         sleep 2
19196
19197         ps -p $pid
19198         [[ $? -eq 0 ]] || error "create should be blocked"
19199
19200         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
19201         stack_trap "rm -f $tempfile"
19202         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
19203         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
19204         # some delay may occur during ChangeLog publishing and file read just
19205         # above, that could allow file write to happen finally
19206         [[ -s $tempfile ]] && echo "file should be empty"
19207
19208         $LCTL set_param fail_loc=0
19209
19210         wait $pid
19211         [[ $? -eq 0 ]] || error "create failed"
19212 }
19213 run_test 161d "create with concurrent .lustre/fid access"
19214
19215 check_path() {
19216         local expected="$1"
19217         shift
19218         local fid="$2"
19219
19220         local path
19221         path=$($LFS fid2path "$@")
19222         local rc=$?
19223
19224         if [ $rc -ne 0 ]; then
19225                 error "path looked up of '$expected' failed: rc=$rc"
19226         elif [ "$path" != "$expected" ]; then
19227                 error "path looked up '$path' instead of '$expected'"
19228         else
19229                 echo "FID '$fid' resolves to path '$path' as expected"
19230         fi
19231 }
19232
19233 test_162a() { # was test_162
19234         test_mkdir -p -c1 $DIR/$tdir/d2
19235         touch $DIR/$tdir/d2/$tfile
19236         touch $DIR/$tdir/d2/x1
19237         touch $DIR/$tdir/d2/x2
19238         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
19239         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
19240         # regular file
19241         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
19242         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
19243
19244         # softlink
19245         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
19246         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
19247         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
19248
19249         # softlink to wrong file
19250         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
19251         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
19252         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
19253
19254         # hardlink
19255         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
19256         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
19257         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
19258         # fid2path dir/fsname should both work
19259         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
19260         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
19261
19262         # hardlink count: check that there are 2 links
19263         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
19264         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
19265
19266         # hardlink indexing: remove the first link
19267         rm $DIR/$tdir/d2/p/q/r/hlink
19268         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
19269 }
19270 run_test 162a "path lookup sanity"
19271
19272 test_162b() {
19273         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19274         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19275
19276         mkdir $DIR/$tdir
19277         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19278                                 error "create striped dir failed"
19279
19280         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
19281                                         tail -n 1 | awk '{print $2}')
19282         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
19283
19284         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
19285         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
19286
19287         # regular file
19288         for ((i=0;i<5;i++)); do
19289                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
19290                         error "get fid for f$i failed"
19291                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
19292
19293                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
19294                         error "get fid for d$i failed"
19295                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
19296         done
19297
19298         return 0
19299 }
19300 run_test 162b "striped directory path lookup sanity"
19301
19302 # LU-4239: Verify fid2path works with paths 100 or more directories deep
19303 test_162c() {
19304         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
19305                 skip "Need MDS version at least 2.7.51"
19306
19307         local lpath=$tdir.local
19308         local rpath=$tdir.remote
19309
19310         test_mkdir $DIR/$lpath
19311         test_mkdir $DIR/$rpath
19312
19313         for ((i = 0; i <= 101; i++)); do
19314                 lpath="$lpath/$i"
19315                 mkdir $DIR/$lpath
19316                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
19317                         error "get fid for local directory $DIR/$lpath failed"
19318                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
19319
19320                 rpath="$rpath/$i"
19321                 test_mkdir $DIR/$rpath
19322                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
19323                         error "get fid for remote directory $DIR/$rpath failed"
19324                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
19325         done
19326
19327         return 0
19328 }
19329 run_test 162c "fid2path works with paths 100 or more directories deep"
19330
19331 oalr_event_count() {
19332         local event="${1}"
19333         local trace="${2}"
19334
19335         awk -v name="${FSNAME}-OST0000" \
19336             -v event="${event}" \
19337             '$1 == "TRACE" && $2 == event && $3 == name' \
19338             "${trace}" |
19339         wc -l
19340 }
19341
19342 oalr_expect_event_count() {
19343         local event="${1}"
19344         local trace="${2}"
19345         local expect="${3}"
19346         local count
19347
19348         count=$(oalr_event_count "${event}" "${trace}")
19349         if ((count == expect)); then
19350                 return 0
19351         fi
19352
19353         error_noexit "${event} event count was '${count}', expected ${expect}"
19354         cat "${trace}" >&2
19355         exit 1
19356 }
19357
19358 cleanup_165() {
19359         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
19360         stop ost1
19361         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
19362 }
19363
19364 setup_165() {
19365         sync # Flush previous IOs so we can count log entries.
19366         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
19367         stack_trap cleanup_165 EXIT
19368 }
19369
19370 test_165a() {
19371         local trace="/tmp/${tfile}.trace"
19372         local rc
19373         local count
19374
19375         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19376                 skip "OFD access log unsupported"
19377
19378         setup_165
19379         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19380         sleep 5
19381
19382         do_facet ost1 ofd_access_log_reader --list
19383         stop ost1
19384
19385         do_facet ost1 killall -TERM ofd_access_log_reader
19386         wait
19387         rc=$?
19388
19389         if ((rc != 0)); then
19390                 error "ofd_access_log_reader exited with rc = '${rc}'"
19391         fi
19392
19393         # Parse trace file for discovery events:
19394         oalr_expect_event_count alr_log_add "${trace}" 1
19395         oalr_expect_event_count alr_log_eof "${trace}" 1
19396         oalr_expect_event_count alr_log_free "${trace}" 1
19397 }
19398 run_test 165a "ofd access log discovery"
19399
19400 test_165b() {
19401         local trace="/tmp/${tfile}.trace"
19402         local file="${DIR}/${tfile}"
19403         local pfid1
19404         local pfid2
19405         local -a entry
19406         local rc
19407         local count
19408         local size
19409         local flags
19410
19411         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19412                 skip "OFD access log unsupported"
19413
19414         setup_165
19415         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19416         sleep 5
19417
19418         do_facet ost1 ofd_access_log_reader --list
19419
19420         lfs setstripe -c 1 -i 0 "${file}"
19421         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19422                 error "cannot create '${file}'"
19423
19424         sleep 5
19425         do_facet ost1 killall -TERM ofd_access_log_reader
19426         wait
19427         rc=$?
19428
19429         if ((rc != 0)); then
19430                 error "ofd_access_log_reader exited with rc = '${rc}'"
19431         fi
19432
19433         oalr_expect_event_count alr_log_entry "${trace}" 1
19434
19435         pfid1=$($LFS path2fid "${file}")
19436
19437         # 1     2             3   4    5     6   7    8    9     10
19438         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
19439         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
19440
19441         echo "entry = '${entry[*]}'" >&2
19442
19443         pfid2=${entry[4]}
19444         if [[ "${pfid1}" != "${pfid2}" ]]; then
19445                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
19446         fi
19447
19448         size=${entry[8]}
19449         if ((size != 1048576)); then
19450                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
19451         fi
19452
19453         flags=${entry[10]}
19454         if [[ "${flags}" != "w" ]]; then
19455                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
19456         fi
19457
19458         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19459         sleep 5
19460
19461         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
19462                 error "cannot read '${file}'"
19463         sleep 5
19464
19465         do_facet ost1 killall -TERM ofd_access_log_reader
19466         wait
19467         rc=$?
19468
19469         if ((rc != 0)); then
19470                 error "ofd_access_log_reader exited with rc = '${rc}'"
19471         fi
19472
19473         oalr_expect_event_count alr_log_entry "${trace}" 1
19474
19475         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
19476         echo "entry = '${entry[*]}'" >&2
19477
19478         pfid2=${entry[4]}
19479         if [[ "${pfid1}" != "${pfid2}" ]]; then
19480                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
19481         fi
19482
19483         size=${entry[8]}
19484         if ((size != 524288)); then
19485                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
19486         fi
19487
19488         flags=${entry[10]}
19489         if [[ "${flags}" != "r" ]]; then
19490                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
19491         fi
19492 }
19493 run_test 165b "ofd access log entries are produced and consumed"
19494
19495 test_165c() {
19496         local trace="/tmp/${tfile}.trace"
19497         local file="${DIR}/${tdir}/${tfile}"
19498
19499         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19500                 skip "OFD access log unsupported"
19501
19502         test_mkdir "${DIR}/${tdir}"
19503
19504         setup_165
19505         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19506         sleep 5
19507
19508         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
19509
19510         # 4096 / 64 = 64. Create twice as many entries.
19511         for ((i = 0; i < 128; i++)); do
19512                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
19513                         error "cannot create file"
19514         done
19515
19516         sync
19517
19518         do_facet ost1 killall -TERM ofd_access_log_reader
19519         wait
19520         rc=$?
19521         if ((rc != 0)); then
19522                 error "ofd_access_log_reader exited with rc = '${rc}'"
19523         fi
19524
19525         unlinkmany  "${file}-%d" 128
19526 }
19527 run_test 165c "full ofd access logs do not block IOs"
19528
19529 oal_get_read_count() {
19530         local stats="$1"
19531
19532         # STATS lustre-OST0001 alr_read_count 1
19533
19534         do_facet ost1 cat "${stats}" |
19535         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
19536              END { print count; }'
19537 }
19538
19539 oal_expect_read_count() {
19540         local stats="$1"
19541         local count
19542         local expect="$2"
19543
19544         # Ask ofd_access_log_reader to write stats.
19545         do_facet ost1 killall -USR1 ofd_access_log_reader
19546
19547         # Allow some time for things to happen.
19548         sleep 1
19549
19550         count=$(oal_get_read_count "${stats}")
19551         if ((count == expect)); then
19552                 return 0
19553         fi
19554
19555         error_noexit "bad read count, got ${count}, expected ${expect}"
19556         do_facet ost1 cat "${stats}" >&2
19557         exit 1
19558 }
19559
19560 test_165d() {
19561         local stats="/tmp/${tfile}.stats"
19562         local file="${DIR}/${tdir}/${tfile}"
19563         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
19564
19565         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19566                 skip "OFD access log unsupported"
19567
19568         test_mkdir "${DIR}/${tdir}"
19569
19570         setup_165
19571         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
19572         sleep 5
19573
19574         lfs setstripe -c 1 -i 0 "${file}"
19575
19576         do_facet ost1 lctl set_param "${param}=rw"
19577         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19578                 error "cannot create '${file}'"
19579         oal_expect_read_count "${stats}" 1
19580
19581         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19582                 error "cannot read '${file}'"
19583         oal_expect_read_count "${stats}" 2
19584
19585         do_facet ost1 lctl set_param "${param}=r"
19586         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19587                 error "cannot create '${file}'"
19588         oal_expect_read_count "${stats}" 2
19589
19590         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19591                 error "cannot read '${file}'"
19592         oal_expect_read_count "${stats}" 3
19593
19594         do_facet ost1 lctl set_param "${param}=w"
19595         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19596                 error "cannot create '${file}'"
19597         oal_expect_read_count "${stats}" 4
19598
19599         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19600                 error "cannot read '${file}'"
19601         oal_expect_read_count "${stats}" 4
19602
19603         do_facet ost1 lctl set_param "${param}=0"
19604         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19605                 error "cannot create '${file}'"
19606         oal_expect_read_count "${stats}" 4
19607
19608         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19609                 error "cannot read '${file}'"
19610         oal_expect_read_count "${stats}" 4
19611
19612         do_facet ost1 killall -TERM ofd_access_log_reader
19613         wait
19614         rc=$?
19615         if ((rc != 0)); then
19616                 error "ofd_access_log_reader exited with rc = '${rc}'"
19617         fi
19618 }
19619 run_test 165d "ofd_access_log mask works"
19620
19621 test_165e() {
19622         local stats="/tmp/${tfile}.stats"
19623         local file0="${DIR}/${tdir}-0/${tfile}"
19624         local file1="${DIR}/${tdir}-1/${tfile}"
19625
19626         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19627                 skip "OFD access log unsupported"
19628
19629         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
19630
19631         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
19632         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
19633
19634         lfs setstripe -c 1 -i 0 "${file0}"
19635         lfs setstripe -c 1 -i 0 "${file1}"
19636
19637         setup_165
19638         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
19639         sleep 5
19640
19641         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
19642                 error "cannot create '${file0}'"
19643         sync
19644         oal_expect_read_count "${stats}" 0
19645
19646         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
19647                 error "cannot create '${file1}'"
19648         sync
19649         oal_expect_read_count "${stats}" 1
19650
19651         do_facet ost1 killall -TERM ofd_access_log_reader
19652         wait
19653         rc=$?
19654         if ((rc != 0)); then
19655                 error "ofd_access_log_reader exited with rc = '${rc}'"
19656         fi
19657 }
19658 run_test 165e "ofd_access_log MDT index filter works"
19659
19660 test_165f() {
19661         local trace="/tmp/${tfile}.trace"
19662         local rc
19663         local count
19664
19665         setup_165
19666         do_facet ost1 timeout 60 ofd_access_log_reader \
19667                 --exit-on-close --debug=- --trace=- > "${trace}" &
19668         sleep 5
19669         stop ost1
19670
19671         wait
19672         rc=$?
19673
19674         if ((rc != 0)); then
19675                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
19676                 cat "${trace}"
19677                 exit 1
19678         fi
19679 }
19680 run_test 165f "ofd_access_log_reader --exit-on-close works"
19681
19682 test_169() {
19683         # do directio so as not to populate the page cache
19684         log "creating a 10 Mb file"
19685         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
19686                 error "multiop failed while creating a file"
19687         log "starting reads"
19688         dd if=$DIR/$tfile of=/dev/null bs=4096 &
19689         log "truncating the file"
19690         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
19691                 error "multiop failed while truncating the file"
19692         log "killing dd"
19693         kill %+ || true # reads might have finished
19694         echo "wait until dd is finished"
19695         wait
19696         log "removing the temporary file"
19697         rm -rf $DIR/$tfile || error "tmp file removal failed"
19698 }
19699 run_test 169 "parallel read and truncate should not deadlock"
19700
19701 test_170() {
19702         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19703
19704         $LCTL clear     # bug 18514
19705         $LCTL debug_daemon start $TMP/${tfile}_log_good
19706         touch $DIR/$tfile
19707         $LCTL debug_daemon stop
19708         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
19709                 error "sed failed to read log_good"
19710
19711         $LCTL debug_daemon start $TMP/${tfile}_log_good
19712         rm -rf $DIR/$tfile
19713         $LCTL debug_daemon stop
19714
19715         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
19716                error "lctl df log_bad failed"
19717
19718         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19719         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19720
19721         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
19722         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
19723
19724         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
19725                 error "bad_line good_line1 good_line2 are empty"
19726
19727         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19728         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
19729         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19730
19731         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
19732         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19733         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19734
19735         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
19736                 error "bad_line_new good_line_new are empty"
19737
19738         local expected_good=$((good_line1 + good_line2*2))
19739
19740         rm -f $TMP/${tfile}*
19741         # LU-231, short malformed line may not be counted into bad lines
19742         if [ $bad_line -ne $bad_line_new ] &&
19743                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
19744                 error "expected $bad_line bad lines, but got $bad_line_new"
19745                 return 1
19746         fi
19747
19748         if [ $expected_good -ne $good_line_new ]; then
19749                 error "expected $expected_good good lines, but got $good_line_new"
19750                 return 2
19751         fi
19752         true
19753 }
19754 run_test 170 "test lctl df to handle corrupted log ====================="
19755
19756 test_171() { # bug20592
19757         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19758
19759         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
19760         $LCTL set_param fail_loc=0x50e
19761         $LCTL set_param fail_val=3000
19762         multiop_bg_pause $DIR/$tfile O_s || true
19763         local MULTIPID=$!
19764         kill -USR1 $MULTIPID
19765         # cause log dump
19766         sleep 3
19767         wait $MULTIPID
19768         if dmesg | grep "recursive fault"; then
19769                 error "caught a recursive fault"
19770         fi
19771         $LCTL set_param fail_loc=0
19772         true
19773 }
19774 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
19775
19776 test_172() {
19777
19778         #define OBD_FAIL_OBD_CLEANUP  0x60e
19779         $LCTL set_param fail_loc=0x60e
19780         umount $MOUNT || error "umount $MOUNT failed"
19781         stack_trap "mount_client $MOUNT"
19782
19783         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
19784                 error "no client OBDs are remained"
19785
19786         $LCTL dl | while read devno state type name foo; do
19787                 case $type in
19788                 lov|osc|lmv|mdc)
19789                         $LCTL --device $name cleanup
19790                         $LCTL --device $name detach
19791                         ;;
19792                 *)
19793                         # skip server devices
19794                         ;;
19795                 esac
19796         done
19797
19798         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
19799                 $LCTL dl | egrep " osc | lov | lmv | mdc "
19800                 error "some client OBDs are still remained"
19801         fi
19802
19803 }
19804 run_test 172 "manual device removal with lctl cleanup/detach ======"
19805
19806 # it would be good to share it with obdfilter-survey/iokit-libecho code
19807 setup_obdecho_osc () {
19808         local rc=0
19809         local ost_nid=$1
19810         local obdfilter_name=$2
19811         echo "Creating new osc for $obdfilter_name on $ost_nid"
19812         # make sure we can find loopback nid
19813         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
19814
19815         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
19816                            ${obdfilter_name}_osc_UUID || rc=2; }
19817         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
19818                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
19819         return $rc
19820 }
19821
19822 cleanup_obdecho_osc () {
19823         local obdfilter_name=$1
19824         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
19825         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
19826         return 0
19827 }
19828
19829 obdecho_test() {
19830         local OBD=$1
19831         local node=$2
19832         local pages=${3:-64}
19833         local rc=0
19834         local id
19835
19836         local count=10
19837         local obd_size=$(get_obd_size $node $OBD)
19838         local page_size=$(get_page_size $node)
19839         if [[ -n "$obd_size" ]]; then
19840                 local new_count=$((obd_size / (pages * page_size / 1024)))
19841                 [[ $new_count -ge $count ]] || count=$new_count
19842         fi
19843
19844         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
19845         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
19846                            rc=2; }
19847         if [ $rc -eq 0 ]; then
19848             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
19849             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
19850         fi
19851         echo "New object id is $id"
19852         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
19853                            rc=4; }
19854         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
19855                            "test_brw $count w v $pages $id" || rc=4; }
19856         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
19857                            rc=4; }
19858         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
19859                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
19860         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
19861                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
19862         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
19863         return $rc
19864 }
19865
19866 test_180a() {
19867         skip "obdecho on osc is no longer supported"
19868 }
19869 run_test 180a "test obdecho on osc"
19870
19871 test_180b() {
19872         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19873         remote_ost_nodsh && skip "remote OST with nodsh"
19874
19875         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19876                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19877                 error "failed to load module obdecho"
19878
19879         local target=$(do_facet ost1 $LCTL dl |
19880                        awk '/obdfilter/ { print $4; exit; }')
19881
19882         if [ -n "$target" ]; then
19883                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
19884         else
19885                 do_facet ost1 $LCTL dl
19886                 error "there is no obdfilter target on ost1"
19887         fi
19888 }
19889 run_test 180b "test obdecho directly on obdfilter"
19890
19891 test_180c() { # LU-2598
19892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19893         remote_ost_nodsh && skip "remote OST with nodsh"
19894         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
19895                 skip "Need MDS version at least 2.4.0"
19896
19897         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19898                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19899                 error "failed to load module obdecho"
19900
19901         local target=$(do_facet ost1 $LCTL dl |
19902                        awk '/obdfilter/ { print $4; exit; }')
19903
19904         if [ -n "$target" ]; then
19905                 local pages=16384 # 64MB bulk I/O RPC size
19906
19907                 obdecho_test "$target" ost1 "$pages" ||
19908                         error "obdecho_test with pages=$pages failed with $?"
19909         else
19910                 do_facet ost1 $LCTL dl
19911                 error "there is no obdfilter target on ost1"
19912         fi
19913 }
19914 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
19915
19916 test_181() { # bug 22177
19917         test_mkdir $DIR/$tdir
19918         # create enough files to index the directory
19919         createmany -o $DIR/$tdir/foobar 4000
19920         # print attributes for debug purpose
19921         lsattr -d .
19922         # open dir
19923         multiop_bg_pause $DIR/$tdir D_Sc || return 1
19924         MULTIPID=$!
19925         # remove the files & current working dir
19926         unlinkmany $DIR/$tdir/foobar 4000
19927         rmdir $DIR/$tdir
19928         kill -USR1 $MULTIPID
19929         wait $MULTIPID
19930         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
19931         return 0
19932 }
19933 run_test 181 "Test open-unlinked dir ========================"
19934
19935 test_182a() {
19936         local fcount=1000
19937         local tcount=10
19938
19939         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19940
19941         $LCTL set_param mdc.*.rpc_stats=clear
19942
19943         for (( i = 0; i < $tcount; i++ )) ; do
19944                 mkdir $DIR/$tdir/$i
19945         done
19946
19947         for (( i = 0; i < $tcount; i++ )) ; do
19948                 createmany -o $DIR/$tdir/$i/f- $fcount &
19949         done
19950         wait
19951
19952         for (( i = 0; i < $tcount; i++ )) ; do
19953                 unlinkmany $DIR/$tdir/$i/f- $fcount &
19954         done
19955         wait
19956
19957         $LCTL get_param mdc.*.rpc_stats
19958
19959         rm -rf $DIR/$tdir
19960 }
19961 run_test 182a "Test parallel modify metadata operations from mdc"
19962
19963 test_182b() {
19964         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19965         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19966         local dcount=1000
19967         local tcount=10
19968         local stime
19969         local etime
19970         local delta
19971
19972         do_facet mds1 $LCTL list_param \
19973                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
19974                 skip "MDS lacks parallel RPC handling"
19975
19976         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19977
19978         rpc_count=$(do_facet mds1 $LCTL get_param -n \
19979                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
19980
19981         stime=$(date +%s)
19982         createmany -i 0 -d $DIR/$tdir/t- $tcount
19983
19984         for (( i = 0; i < $tcount; i++ )) ; do
19985                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19986         done
19987         wait
19988         etime=$(date +%s)
19989         delta=$((etime - stime))
19990         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
19991
19992         stime=$(date +%s)
19993         for (( i = 0; i < $tcount; i++ )) ; do
19994                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
19995         done
19996         wait
19997         etime=$(date +%s)
19998         delta=$((etime - stime))
19999         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
20000
20001         rm -rf $DIR/$tdir
20002
20003         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
20004
20005         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
20006
20007         stime=$(date +%s)
20008         createmany -i 0 -d $DIR/$tdir/t- $tcount
20009
20010         for (( i = 0; i < $tcount; i++ )) ; do
20011                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
20012         done
20013         wait
20014         etime=$(date +%s)
20015         delta=$((etime - stime))
20016         echo "Time for file creation $delta sec for 1 RPC sent at a time"
20017
20018         stime=$(date +%s)
20019         for (( i = 0; i < $tcount; i++ )) ; do
20020                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
20021         done
20022         wait
20023         etime=$(date +%s)
20024         delta=$((etime - stime))
20025         echo "Time for file removal $delta sec for 1 RPC sent at a time"
20026
20027         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
20028 }
20029 run_test 182b "Test parallel modify metadata operations from osp"
20030
20031 test_183() { # LU-2275
20032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20033         remote_mds_nodsh && skip "remote MDS with nodsh"
20034         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
20035                 skip "Need MDS version at least 2.3.56"
20036
20037         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
20038         echo aaa > $DIR/$tdir/$tfile
20039
20040 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
20041         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
20042
20043         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
20044         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
20045
20046         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20047
20048         # Flush negative dentry cache
20049         touch $DIR/$tdir/$tfile
20050
20051         # We are not checking for any leaked references here, they'll
20052         # become evident next time we do cleanup with module unload.
20053         rm -rf $DIR/$tdir
20054 }
20055 run_test 183 "No crash or request leak in case of strange dispositions ========"
20056
20057 # test suite 184 is for LU-2016, LU-2017
20058 test_184a() {
20059         check_swap_layouts_support
20060
20061         dir0=$DIR/$tdir/$testnum
20062         test_mkdir -p -c1 $dir0
20063         ref1=/etc/passwd
20064         ref2=/etc/group
20065         file1=$dir0/f1
20066         file2=$dir0/f2
20067         $LFS setstripe -c1 $file1
20068         cp $ref1 $file1
20069         $LFS setstripe -c2 $file2
20070         cp $ref2 $file2
20071         gen1=$($LFS getstripe -g $file1)
20072         gen2=$($LFS getstripe -g $file2)
20073
20074         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
20075         gen=$($LFS getstripe -g $file1)
20076         [[ $gen1 != $gen ]] ||
20077                 error "Layout generation on $file1 does not change"
20078         gen=$($LFS getstripe -g $file2)
20079         [[ $gen2 != $gen ]] ||
20080                 error "Layout generation on $file2 does not change"
20081
20082         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
20083         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20084
20085         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
20086 }
20087 run_test 184a "Basic layout swap"
20088
20089 test_184b() {
20090         check_swap_layouts_support
20091
20092         dir0=$DIR/$tdir/$testnum
20093         mkdir -p $dir0 || error "creating dir $dir0"
20094         file1=$dir0/f1
20095         file2=$dir0/f2
20096         file3=$dir0/f3
20097         dir1=$dir0/d1
20098         dir2=$dir0/d2
20099         mkdir $dir1 $dir2
20100         $LFS setstripe -c1 $file1
20101         $LFS setstripe -c2 $file2
20102         $LFS setstripe -c1 $file3
20103         chown $RUNAS_ID $file3
20104         gen1=$($LFS getstripe -g $file1)
20105         gen2=$($LFS getstripe -g $file2)
20106
20107         $LFS swap_layouts $dir1 $dir2 &&
20108                 error "swap of directories layouts should fail"
20109         $LFS swap_layouts $dir1 $file1 &&
20110                 error "swap of directory and file layouts should fail"
20111         $RUNAS $LFS swap_layouts $file1 $file2 &&
20112                 error "swap of file we cannot write should fail"
20113         $LFS swap_layouts $file1 $file3 &&
20114                 error "swap of file with different owner should fail"
20115         /bin/true # to clear error code
20116 }
20117 run_test 184b "Forbidden layout swap (will generate errors)"
20118
20119 test_184c() {
20120         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
20121         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
20122         check_swap_layouts_support
20123         check_swap_layout_no_dom $DIR
20124
20125         local dir0=$DIR/$tdir/$testnum
20126         mkdir -p $dir0 || error "creating dir $dir0"
20127
20128         local ref1=$dir0/ref1
20129         local ref2=$dir0/ref2
20130         local file1=$dir0/file1
20131         local file2=$dir0/file2
20132         # create a file large enough for the concurrent test
20133         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
20134         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
20135         echo "ref file size: ref1($(stat -c %s $ref1))," \
20136              "ref2($(stat -c %s $ref2))"
20137
20138         cp $ref2 $file2
20139         dd if=$ref1 of=$file1 bs=16k &
20140         local DD_PID=$!
20141
20142         # Make sure dd starts to copy file, but wait at most 5 seconds
20143         local loops=0
20144         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
20145
20146         $LFS swap_layouts $file1 $file2
20147         local rc=$?
20148         wait $DD_PID
20149         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
20150         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
20151
20152         # how many bytes copied before swapping layout
20153         local copied=$(stat -c %s $file2)
20154         local remaining=$(stat -c %s $ref1)
20155         remaining=$((remaining - copied))
20156         echo "Copied $copied bytes before swapping layout..."
20157
20158         cmp -n $copied $file1 $ref2 | grep differ &&
20159                 error "Content mismatch [0, $copied) of ref2 and file1"
20160         cmp -n $copied $file2 $ref1 ||
20161                 error "Content mismatch [0, $copied) of ref1 and file2"
20162         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
20163                 error "Content mismatch [$copied, EOF) of ref1 and file1"
20164
20165         # clean up
20166         rm -f $ref1 $ref2 $file1 $file2
20167 }
20168 run_test 184c "Concurrent write and layout swap"
20169
20170 test_184d() {
20171         check_swap_layouts_support
20172         check_swap_layout_no_dom $DIR
20173         [ -z "$(which getfattr 2>/dev/null)" ] &&
20174                 skip_env "no getfattr command"
20175
20176         local file1=$DIR/$tdir/$tfile-1
20177         local file2=$DIR/$tdir/$tfile-2
20178         local file3=$DIR/$tdir/$tfile-3
20179         local lovea1
20180         local lovea2
20181
20182         mkdir -p $DIR/$tdir
20183         touch $file1 || error "create $file1 failed"
20184         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
20185                 error "create $file2 failed"
20186         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
20187                 error "create $file3 failed"
20188         lovea1=$(get_layout_param $file1)
20189
20190         $LFS swap_layouts $file2 $file3 ||
20191                 error "swap $file2 $file3 layouts failed"
20192         $LFS swap_layouts $file1 $file2 ||
20193                 error "swap $file1 $file2 layouts failed"
20194
20195         lovea2=$(get_layout_param $file2)
20196         echo "$lovea1"
20197         echo "$lovea2"
20198         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
20199
20200         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
20201         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
20202 }
20203 run_test 184d "allow stripeless layouts swap"
20204
20205 test_184e() {
20206         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
20207                 skip "Need MDS version at least 2.6.94"
20208         check_swap_layouts_support
20209         check_swap_layout_no_dom $DIR
20210         [ -z "$(which getfattr 2>/dev/null)" ] &&
20211                 skip_env "no getfattr command"
20212
20213         local file1=$DIR/$tdir/$tfile-1
20214         local file2=$DIR/$tdir/$tfile-2
20215         local file3=$DIR/$tdir/$tfile-3
20216         local lovea
20217
20218         mkdir -p $DIR/$tdir
20219         touch $file1 || error "create $file1 failed"
20220         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
20221                 error "create $file2 failed"
20222         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
20223                 error "create $file3 failed"
20224
20225         $LFS swap_layouts $file1 $file2 ||
20226                 error "swap $file1 $file2 layouts failed"
20227
20228         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
20229         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
20230
20231         echo 123 > $file1 || error "Should be able to write into $file1"
20232
20233         $LFS swap_layouts $file1 $file3 ||
20234                 error "swap $file1 $file3 layouts failed"
20235
20236         echo 123 > $file1 || error "Should be able to write into $file1"
20237
20238         rm -rf $file1 $file2 $file3
20239 }
20240 run_test 184e "Recreate layout after stripeless layout swaps"
20241
20242 test_184f() {
20243         # Create a file with name longer than sizeof(struct stat) ==
20244         # 144 to see if we can get chars from the file name to appear
20245         # in the returned striping. Note that 'f' == 0x66.
20246         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
20247
20248         mkdir -p $DIR/$tdir
20249         mcreate $DIR/$tdir/$file
20250         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
20251                 error "IOC_MDC_GETFILEINFO returned garbage striping"
20252         fi
20253 }
20254 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
20255
20256 test_185() { # LU-2441
20257         # LU-3553 - no volatile file support in old servers
20258         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
20259                 skip "Need MDS version at least 2.3.60"
20260
20261         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
20262         touch $DIR/$tdir/spoo
20263         local mtime1=$(stat -c "%Y" $DIR/$tdir)
20264         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
20265                 error "cannot create/write a volatile file"
20266         [ "$FILESET" == "" ] &&
20267         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
20268                 error "FID is still valid after close"
20269
20270         multiop_bg_pause $DIR/$tdir Vw4096_c
20271         local multi_pid=$!
20272
20273         local OLD_IFS=$IFS
20274         IFS=":"
20275         local fidv=($fid)
20276         IFS=$OLD_IFS
20277         # assume that the next FID for this client is sequential, since stdout
20278         # is unfortunately eaten by multiop_bg_pause
20279         local n=$((${fidv[1]} + 1))
20280         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
20281         if [ "$FILESET" == "" ]; then
20282                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
20283                         error "FID is missing before close"
20284         fi
20285         kill -USR1 $multi_pid
20286         # 1 second delay, so if mtime change we will see it
20287         sleep 1
20288         local mtime2=$(stat -c "%Y" $DIR/$tdir)
20289         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
20290 }
20291 run_test 185 "Volatile file support"
20292
20293 function create_check_volatile() {
20294         local idx=$1
20295         local tgt
20296
20297         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
20298         local PID=$!
20299         sleep 1
20300         local FID=$(cat /tmp/${tfile}.fid)
20301         [ "$FID" == "" ] && error "can't get FID for volatile"
20302         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
20303         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
20304         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
20305         kill -USR1 $PID
20306         wait
20307         sleep 1
20308         cancel_lru_locks mdc # flush opencache
20309         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
20310         return 0
20311 }
20312
20313 test_185a(){
20314         # LU-12516 - volatile creation via .lustre
20315         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
20316                 skip "Need MDS version at least 2.3.55"
20317
20318         create_check_volatile 0
20319         [ $MDSCOUNT -lt 2 ] && return 0
20320
20321         # DNE case
20322         create_check_volatile 1
20323
20324         return 0
20325 }
20326 run_test 185a "Volatile file creation in .lustre/fid/"
20327
20328 test_187a() {
20329         remote_mds_nodsh && skip "remote MDS with nodsh"
20330         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
20331                 skip "Need MDS version at least 2.3.0"
20332
20333         local dir0=$DIR/$tdir/$testnum
20334         mkdir -p $dir0 || error "creating dir $dir0"
20335
20336         local file=$dir0/file1
20337         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
20338         stack_trap "rm -f $file"
20339         local dv1=$($LFS data_version $file)
20340         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
20341         local dv2=$($LFS data_version $file)
20342         [[ $dv1 != $dv2 ]] ||
20343                 error "data version did not change on write $dv1 == $dv2"
20344 }
20345 run_test 187a "Test data version change"
20346
20347 test_187b() {
20348         remote_mds_nodsh && skip "remote MDS with nodsh"
20349         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
20350                 skip "Need MDS version at least 2.3.0"
20351
20352         local dir0=$DIR/$tdir/$testnum
20353         mkdir -p $dir0 || error "creating dir $dir0"
20354
20355         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
20356         [[ ${DV[0]} != ${DV[1]} ]] ||
20357                 error "data version did not change on write"\
20358                       " ${DV[0]} == ${DV[1]}"
20359
20360         # clean up
20361         rm -f $file1
20362 }
20363 run_test 187b "Test data version change on volatile file"
20364
20365 test_200() {
20366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20367         remote_mgs_nodsh && skip "remote MGS with nodsh"
20368         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
20369
20370         local POOL=${POOL:-cea1}
20371         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
20372         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
20373         # Pool OST targets
20374         local first_ost=0
20375         local last_ost=$(($OSTCOUNT - 1))
20376         local ost_step=2
20377         local ost_list=$(seq $first_ost $ost_step $last_ost)
20378         local ost_range="$first_ost $last_ost $ost_step"
20379         local test_path=$POOL_ROOT/$POOL_DIR_NAME
20380         local file_dir=$POOL_ROOT/file_tst
20381         local subdir=$test_path/subdir
20382         local rc=0
20383
20384         while : ; do
20385                 # former test_200a test_200b
20386                 pool_add $POOL                          || { rc=$? ; break; }
20387                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
20388                 # former test_200c test_200d
20389                 mkdir -p $test_path
20390                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
20391                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
20392                 mkdir -p $subdir
20393                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
20394                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
20395                                                         || { rc=$? ; break; }
20396                 # former test_200e test_200f
20397                 local files=$((OSTCOUNT*3))
20398                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
20399                                                         || { rc=$? ; break; }
20400                 pool_create_files $POOL $file_dir $files "$ost_list" \
20401                                                         || { rc=$? ; break; }
20402                 # former test_200g test_200h
20403                 pool_lfs_df $POOL                       || { rc=$? ; break; }
20404                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
20405
20406                 # former test_201a test_201b test_201c
20407                 pool_remove_first_target $POOL          || { rc=$? ; break; }
20408
20409                 local f=$test_path/$tfile
20410                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
20411                 pool_remove $POOL $f                    || { rc=$? ; break; }
20412                 break
20413         done
20414
20415         destroy_test_pools
20416
20417         return $rc
20418 }
20419 run_test 200 "OST pools"
20420
20421 # usage: default_attr <count | size | offset>
20422 default_attr() {
20423         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
20424 }
20425
20426 # usage: check_default_stripe_attr
20427 check_default_stripe_attr() {
20428         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
20429         case $1 in
20430         --stripe-count|-c)
20431                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
20432         --stripe-size|-S)
20433                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
20434         --stripe-index|-i)
20435                 EXPECTED=-1;;
20436         *)
20437                 error "unknown getstripe attr '$1'"
20438         esac
20439
20440         [ $ACTUAL == $EXPECTED ] ||
20441                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
20442 }
20443
20444 test_204a() {
20445         test_mkdir $DIR/$tdir
20446         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
20447
20448         check_default_stripe_attr --stripe-count
20449         check_default_stripe_attr --stripe-size
20450         check_default_stripe_attr --stripe-index
20451 }
20452 run_test 204a "Print default stripe attributes"
20453
20454 test_204b() {
20455         test_mkdir $DIR/$tdir
20456         $LFS setstripe --stripe-count 1 $DIR/$tdir
20457
20458         check_default_stripe_attr --stripe-size
20459         check_default_stripe_attr --stripe-index
20460 }
20461 run_test 204b "Print default stripe size and offset"
20462
20463 test_204c() {
20464         test_mkdir $DIR/$tdir
20465         $LFS setstripe --stripe-size 65536 $DIR/$tdir
20466
20467         check_default_stripe_attr --stripe-count
20468         check_default_stripe_attr --stripe-index
20469 }
20470 run_test 204c "Print default stripe count and offset"
20471
20472 test_204d() {
20473         test_mkdir $DIR/$tdir
20474         $LFS setstripe --stripe-index 0 $DIR/$tdir
20475
20476         check_default_stripe_attr --stripe-count
20477         check_default_stripe_attr --stripe-size
20478 }
20479 run_test 204d "Print default stripe count and size"
20480
20481 test_204e() {
20482         test_mkdir $DIR/$tdir
20483         $LFS setstripe -d $DIR/$tdir
20484
20485         # LU-16904 check if root is set as PFL layout
20486         local numcomp=$($LFS getstripe --component-count $MOUNT)
20487
20488         if [[ $numcomp -gt 0 ]]; then
20489                 check_default_stripe_attr --stripe-count
20490         else
20491                 check_default_stripe_attr --stripe-count --raw
20492         fi
20493         check_default_stripe_attr --stripe-size --raw
20494         check_default_stripe_attr --stripe-index --raw
20495 }
20496 run_test 204e "Print raw stripe attributes"
20497
20498 test_204f() {
20499         test_mkdir $DIR/$tdir
20500         $LFS setstripe --stripe-count 1 $DIR/$tdir
20501
20502         check_default_stripe_attr --stripe-size --raw
20503         check_default_stripe_attr --stripe-index --raw
20504 }
20505 run_test 204f "Print raw stripe size and offset"
20506
20507 test_204g() {
20508         test_mkdir $DIR/$tdir
20509         $LFS setstripe --stripe-size 65536 $DIR/$tdir
20510
20511         check_default_stripe_attr --stripe-count --raw
20512         check_default_stripe_attr --stripe-index --raw
20513 }
20514 run_test 204g "Print raw stripe count and offset"
20515
20516 test_204h() {
20517         test_mkdir $DIR/$tdir
20518         $LFS setstripe --stripe-index 0 $DIR/$tdir
20519
20520         check_default_stripe_attr --stripe-count --raw
20521         check_default_stripe_attr --stripe-size --raw
20522 }
20523 run_test 204h "Print raw stripe count and size"
20524
20525 # Figure out which job scheduler is being used, if any,
20526 # or use a fake one
20527 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
20528         JOBENV=SLURM_JOB_ID
20529 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
20530         JOBENV=LSB_JOBID
20531 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
20532         JOBENV=PBS_JOBID
20533 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
20534         JOBENV=LOADL_STEP_ID
20535 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
20536         JOBENV=JOB_ID
20537 else
20538         $LCTL list_param jobid_name > /dev/null 2>&1
20539         if [ $? -eq 0 ]; then
20540                 JOBENV=nodelocal
20541         else
20542                 JOBENV=FAKE_JOBID
20543         fi
20544 fi
20545 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
20546
20547 verify_jobstats() {
20548         local cmd=($1)
20549         shift
20550         local facets="$@"
20551
20552 # we don't really need to clear the stats for this test to work, since each
20553 # command has a unique jobid, but it makes debugging easier if needed.
20554 #       for facet in $facets; do
20555 #               local dev=$(convert_facet2label $facet)
20556 #               # clear old jobstats
20557 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
20558 #       done
20559
20560         # use a new JobID for each test, or we might see an old one
20561         [ "$JOBENV" = "FAKE_JOBID" ] &&
20562                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
20563
20564         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
20565
20566         [ "$JOBENV" = "nodelocal" ] && {
20567                 FAKE_JOBID=id.$testnum.%e.$RANDOM
20568                 $LCTL set_param jobid_name=$FAKE_JOBID
20569                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
20570         }
20571
20572         log "Test: ${cmd[*]}"
20573         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
20574
20575         if [ $JOBENV = "FAKE_JOBID" ]; then
20576                 FAKE_JOBID=$JOBVAL ${cmd[*]}
20577         else
20578                 ${cmd[*]}
20579         fi
20580
20581         # all files are created on OST0000
20582         for facet in $facets; do
20583                 local stats="*.$(convert_facet2label $facet).job_stats"
20584
20585                 # strip out libtool wrappers for in-tree executables
20586                 if (( $(do_facet $facet lctl get_param $stats |
20587                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
20588                         do_facet $facet lctl get_param $stats
20589                         error "No jobstats for $JOBVAL found on $facet::$stats"
20590                 fi
20591         done
20592 }
20593
20594 jobstats_set() {
20595         local new_jobenv=$1
20596
20597         set_persistent_param_and_check client "jobid_var" \
20598                 "$FSNAME.sys.jobid_var" $new_jobenv
20599 }
20600
20601 test_205a() { # Job stats
20602         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20603         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
20604                 skip "Need MDS version with at least 2.7.1"
20605         remote_mgs_nodsh && skip "remote MGS with nodsh"
20606         remote_mds_nodsh && skip "remote MDS with nodsh"
20607         remote_ost_nodsh && skip "remote OST with nodsh"
20608         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
20609                 skip "Server doesn't support jobstats"
20610         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
20611
20612         local old_jobenv=$($LCTL get_param -n jobid_var)
20613         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
20614         stack_trap "jobstats_set $old_jobenv" EXIT
20615
20616         changelog_register
20617
20618         local old_jobid_name=$($LCTL get_param jobid_name)
20619         stack_trap "$LCTL set_param $old_jobid_name" EXIT
20620
20621         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
20622                                 mdt.*.job_cleanup_interval | head -n 1)
20623         local new_interval=5
20624         do_facet $SINGLEMDS \
20625                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
20626         stack_trap "do_facet $SINGLEMDS \
20627                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
20628         local start=$SECONDS
20629
20630         local cmd
20631         # mkdir
20632         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
20633         verify_jobstats "$cmd" "$SINGLEMDS"
20634         # rmdir
20635         cmd="rmdir $DIR/$tdir"
20636         verify_jobstats "$cmd" "$SINGLEMDS"
20637         # mkdir on secondary MDT
20638         if [ $MDSCOUNT -gt 1 ]; then
20639                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
20640                 verify_jobstats "$cmd" "mds2"
20641         fi
20642         # mknod
20643         cmd="mknod $DIR/$tfile c 1 3"
20644         verify_jobstats "$cmd" "$SINGLEMDS"
20645         # unlink
20646         cmd="rm -f $DIR/$tfile"
20647         verify_jobstats "$cmd" "$SINGLEMDS"
20648         # create all files on OST0000 so verify_jobstats can find OST stats
20649         # open & close
20650         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
20651         verify_jobstats "$cmd" "$SINGLEMDS"
20652         # setattr
20653         cmd="touch $DIR/$tfile"
20654         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20655         # write
20656         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
20657         verify_jobstats "$cmd" "ost1"
20658         # read
20659         cancel_lru_locks osc
20660         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
20661         verify_jobstats "$cmd" "ost1"
20662         # truncate
20663         cmd="$TRUNCATE $DIR/$tfile 0"
20664         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20665         # rename
20666         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
20667         verify_jobstats "$cmd" "$SINGLEMDS"
20668         # jobstats expiry - sleep until old stats should be expired
20669         local left=$((new_interval + 5 - (SECONDS - start)))
20670         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
20671                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
20672                         "0" $left
20673         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
20674         verify_jobstats "$cmd" "$SINGLEMDS"
20675         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
20676             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
20677
20678         # Ensure that jobid are present in changelog (if supported by MDS)
20679         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
20680                 changelog_dump | tail -10
20681                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
20682                 [ $jobids -eq 9 ] ||
20683                         error "Wrong changelog jobid count $jobids != 9"
20684
20685                 # LU-5862
20686                 JOBENV="disable"
20687                 jobstats_set $JOBENV
20688                 touch $DIR/$tfile
20689                 changelog_dump | grep $tfile
20690                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
20691                 [ $jobids -eq 0 ] ||
20692                         error "Unexpected jobids when jobid_var=$JOBENV"
20693         fi
20694
20695         # test '%j' access to environment variable - if supported
20696         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
20697                 JOBENV="JOBCOMPLEX"
20698                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20699
20700                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20701         fi
20702
20703         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
20704                 JOBENV="JOBCOMPLEX"
20705                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
20706
20707                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20708         fi
20709
20710         # test '%j' access to per-session jobid - if supported
20711         if lctl list_param jobid_this_session > /dev/null 2>&1
20712         then
20713                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
20714                 lctl set_param jobid_this_session=$USER
20715
20716                 JOBENV="JOBCOMPLEX"
20717                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20718
20719                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20720         fi
20721 }
20722 run_test 205a "Verify job stats"
20723
20724 # LU-13117, LU-13597, LU-16599
20725 test_205b() {
20726         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
20727                 skip "Need MDS version at least 2.13.54.91"
20728
20729         local job_stats="mdt.*.job_stats"
20730         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
20731
20732         do_facet mds1 $LCTL set_param $job_stats=clear
20733
20734         # Setting jobid_var to USER might not be supported
20735         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
20736         $LCTL set_param jobid_var=USER || true
20737         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
20738         $LCTL set_param jobid_name="%j.%e.%u"
20739
20740         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
20741         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
20742                 { do_facet mds1 $LCTL get_param $job_stats;
20743                   error "Unexpected jobid found"; }
20744         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
20745                 { do_facet mds1 $LCTL get_param $job_stats;
20746                   error "wrong job_stats format found"; }
20747
20748         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
20749                 echo "MDS does not yet escape jobid" && return 0
20750
20751         mkdir_on_mdt0 $DIR/$tdir
20752         $LCTL set_param jobid_var=TEST205b
20753         env -i TEST205b="has sp" touch $DIR/$tdir/$tfile.2
20754         local jobid=$(do_facet mds1 $LCTL get_param $job_stats |
20755                       awk '/has\\x20sp/ {print $3}')
20756         [[ -n "$jobid" ]] || { do_facet mds1 $LCTL get_param $job_stats;
20757                   error "jobid not escaped"; }
20758
20759         if (( $MDS1_VERSION >= $(version_code 2.15.53.139) )); then
20760                 # need to run such a command on mds1:
20761                 # lctl set_param mdt.$FSNAME-MDT0000.job_stats='"has\x20sp.touch.0"'
20762                 #
20763                 # there might be multiple MDTs on single mds server, so need to
20764                 # specifiy MDT0000. Or the command will fail due to other MDTs
20765                 do_facet_vp mds1 $LCTL set_param mdt.$FSNAME-MDT0000.job_stats=$jobid ||
20766                         error "cannot clear escaped jobid in job_stats";
20767         else
20768                 echo "MDS does not support clearing escaped jobid"
20769         fi
20770 }
20771 run_test 205b "Verify job stats jobid and output format"
20772
20773 # LU-13733
20774 test_205c() {
20775         $LCTL set_param llite.*.stats=0
20776         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
20777         $LCTL get_param llite.*.stats
20778         $LCTL get_param llite.*.stats | grep \
20779                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
20780                         error "wrong client stats format found"
20781 }
20782 run_test 205c "Verify client stats format"
20783
20784 test_205d() {
20785         local file=$DIR/$tdir/$tfile
20786
20787         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20788                 skip "need lustre >= 2.15.53 for lljobstat"
20789         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20790                 skip "need lustre >= 2.15.53 for lljobstat"
20791         verify_yaml_available || skip_env "YAML verification not installed"
20792
20793         test_mkdir -i 0 $DIR/$tdir
20794         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
20795         stack_trap "rm -rf $DIR/$tdir"
20796
20797         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
20798                 error "failed to write data to $file"
20799         mv $file $file.2
20800
20801         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
20802         echo -n 'verify rename_stats...'
20803         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
20804                 verify_yaml || error "rename_stats is not valid YAML"
20805         echo " OK"
20806
20807         echo -n 'verify mdt job_stats...'
20808         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
20809                 verify_yaml || error "job_stats on mds1 is not valid YAML"
20810         echo " OK"
20811
20812         echo -n 'verify ost job_stats...'
20813         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
20814                 verify_yaml || error "job_stats on ost1 is not valid YAML"
20815         echo " OK"
20816 }
20817 run_test 205d "verify the format of some stats files"
20818
20819 test_205e() {
20820         local ops_comma
20821         local file=$DIR/$tdir/$tfile
20822         local -a cli_params
20823
20824         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20825                 skip "need lustre >= 2.15.53 for lljobstat"
20826         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20827                 skip "need lustre >= 2.15.53 for lljobstat"
20828         verify_yaml_available || skip_env "YAML verification not installed"
20829
20830         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20831         $LCTL set_param jobid_var=nodelocal jobid_name=205e.%e.%u
20832         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20833
20834         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
20835         stack_trap "rm -rf $DIR/$tdir"
20836
20837         $LFS setstripe -E EOF -i 0 -c 1 $file ||
20838                 error "failed to create $file on ost1"
20839         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
20840                 error "failed to write data to $file"
20841
20842         do_facet mds1 "$LCTL get_param *.*.job_stats"
20843         do_facet ost1 "$LCTL get_param *.*.job_stats"
20844
20845         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
20846         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
20847                 error "The output of lljobstat is not an valid YAML"
20848
20849         # verify that job dd.0 does exist and has some ops on ost1
20850         # typically this line is like:
20851         # - 205e.dd.0:            {ops: 20, ...}
20852         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
20853                     awk '$2=="205e.dd.0:" {print $4}')
20854
20855         (( ${ops_comma%,} >= 10 )) ||
20856                 error "cannot find job 205e.dd.0 with ops >= 10"
20857 }
20858 run_test 205e "verify the output of lljobstat"
20859
20860 test_205f() {
20861         verify_yaml_available || skip_env "YAML verification not installed"
20862
20863         # check both qos_ost_weights and qos_mdt_weights
20864         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
20865         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
20866                 error "qos_ost_weights is not valid YAML"
20867 }
20868 run_test 205f "verify qos_ost_weights YAML format "
20869
20870 __test_205_jobstats_dump() {
20871         local -a pids
20872         local nbr_instance=$1
20873
20874         while true; do
20875                 if (( ${#pids[@]} >= nbr_instance )); then
20876                         wait ${pids[@]}
20877                         pids=()
20878                 fi
20879
20880                 do_facet mds1 "$LCTL get_param mdt.*.job_stats > /dev/null" &
20881                 pids+=( $! )
20882         done
20883 }
20884
20885 __test_205_cleanup() {
20886         kill $@
20887         # Clear all job entries
20888         do_facet mds1 "$LCTL set_param mdt.*.job_stats=clear"
20889 }
20890
20891 test_205g() {
20892         local -a mds1_params
20893         local -a cli_params
20894         local pids
20895         local interval=5
20896
20897         mds1_params=( $(do_facet mds1 $LCTL get_param mdt.*.job_cleanup_interval) )
20898         do_facet mds1 $LCTL set_param mdt.*.job_cleanup_interval=$interval
20899         stack_trap "do_facet mds1 $LCTL set_param ${mds1_params[*]}" EXIT
20900
20901         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20902         $LCTL set_param jobid_var=TEST205G_ID jobid_name=%j.%p
20903         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20904
20905         # start jobs loop
20906         export TEST205G_ID=205g
20907         stack_trap "unset TEST205G_ID" EXIT
20908         while true; do
20909                 printf $DIR/$tfile.{0001..1000} | xargs -P10 -n1 touch
20910         done & pids="$! "
20911
20912         __test_205_jobstats_dump 4 & pids+="$! "
20913         stack_trap "__test_205_cleanup $pids" EXIT INT
20914
20915         [[ $SLOW == "no" ]] && sleep 90 || sleep 240
20916 }
20917 run_test 205g "stress test for job_stats procfile"
20918
20919 test_205h() {
20920         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
20921                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
20922         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
20923
20924         local dir=$DIR/$tdir
20925         local f=$dir/$tfile
20926         local f2=$dir/$tfile-2
20927         local f3=$dir/$tfile-3
20928         local subdir=$DIR/dir
20929         local val
20930
20931         local mdts=$(comma_list $(mdts_nodes))
20932         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20933         local client_saved=$($LCTL get_param -n jobid_var)
20934
20935         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20936         stack_trap "$LCTL set_param jobid_var=$client_saved" EXIT
20937
20938         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job ||
20939                 error "failed to set job_xattr parameter to user.job"
20940         $LCTL set_param jobid_var=procname.uid ||
20941                 error "failed to set jobid_var parameter"
20942
20943         test_mkdir $dir
20944
20945         touch $f
20946         val=$(getfattr -n user.job $f | grep user.job)
20947         [[ $val = user.job=\"touch.0\" ]] ||
20948                 error "expected user.job=\"touch.0\", got '$val'"
20949
20950         mkdir $subdir
20951         val=$(getfattr -n user.job $subdir | grep user.job)
20952         [[ $val = user.job=\"mkdir.0\" ]] ||
20953                 error "expected user.job=\"mkdir.0\", got '$val'"
20954
20955         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE ||
20956                 error "failed to set job_xattr parameter to NONE"
20957
20958         touch $f2
20959         val=$(getfattr -d $f2)
20960         [[ -z $val ]] ||
20961                 error "expected no user xattr, got '$val'"
20962
20963         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=trusted.job ||
20964                 error "failed to set job_xattr parameter to trusted.job"
20965
20966         touch $f3
20967         val=$(getfattr -n trusted.job $f3 | grep trusted.job)
20968         [[ $val = trusted.job=\"touch.0\" ]] ||
20969                 error "expected trusted.job=\"touch.0\", got '$val'"
20970 }
20971 run_test 205h "check jobid xattr is stored correctly"
20972
20973 test_205i() {
20974         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
20975                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
20976
20977         local mdts=$(comma_list $(mdts_nodes))
20978         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20979
20980         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20981
20982         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.1234567 ||
20983                 error "failed to set mdt.*.job_xattr to user.1234567"
20984
20985         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.12345678 &&
20986                 error "failed to reject too long job_xattr name"
20987
20988         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=userjob &&
20989                 error "failed to reject job_xattr name in bad format"
20990
20991         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job/ &&
20992                 error "failed to reject job_xattr name with invalid character"
20993
20994         do_nodes $mdts "printf 'mdt.*.job_xattr=user.job\x80' |
20995                         xargs $LCTL set_param" &&
20996                 error "failed to reject job_xattr name with non-ascii character"
20997
20998         return 0
20999 }
21000 run_test 205i "check job_xattr parameter accepts and rejects values correctly"
21001
21002 # LU-1480, LU-1773 and LU-1657
21003 test_206() {
21004         mkdir -p $DIR/$tdir
21005         $LFS setstripe -c -1 $DIR/$tdir
21006 #define OBD_FAIL_LOV_INIT 0x1403
21007         $LCTL set_param fail_loc=0xa0001403
21008         $LCTL set_param fail_val=1
21009         touch $DIR/$tdir/$tfile || true
21010 }
21011 run_test 206 "fail lov_init_raid0() doesn't lbug"
21012
21013 test_207a() {
21014         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
21015         local fsz=`stat -c %s $DIR/$tfile`
21016         cancel_lru_locks mdc
21017
21018         # do not return layout in getattr intent
21019 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
21020         $LCTL set_param fail_loc=0x170
21021         local sz=`stat -c %s $DIR/$tfile`
21022
21023         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
21024
21025         rm -rf $DIR/$tfile
21026 }
21027 run_test 207a "can refresh layout at glimpse"
21028
21029 test_207b() {
21030         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
21031         local cksum=`md5sum $DIR/$tfile`
21032         local fsz=`stat -c %s $DIR/$tfile`
21033         cancel_lru_locks mdc
21034         cancel_lru_locks osc
21035
21036         # do not return layout in getattr intent
21037 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
21038         $LCTL set_param fail_loc=0x171
21039
21040         # it will refresh layout after the file is opened but before read issues
21041         echo checksum is "$cksum"
21042         echo "$cksum" |md5sum -c --quiet || error "file differs"
21043
21044         rm -rf $DIR/$tfile
21045 }
21046 run_test 207b "can refresh layout at open"
21047
21048 test_208() {
21049         # FIXME: in this test suite, only RD lease is used. This is okay
21050         # for now as only exclusive open is supported. After generic lease
21051         # is done, this test suite should be revised. - Jinshan
21052
21053         remote_mds_nodsh && skip "remote MDS with nodsh"
21054         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
21055                 skip "Need MDS version at least 2.4.52"
21056
21057         echo "==== test 1: verify get lease work"
21058         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
21059
21060         echo "==== test 2: verify lease can be broken by upcoming open"
21061         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
21062         local PID=$!
21063         sleep 2
21064
21065         $MULTIOP $DIR/$tfile oO_RDWR:c
21066         kill -USR1 $PID && wait $PID || error "break lease error"
21067
21068         echo "==== test 3: verify lease can't be granted if an open already exists"
21069         $MULTIOP $DIR/$tfile oO_RDWR:_c &
21070         local PID=$!
21071         sleep 2
21072
21073         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
21074         kill -USR1 $PID && wait $PID || error "open file error"
21075
21076         echo "==== test 4: lease can sustain over recovery"
21077         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
21078         PID=$!
21079         sleep 2
21080
21081         fail mds1
21082
21083         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
21084
21085         echo "==== test 5: lease broken can't be regained by replay"
21086         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
21087         PID=$!
21088         sleep 2
21089
21090         # open file to break lease and then recovery
21091         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
21092         fail mds1
21093
21094         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
21095
21096         rm -f $DIR/$tfile
21097 }
21098 run_test 208 "Exclusive open"
21099
21100 test_209() {
21101         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
21102                 skip_env "must have disp_stripe"
21103
21104         touch $DIR/$tfile
21105         sync; sleep 5; sync;
21106
21107         echo 3 > /proc/sys/vm/drop_caches
21108         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
21109                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
21110         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
21111
21112         # open/close 500 times
21113         for i in $(seq 500); do
21114                 cat $DIR/$tfile
21115         done
21116
21117         echo 3 > /proc/sys/vm/drop_caches
21118         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
21119                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
21120         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
21121
21122         echo "before: $req_before, after: $req_after"
21123         [ $((req_after - req_before)) -ge 300 ] &&
21124                 error "open/close requests are not freed"
21125         return 0
21126 }
21127 run_test 209 "read-only open/close requests should be freed promptly"
21128
21129 test_210() {
21130         local pid
21131
21132         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
21133         pid=$!
21134         sleep 1
21135
21136         $LFS getstripe $DIR/$tfile
21137         kill -USR1 $pid
21138         wait $pid || error "multiop failed"
21139
21140         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
21141         pid=$!
21142         sleep 1
21143
21144         $LFS getstripe $DIR/$tfile
21145         kill -USR1 $pid
21146         wait $pid || error "multiop failed"
21147 }
21148 run_test 210 "lfs getstripe does not break leases"
21149
21150 function test_211() {
21151         local PID
21152         local id
21153         local rc
21154
21155         stack_trap "rm -f $DIR/$tfile" EXIT
21156         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=10 oflag=direct ||
21157                 error "can't create file"
21158         $LFS mirror extend -N $DIR/$tfile ||
21159                 error "can't create a replica"
21160         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
21161         $LFS getstripe $DIR/$tfile
21162         stale=$($LFS getstripe $DIR/$tfile | grep stale | wc -l)
21163         (( $stale != 1 )) && error "expected 1 stale, found $stale"
21164
21165         $MULTIOP $DIR/$tfile OeW_E+eUc &
21166         PID=$!
21167         sleep 0.3
21168
21169         id=$($LFS getstripe $DIR/$tfile |
21170                 awk '/lcme_mirror_id:/{id=$2}/lcme_flags.*init$/{print id}')
21171         $LFS mirror split -d --mirror-id $id $DIR/$tfile &&
21172                 error "removed last in-sync replica?"
21173
21174         kill -USR1 $PID
21175         wait $PID
21176         (( $? == 0 )) || error "failed split broke the lease"
21177 }
21178 run_test 211 "failed mirror split doesn't break write lease"
21179
21180 test_212() {
21181         size=`date +%s`
21182         size=$((size % 8192 + 1))
21183         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
21184         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
21185         rm -f $DIR/f212 $DIR/f212.xyz
21186 }
21187 run_test 212 "Sendfile test ============================================"
21188
21189 test_213() {
21190         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
21191         cancel_lru_locks osc
21192         lctl set_param fail_loc=0x8000040f
21193         # generate a read lock
21194         cat $DIR/$tfile > /dev/null
21195         # write to the file, it will try to cancel the above read lock.
21196         cat /etc/hosts >> $DIR/$tfile
21197 }
21198 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
21199
21200 test_214() { # for bug 20133
21201         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
21202         for (( i=0; i < 340; i++ )) ; do
21203                 touch $DIR/$tdir/d214c/a$i
21204         done
21205
21206         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
21207         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
21208         ls $DIR/d214c || error "ls $DIR/d214c failed"
21209         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
21210         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
21211 }
21212 run_test 214 "hash-indexed directory test - bug 20133"
21213
21214 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
21215 create_lnet_proc_files() {
21216         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
21217 }
21218
21219 # counterpart of create_lnet_proc_files
21220 remove_lnet_proc_files() {
21221         rm -f $TMP/lnet_$1.sys
21222 }
21223
21224 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
21225 # 3rd arg as regexp for body
21226 check_lnet_proc_stats() {
21227         local l=$(cat "$TMP/lnet_$1" |wc -l)
21228         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
21229
21230         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
21231 }
21232
21233 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
21234 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
21235 # optional and can be regexp for 2nd line (lnet.routes case)
21236 check_lnet_proc_entry() {
21237         local blp=2          # blp stands for 'position of 1st line of body'
21238         [ -z "$5" ] || blp=3 # lnet.routes case
21239
21240         local l=$(cat "$TMP/lnet_$1" |wc -l)
21241         # subtracting one from $blp because the body can be empty
21242         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
21243
21244         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
21245                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
21246
21247         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
21248                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
21249
21250         # bail out if any unexpected line happened
21251         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
21252         [ "$?" != 0 ] || error "$2 misformatted"
21253 }
21254
21255 test_215() { # for bugs 18102, 21079, 21517
21256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21257
21258         local N='(0|[1-9][0-9]*)'       # non-negative numeric
21259         local P='[1-9][0-9]*'           # positive numeric
21260         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
21261         local NET='[a-z][a-z0-9]*'      # LNet net like o2ib2
21262         local ADDR='[0-9.]+'            # LNet addr like 10.0.0.1
21263         local ADDR6='([0-9a-f]{0,4}:){2,7}[0-9a-f]{0,4}' # IPv6 LNet addr
21264         local NID="$ADDR@$NET"          # LNet nid like 10.0.0.1@o2ib2
21265         local NID6="$ADDR6@$NET"        # LNet nid like 2601:8c1:c180::cbdd@tcp
21266
21267         local L1 # regexp for 1st line
21268         local L2 # regexp for 2nd line (optional)
21269         local BR # regexp for the rest (body)
21270
21271         # lnet.stats should look as 11 space-separated non-negative numerics
21272         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
21273         create_lnet_proc_files "stats"
21274         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
21275         remove_lnet_proc_files "stats"
21276
21277         # lnet.routes should look like this:
21278         # Routing disabled/enabled
21279         # net hops priority state router
21280         # where net is a string like tcp0, hops > 0, priority >= 0,
21281         # state is up/down,
21282         # router is a string like 192.168.1.1@tcp2
21283         L1="^Routing (disabled|enabled)$"
21284         L2="^net +hops +priority +state +router$"
21285         BR="^$NET +$N +(0|1) +(up|down) +($NID|$NID6)$"
21286         create_lnet_proc_files "routes"
21287         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
21288         remove_lnet_proc_files "routes"
21289
21290         # lnet.routers should look like this:
21291         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
21292         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
21293         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
21294         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
21295         L1="^ref +rtr_ref +alive +router$"
21296         BR="^$P +$P +(up|down) +($NID|$NID6)$"
21297         create_lnet_proc_files "routers"
21298         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
21299         remove_lnet_proc_files "routers"
21300
21301         # lnet.peers should look like this:
21302         # nid refs state last max rtr min tx min queue
21303         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
21304         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
21305         # numeric (0 or >0 or <0), queue >= 0.
21306         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
21307         BR="^($NID|$NID6) +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
21308         create_lnet_proc_files "peers"
21309         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
21310         remove_lnet_proc_files "peers"
21311
21312         # lnet.buffers  should look like this:
21313         # pages count credits min
21314         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
21315         L1="^pages +count +credits +min$"
21316         BR="^ +$N +$N +$I +$I$"
21317         create_lnet_proc_files "buffers"
21318         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
21319         remove_lnet_proc_files "buffers"
21320
21321         # lnet.nis should look like this:
21322         # nid status alive refs peer rtr max tx min
21323         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
21324         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
21325         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
21326         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
21327         BR="^($NID|$NID6) +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
21328         create_lnet_proc_files "nis"
21329         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
21330         remove_lnet_proc_files "nis"
21331
21332         # can we successfully write to lnet.stats?
21333         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
21334 }
21335 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
21336
21337 test_216() { # bug 20317
21338         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21339         remote_ost_nodsh && skip "remote OST with nodsh"
21340
21341         local node
21342         local facets=$(get_facets OST)
21343         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
21344
21345         save_lustre_params client "osc.*.contention_seconds" > $p
21346         save_lustre_params $facets \
21347                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
21348         save_lustre_params $facets \
21349                 "ldlm.namespaces.filter-*.contended_locks" >> $p
21350         save_lustre_params $facets \
21351                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
21352         clear_stats osc.*.osc_stats
21353
21354         # agressive lockless i/o settings
21355         do_nodes $(comma_list $(osts_nodes)) \
21356                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
21357                         ldlm.namespaces.filter-*.contended_locks=0 \
21358                         ldlm.namespaces.filter-*.contention_seconds=60"
21359         lctl set_param -n osc.*.contention_seconds=60
21360
21361         $DIRECTIO write $DIR/$tfile 0 10 4096
21362         $CHECKSTAT -s 40960 $DIR/$tfile
21363
21364         # disable lockless i/o
21365         do_nodes $(comma_list $(osts_nodes)) \
21366                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
21367                         ldlm.namespaces.filter-*.contended_locks=32 \
21368                         ldlm.namespaces.filter-*.contention_seconds=0"
21369         lctl set_param -n osc.*.contention_seconds=0
21370         clear_stats osc.*.osc_stats
21371
21372         dd if=/dev/zero of=$DIR/$tfile count=0
21373         $CHECKSTAT -s 0 $DIR/$tfile
21374
21375         restore_lustre_params <$p
21376         rm -f $p
21377         rm $DIR/$tfile
21378 }
21379 run_test 216 "check lockless direct write updates file size and kms correctly"
21380
21381 test_217() { # bug 22430
21382         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21383
21384         local node
21385
21386         for node in $(nodes_list); do
21387                 local nid=$(host_nids_address $node $NETTYPE)
21388                 local node_ip=$(do_node $node getent ahostsv4 $node |
21389                                 awk '{ print $1; exit; }')
21390
21391                 echo "node: '$node', nid: '$nid', node_ip='$node_ip'"
21392                 # if hostname matches any NID, use hostname for better testing
21393                 if [[ -z "$nid" || "$nid" =~ "$node_ip" ]]; then
21394                         echo "lctl ping node $node@$NETTYPE"
21395                         lctl ping $node@$NETTYPE ||
21396                                 error "ping $node@$NETTYPE failed rc=$?"
21397                 else # otherwise, at least test 'lctl ping' is working
21398                         echo "lctl ping nid $(h2nettype $nid)"
21399                         lctl ping $(h2nettype $nid) ||
21400                                 error "ping $(h2nettype $nid) failed rc=$?"
21401                         echo "skipping $node (no hyphen detected)"
21402                 fi
21403         done
21404
21405         return 0
21406 }
21407 run_test 217 "check lctl ping for hostnames with embedded hyphen ('-')"
21408
21409 test_218() {
21410         # do directio so as not to populate the page cache
21411         log "creating a 10 Mb file"
21412         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
21413                 error "multiop failed while creating a file"
21414         log "starting reads"
21415         dd if=$DIR/$tfile of=/dev/null bs=4096 &
21416         log "truncating the file"
21417         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
21418                 error "multiop failed while truncating the file"
21419         log "killing dd"
21420         kill %+ || true # reads might have finished
21421         echo "wait until dd is finished"
21422         wait
21423         log "removing the temporary file"
21424         rm -rf $DIR/$tfile || error "tmp file removal failed"
21425 }
21426 run_test 218 "parallel read and truncate should not deadlock"
21427
21428 test_219() {
21429         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21430
21431         # write one partial page
21432         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
21433         # set no grant so vvp_io_commit_write will do sync write
21434         $LCTL set_param fail_loc=0x411
21435         # write a full page at the end of file
21436         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
21437
21438         $LCTL set_param fail_loc=0
21439         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
21440         $LCTL set_param fail_loc=0x411
21441         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
21442
21443         # LU-4201
21444         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
21445         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
21446 }
21447 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
21448
21449 test_220() { #LU-325
21450         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21451         remote_ost_nodsh && skip "remote OST with nodsh"
21452         remote_mds_nodsh && skip "remote MDS with nodsh"
21453         remote_mgs_nodsh && skip "remote MGS with nodsh"
21454
21455         local OSTIDX=0
21456
21457         # create on MDT0000 so the last_id and next_id are correct
21458         mkdir_on_mdt0 $DIR/$tdir
21459         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
21460         OST=${OST%_UUID}
21461
21462         # on the mdt's osc
21463         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
21464         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
21465                         osp.$mdtosc_proc1.prealloc_last_id)
21466         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
21467                         osp.$mdtosc_proc1.prealloc_next_id)
21468
21469         $LFS df -i
21470
21471         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
21472         #define OBD_FAIL_OST_ENOINO              0x229
21473         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
21474         create_pool $FSNAME.$TESTNAME || return 1
21475         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
21476
21477         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
21478
21479         MDSOBJS=$((last_id - next_id))
21480         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
21481
21482         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
21483         echo "OST still has $count kbytes free"
21484
21485         echo "create $MDSOBJS files @next_id..."
21486         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
21487
21488         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
21489                         osp.$mdtosc_proc1.prealloc_last_id)
21490         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
21491                         osp.$mdtosc_proc1.prealloc_next_id)
21492
21493         echo "after creation, last_id=$last_id2, next_id=$next_id2"
21494         $LFS df -i
21495
21496         echo "cleanup..."
21497
21498         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
21499         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
21500
21501         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
21502                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
21503         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
21504                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
21505         echo "unlink $MDSOBJS files @$next_id..."
21506         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
21507 }
21508 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
21509
21510 test_221() {
21511         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21512
21513         dd if=`which date` of=$MOUNT/date oflag=sync
21514         chmod +x $MOUNT/date
21515
21516         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
21517         $LCTL set_param fail_loc=0x80001401
21518
21519         $MOUNT/date > /dev/null
21520         rm -f $MOUNT/date
21521 }
21522 run_test 221 "make sure fault and truncate race to not cause OOM"
21523
21524 test_222a () {
21525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21526
21527         rm -rf $DIR/$tdir
21528         test_mkdir $DIR/$tdir
21529         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21530         createmany -o $DIR/$tdir/$tfile 10
21531         cancel_lru_locks mdc
21532         cancel_lru_locks osc
21533         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21534         $LCTL set_param fail_loc=0x31a
21535         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
21536         $LCTL set_param fail_loc=0
21537         rm -r $DIR/$tdir
21538 }
21539 run_test 222a "AGL for ls should not trigger CLIO lock failure"
21540
21541 test_222b () {
21542         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21543
21544         rm -rf $DIR/$tdir
21545         test_mkdir $DIR/$tdir
21546         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21547         createmany -o $DIR/$tdir/$tfile 10
21548         cancel_lru_locks mdc
21549         cancel_lru_locks osc
21550         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21551         $LCTL set_param fail_loc=0x31a
21552         rm -r $DIR/$tdir || error "AGL for rmdir failed"
21553         $LCTL set_param fail_loc=0
21554 }
21555 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
21556
21557 test_223 () {
21558         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21559
21560         rm -rf $DIR/$tdir
21561         test_mkdir $DIR/$tdir
21562         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21563         createmany -o $DIR/$tdir/$tfile 10
21564         cancel_lru_locks mdc
21565         cancel_lru_locks osc
21566         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
21567         $LCTL set_param fail_loc=0x31b
21568         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
21569         $LCTL set_param fail_loc=0
21570         rm -r $DIR/$tdir
21571 }
21572 run_test 223 "osc reenqueue if without AGL lock granted ======================="
21573
21574 test_224a() { # LU-1039, MRP-303
21575         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21576         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
21577         $LCTL set_param fail_loc=0x508
21578         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
21579         $LCTL set_param fail_loc=0
21580         df $DIR
21581 }
21582 run_test 224a "Don't panic on bulk IO failure"
21583
21584 test_224bd_sub() { # LU-1039, MRP-303
21585         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21586         local timeout=$1
21587
21588         shift
21589         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
21590
21591         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21592
21593         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
21594         cancel_lru_locks osc
21595         set_checksums 0
21596         stack_trap "set_checksums $ORIG_CSUM" EXIT
21597         local at_max_saved=0
21598
21599         # adaptive timeouts may prevent seeing the issue
21600         if at_is_enabled; then
21601                 at_max_saved=$(at_max_get mds)
21602                 at_max_set 0 mds client
21603                 stack_trap "at_max_set $at_max_saved mds client" EXIT
21604         fi
21605
21606         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
21607         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
21608         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
21609
21610         do_facet ost1 $LCTL set_param fail_loc=0
21611         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
21612         df $DIR
21613 }
21614
21615 test_224b() {
21616         test_224bd_sub 3 error "dd failed"
21617 }
21618 run_test 224b "Don't panic on bulk IO failure"
21619
21620 test_224c() { # LU-6441
21621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21622         remote_mds_nodsh && skip "remote MDS with nodsh"
21623
21624         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
21625         save_writethrough $p
21626         set_cache writethrough on
21627
21628         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
21629         local at_max=$($LCTL get_param -n at_max)
21630         local timeout=$($LCTL get_param -n timeout)
21631         local test_at="at_max"
21632         local param_at="$FSNAME.sys.at_max"
21633         local test_timeout="timeout"
21634         local param_timeout="$FSNAME.sys.timeout"
21635
21636         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
21637
21638         set_persistent_param_and_check client "$test_at" "$param_at" 0
21639         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
21640
21641         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
21642         do_facet ost1 "$LCTL set_param fail_loc=0x520"
21643         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21644         stack_trap "rm -f $DIR/$tfile"
21645         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
21646         sync
21647         do_facet ost1 "$LCTL set_param fail_loc=0"
21648
21649         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
21650         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
21651                 $timeout
21652
21653         $LCTL set_param -n $pages_per_rpc
21654         restore_lustre_params < $p
21655         rm -f $p
21656 }
21657 run_test 224c "Don't hang if one of md lost during large bulk RPC"
21658
21659 test_224d() { # LU-11169
21660         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
21661 }
21662 run_test 224d "Don't corrupt data on bulk IO timeout"
21663
21664 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
21665 test_225a () {
21666         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21667         if [ -z ${MDSSURVEY} ]; then
21668                 skip_env "mds-survey not found"
21669         fi
21670         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21671                 skip "Need MDS version at least 2.2.51"
21672
21673         local mds=$(facet_host $SINGLEMDS)
21674         local target=$(do_nodes $mds 'lctl dl' |
21675                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21676
21677         local cmd1="file_count=1000 thrhi=4"
21678         local cmd2="dir_count=2 layer=mdd stripe_count=0"
21679         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21680         local cmd="$cmd1 $cmd2 $cmd3"
21681
21682         rm -f ${TMP}/mds_survey*
21683         echo + $cmd
21684         eval $cmd || error "mds-survey with zero-stripe failed"
21685         cat ${TMP}/mds_survey*
21686         rm -f ${TMP}/mds_survey*
21687 }
21688 run_test 225a "Metadata survey sanity with zero-stripe"
21689
21690 test_225b () {
21691         if [ -z ${MDSSURVEY} ]; then
21692                 skip_env "mds-survey not found"
21693         fi
21694         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21695                 skip "Need MDS version at least 2.2.51"
21696         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21697         remote_mds_nodsh && skip "remote MDS with nodsh"
21698         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
21699                 skip_env "Need to mount OST to test"
21700         fi
21701
21702         local mds=$(facet_host $SINGLEMDS)
21703         local target=$(do_nodes $mds 'lctl dl' |
21704                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21705
21706         local cmd1="file_count=1000 thrhi=4"
21707         local cmd2="dir_count=2 layer=mdd stripe_count=1"
21708         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21709         local cmd="$cmd1 $cmd2 $cmd3"
21710
21711         rm -f ${TMP}/mds_survey*
21712         echo + $cmd
21713         eval $cmd || error "mds-survey with stripe_count failed"
21714         cat ${TMP}/mds_survey*
21715         rm -f ${TMP}/mds_survey*
21716 }
21717 run_test 225b "Metadata survey sanity with stripe_count = 1"
21718
21719 mcreate_path2fid () {
21720         local mode=$1
21721         local major=$2
21722         local minor=$3
21723         local name=$4
21724         local desc=$5
21725         local path=$DIR/$tdir/$name
21726         local fid
21727         local rc
21728         local fid_path
21729
21730         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
21731                 error "cannot create $desc"
21732
21733         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
21734         rc=$?
21735         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
21736
21737         fid_path=$($LFS fid2path $MOUNT $fid)
21738         rc=$?
21739         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
21740
21741         [ "$path" == "$fid_path" ] ||
21742                 error "fid2path returned $fid_path, expected $path"
21743
21744         echo "pass with $path and $fid"
21745 }
21746
21747 test_226a () {
21748         rm -rf $DIR/$tdir
21749         mkdir -p $DIR/$tdir
21750
21751         mcreate_path2fid 0010666 0 0 fifo "FIFO"
21752         mcreate_path2fid 0020666 1 3 null "character special file (null)"
21753         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
21754         mcreate_path2fid 0040666 0 0 dir "directory"
21755         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
21756         mcreate_path2fid 0100666 0 0 file "regular file"
21757         mcreate_path2fid 0120666 0 0 link "symbolic link"
21758         mcreate_path2fid 0140666 0 0 sock "socket"
21759 }
21760 run_test 226a "call path2fid and fid2path on files of all type"
21761
21762 test_226b () {
21763         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21764
21765         local MDTIDX=1
21766
21767         rm -rf $DIR/$tdir
21768         mkdir -p $DIR/$tdir
21769         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
21770                 error "create remote directory failed"
21771         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
21772         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
21773                                 "character special file (null)"
21774         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
21775                                 "character special file (no device)"
21776         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
21777         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
21778                                 "block special file (loop)"
21779         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
21780         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
21781         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
21782 }
21783 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
21784
21785 test_226c () {
21786         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21787         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
21788                 skip "Need MDS version at least 2.13.55"
21789
21790         local submnt=/mnt/submnt
21791         local srcfile=/etc/passwd
21792         local dstfile=$submnt/passwd
21793         local path
21794         local fid
21795
21796         rm -rf $DIR/$tdir
21797         rm -rf $submnt
21798         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
21799                 error "create remote directory failed"
21800         mkdir -p $submnt || error "create $submnt failed"
21801         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
21802                 error "mount $submnt failed"
21803         stack_trap "umount $submnt" EXIT
21804
21805         cp $srcfile $dstfile
21806         fid=$($LFS path2fid $dstfile)
21807         path=$($LFS fid2path $submnt "$fid")
21808         [ "$path" = "$dstfile" ] ||
21809                 error "fid2path $submnt $fid failed ($path != $dstfile)"
21810 }
21811 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
21812
21813 test_226d () {
21814         (( $CLIENT_VERSION >= $(version_code 2.15.57) )) ||
21815                 skip "Need client at least version 2.15.57"
21816
21817         # Define First test dataset
21818         local testdirs_01=$DIR/$tdir
21819         local testdata_01=$testdirs_01/${tdir}_01
21820         local testresult_01=${tdir}_01
21821         # Define Second test dataset
21822         local testdirs_02=$DIR/$tdir/$tdir
21823         local testdata_02=$testdirs_02/${tdir}_02
21824         local testresult_02=${tdir}_02
21825         # Define third test dataset (top level)
21826         local testdata_03=$DIR/${tdir}_03
21827         local testresult_03=${tdir}_03
21828
21829         # Create first test dataset
21830         mkdir -p $testdirs_01 || error "cannot create dir $testdirs_01"
21831         touch $testdata_01 || error "cannot create file $testdata_01"
21832
21833         # Create second test dataset
21834         mkdir -p $testdirs_02 || error "cannot create dir $testdirs_02"
21835         touch $testdata_02 || error "cannot create file $testdata_02"
21836
21837         # Create third test dataset
21838         touch $testdata_03 || error "cannot create file $testdata_03"
21839
21840         local fid01=$($LFS getstripe -F "$testdata_01") ||
21841                 error "getstripe failed on $testdata_01"
21842         local fid02=$($LFS getstripe -F "$testdata_02") ||
21843                 error "getstripe failed on $testdata_01"
21844         local fid03=$($LFS getstripe -F "$testdata_03") ||
21845                 error "getstripe failed on $testdata_03"
21846
21847         # Verify only -n option
21848         local out1=$($LFS fid2path -n $DIR $fid01) ||
21849                 error "fid2path failed on $fid01"
21850         local out2=$($LFS fid2path -n $DIR $fid02) ||
21851                 error "fid2path failed on $fid02"
21852         local out3=$($LFS fid2path -n $DIR $fid03) ||
21853                 error "fid2path failed on $fid03"
21854
21855         [[ "$out1" == "$testresult_01" ]] ||
21856                 error "fid2path failed: Expected $testresult_01 got $out1"
21857         [[ "$out2" == "$testresult_02" ]] ||
21858                 error "fid2path failed: Expected $testresult_02 got $out2"
21859         [[ "$out3" == "$testresult_03" ]] ||
21860                 error "fid2path failed: Expected $testresult_03 got $out3"
21861
21862         # Verify with option -fn together
21863         out1=$($LFS fid2path -fn $DIR $fid01) ||
21864                 error "fid2path -fn failed on $fid01"
21865         out2=$($LFS fid2path -fn $DIR $fid02) ||
21866                 error "fid2path -fn failed on $fid02"
21867         out3=$($LFS fid2path -fn $DIR $fid03) ||
21868                 error "fid2path -fn failed on $fid03"
21869
21870         local tmpout=$(echo $out1 | cut -d" " -f2)
21871         [[ "$tmpout" == "$testresult_01" ]] ||
21872                 error "fid2path -fn failed: Expected $testresult_01 got $out1"
21873
21874         tmpout=$(echo $out2 | cut -d" " -f2)
21875         [[ "$tmpout" == "$testresult_02" ]] ||
21876                 error "fid2path -fn failed: Expected $testresult_02 got $out2"
21877
21878         tmpout=$(echo $out3 | cut -d" " -f2)
21879         [[ "$tmpout" == "$testresult_03" ]] ||
21880                 error "fid2path -fn failed: Expected $testresult_03 got $out3"
21881 }
21882 run_test 226d "verify fid2path with -n and -fn option"
21883
21884 test_226e () {
21885         (( $CLIENT_VERSION >= $(version_code 2.15.56) )) ||
21886                 skip "Need client at least version 2.15.56"
21887
21888         # Define filename with 'newline' and a space
21889         local testfile="Test"$'\n'"file 01"
21890         # Define link name with multiple 'newline' and a space
21891         local linkfile="Link"$'\n'"file "$'\n'"01"
21892         # Remove prior hard link
21893         rm -f $DIR/"$linkfile"
21894
21895         # Create file
21896         touch $DIR/"$testfile"
21897         # Create link
21898         ln $DIR/"$testfile" $DIR/"$linkfile"
21899
21900         local fid=$($LFS getstripe -F "$DIR/$testfile") ||
21901                 error "getstripe failed on $DIR/$testfile"
21902
21903         # Call with -0 option
21904         local out1=$($LFS fid2path -0 $DIR $fid | xargs --null -n1 \
21905                 echo "FILE:" | grep -c "FILE:")
21906
21907         # With -0 option the output should be exactly 2 lines.
21908         (( $out1 == 2 )) || error "fid2path -0 failed on $fid, $out1"
21909 }
21910 run_test 226e "Verify path2fid -0 option with newline and space"
21911
21912 # LU-1299 Executing or running ldd on a truncated executable does not
21913 # cause an out-of-memory condition.
21914 test_227() {
21915         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21916         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
21917
21918         dd if=$(which date) of=$MOUNT/date bs=1k count=1
21919         chmod +x $MOUNT/date
21920
21921         $MOUNT/date > /dev/null
21922         ldd $MOUNT/date > /dev/null
21923         rm -f $MOUNT/date
21924 }
21925 run_test 227 "running truncated executable does not cause OOM"
21926
21927 # LU-1512 try to reuse idle OI blocks
21928 test_228a() {
21929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21930         remote_mds_nodsh && skip "remote MDS with nodsh"
21931         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21932
21933         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21934         local myDIR=$DIR/$tdir
21935
21936         mkdir -p $myDIR
21937         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21938         $LCTL set_param fail_loc=0x80001002
21939         createmany -o $myDIR/t- 10000
21940         $LCTL set_param fail_loc=0
21941         # The guard is current the largest FID holder
21942         touch $myDIR/guard
21943         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21944                     tr -d '[')
21945         local IDX=$(($SEQ % 64))
21946
21947         do_facet $SINGLEMDS sync
21948         # Make sure journal flushed.
21949         sleep 6
21950         local blk1=$(do_facet $SINGLEMDS \
21951                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21952                      grep Blockcount | awk '{print $4}')
21953
21954         # Remove old files, some OI blocks will become idle.
21955         unlinkmany $myDIR/t- 10000
21956         # Create new files, idle OI blocks should be reused.
21957         createmany -o $myDIR/t- 2000
21958         do_facet $SINGLEMDS sync
21959         # Make sure journal flushed.
21960         sleep 6
21961         local blk2=$(do_facet $SINGLEMDS \
21962                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21963                      grep Blockcount | awk '{print $4}')
21964
21965         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21966 }
21967 run_test 228a "try to reuse idle OI blocks"
21968
21969 test_228b() {
21970         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21971         remote_mds_nodsh && skip "remote MDS with nodsh"
21972         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21973
21974         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21975         local myDIR=$DIR/$tdir
21976
21977         mkdir -p $myDIR
21978         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21979         $LCTL set_param fail_loc=0x80001002
21980         createmany -o $myDIR/t- 10000
21981         $LCTL set_param fail_loc=0
21982         # The guard is current the largest FID holder
21983         touch $myDIR/guard
21984         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21985                     tr -d '[')
21986         local IDX=$(($SEQ % 64))
21987
21988         do_facet $SINGLEMDS sync
21989         # Make sure journal flushed.
21990         sleep 6
21991         local blk1=$(do_facet $SINGLEMDS \
21992                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21993                      grep Blockcount | awk '{print $4}')
21994
21995         # Remove old files, some OI blocks will become idle.
21996         unlinkmany $myDIR/t- 10000
21997
21998         # stop the MDT
21999         stop $SINGLEMDS || error "Fail to stop MDT."
22000         # remount the MDT
22001         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
22002                 error "Fail to start MDT."
22003
22004         client_up || error "Fail to df."
22005         # Create new files, idle OI blocks should be reused.
22006         createmany -o $myDIR/t- 2000
22007         do_facet $SINGLEMDS sync
22008         # Make sure journal flushed.
22009         sleep 6
22010         local blk2=$(do_facet $SINGLEMDS \
22011                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
22012                      grep Blockcount | awk '{print $4}')
22013
22014         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
22015 }
22016 run_test 228b "idle OI blocks can be reused after MDT restart"
22017
22018 #LU-1881
22019 test_228c() {
22020         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22021         remote_mds_nodsh && skip "remote MDS with nodsh"
22022         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
22023
22024         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
22025         local myDIR=$DIR/$tdir
22026
22027         mkdir -p $myDIR
22028         #define OBD_FAIL_SEQ_EXHAUST             0x1002
22029         $LCTL set_param fail_loc=0x80001002
22030         # 20000 files can guarantee there are index nodes in the OI file
22031         createmany -o $myDIR/t- 20000
22032         $LCTL set_param fail_loc=0
22033         # The guard is current the largest FID holder
22034         touch $myDIR/guard
22035         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
22036                     tr -d '[')
22037         local IDX=$(($SEQ % 64))
22038
22039         do_facet $SINGLEMDS sync
22040         # Make sure journal flushed.
22041         sleep 6
22042         local blk1=$(do_facet $SINGLEMDS \
22043                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
22044                      grep Blockcount | awk '{print $4}')
22045
22046         # Remove old files, some OI blocks will become idle.
22047         unlinkmany $myDIR/t- 20000
22048         rm -f $myDIR/guard
22049         # The OI file should become empty now
22050
22051         # Create new files, idle OI blocks should be reused.
22052         createmany -o $myDIR/t- 2000
22053         do_facet $SINGLEMDS sync
22054         # Make sure journal flushed.
22055         sleep 6
22056         local blk2=$(do_facet $SINGLEMDS \
22057                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
22058                      grep Blockcount | awk '{print $4}')
22059
22060         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
22061 }
22062 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
22063
22064 test_229() { # LU-2482, LU-3448
22065         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22066         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
22067         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
22068                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
22069
22070         rm -f $DIR/$tfile
22071
22072         # Create a file with a released layout and stripe count 2.
22073         $MULTIOP $DIR/$tfile H2c ||
22074                 error "failed to create file with released layout"
22075
22076         $LFS getstripe -v $DIR/$tfile
22077
22078         local pattern=$($LFS getstripe -L $DIR/$tfile)
22079         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
22080
22081         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
22082                 error "getstripe"
22083         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
22084         stat $DIR/$tfile || error "failed to stat released file"
22085
22086         chown $RUNAS_ID $DIR/$tfile ||
22087                 error "chown $RUNAS_ID $DIR/$tfile failed"
22088
22089         chgrp $RUNAS_ID $DIR/$tfile ||
22090                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
22091
22092         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
22093         rm $DIR/$tfile || error "failed to remove released file"
22094 }
22095 run_test 229 "getstripe/stat/rm/attr changes work on released files"
22096
22097 test_230a() {
22098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22099         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22100         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22101                 skip "Need MDS version at least 2.11.52"
22102
22103         local MDTIDX=1
22104
22105         test_mkdir $DIR/$tdir
22106         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
22107         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
22108         [ $mdt_idx -ne 0 ] &&
22109                 error "create local directory on wrong MDT $mdt_idx"
22110
22111         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
22112                         error "create remote directory failed"
22113         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
22114         [ $mdt_idx -ne $MDTIDX ] &&
22115                 error "create remote directory on wrong MDT $mdt_idx"
22116
22117         createmany -o $DIR/$tdir/test_230/t- 10 ||
22118                 error "create files on remote directory failed"
22119         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
22120         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
22121         rm -r $DIR/$tdir || error "unlink remote directory failed"
22122 }
22123 run_test 230a "Create remote directory and files under the remote directory"
22124
22125 test_230b() {
22126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22127         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22128         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22129                 skip "Need MDS version at least 2.11.52"
22130
22131         local MDTIDX=1
22132         local mdt_index
22133         local i
22134         local file
22135         local pid
22136         local stripe_count
22137         local migrate_dir=$DIR/$tdir/migrate_dir
22138         local other_dir=$DIR/$tdir/other_dir
22139
22140         test_mkdir $DIR/$tdir
22141         test_mkdir -i0 -c1 $migrate_dir
22142         test_mkdir -i0 -c1 $other_dir
22143         for ((i=0; i<10; i++)); do
22144                 mkdir -p $migrate_dir/dir_${i}
22145                 createmany -o $migrate_dir/dir_${i}/f 10 ||
22146                         error "create files under remote dir failed $i"
22147         done
22148
22149         cp /etc/passwd $migrate_dir/$tfile
22150         cp /etc/passwd $other_dir/$tfile
22151         chattr +SAD $migrate_dir
22152         chattr +SAD $migrate_dir/$tfile
22153
22154         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
22155         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
22156         local old_dir_mode=$(stat -c%f $migrate_dir)
22157         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
22158
22159         mkdir -p $migrate_dir/dir_default_stripe2
22160         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
22161         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
22162
22163         mkdir -p $other_dir
22164         ln $migrate_dir/$tfile $other_dir/luna
22165         ln $migrate_dir/$tfile $migrate_dir/sofia
22166         ln $other_dir/$tfile $migrate_dir/david
22167         ln -s $migrate_dir/$tfile $other_dir/zachary
22168         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
22169         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
22170
22171         local len
22172         local lnktgt
22173
22174         # inline symlink
22175         for len in 58 59 60; do
22176                 lnktgt=$(str_repeat 'l' $len)
22177                 touch $migrate_dir/$lnktgt
22178                 ln -s $lnktgt $migrate_dir/${len}char_ln
22179         done
22180
22181         # PATH_MAX
22182         for len in 4094 4095; do
22183                 lnktgt=$(str_repeat 'l' $len)
22184                 ln -s $lnktgt $migrate_dir/${len}char_ln
22185         done
22186
22187         # NAME_MAX
22188         for len in 254 255; do
22189                 touch $migrate_dir/$(str_repeat 'l' $len)
22190         done
22191
22192         $LFS migrate -m $MDTIDX $migrate_dir ||
22193                 error "fails on migrating remote dir to MDT1"
22194
22195         echo "migratate to MDT1, then checking.."
22196         for ((i = 0; i < 10; i++)); do
22197                 for file in $(find $migrate_dir/dir_${i}); do
22198                         mdt_index=$($LFS getstripe -m $file)
22199                         # broken symlink getstripe will fail
22200                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
22201                                 error "$file is not on MDT${MDTIDX}"
22202                 done
22203         done
22204
22205         # the multiple link file should still in MDT0
22206         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
22207         [ $mdt_index == 0 ] ||
22208                 error "$file is not on MDT${MDTIDX}"
22209
22210         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
22211         [ "$old_dir_flag" = "$new_dir_flag" ] ||
22212                 error " expect $old_dir_flag get $new_dir_flag"
22213
22214         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
22215         [ "$old_file_flag" = "$new_file_flag" ] ||
22216                 error " expect $old_file_flag get $new_file_flag"
22217
22218         local new_dir_mode=$(stat -c%f $migrate_dir)
22219         [ "$old_dir_mode" = "$new_dir_mode" ] ||
22220                 error "expect mode $old_dir_mode get $new_dir_mode"
22221
22222         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
22223         [ "$old_file_mode" = "$new_file_mode" ] ||
22224                 error "expect mode $old_file_mode get $new_file_mode"
22225
22226         diff /etc/passwd $migrate_dir/$tfile ||
22227                 error "$tfile different after migration"
22228
22229         diff /etc/passwd $other_dir/luna ||
22230                 error "luna different after migration"
22231
22232         diff /etc/passwd $migrate_dir/sofia ||
22233                 error "sofia different after migration"
22234
22235         diff /etc/passwd $migrate_dir/david ||
22236                 error "david different after migration"
22237
22238         diff /etc/passwd $other_dir/zachary ||
22239                 error "zachary different after migration"
22240
22241         diff /etc/passwd $migrate_dir/${tfile}_ln ||
22242                 error "${tfile}_ln different after migration"
22243
22244         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
22245                 error "${tfile}_ln_other different after migration"
22246
22247         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
22248         [ $stripe_count = 2 ] ||
22249                 error "dir strpe_count $d != 2 after migration."
22250
22251         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
22252         [ $stripe_count = 2 ] ||
22253                 error "file strpe_count $d != 2 after migration."
22254
22255         #migrate back to MDT0
22256         MDTIDX=0
22257
22258         $LFS migrate -m $MDTIDX $migrate_dir ||
22259                 error "fails on migrating remote dir to MDT0"
22260
22261         echo "migrate back to MDT0, checking.."
22262         for file in $(find $migrate_dir); do
22263                 mdt_index=$($LFS getstripe -m $file)
22264                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
22265                         error "$file is not on MDT${MDTIDX}"
22266         done
22267
22268         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
22269         [ "$old_dir_flag" = "$new_dir_flag" ] ||
22270                 error " expect $old_dir_flag get $new_dir_flag"
22271
22272         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
22273         [ "$old_file_flag" = "$new_file_flag" ] ||
22274                 error " expect $old_file_flag get $new_file_flag"
22275
22276         local new_dir_mode=$(stat -c%f $migrate_dir)
22277         [ "$old_dir_mode" = "$new_dir_mode" ] ||
22278                 error "expect mode $old_dir_mode get $new_dir_mode"
22279
22280         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
22281         [ "$old_file_mode" = "$new_file_mode" ] ||
22282                 error "expect mode $old_file_mode get $new_file_mode"
22283
22284         diff /etc/passwd ${migrate_dir}/$tfile ||
22285                 error "$tfile different after migration"
22286
22287         diff /etc/passwd ${other_dir}/luna ||
22288                 error "luna different after migration"
22289
22290         diff /etc/passwd ${migrate_dir}/sofia ||
22291                 error "sofia different after migration"
22292
22293         diff /etc/passwd ${other_dir}/zachary ||
22294                 error "zachary different after migration"
22295
22296         diff /etc/passwd $migrate_dir/${tfile}_ln ||
22297                 error "${tfile}_ln different after migration"
22298
22299         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
22300                 error "${tfile}_ln_other different after migration"
22301
22302         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
22303         [ $stripe_count = 2 ] ||
22304                 error "dir strpe_count $d != 2 after migration."
22305
22306         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
22307         [ $stripe_count = 2 ] ||
22308                 error "file strpe_count $d != 2 after migration."
22309
22310         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22311 }
22312 run_test 230b "migrate directory"
22313
22314 test_230c() {
22315         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22316         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22317         remote_mds_nodsh && skip "remote MDS with nodsh"
22318         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22319                 skip "Need MDS version at least 2.11.52"
22320
22321         local MDTIDX=1
22322         local total=3
22323         local mdt_index
22324         local file
22325         local migrate_dir=$DIR/$tdir/migrate_dir
22326
22327         #If migrating directory fails in the middle, all entries of
22328         #the directory is still accessiable.
22329         test_mkdir $DIR/$tdir
22330         test_mkdir -i0 -c1 $migrate_dir
22331         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
22332         stat $migrate_dir
22333         createmany -o $migrate_dir/f $total ||
22334                 error "create files under ${migrate_dir} failed"
22335
22336         # fail after migrating top dir, and this will fail only once, so the
22337         # first sub file migration will fail (currently f3), others succeed.
22338         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
22339         do_facet mds1 lctl set_param fail_loc=0x1801
22340         local t=$(ls $migrate_dir | wc -l)
22341         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
22342                 error "migrate should fail"
22343         local u=$(ls $migrate_dir | wc -l)
22344         [ "$u" == "$t" ] || error "$u != $t during migration"
22345
22346         # add new dir/file should succeed
22347         mkdir $migrate_dir/dir ||
22348                 error "mkdir failed under migrating directory"
22349         touch $migrate_dir/file ||
22350                 error "create file failed under migrating directory"
22351
22352         # add file with existing name should fail
22353         for file in $migrate_dir/f*; do
22354                 stat $file > /dev/null || error "stat $file failed"
22355                 $OPENFILE -f O_CREAT:O_EXCL $file &&
22356                         error "open(O_CREAT|O_EXCL) $file should fail"
22357                 $MULTIOP $file m && error "create $file should fail"
22358                 touch $DIR/$tdir/remote_dir/$tfile ||
22359                         error "touch $tfile failed"
22360                 ln $DIR/$tdir/remote_dir/$tfile $file &&
22361                         error "link $file should fail"
22362                 mdt_index=$($LFS getstripe -m $file)
22363                 if [ $mdt_index == 0 ]; then
22364                         # file failed to migrate is not allowed to rename to
22365                         mv $DIR/$tdir/remote_dir/$tfile $file &&
22366                                 error "rename to $file should fail"
22367                 else
22368                         mv $DIR/$tdir/remote_dir/$tfile $file ||
22369                                 error "rename to $file failed"
22370                 fi
22371                 echo hello >> $file || error "write $file failed"
22372         done
22373
22374         # resume migration with different options should fail
22375         $LFS migrate -m 0 $migrate_dir &&
22376                 error "migrate -m 0 $migrate_dir should fail"
22377
22378         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
22379                 error "migrate -c 2 $migrate_dir should fail"
22380
22381         # resume migration should succeed
22382         $LFS migrate -m $MDTIDX $migrate_dir ||
22383                 error "migrate $migrate_dir failed"
22384
22385         echo "Finish migration, then checking.."
22386         for file in $(find $migrate_dir); do
22387                 mdt_index=$($LFS getstripe -m $file)
22388                 [ $mdt_index == $MDTIDX ] ||
22389                         error "$file is not on MDT${MDTIDX}"
22390         done
22391
22392         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22393 }
22394 run_test 230c "check directory accessiblity if migration failed"
22395
22396 test_230d() {
22397         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22398         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22399         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22400                 skip "Need MDS version at least 2.11.52"
22401         # LU-11235
22402         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
22403
22404         local migrate_dir=$DIR/$tdir/migrate_dir
22405         local old_index
22406         local new_index
22407         local old_count
22408         local new_count
22409         local new_hash
22410         local mdt_index
22411         local i
22412         local j
22413
22414         old_index=$((RANDOM % MDSCOUNT))
22415         old_count=$((MDSCOUNT - old_index))
22416         new_index=$((RANDOM % MDSCOUNT))
22417         new_count=$((MDSCOUNT - new_index))
22418         new_hash=1 # for all_char
22419
22420         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
22421         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
22422
22423         test_mkdir $DIR/$tdir
22424         test_mkdir -i $old_index -c $old_count $migrate_dir
22425
22426         for ((i=0; i<100; i++)); do
22427                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
22428                 createmany -o $migrate_dir/dir_${i}/f 100 ||
22429                         error "create files under remote dir failed $i"
22430         done
22431
22432         echo -n "Migrate from MDT$old_index "
22433         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
22434         echo -n "to MDT$new_index"
22435         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
22436         echo
22437
22438         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
22439         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
22440                 error "migrate remote dir error"
22441
22442         echo "Finish migration, then checking.."
22443         for file in $(find $migrate_dir -maxdepth 1); do
22444                 mdt_index=$($LFS getstripe -m $file)
22445                 if [ $mdt_index -lt $new_index ] ||
22446                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
22447                         error "$file is on MDT$mdt_index"
22448                 fi
22449         done
22450
22451         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22452 }
22453 run_test 230d "check migrate big directory"
22454
22455 test_230e() {
22456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22457         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22458         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22459                 skip "Need MDS version at least 2.11.52"
22460
22461         local i
22462         local j
22463         local a_fid
22464         local b_fid
22465
22466         mkdir_on_mdt0 $DIR/$tdir
22467         mkdir $DIR/$tdir/migrate_dir
22468         mkdir $DIR/$tdir/other_dir
22469         touch $DIR/$tdir/migrate_dir/a
22470         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
22471         ls $DIR/$tdir/other_dir
22472
22473         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22474                 error "migrate dir fails"
22475
22476         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
22477         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
22478
22479         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22480         [ $mdt_index == 0 ] || error "a is not on MDT0"
22481
22482         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
22483                 error "migrate dir fails"
22484
22485         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
22486         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
22487
22488         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22489         [ $mdt_index == 1 ] || error "a is not on MDT1"
22490
22491         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
22492         [ $mdt_index == 1 ] || error "b is not on MDT1"
22493
22494         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
22495         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
22496
22497         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
22498
22499         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22500 }
22501 run_test 230e "migrate mulitple local link files"
22502
22503 test_230f() {
22504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22505         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22506         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22507                 skip "Need MDS version at least 2.11.52"
22508
22509         local a_fid
22510         local ln_fid
22511
22512         mkdir -p $DIR/$tdir
22513         mkdir $DIR/$tdir/migrate_dir
22514         $LFS mkdir -i1 $DIR/$tdir/other_dir
22515         touch $DIR/$tdir/migrate_dir/a
22516         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
22517         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
22518         ls $DIR/$tdir/other_dir
22519
22520         # a should be migrated to MDT1, since no other links on MDT0
22521         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22522                 error "#1 migrate dir fails"
22523         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
22524         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
22525         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22526         [ $mdt_index == 1 ] || error "a is not on MDT1"
22527
22528         # a should stay on MDT1, because it is a mulitple link file
22529         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22530                 error "#2 migrate dir fails"
22531         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22532         [ $mdt_index == 1 ] || error "a is not on MDT1"
22533
22534         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22535                 error "#3 migrate dir fails"
22536
22537         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
22538         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
22539         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
22540
22541         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
22542         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
22543
22544         # a should be migrated to MDT0, since no other links on MDT1
22545         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22546                 error "#4 migrate dir fails"
22547         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22548         [ $mdt_index == 0 ] || error "a is not on MDT0"
22549
22550         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22551 }
22552 run_test 230f "migrate mulitple remote link files"
22553
22554 test_230g() {
22555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22556         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22557         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22558                 skip "Need MDS version at least 2.11.52"
22559
22560         mkdir -p $DIR/$tdir/migrate_dir
22561
22562         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
22563                 error "migrating dir to non-exist MDT succeeds"
22564         true
22565 }
22566 run_test 230g "migrate dir to non-exist MDT"
22567
22568 test_230h() {
22569         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22570         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22571         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22572                 skip "Need MDS version at least 2.11.52"
22573
22574         local mdt_index
22575
22576         mkdir -p $DIR/$tdir/migrate_dir
22577
22578         $LFS migrate -m1 $DIR &&
22579                 error "migrating mountpoint1 should fail"
22580
22581         $LFS migrate -m1 $DIR/$tdir/.. &&
22582                 error "migrating mountpoint2 should fail"
22583
22584         # same as mv
22585         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
22586                 error "migrating $tdir/migrate_dir/.. should fail"
22587
22588         true
22589 }
22590 run_test 230h "migrate .. and root"
22591
22592 test_230i() {
22593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22594         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22595         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22596                 skip "Need MDS version at least 2.11.52"
22597
22598         mkdir -p $DIR/$tdir/migrate_dir
22599
22600         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
22601                 error "migration fails with a tailing slash"
22602
22603         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
22604                 error "migration fails with two tailing slashes"
22605 }
22606 run_test 230i "lfs migrate -m tolerates trailing slashes"
22607
22608 test_230j() {
22609         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22610         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
22611                 skip "Need MDS version at least 2.11.52"
22612
22613         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22614         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
22615                 error "create $tfile failed"
22616         cat /etc/passwd > $DIR/$tdir/$tfile
22617
22618         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22619
22620         cmp /etc/passwd $DIR/$tdir/$tfile ||
22621                 error "DoM file mismatch after migration"
22622 }
22623 run_test 230j "DoM file data not changed after dir migration"
22624
22625 test_230k() {
22626         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
22627         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22628                 skip "Need MDS version at least 2.11.56"
22629
22630         local total=20
22631         local files_on_starting_mdt=0
22632
22633         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
22634         $LFS getdirstripe $DIR/$tdir
22635         for i in $(seq $total); do
22636                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
22637                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22638                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22639         done
22640
22641         echo "$files_on_starting_mdt files on MDT0"
22642
22643         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
22644         $LFS getdirstripe $DIR/$tdir
22645
22646         files_on_starting_mdt=0
22647         for i in $(seq $total); do
22648                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22649                         error "file $tfile.$i mismatch after migration"
22650                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
22651                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22652         done
22653
22654         echo "$files_on_starting_mdt files on MDT1 after migration"
22655         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
22656
22657         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
22658         $LFS getdirstripe $DIR/$tdir
22659
22660         files_on_starting_mdt=0
22661         for i in $(seq $total); do
22662                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22663                         error "file $tfile.$i mismatch after 2nd migration"
22664                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22665                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22666         done
22667
22668         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
22669         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
22670
22671         true
22672 }
22673 run_test 230k "file data not changed after dir migration"
22674
22675 test_230l() {
22676         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22677         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22678                 skip "Need MDS version at least 2.11.56"
22679
22680         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
22681         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
22682                 error "create files under remote dir failed $i"
22683         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22684 }
22685 run_test 230l "readdir between MDTs won't crash"
22686
22687 test_230m() {
22688         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22689         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22690                 skip "Need MDS version at least 2.11.56"
22691
22692         local MDTIDX=1
22693         local mig_dir=$DIR/$tdir/migrate_dir
22694         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
22695         local shortstr="b"
22696         local val
22697
22698         echo "Creating files and dirs with xattrs"
22699         test_mkdir $DIR/$tdir
22700         test_mkdir -i0 -c1 $mig_dir
22701         mkdir $mig_dir/dir
22702         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
22703                 error "cannot set xattr attr1 on dir"
22704         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
22705                 error "cannot set xattr attr2 on dir"
22706         touch $mig_dir/dir/f0
22707         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
22708                 error "cannot set xattr attr1 on file"
22709         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
22710                 error "cannot set xattr attr2 on file"
22711         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22712         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22713         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
22714         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22715         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
22716         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22717         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
22718         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22719         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
22720
22721         echo "Migrating to MDT1"
22722         $LFS migrate -m $MDTIDX $mig_dir ||
22723                 error "fails on migrating dir to MDT1"
22724
22725         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22726         echo "Checking xattrs"
22727         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22728         [ "$val" = $longstr ] ||
22729                 error "expecting xattr1 $longstr on dir, found $val"
22730         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22731         [ "$val" = $shortstr ] ||
22732                 error "expecting xattr2 $shortstr on dir, found $val"
22733         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22734         [ "$val" = $longstr ] ||
22735                 error "expecting xattr1 $longstr on file, found $val"
22736         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22737         [ "$val" = $shortstr ] ||
22738                 error "expecting xattr2 $shortstr on file, found $val"
22739 }
22740 run_test 230m "xattrs not changed after dir migration"
22741
22742 test_230n() {
22743         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22744         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22745                 skip "Need MDS version at least 2.13.53"
22746
22747         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
22748         cat /etc/hosts > $DIR/$tdir/$tfile
22749         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
22750         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
22751
22752         cmp /etc/hosts $DIR/$tdir/$tfile ||
22753                 error "File data mismatch after migration"
22754 }
22755 run_test 230n "Dir migration with mirrored file"
22756
22757 test_230o() {
22758         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
22759         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22760                 skip "Need MDS version at least 2.13.52"
22761
22762         local mdts=$(comma_list $(mdts_nodes))
22763         local timeout=100
22764         local restripe_status
22765         local delta
22766         local i
22767
22768         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22769
22770         # in case "crush" hash type is not set
22771         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22772
22773         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22774                            mdt.*MDT0000.enable_dir_restripe)
22775         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22776         stack_trap "do_nodes $mdts $LCTL set_param \
22777                     mdt.*.enable_dir_restripe=$restripe_status"
22778
22779         mkdir $DIR/$tdir
22780         createmany -m $DIR/$tdir/f 100 ||
22781                 error "create files under remote dir failed $i"
22782         createmany -d $DIR/$tdir/d 100 ||
22783                 error "create dirs under remote dir failed $i"
22784
22785         for i in $(seq 2 $MDSCOUNT); do
22786                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22787                 $LFS setdirstripe -c $i $DIR/$tdir ||
22788                         error "split -c $i $tdir failed"
22789                 wait_update $HOSTNAME \
22790                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
22791                         error "dir split not finished"
22792                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22793                         awk '/migrate/ {sum += $2} END { print sum }')
22794                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
22795                 # delta is around total_files/stripe_count
22796                 (( $delta < 200 / (i - 1) + 4 )) ||
22797                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
22798         done
22799 }
22800 run_test 230o "dir split"
22801
22802 test_230p() {
22803         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22804         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22805                 skip "Need MDS version at least 2.13.52"
22806
22807         local mdts=$(comma_list $(mdts_nodes))
22808         local timeout=100
22809         local restripe_status
22810         local delta
22811         local c
22812
22813         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22814
22815         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22816
22817         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22818                            mdt.*MDT0000.enable_dir_restripe)
22819         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22820         stack_trap "do_nodes $mdts $LCTL set_param \
22821                     mdt.*.enable_dir_restripe=$restripe_status"
22822
22823         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
22824         createmany -m $DIR/$tdir/f 100 ||
22825                 error "create files under remote dir failed"
22826         createmany -d $DIR/$tdir/d 100 ||
22827                 error "create dirs under remote dir failed"
22828
22829         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
22830                 local mdt_hash="crush"
22831
22832                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22833                 $LFS setdirstripe -c $c $DIR/$tdir ||
22834                         error "split -c $c $tdir failed"
22835                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
22836                         mdt_hash="$mdt_hash,fixed"
22837                 elif [ $c -eq 1 ]; then
22838                         mdt_hash="none"
22839                 fi
22840                 wait_update $HOSTNAME \
22841                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
22842                         error "dir merge not finished"
22843                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22844                         awk '/migrate/ {sum += $2} END { print sum }')
22845                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
22846                 # delta is around total_files/stripe_count
22847                 (( delta < 200 / c + 4 )) ||
22848                         error "$delta files migrated >= $((200 / c + 4))"
22849         done
22850 }
22851 run_test 230p "dir merge"
22852
22853 test_230q() {
22854         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
22855         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22856                 skip "Need MDS version at least 2.13.52"
22857
22858         local mdts=$(comma_list $(mdts_nodes))
22859         local saved_threshold=$(do_facet mds1 \
22860                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
22861         local saved_delta=$(do_facet mds1 \
22862                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
22863         local threshold=100
22864         local delta=2
22865         local total=0
22866         local stripe_count=0
22867         local stripe_index
22868         local nr_files
22869         local create
22870
22871         # test with fewer files on ZFS
22872         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
22873
22874         stack_trap "do_nodes $mdts $LCTL set_param \
22875                     mdt.*.dir_split_count=$saved_threshold"
22876         stack_trap "do_nodes $mdts $LCTL set_param \
22877                     mdt.*.dir_split_delta=$saved_delta"
22878         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
22879         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
22880         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
22881         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
22882         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
22883         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22884
22885         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22886         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22887
22888         create=$((threshold * 3 / 2))
22889         while [ $stripe_count -lt $MDSCOUNT ]; do
22890                 createmany -m $DIR/$tdir/f $total $create ||
22891                         error "create sub files failed"
22892                 stat $DIR/$tdir > /dev/null
22893                 total=$((total + create))
22894                 stripe_count=$((stripe_count + delta))
22895                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
22896
22897                 wait_update $HOSTNAME \
22898                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
22899                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
22900
22901                 wait_update $HOSTNAME \
22902                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
22903                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
22904
22905                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
22906                 echo "$nr_files/$total files on MDT$stripe_index after split"
22907                 # allow 10% margin of imbalance with crush hash
22908                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
22909                         error "$nr_files files on MDT$stripe_index after split"
22910
22911                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
22912                 [ $nr_files -eq $total ] ||
22913                         error "total sub files $nr_files != $total"
22914         done
22915
22916         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
22917
22918         echo "fixed layout directory won't auto split"
22919         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
22920         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
22921                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
22922         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
22923                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
22924 }
22925 run_test 230q "dir auto split"
22926
22927 test_230r() {
22928         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
22929         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
22930         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
22931                 skip "Need MDS version at least 2.13.54"
22932
22933         # maximum amount of local locks:
22934         # parent striped dir - 2 locks
22935         # new stripe in parent to migrate to - 1 lock
22936         # source and target - 2 locks
22937         # Total 5 locks for regular file
22938         mkdir -p $DIR/$tdir
22939         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
22940         touch $DIR/$tdir/dir1/eee
22941
22942         # create 4 hardlink for 4 more locks
22943         # Total: 9 locks > RS_MAX_LOCKS (8)
22944         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
22945         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
22946         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
22947         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
22948         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
22949         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
22950         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
22951         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
22952
22953         cancel_lru_locks mdc
22954
22955         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
22956                 error "migrate dir fails"
22957
22958         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22959 }
22960 run_test 230r "migrate with too many local locks"
22961
22962 test_230s() {
22963         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
22964                 skip "Need MDS version at least 2.14.52"
22965
22966         local mdts=$(comma_list $(mdts_nodes))
22967         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
22968                                 mdt.*MDT0000.enable_dir_restripe)
22969
22970         stack_trap "do_nodes $mdts $LCTL set_param \
22971                     mdt.*.enable_dir_restripe=$restripe_status"
22972
22973         local st
22974         for st in 0 1; do
22975                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
22976                 test_mkdir $DIR/$tdir
22977                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
22978                         error "$LFS mkdir should return EEXIST if target exists"
22979                 rmdir $DIR/$tdir
22980         done
22981 }
22982 run_test 230s "lfs mkdir should return -EEXIST if target exists"
22983
22984 test_230t()
22985 {
22986         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
22987         (( $MDS1_VERSION >= $(version_code 2.14.50) )) ||
22988                 skip "Need MDS version at least 2.14.50"
22989
22990         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
22991         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
22992         $LFS project -p 1 -s $DIR/$tdir ||
22993                 error "set $tdir project id failed"
22994         $LFS project -p 2 -s $DIR/$tdir/subdir ||
22995                 error "set subdir project id failed"
22996         local pbefore="$($LFS project -d $DIR/$tdir)"
22997         local sbefore="$($LFS project -d $DIR/$tdir/subdir)"
22998         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
22999
23000         local pafter="$($LFS project -d $DIR/$tdir)"
23001         local safter="$($LFS project -d $DIR/$tdir/subdir)"
23002         [[ "$pbefore" == "$pafter" ]] || error "projid '$pbefore' != '$pafter'"
23003         [[ "$sbefore" == "$safter" ]] || error "projid '$sbefore' != '$safter'"
23004
23005         (( $MDS1_VERSION >= $(version_code 2.15.59.107) )) ||
23006                 { echo "Need MDS >= 2.15.59.107 for projid rename"; return 0; }
23007
23008         # check rename works, even if source parent projid differs (LU-17016)
23009         test_mkdir $DIR/$tdir.2 || error "mkdir $tdir.2 failed"
23010         local fid_before=$($LFS path2fid $DIR/$tdir/subdir)
23011
23012         $LFS project -p 2 -s $DIR/$tdir.2 || error "set $tdir.2 projid failed"
23013         mrename $DIR/$tdir/subdir $DIR/$tdir.2/subdir ||
23014                 error "subdir failed rename for different source parent projid"
23015         local fid_after=$($LFS path2fid $DIR/$tdir.2/subdir)
23016
23017         [[ "$fid_before" == "$fid_after" ]] ||
23018                 error "fid before '$fid_before' != after '$fid_after'"
23019 }
23020 run_test 230t "migrate directory with project ID set"
23021
23022 test_230u()
23023 {
23024         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
23025         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
23026                 skip "Need MDS version at least 2.14.53"
23027
23028         local count
23029
23030         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
23031         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
23032         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
23033         for i in $(seq 0 $((MDSCOUNT - 1))); do
23034                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
23035                 echo "$count dirs migrated to MDT$i"
23036         done
23037         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
23038         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
23039 }
23040 run_test 230u "migrate directory by QOS"
23041
23042 test_230v()
23043 {
23044         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
23045         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
23046                 skip "Need MDS version at least 2.14.53"
23047
23048         local count
23049
23050         mkdir $DIR/$tdir || error "mkdir $tdir failed"
23051         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
23052         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
23053         for i in $(seq 0 $((MDSCOUNT - 1))); do
23054                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
23055                 echo "$count subdirs migrated to MDT$i"
23056                 (( i == 3 )) && (( count > 0 )) &&
23057                         error "subdir shouldn't be migrated to MDT3"
23058         done
23059         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
23060         (( count == 3 )) || error "dirs migrated to $count MDTs"
23061 }
23062 run_test 230v "subdir migrated to the MDT where its parent is located"
23063
23064 test_230w() {
23065         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23066         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
23067                 skip "Need MDS version at least 2.15.0"
23068
23069         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
23070         createmany -o $DIR/$tdir/f 10 || error "create files failed"
23071         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
23072
23073         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
23074                 error "migrate failed"
23075
23076         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
23077                 error "$tdir stripe count mismatch"
23078
23079         for i in $(seq 0 9); do
23080                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
23081                         error "d$i is striped"
23082         done
23083 }
23084 run_test 230w "non-recursive mode dir migration"
23085
23086 test_230x() {
23087         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23088         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
23089                 skip "Need MDS version at least 2.15.0"
23090
23091         mkdir -p $DIR/$tdir || error "mkdir failed"
23092         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
23093
23094         local mdt_name=$(mdtname_from_index 0)
23095         local low=$(do_facet mds2 $LCTL get_param -n \
23096                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
23097         local high=$(do_facet mds2 $LCTL get_param -n \
23098                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
23099         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
23100         local maxage=$(do_facet mds2 $LCTL get_param -n \
23101                 osp.*$mdt_name-osp-MDT0001.maxage)
23102
23103         stack_trap "do_facet mds2 $LCTL set_param -n \
23104                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
23105                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
23106         stack_trap "do_facet mds2 $LCTL set_param -n \
23107                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
23108
23109         do_facet mds2 $LCTL set_param -n \
23110                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
23111         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
23112         sleep 4
23113         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
23114                 error "migrate $tdir should fail"
23115
23116         do_facet mds2 $LCTL set_param -n \
23117                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
23118         do_facet mds2 $LCTL set_param -n \
23119                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
23120         sleep 4
23121         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
23122                 error "migrate failed"
23123         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
23124                 error "$tdir stripe count mismatch"
23125 }
23126 run_test 230x "dir migration check space"
23127
23128 test_230y() {
23129         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23130         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
23131                 skip "Need MDS version at least 2.15.55.45"
23132
23133         local pid
23134
23135         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
23136         $LFS getdirstripe $DIR/$tdir
23137         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
23138         $LFS migrate -m 1 -c 2 $DIR/$tdir &
23139         pid=$!
23140         sleep 1
23141
23142         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
23143         do_facet mds2 lctl set_param fail_loc=0x1802
23144
23145         wait $pid
23146         do_facet mds2 lctl set_param fail_loc=0
23147         $LFS getdirstripe $DIR/$tdir
23148         unlinkmany -d $DIR/$tdir/d 100 || error "unlinkmany failed"
23149         rmdir $DIR/$tdir || error "rmdir $tdir failed"
23150 }
23151 run_test 230y "unlink dir with bad hash type"
23152
23153 test_230z() {
23154         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23155         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
23156                 skip "Need MDS version at least 2.15.55.45"
23157
23158         local pid
23159
23160         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
23161         $LFS getdirstripe $DIR/$tdir
23162         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
23163         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir &
23164         pid=$!
23165         sleep 1
23166
23167         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
23168         do_facet mds2 lctl set_param fail_loc=0x1802
23169
23170         wait $pid
23171         do_facet mds2 lctl set_param fail_loc=0
23172         $LFS getdirstripe $DIR/$tdir
23173
23174         # resume migration
23175         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir ||
23176                 error "resume migration failed"
23177         $LFS getdirstripe $DIR/$tdir
23178         [ $($LFS getdirstripe -H $DIR/$tdir) == "fnv_1a_64,fixed" ] ||
23179                 error "migration is not finished"
23180 }
23181 run_test 230z "resume dir migration with bad hash type"
23182
23183 test_231a()
23184 {
23185         # For simplicity this test assumes that max_pages_per_rpc
23186         # is the same across all OSCs
23187         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
23188         local bulk_size=$((max_pages * PAGE_SIZE))
23189         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
23190                                        head -n 1)
23191
23192         mkdir -p $DIR/$tdir
23193         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
23194                 error "failed to set stripe with -S ${brw_size}M option"
23195         stack_trap "rm -rf $DIR/$tdir"
23196
23197         # clear the OSC stats
23198         $LCTL set_param osc.*.stats=0 &>/dev/null
23199         stop_writeback
23200
23201         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
23202         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
23203                 oflag=direct &>/dev/null || error "dd failed"
23204
23205         sync; sleep 1; sync # just to be safe
23206         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
23207         if [ x$nrpcs != "x1" ]; then
23208                 $LCTL get_param osc.*.stats
23209                 error "found $nrpcs ost_write RPCs, not 1 as expected"
23210         fi
23211
23212         start_writeback
23213         # Drop the OSC cache, otherwise we will read from it
23214         cancel_lru_locks osc
23215
23216         # clear the OSC stats
23217         $LCTL set_param osc.*.stats=0 &>/dev/null
23218
23219         # Client reads $bulk_size.
23220         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
23221                 iflag=direct &>/dev/null || error "dd failed"
23222
23223         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
23224         if [ x$nrpcs != "x1" ]; then
23225                 $LCTL get_param osc.*.stats
23226                 error "found $nrpcs ost_read RPCs, not 1 as expected"
23227         fi
23228 }
23229 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
23230
23231 test_231b() {
23232         mkdir -p $DIR/$tdir
23233         stack_trap "rm -rf $DIR/$tdir"
23234         local i
23235         for i in {0..1023}; do
23236                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
23237                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
23238                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
23239         done
23240         sync
23241 }
23242 run_test 231b "must not assert on fully utilized OST request buffer"
23243
23244 test_232a() {
23245         mkdir -p $DIR/$tdir
23246         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
23247
23248         #define OBD_FAIL_LDLM_OST_LVB            0x31c
23249         do_facet ost1 $LCTL set_param fail_loc=0x31c
23250
23251         # ignore dd failure
23252         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
23253         stack_trap "rm -f $DIR/$tdir/$tfile"
23254
23255         do_facet ost1 $LCTL set_param fail_loc=0
23256         umount_client $MOUNT || error "umount failed"
23257         mount_client $MOUNT || error "mount failed"
23258         stop ost1 || error "cannot stop ost1"
23259         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23260 }
23261 run_test 232a "failed lock should not block umount"
23262
23263 test_232b() {
23264         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
23265                 skip "Need MDS version at least 2.10.58"
23266
23267         mkdir -p $DIR/$tdir
23268         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
23269         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
23270         stack_trap "rm -f $DIR/$tdir/$tfile"
23271         sync
23272         cancel_lru_locks osc
23273
23274         #define OBD_FAIL_LDLM_OST_LVB            0x31c
23275         do_facet ost1 $LCTL set_param fail_loc=0x31c
23276
23277         # ignore failure
23278         $LFS data_version $DIR/$tdir/$tfile || true
23279
23280         do_facet ost1 $LCTL set_param fail_loc=0
23281         umount_client $MOUNT || error "umount failed"
23282         mount_client $MOUNT || error "mount failed"
23283         stop ost1 || error "cannot stop ost1"
23284         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23285 }
23286 run_test 232b "failed data version lock should not block umount"
23287
23288 test_233a() {
23289         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
23290                 skip "Need MDS version at least 2.3.64"
23291         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
23292
23293         local fid=$($LFS path2fid $MOUNT)
23294
23295         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23296                 error "cannot access $MOUNT using its FID '$fid'"
23297 }
23298 run_test 233a "checking that OBF of the FS root succeeds"
23299
23300 test_233b() {
23301         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
23302                 skip "Need MDS version at least 2.5.90"
23303         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
23304
23305         local fid=$($LFS path2fid $MOUNT/.lustre)
23306
23307         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23308                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
23309
23310         fid=$($LFS path2fid $MOUNT/.lustre/fid)
23311         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23312                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
23313 }
23314 run_test 233b "checking that OBF of the FS .lustre succeeds"
23315
23316 test_234() {
23317         local p="$TMP/sanityN-$TESTNAME.parameters"
23318         save_lustre_params client "llite.*.xattr_cache" > $p
23319         lctl set_param llite.*.xattr_cache 1 ||
23320                 skip_env "xattr cache is not supported"
23321
23322         mkdir -p $DIR/$tdir || error "mkdir failed"
23323         touch $DIR/$tdir/$tfile || error "touch failed"
23324         # OBD_FAIL_LLITE_XATTR_ENOMEM
23325         $LCTL set_param fail_loc=0x1405
23326         getfattr -n user.attr $DIR/$tdir/$tfile &&
23327                 error "getfattr should have failed with ENOMEM"
23328         $LCTL set_param fail_loc=0x0
23329         rm -rf $DIR/$tdir
23330
23331         restore_lustre_params < $p
23332         rm -f $p
23333 }
23334 run_test 234 "xattr cache should not crash on ENOMEM"
23335
23336 test_235() {
23337         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
23338                 skip "Need MDS version at least 2.4.52"
23339
23340         flock_deadlock $DIR/$tfile
23341         local RC=$?
23342         case $RC in
23343                 0)
23344                 ;;
23345                 124) error "process hangs on a deadlock"
23346                 ;;
23347                 *) error "error executing flock_deadlock $DIR/$tfile"
23348                 ;;
23349         esac
23350 }
23351 run_test 235 "LU-1715: flock deadlock detection does not work properly"
23352
23353 #LU-2935
23354 test_236() {
23355         check_swap_layouts_support
23356
23357         local ref1=/etc/passwd
23358         local ref2=/etc/group
23359         local file1=$DIR/$tdir/f1
23360         local file2=$DIR/$tdir/f2
23361
23362         test_mkdir -c1 $DIR/$tdir
23363         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
23364         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
23365         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
23366         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
23367         local fd=$(free_fd)
23368         local cmd="exec $fd<>$file2"
23369         eval $cmd
23370         rm $file2
23371         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
23372                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
23373         cmd="exec $fd>&-"
23374         eval $cmd
23375         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
23376
23377         #cleanup
23378         rm -rf $DIR/$tdir
23379 }
23380 run_test 236 "Layout swap on open unlinked file"
23381
23382 # LU-4659 linkea consistency
23383 test_238() {
23384         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
23385                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
23386                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
23387                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
23388
23389         touch $DIR/$tfile
23390         ln $DIR/$tfile $DIR/$tfile.lnk
23391         touch $DIR/$tfile.new
23392         mv $DIR/$tfile.new $DIR/$tfile
23393         local fid1=$($LFS path2fid $DIR/$tfile)
23394         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
23395         local path1=$($LFS fid2path $FSNAME "$fid1")
23396         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
23397         local path2=$($LFS fid2path $FSNAME "$fid2")
23398         [ $tfile.lnk == $path2 ] ||
23399                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
23400         rm -f $DIR/$tfile*
23401 }
23402 run_test 238 "Verify linkea consistency"
23403
23404 test_239A() { # was test_239
23405         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
23406                 skip "Need MDS version at least 2.5.60"
23407
23408         local list=$(comma_list $(mdts_nodes))
23409
23410         mkdir -p $DIR/$tdir
23411         createmany -o $DIR/$tdir/f- 5000
23412         unlinkmany $DIR/$tdir/f- 5000
23413         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
23414                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
23415         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
23416                         osp.*MDT*.sync_in_flight" | calc_sum)
23417         [ "$changes" -eq 0 ] || error "$changes not synced"
23418 }
23419 run_test 239A "osp_sync test"
23420
23421 test_239a() { #LU-5297
23422         remote_mds_nodsh && skip "remote MDS with nodsh"
23423
23424         touch $DIR/$tfile
23425         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
23426         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
23427         chgrp $RUNAS_GID $DIR/$tfile
23428         wait_delete_completed
23429 }
23430 run_test 239a "process invalid osp sync record correctly"
23431
23432 test_239b() { #LU-5297
23433         remote_mds_nodsh && skip "remote MDS with nodsh"
23434
23435         touch $DIR/$tfile1
23436         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
23437         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
23438         chgrp $RUNAS_GID $DIR/$tfile1
23439         wait_delete_completed
23440         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
23441         touch $DIR/$tfile2
23442         chgrp $RUNAS_GID $DIR/$tfile2
23443         wait_delete_completed
23444 }
23445 run_test 239b "process osp sync record with ENOMEM error correctly"
23446
23447 test_240() {
23448         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23449         remote_mds_nodsh && skip "remote MDS with nodsh"
23450
23451         mkdir -p $DIR/$tdir
23452
23453         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
23454                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
23455         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
23456                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
23457
23458         umount_client $MOUNT || error "umount failed"
23459         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
23460         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
23461         mount_client $MOUNT || error "failed to mount client"
23462
23463         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
23464         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
23465 }
23466 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
23467
23468 test_241_bio() {
23469         local count=$1
23470         local bsize=$2
23471
23472         for LOOP in $(seq $count); do
23473                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
23474                 cancel_lru_locks $OSC || true
23475         done
23476 }
23477
23478 test_241_dio() {
23479         local count=$1
23480         local bsize=$2
23481
23482         for LOOP in $(seq $1); do
23483                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
23484                         2>/dev/null
23485         done
23486 }
23487
23488 test_241a() { # was test_241
23489         local bsize=$PAGE_SIZE
23490
23491         (( bsize < 40960 )) && bsize=40960
23492         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
23493         ls -la $DIR/$tfile
23494         cancel_lru_locks $OSC
23495         test_241_bio 1000 $bsize &
23496         PID=$!
23497         test_241_dio 1000 $bsize
23498         wait $PID
23499 }
23500 run_test 241a "bio vs dio"
23501
23502 test_241b() {
23503         local bsize=$PAGE_SIZE
23504
23505         (( bsize < 40960 )) && bsize=40960
23506         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
23507         ls -la $DIR/$tfile
23508         test_241_dio 1000 $bsize &
23509         PID=$!
23510         test_241_dio 1000 $bsize
23511         wait $PID
23512 }
23513 run_test 241b "dio vs dio"
23514
23515 test_242() {
23516         remote_mds_nodsh && skip "remote MDS with nodsh"
23517
23518         mkdir_on_mdt0 $DIR/$tdir
23519         touch $DIR/$tdir/$tfile
23520
23521         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
23522         do_facet mds1 lctl set_param fail_loc=0x105
23523         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
23524
23525         do_facet mds1 lctl set_param fail_loc=0
23526         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
23527 }
23528 run_test 242 "mdt_readpage failure should not cause directory unreadable"
23529
23530 test_243()
23531 {
23532         test_mkdir $DIR/$tdir
23533         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
23534 }
23535 run_test 243 "various group lock tests"
23536
23537 test_244a()
23538 {
23539         test_mkdir $DIR/$tdir
23540         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
23541         sendfile_grouplock $DIR/$tdir/$tfile || \
23542                 error "sendfile+grouplock failed"
23543         rm -rf $DIR/$tdir
23544 }
23545 run_test 244a "sendfile with group lock tests"
23546
23547 test_244b()
23548 {
23549         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23550
23551         local threads=50
23552         local size=$((1024*1024))
23553
23554         test_mkdir $DIR/$tdir
23555         for i in $(seq 1 $threads); do
23556                 local file=$DIR/$tdir/file_$((i / 10))
23557                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
23558                 local pids[$i]=$!
23559         done
23560         for i in $(seq 1 $threads); do
23561                 wait ${pids[$i]}
23562         done
23563 }
23564 run_test 244b "multi-threaded write with group lock"
23565
23566 test_245a() {
23567         local flagname="multi_mod_rpcs"
23568         local connect_data_name="max_mod_rpcs"
23569         local out
23570
23571         # check if multiple modify RPCs flag is set
23572         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
23573                 grep "connect_flags:")
23574         echo "$out"
23575
23576         echo "$out" | grep -qw $flagname
23577         if [ $? -ne 0 ]; then
23578                 echo "connect flag $flagname is not set"
23579                 return
23580         fi
23581
23582         # check if multiple modify RPCs data is set
23583         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
23584         echo "$out"
23585
23586         echo "$out" | grep -qw $connect_data_name ||
23587                 error "import should have connect data $connect_data_name"
23588 }
23589 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
23590
23591 test_245b() {
23592         local flagname="multi_mod_rpcs"
23593         local connect_data_name="max_mod_rpcs"
23594         local out
23595
23596         remote_mds_nodsh && skip "remote MDS with nodsh"
23597         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
23598
23599         # check if multiple modify RPCs flag is set
23600         out=$(do_facet mds1 \
23601               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
23602               grep "connect_flags:")
23603         echo "$out"
23604
23605         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
23606
23607         # check if multiple modify RPCs data is set
23608         out=$(do_facet mds1 \
23609               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
23610
23611         [[ "$out" =~ $connect_data_name ]] ||
23612                 {
23613                         echo "$out"
23614                         error "missing connect data $connect_data_name"
23615                 }
23616 }
23617 run_test 245b "check osp connection flag/data: multiple modify RPCs"
23618
23619 cleanup_247() {
23620         local submount=$1
23621
23622         trap 0
23623         umount_client $submount
23624         rmdir $submount
23625 }
23626
23627 test_247a() {
23628         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23629                 grep -q subtree ||
23630                 skip_env "Fileset feature is not supported"
23631
23632         local submount=${MOUNT}_$tdir
23633
23634         mkdir $MOUNT/$tdir
23635         mkdir -p $submount || error "mkdir $submount failed"
23636         FILESET="$FILESET/$tdir" mount_client $submount ||
23637                 error "mount $submount failed"
23638         trap "cleanup_247 $submount" EXIT
23639         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
23640         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
23641                 error "read $MOUNT/$tdir/$tfile failed"
23642         cleanup_247 $submount
23643 }
23644 run_test 247a "mount subdir as fileset"
23645
23646 test_247b() {
23647         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23648                 skip_env "Fileset feature is not supported"
23649
23650         local submount=${MOUNT}_$tdir
23651
23652         rm -rf $MOUNT/$tdir
23653         mkdir -p $submount || error "mkdir $submount failed"
23654         SKIP_FILESET=1
23655         FILESET="$FILESET/$tdir" mount_client $submount &&
23656                 error "mount $submount should fail"
23657         rmdir $submount
23658 }
23659 run_test 247b "mount subdir that dose not exist"
23660
23661 test_247c() {
23662         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23663                 skip_env "Fileset feature is not supported"
23664
23665         local submount=${MOUNT}_$tdir
23666
23667         mkdir -p $MOUNT/$tdir/dir1
23668         mkdir -p $submount || error "mkdir $submount failed"
23669         trap "cleanup_247 $submount" EXIT
23670         FILESET="$FILESET/$tdir" mount_client $submount ||
23671                 error "mount $submount failed"
23672         local fid=$($LFS path2fid $MOUNT/)
23673         $LFS fid2path $submount $fid && error "fid2path should fail"
23674         cleanup_247 $submount
23675 }
23676 run_test 247c "running fid2path outside subdirectory root"
23677
23678 test_247d() {
23679         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23680                 skip "Fileset feature is not supported"
23681
23682         local submount=${MOUNT}_$tdir
23683
23684         mkdir -p $MOUNT/$tdir/dir1
23685         mkdir -p $submount || error "mkdir $submount failed"
23686         FILESET="$FILESET/$tdir" mount_client $submount ||
23687                 error "mount $submount failed"
23688         trap "cleanup_247 $submount" EXIT
23689
23690         local td=$submount/dir1
23691         local fid=$($LFS path2fid $td)
23692         [ -z "$fid" ] && error "path2fid unable to get $td FID"
23693
23694         # check that we get the same pathname back
23695         local rootpath
23696         local found
23697         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
23698                 echo "$rootpath $fid"
23699                 found=$($LFS fid2path $rootpath "$fid")
23700                 [ -n "$found" ] || error "fid2path should succeed"
23701                 [ "$found" == "$td" ] || error "fid2path $found != $td"
23702         done
23703         # check wrong root path format
23704         rootpath=$submount"_wrong"
23705         found=$($LFS fid2path $rootpath "$fid")
23706         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
23707
23708         cleanup_247 $submount
23709 }
23710 run_test 247d "running fid2path inside subdirectory root"
23711
23712 # LU-8037
23713 test_247e() {
23714         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23715                 grep -q subtree ||
23716                 skip "Fileset feature is not supported"
23717
23718         local submount=${MOUNT}_$tdir
23719
23720         mkdir $MOUNT/$tdir
23721         mkdir -p $submount || error "mkdir $submount failed"
23722         FILESET="$FILESET/.." mount_client $submount &&
23723                 error "mount $submount should fail"
23724         rmdir $submount
23725 }
23726 run_test 247e "mount .. as fileset"
23727
23728 test_247f() {
23729         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
23730         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
23731                 skip "Need at least version 2.14.50.162"
23732         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23733                 skip "Fileset feature is not supported"
23734
23735         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
23736         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
23737                 error "mkdir remote failed"
23738         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
23739                 error "mkdir remote/subdir failed"
23740         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
23741                 error "mkdir striped failed"
23742         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
23743
23744         local submount=${MOUNT}_$tdir
23745
23746         mkdir -p $submount || error "mkdir $submount failed"
23747         stack_trap "rmdir $submount"
23748
23749         local dir
23750         local fileset=$FILESET
23751         local mdts=$(comma_list $(mdts_nodes))
23752
23753         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
23754         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
23755                 $tdir/striped/subdir $tdir/striped/.; do
23756                 FILESET="$fileset/$dir" mount_client $submount ||
23757                         error "mount $dir failed"
23758                 umount_client $submount
23759         done
23760 }
23761 run_test 247f "mount striped or remote directory as fileset"
23762
23763 test_subdir_mount_lock()
23764 {
23765         local testdir=$1
23766         local submount=${MOUNT}_$(basename $testdir)
23767
23768         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
23769
23770         mkdir -p $submount || error "mkdir $submount failed"
23771         stack_trap "rmdir $submount"
23772
23773         FILESET="$fileset/$testdir" mount_client $submount ||
23774                 error "mount $FILESET failed"
23775         stack_trap "umount $submount"
23776
23777         local mdts=$(comma_list $(mdts_nodes))
23778
23779         local nrpcs
23780
23781         stat $submount > /dev/null || error "stat $submount failed"
23782         cancel_lru_locks $MDC
23783         stat $submount > /dev/null || error "stat $submount failed"
23784         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23785         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
23786         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23787         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
23788                 awk '/getattr/ {sum += $2} END {print sum}')
23789
23790         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
23791 }
23792
23793 test_247g() {
23794         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23795
23796         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
23797                 error "mkdir $tdir failed"
23798         test_subdir_mount_lock $tdir
23799 }
23800 run_test 247g "striped directory submount revalidate ROOT from cache"
23801
23802 test_247h() {
23803         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23804         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
23805                 skip "Need MDS version at least 2.15.51"
23806
23807         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23808         test_subdir_mount_lock $tdir
23809         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
23810         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
23811                 error "mkdir $tdir.1 failed"
23812         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
23813 }
23814 run_test 247h "remote directory submount revalidate ROOT from cache"
23815
23816 test_248a() {
23817         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
23818         [ -z "$fast_read_sav" ] && skip "no fast read support"
23819
23820         # create a large file for fast read verification
23821         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
23822
23823         # make sure the file is created correctly
23824         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
23825                 { rm -f $DIR/$tfile; skip "file creation error"; }
23826
23827         echo "Test 1: verify that fast read is 4 times faster on cache read"
23828
23829         # small read with fast read enabled
23830         $LCTL set_param -n llite.*.fast_read=1
23831         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23832                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23833                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23834         # small read with fast read disabled
23835         $LCTL set_param -n llite.*.fast_read=0
23836         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23837                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23838                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23839
23840         # verify that fast read is 4 times faster for cache read
23841         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
23842                 error_not_in_vm "fast read was not 4 times faster: " \
23843                            "$t_fast vs $t_slow"
23844
23845         echo "Test 2: verify the performance between big and small read"
23846         $LCTL set_param -n llite.*.fast_read=1
23847
23848         # 1k non-cache read
23849         cancel_lru_locks osc
23850         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23851                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23852                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23853
23854         # 1M non-cache read
23855         cancel_lru_locks osc
23856         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23857                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23858                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23859
23860         # verify that big IO is not 4 times faster than small IO
23861         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
23862                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
23863
23864         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
23865         rm -f $DIR/$tfile
23866 }
23867 run_test 248a "fast read verification"
23868
23869 test_248b() {
23870         # Default short_io_bytes=16384, try both smaller and larger sizes.
23871         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
23872         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
23873         echo "bs=53248 count=113 normal buffered write"
23874         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
23875                 error "dd of initial data file failed"
23876         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
23877
23878         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
23879         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
23880                 error "dd with sync normal writes failed"
23881         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
23882
23883         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
23884         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
23885                 error "dd with sync small writes failed"
23886         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
23887
23888         cancel_lru_locks osc
23889
23890         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
23891         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
23892         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
23893         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
23894                 iflag=direct || error "dd with O_DIRECT small read failed"
23895         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
23896         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
23897                 error "compare $TMP/$tfile.1 failed"
23898
23899         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
23900         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
23901
23902         # just to see what the maximum tunable value is, and test parsing
23903         echo "test invalid parameter 2MB"
23904         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
23905                 error "too-large short_io_bytes allowed"
23906         echo "test maximum parameter 512KB"
23907         # if we can set a larger short_io_bytes, run test regardless of version
23908         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
23909                 # older clients may not allow setting it this large, that's OK
23910                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
23911                         skip "Need at least client version 2.13.50"
23912                 error "medium short_io_bytes failed"
23913         fi
23914         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23915         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
23916
23917         echo "test large parameter 64KB"
23918         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
23919         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23920
23921         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
23922         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
23923                 error "dd with sync large writes failed"
23924         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
23925
23926         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
23927         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
23928         num=$((113 * 4096 / PAGE_SIZE))
23929         echo "bs=$size count=$num oflag=direct large write $tfile.3"
23930         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
23931                 error "dd with O_DIRECT large writes failed"
23932         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
23933                 error "compare $DIR/$tfile.3 failed"
23934
23935         cancel_lru_locks osc
23936
23937         echo "bs=$size count=$num iflag=direct large read $tfile.2"
23938         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
23939                 error "dd with O_DIRECT large read failed"
23940         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
23941                 error "compare $TMP/$tfile.2 failed"
23942
23943         echo "bs=$size count=$num iflag=direct large read $tfile.3"
23944         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
23945                 error "dd with O_DIRECT large read failed"
23946         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
23947                 error "compare $TMP/$tfile.3 failed"
23948 }
23949 run_test 248b "test short_io read and write for both small and large sizes"
23950
23951 test_248c() {
23952         $LCTL set_param llite.*.read_ahead_stats=c
23953         # This test compares whole file readahead to non-whole file readahead
23954         # The performance should be consistently slightly faster for whole file,
23955         # and the bug caused whole file readahead to be 80-100x slower, but to
23956         # account for possible test system lag, we require whole file to be
23957         # <= 1.5xnon-whole file, and require 3 failures in a row to fail the
23958         # test
23959         local time1
23960         local time2
23961         local whole_mb=$($LCTL get_param -n llite.*.max_read_ahead_whole_mb)
23962         stack_trap "$LCTL set_param llite.*.max_read_ahead_whole_mb=$whole_mb" EXIT
23963         counter=0
23964
23965         while [ $counter -lt 3 ]; do
23966                 # Increment the counter
23967                 ((counter++))
23968
23969                 $LCTL set_param llite.*.max_read_ahead_whole_mb=64
23970                 rm -f $DIR/$tfile
23971                 touch $DIR/$tfile || error "(0) failed to create file"
23972                 # 64 MiB
23973                 $TRUNCATE $DIR/$tfile 67108864 || error "(1) failed to truncate file"
23974                 time1=$(dd if=$DIR/$tfile bs=4K of=/dev/null 2>&1 | awk '/bytes/ {print $8}')
23975                 echo "whole file readahead of 64 MiB took $time1 seconds"
23976                 $LCTL get_param llite.*.read_ahead_stats
23977
23978                 $LCTL set_param llite.*.read_ahead_stats=c
23979                 $LCTL set_param llite.*.max_read_ahead_whole_mb=8
23980                 rm -f $DIR/$tfile
23981                 touch $DIR/$tfile || error "(2) failed to create file"
23982                 # 64 MiB
23983                 $TRUNCATE $DIR/$tfile 67108864 || error "(3) failed to create file"
23984                 time2=$(dd if=$DIR/$tfile bs=4K of=/dev/null 2>&1 | awk '/bytes/ {print $8}')
23985                 echo "non-whole file readahead of 64 MiB took $time2 seconds"
23986                 $LCTL get_param llite.*.read_ahead_stats
23987
23988                 # Check if time1 is not more than 1.5 times2
23989                 timecheck=$(echo "$time1 <= (1.5 * $time2)" | bc -l)
23990
23991                 if [[ $timecheck -eq 1 ]]; then
23992                         echo "Test passed on attempt $counter"
23993                         # Exit the loop
23994                         counter=4
23995                 else
23996                         echo "Attempt $counter failed: whole file readahead took: $time1, greater than non: $time2"
23997                 fi
23998         done
23999         if [ $counter -eq 3 ]; then
24000                 error "whole file readahead check failed 3 times in a row, probably not just VM lag"
24001         fi
24002
24003 }
24004 run_test 248c "verify whole file read behavior"
24005
24006 test_249() { # LU-7890
24007         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
24008                 skip "Need at least version 2.8.54"
24009
24010         rm -f $DIR/$tfile
24011         $LFS setstripe -c 1 $DIR/$tfile
24012         # Offset 2T == 4k * 512M
24013         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
24014                 error "dd to 2T offset failed"
24015 }
24016 run_test 249 "Write above 2T file size"
24017
24018 test_250() {
24019         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
24020          && skip "no 16TB file size limit on ZFS"
24021
24022         $LFS setstripe -c 1 $DIR/$tfile
24023         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
24024         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
24025         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
24026         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
24027                 conv=notrunc,fsync && error "append succeeded"
24028         return 0
24029 }
24030 run_test 250 "Write above 16T limit"
24031
24032 test_251a() {
24033         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
24034
24035         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
24036         #Skip once - writing the first stripe will succeed
24037         $LCTL set_param fail_loc=0xa0001407 fail_val=1
24038         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
24039                 error "short write happened"
24040
24041         $LCTL set_param fail_loc=0xa0001407 fail_val=1
24042         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
24043                 error "short read happened"
24044
24045         rm -f $DIR/$tfile
24046 }
24047 run_test 251a "Handling short read and write correctly"
24048
24049 test_251b() {
24050         dd if=/dev/zero of=$DIR/$tfile bs=1k count=4 ||
24051                 error "write $tfile failed"
24052
24053         sleep 2 && echo 12345 >> $DIR/$tfile &
24054
24055         #define OBD_FAIL_LLITE_READ_PAUSE 0x1431
24056         $LCTL set_param fail_loc=0x1431 fail_val=5
24057         # seek to 4096, 2 seconds later, file size expand to 4102, and after
24058         # 5 seconds, read 10 bytes, the short read should
24059         # report:
24060         #                start ->+ read_len -> offset_after_read read_count
24061         #     short read: 4096 ->+ 10 -> 4096 0
24062         # not:
24063         #     short read: 4096 ->+ 10 -> 4102 0
24064         local off=$($MULTIOP $DIR/$tfile oO_RDONLY:z4096r10c 2>&1 | \
24065                         awk '/short read/ { print $7 }')
24066         (( off == 4096 )) ||
24067                 error "short read should set offset at 4096, not $off"
24068 }
24069 run_test 251b "short read restore offset correctly"
24070
24071 test_252() {
24072         remote_mds_nodsh && skip "remote MDS with nodsh"
24073         remote_ost_nodsh && skip "remote OST with nodsh"
24074         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
24075                 skip_env "ldiskfs only test"
24076         fi
24077
24078         local tgt
24079         local dev
24080         local out
24081         local uuid
24082         local num
24083         local gen
24084
24085         # check lr_reader on OST0000
24086         tgt=ost1
24087         dev=$(facet_device $tgt)
24088         out=$(do_facet $tgt $LR_READER $dev)
24089         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
24090         echo "$out"
24091         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
24092         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
24093                 error "Invalid uuid returned by $LR_READER on target $tgt"
24094         echo -e "uuid returned by $LR_READER is '$uuid'\n"
24095
24096         # check lr_reader -c on MDT0000
24097         tgt=mds1
24098         dev=$(facet_device $tgt)
24099         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
24100                 skip "$LR_READER does not support additional options"
24101         fi
24102         out=$(do_facet $tgt $LR_READER -c $dev)
24103         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
24104         echo "$out"
24105         num=$(echo "$out" | grep -c "mdtlov")
24106         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
24107                 error "Invalid number of mdtlov clients returned by $LR_READER"
24108         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
24109
24110         # check lr_reader -cr on MDT0000
24111         out=$(do_facet $tgt $LR_READER -cr $dev)
24112         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
24113         echo "$out"
24114         echo "$out" | grep -q "^reply_data:$" ||
24115                 error "$LR_READER should have returned 'reply_data' section"
24116         num=$(echo "$out" | grep -c "client_generation")
24117         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
24118 }
24119 run_test 252 "check lr_reader tool"
24120
24121 test_253() {
24122         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24123         remote_mds_nodsh && skip "remote MDS with nodsh"
24124         remote_mgs_nodsh && skip "remote MGS with nodsh"
24125         check_set_fallocate_or_skip
24126
24127         local ostidx=0
24128         local rc=0
24129         local ost_name=$(ostname_from_index $ostidx)
24130
24131         # on the mdt's osc
24132         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
24133         do_facet $SINGLEMDS $LCTL get_param -n \
24134                 osp.$mdtosc_proc1.reserved_mb_high ||
24135                 skip  "remote MDS does not support reserved_mb_high"
24136
24137         rm -rf $DIR/$tdir
24138         wait_mds_ost_sync
24139         wait_delete_completed
24140         mkdir $DIR/$tdir
24141         stack_trap "rm -rf $DIR/$tdir"
24142
24143         pool_add $TESTNAME || error "Pool creation failed"
24144         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
24145
24146         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
24147                 error "Setstripe failed"
24148
24149         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
24150
24151         local wms=$(ost_watermarks_get $ostidx)
24152
24153         ost_watermarks_set $ostidx 60 50
24154         stack_trap "ost_watermarks_set $ostidx $wms"
24155
24156         local free_kb=$($LFS df $MOUNT | awk "/$ost_name/ { print \$4 }")
24157         local size=$((free_kb * 1024))
24158
24159         fallocate -l $size $DIR/$tdir/fill_ost$ostidx ||
24160                 error "fallocate failed"
24161         sleep_maxage
24162
24163         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
24164                         osp.$mdtosc_proc1.prealloc_status)
24165         echo "prealloc_status $oa_status"
24166
24167         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
24168                 error "File creation should fail"
24169
24170         #object allocation was stopped, but we still able to append files
24171         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
24172                 oflag=append || error "Append failed"
24173
24174         rm -f $DIR/$tdir/$tfile.0
24175         rm -f $DIR/$tdir/fill_ost$ostidx
24176
24177         wait_delete_completed
24178         sleep_maxage
24179
24180         for i in $(seq 10 12); do
24181                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
24182                         2>/dev/null || error "File creation failed after rm"
24183         done
24184
24185         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
24186                         osp.$mdtosc_proc1.prealloc_status)
24187         echo "prealloc_status $oa_status"
24188
24189         if (( oa_status != 0 )); then
24190                 error "Object allocation still disable after rm"
24191         fi
24192 }
24193 run_test 253 "Check object allocation limit"
24194
24195 test_254() {
24196         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24197         remote_mds_nodsh && skip "remote MDS with nodsh"
24198
24199         local mdt=$(facet_svc $SINGLEMDS)
24200
24201         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
24202                 skip "MDS does not support changelog_size"
24203
24204         local cl_user
24205
24206         changelog_register || error "changelog_register failed"
24207
24208         changelog_clear 0 || error "changelog_clear failed"
24209
24210         local size1=$(do_facet $SINGLEMDS \
24211                       $LCTL get_param -n mdd.$mdt.changelog_size)
24212         echo "Changelog size $size1"
24213
24214         rm -rf $DIR/$tdir
24215         $LFS mkdir -i 0 $DIR/$tdir
24216         # change something
24217         mkdir -p $DIR/$tdir/pics/2008/zachy
24218         touch $DIR/$tdir/pics/2008/zachy/timestamp
24219         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
24220         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
24221         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
24222         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
24223         rm $DIR/$tdir/pics/desktop.jpg
24224
24225         local size2=$(do_facet $SINGLEMDS \
24226                       $LCTL get_param -n mdd.$mdt.changelog_size)
24227         echo "Changelog size after work $size2"
24228
24229         (( $size2 > $size1 )) ||
24230                 error "new Changelog size=$size2 less than old size=$size1"
24231 }
24232 run_test 254 "Check changelog size"
24233
24234 ladvise_no_type()
24235 {
24236         local type=$1
24237         local file=$2
24238
24239         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
24240                 awk -F: '{print $2}' | grep $type > /dev/null
24241         if [ $? -ne 0 ]; then
24242                 return 0
24243         fi
24244         return 1
24245 }
24246
24247 ladvise_no_ioctl()
24248 {
24249         local file=$1
24250
24251         lfs ladvise -a willread $file > /dev/null 2>&1
24252         if [ $? -eq 0 ]; then
24253                 return 1
24254         fi
24255
24256         lfs ladvise -a willread $file 2>&1 |
24257                 grep "Inappropriate ioctl for device" > /dev/null
24258         if [ $? -eq 0 ]; then
24259                 return 0
24260         fi
24261         return 1
24262 }
24263
24264 percent() {
24265         bc <<<"scale=2; ($1 - $2) * 100 / $2"
24266 }
24267
24268 # run a random read IO workload
24269 # usage: random_read_iops <filename> <filesize> <iosize>
24270 random_read_iops() {
24271         local file=$1
24272         local fsize=$2
24273         local iosize=${3:-4096}
24274
24275         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
24276                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
24277 }
24278
24279 drop_file_oss_cache() {
24280         local file="$1"
24281         local nodes="$2"
24282
24283         $LFS ladvise -a dontneed $file 2>/dev/null ||
24284                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
24285 }
24286
24287 ladvise_willread_performance()
24288 {
24289         local repeat=10
24290         local average_origin=0
24291         local average_cache=0
24292         local average_ladvise=0
24293
24294         for ((i = 1; i <= $repeat; i++)); do
24295                 echo "Iter $i/$repeat: reading without willread hint"
24296                 cancel_lru_locks osc
24297                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
24298                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
24299                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
24300                 average_origin=$(bc <<<"$average_origin + $speed_origin")
24301
24302                 cancel_lru_locks osc
24303                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
24304                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
24305                 average_cache=$(bc <<<"$average_cache + $speed_cache")
24306
24307                 cancel_lru_locks osc
24308                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
24309                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
24310                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
24311                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
24312                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
24313         done
24314         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
24315         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
24316         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
24317
24318         speedup_cache=$(percent $average_cache $average_origin)
24319         speedup_ladvise=$(percent $average_ladvise $average_origin)
24320
24321         echo "Average uncached read: $average_origin"
24322         echo "Average speedup with OSS cached read:" \
24323                 "$average_cache = +$speedup_cache%"
24324         echo "Average speedup with ladvise willread:" \
24325                 "$average_ladvise = +$speedup_ladvise%"
24326
24327         local lowest_speedup=20
24328         if (( ${speedup_cache%.*} < $lowest_speedup )); then
24329                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
24330                      "got $speedup_cache%. Skipping ladvise willread check."
24331                 return 0
24332         fi
24333
24334         # the test won't work on ZFS until it supports 'ladvise dontneed', but
24335         # it is still good to run until then to exercise 'ladvise willread'
24336         ! $LFS ladvise -a dontneed $DIR/$tfile &&
24337                 [ "$ost1_FSTYPE" = "zfs" ] &&
24338                 echo "osd-zfs does not support dontneed or drop_caches" &&
24339                 return 0
24340
24341         lowest_speedup=$(bc <<<"scale=2; $speedup_cache / 2")
24342         (( ${speedup_ladvise%.*} > ${lowest_speedup%.*} )) ||
24343                 error_not_in_vm "Speedup with willread is less than " \
24344                         "$lowest_speedup%, got $speedup_ladvise%"
24345 }
24346
24347 test_255a() {
24348         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
24349                 skip "lustre < 2.8.54 does not support ladvise "
24350         remote_ost_nodsh && skip "remote OST with nodsh"
24351
24352         stack_trap "rm -f $DIR/$tfile"
24353         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
24354
24355         ladvise_no_type willread $DIR/$tfile &&
24356                 skip "willread ladvise is not supported"
24357
24358         ladvise_no_ioctl $DIR/$tfile &&
24359                 skip "ladvise ioctl is not supported"
24360
24361         local size_mb=100
24362         local size=$((size_mb * 1048576))
24363         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
24364                 error "dd to $DIR/$tfile failed"
24365
24366         lfs ladvise -a willread $DIR/$tfile ||
24367                 error "Ladvise failed with no range argument"
24368
24369         lfs ladvise -a willread -s 0 $DIR/$tfile ||
24370                 error "Ladvise failed with no -l or -e argument"
24371
24372         lfs ladvise -a willread -e 1 $DIR/$tfile ||
24373                 error "Ladvise failed with only -e argument"
24374
24375         lfs ladvise -a willread -l 1 $DIR/$tfile ||
24376                 error "Ladvise failed with only -l argument"
24377
24378         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
24379                 error "End offset should not be smaller than start offset"
24380
24381         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
24382                 error "End offset should not be equal to start offset"
24383
24384         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
24385                 error "Ladvise failed with overflowing -s argument"
24386
24387         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
24388                 error "Ladvise failed with overflowing -e argument"
24389
24390         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
24391                 error "Ladvise failed with overflowing -l argument"
24392
24393         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
24394                 error "Ladvise succeeded with conflicting -l and -e arguments"
24395
24396         echo "Synchronous ladvise should wait"
24397         local delay=8
24398 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
24399         do_nodes $(comma_list $(osts_nodes)) \
24400                 $LCTL set_param fail_val=$delay fail_loc=0x237
24401         stack_trap "do_nodes $(comma_list $(osts_nodes)) \
24402                 $LCTL set_param fail_loc=0"
24403
24404         local start_ts=$SECONDS
24405         lfs ladvise -a willread $DIR/$tfile ||
24406                 error "Ladvise failed with no range argument"
24407         local end_ts=$SECONDS
24408         local inteval_ts=$((end_ts - start_ts))
24409
24410         if [ $inteval_ts -lt $(($delay - 1)) ]; then
24411                 error "Synchronous advice didn't wait reply"
24412         fi
24413
24414         echo "Asynchronous ladvise shouldn't wait"
24415         local start_ts=$SECONDS
24416         lfs ladvise -a willread -b $DIR/$tfile ||
24417                 error "Ladvise failed with no range argument"
24418         local end_ts=$SECONDS
24419         local inteval_ts=$((end_ts - start_ts))
24420
24421         if [ $inteval_ts -gt $(($delay / 2)) ]; then
24422                 error "Asynchronous advice blocked"
24423         fi
24424
24425         ladvise_willread_performance
24426 }
24427 run_test 255a "check 'lfs ladvise -a willread'"
24428
24429 facet_meminfo() {
24430         local facet=$1
24431         local info=$2
24432
24433         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
24434 }
24435
24436 test_255b() {
24437         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
24438                 skip "lustre < 2.8.54 does not support ladvise "
24439         remote_ost_nodsh && skip "remote OST with nodsh"
24440
24441         stack_trap "rm -f $DIR/$tfile"
24442         lfs setstripe -c 1 -i 0 $DIR/$tfile
24443
24444         ladvise_no_type dontneed $DIR/$tfile &&
24445                 skip "dontneed ladvise is not supported"
24446
24447         ladvise_no_ioctl $DIR/$tfile &&
24448                 skip "ladvise ioctl is not supported"
24449
24450         ! $LFS ladvise -a dontneed $DIR/$tfile &&
24451                 [ "$ost1_FSTYPE" = "zfs" ] &&
24452                 skip "zfs-osd does not support 'ladvise dontneed'"
24453
24454         local size_mb=100
24455         local size=$((size_mb * 1048576))
24456         # In order to prevent disturbance of other processes, only check 3/4
24457         # of the memory usage
24458         local kibibytes=$((size_mb * 1024 * 3 / 4))
24459
24460         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
24461                 error "dd to $DIR/$tfile failed"
24462
24463         #force write to complete before dropping OST cache & checking memory
24464         sync
24465
24466         local total=$(facet_meminfo ost1 MemTotal)
24467         echo "Total memory: $total KiB"
24468
24469         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
24470         local before_read=$(facet_meminfo ost1 Cached)
24471         echo "Cache used before read: $before_read KiB"
24472
24473         lfs ladvise -a willread $DIR/$tfile ||
24474                 error "Ladvise willread failed"
24475         local after_read=$(facet_meminfo ost1 Cached)
24476         echo "Cache used after read: $after_read KiB"
24477
24478         lfs ladvise -a dontneed $DIR/$tfile ||
24479                 error "Ladvise dontneed again failed"
24480         local no_read=$(facet_meminfo ost1 Cached)
24481         echo "Cache used after dontneed ladvise: $no_read KiB"
24482
24483         if [ $total -lt $((before_read + kibibytes)) ]; then
24484                 echo "Memory is too small, abort checking"
24485                 return 0
24486         fi
24487
24488         if [ $((before_read + kibibytes)) -gt $after_read ]; then
24489                 error "Ladvise willread should use more memory" \
24490                         "than $kibibytes KiB"
24491         fi
24492
24493         if [ $((no_read + kibibytes)) -gt $after_read ]; then
24494                 error "Ladvise dontneed should release more memory" \
24495                         "than $kibibytes KiB"
24496         fi
24497 }
24498 run_test 255b "check 'lfs ladvise -a dontneed'"
24499
24500 test_255c() {
24501         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
24502                 skip "lustre < 2.10.50 does not support lockahead"
24503
24504         local ost1_imp=$(get_osc_import_name client ost1)
24505         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24506                          cut -d'.' -f2)
24507         local count
24508         local new_count
24509         local difference
24510         local i
24511         local rc
24512
24513         test_mkdir -p $DIR/$tdir
24514         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24515
24516         #test 10 returns only success/failure
24517         i=10
24518         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24519         rc=$?
24520         if [ $rc -eq 255 ]; then
24521                 error "Ladvise test${i} failed, ${rc}"
24522         fi
24523
24524         #test 11 counts lock enqueue requests, all others count new locks
24525         i=11
24526         count=$(do_facet ost1 \
24527                 $LCTL get_param -n ost.OSS.ost.stats)
24528         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
24529
24530         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24531         rc=$?
24532         if [ $rc -eq 255 ]; then
24533                 error "Ladvise test${i} failed, ${rc}"
24534         fi
24535
24536         new_count=$(do_facet ost1 \
24537                 $LCTL get_param -n ost.OSS.ost.stats)
24538         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
24539                    awk '{ print $2 }')
24540
24541         difference="$((new_count - count))"
24542         if [ $difference -ne $rc ]; then
24543                 error "Ladvise test${i}, bad enqueue count, returned " \
24544                       "${rc}, actual ${difference}"
24545         fi
24546
24547         for i in $(seq 12 21); do
24548                 # If we do not do this, we run the risk of having too many
24549                 # locks and starting lock cancellation while we are checking
24550                 # lock counts.
24551                 cancel_lru_locks osc
24552
24553                 count=$($LCTL get_param -n \
24554                        ldlm.namespaces.$imp_name.lock_unused_count)
24555
24556                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
24557                 rc=$?
24558                 if [ $rc -eq 255 ]; then
24559                         error "Ladvise test ${i} failed, ${rc}"
24560                 fi
24561
24562                 new_count=$($LCTL get_param -n \
24563                        ldlm.namespaces.$imp_name.lock_unused_count)
24564                 difference="$((new_count - count))"
24565
24566                 # Test 15 output is divided by 100 to map down to valid return
24567                 if [ $i -eq 15 ]; then
24568                         rc="$((rc * 100))"
24569                 fi
24570
24571                 if [ $difference -ne $rc ]; then
24572                         error "Ladvise test ${i}, bad lock count, returned " \
24573                               "${rc}, actual ${difference}"
24574                 fi
24575         done
24576
24577         #test 22 returns only success/failure
24578         i=22
24579         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24580         rc=$?
24581         if [ $rc -eq 255 ]; then
24582                 error "Ladvise test${i} failed, ${rc}"
24583         fi
24584 }
24585 run_test 255c "suite of ladvise lockahead tests"
24586
24587 test_256() {
24588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24589         remote_mds_nodsh && skip "remote MDS with nodsh"
24590         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
24591         changelog_users $SINGLEMDS | grep "^cl" &&
24592                 skip "active changelog user"
24593
24594         local cl_user
24595         local cat_sl
24596         local mdt_dev
24597
24598         mdt_dev=$(facet_device $SINGLEMDS)
24599         echo $mdt_dev
24600
24601         changelog_register || error "changelog_register failed"
24602
24603         rm -rf $DIR/$tdir
24604         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
24605
24606         changelog_clear 0 || error "changelog_clear failed"
24607
24608         # change something
24609         touch $DIR/$tdir/{1..10}
24610
24611         # stop the MDT
24612         stop $SINGLEMDS || error "Fail to stop MDT"
24613
24614         # remount the MDT
24615         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
24616                 error "Fail to start MDT"
24617
24618         #after mount new plainllog is used
24619         touch $DIR/$tdir/{11..19}
24620         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
24621         stack_trap "rm -f $tmpfile"
24622         cat_sl=$(do_facet $SINGLEMDS "sync; \
24623                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24624                  llog_reader $tmpfile | grep -c type=1064553b")
24625         do_facet $SINGLEMDS llog_reader $tmpfile
24626
24627         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
24628
24629         changelog_clear 0 || error "changelog_clear failed"
24630
24631         cat_sl=$(do_facet $SINGLEMDS "sync; \
24632                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24633                  llog_reader $tmpfile | grep -c type=1064553b")
24634
24635         if (( cat_sl == 2 )); then
24636                 error "Empty plain llog was not deleted from changelog catalog"
24637         elif (( cat_sl != 1 )); then
24638                 error "Active plain llog shouldn't be deleted from catalog"
24639         fi
24640 }
24641 run_test 256 "Check llog delete for empty and not full state"
24642
24643 test_257() {
24644         remote_mds_nodsh && skip "remote MDS with nodsh"
24645         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
24646                 skip "Need MDS version at least 2.8.55"
24647
24648         test_mkdir $DIR/$tdir
24649
24650         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
24651                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
24652         stat $DIR/$tdir
24653
24654 #define OBD_FAIL_MDS_XATTR_REP                  0x161
24655         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
24656         local facet=mds$((mdtidx + 1))
24657         set_nodes_failloc $(facet_active_host $facet) 0x80000161
24658         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
24659
24660         stop $facet || error "stop MDS failed"
24661         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
24662                 error "start MDS fail"
24663         wait_recovery_complete $facet
24664 }
24665 run_test 257 "xattr locks are not lost"
24666
24667 # Verify we take the i_mutex when security requires it
24668 test_258a() {
24669 #define OBD_FAIL_IMUTEX_SEC 0x141c
24670         $LCTL set_param fail_loc=0x141c
24671         touch $DIR/$tfile
24672         chmod u+s $DIR/$tfile
24673         chmod a+rwx $DIR/$tfile
24674         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24675         RC=$?
24676         if [ $RC -ne 0 ]; then
24677                 error "error, failed to take i_mutex, rc=$?"
24678         fi
24679         rm -f $DIR/$tfile
24680 }
24681 run_test 258a "verify i_mutex security behavior when suid attributes is set"
24682
24683 # Verify we do NOT take the i_mutex in the normal case
24684 test_258b() {
24685 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
24686         $LCTL set_param fail_loc=0x141d
24687         touch $DIR/$tfile
24688         chmod a+rwx $DIR
24689         chmod a+rw $DIR/$tfile
24690         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24691         RC=$?
24692         if [ $RC -ne 0 ]; then
24693                 error "error, took i_mutex unnecessarily, rc=$?"
24694         fi
24695         rm -f $DIR/$tfile
24696
24697 }
24698 run_test 258b "verify i_mutex security behavior"
24699
24700 test_259() {
24701         local file=$DIR/$tfile
24702         local before
24703         local after
24704
24705         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
24706
24707         stack_trap "rm -f $file" EXIT
24708
24709         wait_delete_completed
24710         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24711         echo "before: $before"
24712
24713         $LFS setstripe -i 0 -c 1 $file
24714         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
24715         sync_all_data
24716         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24717         echo "after write: $after"
24718
24719 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
24720         do_facet ost1 $LCTL set_param fail_loc=0x2301
24721         $TRUNCATE $file 0
24722         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24723         echo "after truncate: $after"
24724
24725         stop ost1
24726         do_facet ost1 $LCTL set_param fail_loc=0
24727         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
24728         sleep 2
24729         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24730         echo "after restart: $after"
24731         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
24732                 error "missing truncate?"
24733
24734         return 0
24735 }
24736 run_test 259 "crash at delayed truncate"
24737
24738 test_260() {
24739 #define OBD_FAIL_MDC_CLOSE               0x806
24740         $LCTL set_param fail_loc=0x80000806
24741         touch $DIR/$tfile
24742
24743 }
24744 run_test 260 "Check mdc_close fail"
24745
24746 ### Data-on-MDT sanity tests ###
24747 test_270a() {
24748         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24749                 skip "Need MDS version at least 2.10.55 for DoM"
24750
24751         # create DoM file
24752         local dom=$DIR/$tdir/dom_file
24753         local tmp=$DIR/$tdir/tmp_file
24754
24755         mkdir_on_mdt0 $DIR/$tdir
24756
24757         # basic checks for DoM component creation
24758         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
24759                 error "Can set MDT layout to non-first entry"
24760
24761         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
24762                 error "Can define multiple entries as MDT layout"
24763
24764         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
24765
24766         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
24767         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
24768         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
24769
24770         local mdtidx=$($LFS getstripe -m $dom)
24771         local mdtname=MDT$(printf %04x $mdtidx)
24772         local facet=mds$((mdtidx + 1))
24773         local space_check=1
24774
24775         # Skip free space checks with ZFS
24776         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
24777
24778         # write
24779         sync
24780         local size_tmp=$((65536 * 3))
24781         local mdtfree1=$(do_facet $facet \
24782                          lctl get_param -n osd*.*$mdtname.kbytesfree)
24783
24784         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24785         # check also direct IO along write
24786         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
24787         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24788         sync
24789         cmp $tmp $dom || error "file data is different"
24790         [ $(stat -c%s $dom) == $size_tmp ] ||
24791                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24792         if [ $space_check == 1 ]; then
24793                 local mdtfree2=$(do_facet $facet \
24794                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
24795
24796                 # increase in usage from by $size_tmp
24797                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24798                         error "MDT free space wrong after write: " \
24799                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24800         fi
24801
24802         # truncate
24803         local size_dom=10000
24804
24805         $TRUNCATE $dom $size_dom
24806         [ $(stat -c%s $dom) == $size_dom ] ||
24807                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
24808         if [ $space_check == 1 ]; then
24809                 mdtfree1=$(do_facet $facet \
24810                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24811                 # decrease in usage from $size_tmp to new $size_dom
24812                 [ $(($mdtfree1 - $mdtfree2)) -ge \
24813                   $(((size_tmp - size_dom) / 1024)) ] ||
24814                         error "MDT free space is wrong after truncate: " \
24815                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
24816         fi
24817
24818         # append
24819         cat $tmp >> $dom
24820         sync
24821         size_dom=$((size_dom + size_tmp))
24822         [ $(stat -c%s $dom) == $size_dom ] ||
24823                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
24824         if [ $space_check == 1 ]; then
24825                 mdtfree2=$(do_facet $facet \
24826                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24827                 # increase in usage by $size_tmp from previous
24828                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24829                         error "MDT free space is wrong after append: " \
24830                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24831         fi
24832
24833         # delete
24834         rm $dom
24835         if [ $space_check == 1 ]; then
24836                 mdtfree1=$(do_facet $facet \
24837                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24838                 # decrease in usage by $size_dom from previous
24839                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
24840                         error "MDT free space is wrong after removal: " \
24841                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
24842         fi
24843
24844         # combined striping
24845         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
24846                 error "Can't create DoM + OST striping"
24847
24848         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
24849         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24850         # check also direct IO along write
24851         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24852         sync
24853         cmp $tmp $dom || error "file data is different"
24854         [ $(stat -c%s $dom) == $size_tmp ] ||
24855                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24856         rm $dom $tmp
24857
24858         return 0
24859 }
24860 run_test 270a "DoM: basic functionality tests"
24861
24862 test_270b() {
24863         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24864                 skip "Need MDS version at least 2.10.55"
24865
24866         local dom=$DIR/$tdir/dom_file
24867         local max_size=1048576
24868
24869         mkdir -p $DIR/$tdir
24870         $LFS setstripe -E $max_size -L mdt $dom
24871
24872         # truncate over the limit
24873         $TRUNCATE $dom $(($max_size + 1)) &&
24874                 error "successful truncate over the maximum size"
24875         # write over the limit
24876         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
24877                 error "successful write over the maximum size"
24878         # append over the limit
24879         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
24880         echo "12345" >> $dom && error "successful append over the maximum size"
24881         rm $dom
24882
24883         return 0
24884 }
24885 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
24886
24887 test_270c() {
24888         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24889                 skip "Need MDS version at least 2.10.55"
24890
24891         mkdir -p $DIR/$tdir
24892         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24893
24894         # check files inherit DoM EA
24895         touch $DIR/$tdir/first
24896         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
24897                 error "bad pattern"
24898         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
24899                 error "bad stripe count"
24900         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
24901                 error "bad stripe size"
24902
24903         # check directory inherits DoM EA and uses it as default
24904         mkdir $DIR/$tdir/subdir
24905         touch $DIR/$tdir/subdir/second
24906         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
24907                 error "bad pattern in sub-directory"
24908         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
24909                 error "bad stripe count in sub-directory"
24910         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
24911                 error "bad stripe size in sub-directory"
24912         return 0
24913 }
24914 run_test 270c "DoM: DoM EA inheritance tests"
24915
24916 test_270d() {
24917         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24918                 skip "Need MDS version at least 2.10.55"
24919
24920         mkdir -p $DIR/$tdir
24921         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24922
24923         # inherit default DoM striping
24924         mkdir $DIR/$tdir/subdir
24925         touch $DIR/$tdir/subdir/f1
24926
24927         # change default directory striping
24928         $LFS setstripe -c 1 $DIR/$tdir/subdir
24929         touch $DIR/$tdir/subdir/f2
24930         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
24931                 error "wrong default striping in file 2"
24932         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
24933                 error "bad pattern in file 2"
24934         return 0
24935 }
24936 run_test 270d "DoM: change striping from DoM to RAID0"
24937
24938 test_270e() {
24939         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24940                 skip "Need MDS version at least 2.10.55"
24941
24942         mkdir -p $DIR/$tdir/dom
24943         mkdir -p $DIR/$tdir/norm
24944         DOMFILES=20
24945         NORMFILES=10
24946         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
24947         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
24948
24949         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
24950         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
24951
24952         # find DoM files by layout
24953         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
24954         [ $NUM -eq  $DOMFILES ] ||
24955                 error "lfs find -L: found $NUM, expected $DOMFILES"
24956         echo "Test 1: lfs find 20 DOM files by layout: OK"
24957
24958         # there should be 1 dir with default DOM striping
24959         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
24960         [ $NUM -eq  1 ] ||
24961                 error "lfs find -L: found $NUM, expected 1 dir"
24962         echo "Test 2: lfs find 1 DOM dir by layout: OK"
24963
24964         # find DoM files by stripe size
24965         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
24966         [ $NUM -eq  $DOMFILES ] ||
24967                 error "lfs find -S: found $NUM, expected $DOMFILES"
24968         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
24969
24970         # find files by stripe offset except DoM files
24971         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
24972         [ $NUM -eq  $NORMFILES ] ||
24973                 error "lfs find -i: found $NUM, expected $NORMFILES"
24974         echo "Test 5: lfs find no DOM files by stripe index: OK"
24975         return 0
24976 }
24977 run_test 270e "DoM: lfs find with DoM files test"
24978
24979 test_270f() {
24980         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24981                 skip "Need MDS version at least 2.10.55"
24982
24983         local mdtname=${FSNAME}-MDT0000-mdtlov
24984         local dom=$DIR/$tdir/dom_file
24985         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
24986                                                 lod.$mdtname.dom_stripesize)
24987         local dom_limit=131072
24988
24989         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
24990         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24991                                                 lod.$mdtname.dom_stripesize)
24992         [ ${dom_limit} -eq ${dom_current} ] ||
24993                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
24994
24995         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24996         $LFS setstripe -d $DIR/$tdir
24997         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
24998                 error "Can't set directory default striping"
24999
25000         # exceed maximum stripe size
25001         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
25002                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
25003         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
25004                 error "Able to create DoM component size more than LOD limit"
25005
25006         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
25007         dom_current=$(do_facet mds1 $LCTL get_param -n \
25008                                                 lod.$mdtname.dom_stripesize)
25009         [ 0 -eq ${dom_current} ] ||
25010                 error "Can't set zero DoM stripe limit"
25011         rm $dom
25012
25013         # attempt to create DoM file on server with disabled DoM should
25014         # remove DoM entry from layout and be succeed
25015         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
25016                 error "Can't create DoM file (DoM is disabled)"
25017         [ $($LFS getstripe -L $dom) == "mdt" ] &&
25018                 error "File has DoM component while DoM is disabled"
25019         rm $dom
25020
25021         # attempt to create DoM file with only DoM stripe should return error
25022         $LFS setstripe -E $dom_limit -L mdt $dom &&
25023                 error "Able to create DoM-only file while DoM is disabled"
25024
25025         # too low values to be aligned with smallest stripe size 64K
25026         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
25027         dom_current=$(do_facet mds1 $LCTL get_param -n \
25028                                                 lod.$mdtname.dom_stripesize)
25029         [ 30000 -eq ${dom_current} ] &&
25030                 error "Can set too small DoM stripe limit"
25031
25032         # 64K is a minimal stripe size in Lustre, expect limit of that size
25033         [ 65536 -eq ${dom_current} ] ||
25034                 error "Limit is not set to 64K but ${dom_current}"
25035
25036         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
25037         dom_current=$(do_facet mds1 $LCTL get_param -n \
25038                                                 lod.$mdtname.dom_stripesize)
25039         echo $dom_current
25040         [ 2147483648 -eq ${dom_current} ] &&
25041                 error "Can set too large DoM stripe limit"
25042
25043         do_facet mds1 $LCTL set_param -n \
25044                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
25045         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
25046                 error "Can't create DoM component size after limit change"
25047         do_facet mds1 $LCTL set_param -n \
25048                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
25049         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
25050                 error "Can't create DoM file after limit decrease"
25051         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
25052                 error "Can create big DoM component after limit decrease"
25053         touch ${dom}_def ||
25054                 error "Can't create file with old default layout"
25055
25056         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
25057         return 0
25058 }
25059 run_test 270f "DoM: maximum DoM stripe size checks"
25060
25061 test_270g() {
25062         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
25063                 skip "Need MDS version at least 2.13.52"
25064         local dom=$DIR/$tdir/$tfile
25065
25066         $LFS mkdir -i 0 -c 1 $DIR/$tdir
25067         local lodname=${FSNAME}-MDT0000-mdtlov
25068
25069         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25070         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
25071         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
25072         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25073
25074         local dom_limit=1024
25075         local dom_threshold="50%"
25076
25077         $LFS setstripe -d $DIR/$tdir
25078         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
25079                 error "Can't set directory default striping"
25080
25081         do_facet mds1 $LCTL set_param -n \
25082                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
25083         # set 0 threshold and create DOM file to change tunable stripesize
25084         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
25085         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
25086                 error "Failed to create $dom file"
25087         # now tunable dom_cur_stripesize should reach maximum
25088         local dom_current=$(do_facet mds1 $LCTL get_param -n \
25089                                         lod.${lodname}.dom_stripesize_cur_kb)
25090         [[ $dom_current == $dom_limit ]] ||
25091                 error "Current DOM stripesize is not maximum"
25092         rm $dom
25093
25094         # set threshold for further tests
25095         do_facet mds1 $LCTL set_param -n \
25096                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
25097         echo "DOM threshold is $dom_threshold free space"
25098         local dom_def
25099         local dom_set
25100         # Spoof bfree to exceed threshold
25101         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
25102         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
25103         for spfree in 40 20 0 15 30 55; do
25104                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
25105                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
25106                         error "Failed to create $dom file"
25107                 dom_def=$(do_facet mds1 $LCTL get_param -n \
25108                                         lod.${lodname}.dom_stripesize_cur_kb)
25109                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
25110                 [[ $dom_def != $dom_current ]] ||
25111                         error "Default stripe size was not changed"
25112                 if (( spfree > 0 )) ; then
25113                         dom_set=$($LFS getstripe -S $dom)
25114                         (( dom_set == dom_def * 1024 )) ||
25115                                 error "DOM component size is still old"
25116                 else
25117                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
25118                                 error "DoM component is set with no free space"
25119                 fi
25120                 rm $dom
25121                 dom_current=$dom_def
25122         done
25123 }
25124 run_test 270g "DoM: default DoM stripe size depends on free space"
25125
25126 test_270h() {
25127         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
25128                 skip "Need MDS version at least 2.13.53"
25129
25130         local mdtname=${FSNAME}-MDT0000-mdtlov
25131         local dom=$DIR/$tdir/$tfile
25132         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25133
25134         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
25135         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25136
25137         $LFS mkdir -i 0 -c 1 $DIR/$tdir
25138         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
25139                 error "can't create OST file"
25140         # mirrored file with DOM entry in the second mirror
25141         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
25142                 error "can't create mirror with DoM component"
25143
25144         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
25145
25146         # DOM component in the middle and has other enries in the same mirror,
25147         # should succeed but lost DoM component
25148         $LFS setstripe --copy=${dom}_1 $dom ||
25149                 error "Can't create file from OST|DOM mirror layout"
25150         # check new file has no DoM layout after all
25151         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
25152                 error "File has DoM component while DoM is disabled"
25153 }
25154 run_test 270h "DoM: DoM stripe removal when disabled on server"
25155
25156 test_270i() {
25157         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
25158                 skip "Need MDS version at least 2.14.54"
25159
25160         mkdir $DIR/$tdir
25161         # DoM with plain layout
25162         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
25163                 error "default plain layout with DoM must fail"
25164         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
25165                 error "setstripe plain file layout with DoM must fail"
25166         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
25167                 error "default DoM layout with bad striping must fail"
25168         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
25169                 error "setstripe to DoM layout with bad striping must fail"
25170         return 0
25171 }
25172 run_test 270i "DoM: setting invalid DoM striping should fail"
25173
25174 test_270j() {
25175         (( $MDS1_VERSION >= $(version_code 2.15.55.203) )) ||
25176                 skip "Need MDS version at least 2.15.55.203"
25177
25178         local dom=$DIR/$tdir/$tfile
25179         local odv
25180         local ndv
25181
25182         mkdir -p $DIR/$tdir
25183
25184         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25185
25186         odv=$($LFS data_version $dom)
25187         chmod 666 $dom
25188         mv $dom ${dom}_moved
25189         link ${dom}_moved $dom
25190         setfattr -n user.attrx -v "some_attr" $dom
25191         ndv=$($LFS data_version $dom)
25192         (( $ndv == $odv )) ||
25193                 error "data version was changed by metadata operations"
25194
25195         dd if=/dev/urandom of=$dom bs=1M count=1 ||
25196                 error "failed to write data into $dom"
25197         cancel_lru_locks mdc
25198         ndv=$($LFS data_version $dom)
25199         (( $ndv != $odv )) ||
25200                 error "data version wasn't changed on write"
25201
25202         odv=$ndv
25203         $TRUNCATE $dom 1000 || error "failed to truncate $dom"
25204         ndv=$($LFS data_version $dom)
25205         (( $ndv != $odv )) ||
25206                 error "data version wasn't changed on truncate down"
25207
25208         odv=$ndv
25209         $TRUNCATE $dom 25000
25210         ndv=$($LFS data_version $dom)
25211         (( $ndv != $odv )) ||
25212                 error "data version wasn't changed on truncate up"
25213
25214         # check also fallocate for ldiskfs
25215         if [[ "$mds1_FSTYPE" == ldiskfs ]]; then
25216                 odv=$ndv
25217                 fallocate -l 1048576 $dom
25218                 ndv=$($LFS data_version $dom)
25219                 (( $ndv != $odv )) ||
25220                         error "data version wasn't changed on fallocate"
25221
25222                 odv=$ndv
25223                 fallocate -p --offset 4096 -l 4096 $dom
25224                 ndv=$($LFS data_version $dom)
25225                 (( $ndv != $odv )) ||
25226                         error "data version wasn't changed on fallocate punch"
25227         fi
25228 }
25229 run_test 270j "DoM migration: DOM file to the OST-striped file (plain)"
25230
25231 test_271a() {
25232         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25233                 skip "Need MDS version at least 2.10.55"
25234
25235         local dom=$DIR/$tdir/dom
25236
25237         mkdir -p $DIR/$tdir
25238
25239         $LFS setstripe -E 1024K -L mdt $dom
25240
25241         lctl set_param -n mdc.*.stats=clear
25242         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
25243         cat $dom > /dev/null
25244         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
25245         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
25246         ls $dom
25247         rm -f $dom
25248 }
25249 run_test 271a "DoM: data is cached for read after write"
25250
25251 test_271b() {
25252         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25253                 skip "Need MDS version at least 2.10.55"
25254
25255         local dom=$DIR/$tdir/dom
25256
25257         mkdir -p $DIR/$tdir
25258
25259         $LFS setstripe -E 1024K -L mdt -E EOF $dom
25260
25261         lctl set_param -n mdc.*.stats=clear
25262         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
25263         cancel_lru_locks mdc
25264         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
25265         # second stat to check size is cached on client
25266         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
25267         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
25268         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
25269         rm -f $dom
25270 }
25271 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
25272
25273 test_271ba() {
25274         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25275                 skip "Need MDS version at least 2.10.55"
25276
25277         local dom=$DIR/$tdir/dom
25278
25279         mkdir -p $DIR/$tdir
25280
25281         $LFS setstripe -E 1024K -L mdt -E EOF $dom
25282
25283         lctl set_param -n mdc.*.stats=clear
25284         lctl set_param -n osc.*.stats=clear
25285         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
25286         cancel_lru_locks mdc
25287         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
25288         # second stat to check size is cached on client
25289         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
25290         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
25291         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
25292         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
25293         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
25294         rm -f $dom
25295 }
25296 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
25297
25298
25299 get_mdc_stats() {
25300         local mdtidx=$1
25301         local param=$2
25302         local mdt=MDT$(printf %04x $mdtidx)
25303
25304         if [ -z $param ]; then
25305                 lctl get_param -n mdc.*$mdt*.stats
25306         else
25307                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
25308         fi
25309 }
25310
25311 test_271c() {
25312         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25313                 skip "Need MDS version at least 2.10.55"
25314
25315         local dom=$DIR/$tdir/dom
25316
25317         mkdir -p $DIR/$tdir
25318
25319         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25320
25321         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
25322         local facet=mds$((mdtidx + 1))
25323
25324         cancel_lru_locks mdc
25325         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
25326         createmany -o $dom 1000
25327         lctl set_param -n mdc.*.stats=clear
25328         smalliomany -w $dom 1000 200
25329         get_mdc_stats $mdtidx
25330         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
25331         # Each file has 1 open, 1 IO enqueues, total 2000
25332         # but now we have also +1 getxattr for security.capability, total 3000
25333         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
25334         unlinkmany $dom 1000
25335
25336         cancel_lru_locks mdc
25337         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
25338         createmany -o $dom 1000
25339         lctl set_param -n mdc.*.stats=clear
25340         smalliomany -w $dom 1000 200
25341         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
25342         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
25343         # for OPEN and IO lock.
25344         [ $((enq - enq_2)) -ge 1000 ] ||
25345                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
25346         unlinkmany $dom 1000
25347         return 0
25348 }
25349 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
25350
25351 cleanup_271def_tests() {
25352         trap 0
25353         rm -f $1
25354 }
25355
25356 test_271d() {
25357         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
25358                 skip "Need MDS version at least 2.10.57"
25359
25360         local dom=$DIR/$tdir/dom
25361         local tmp=$TMP/$tfile
25362         trap "cleanup_271def_tests $tmp" EXIT
25363
25364         mkdir -p $DIR/$tdir
25365
25366         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25367
25368         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
25369
25370         cancel_lru_locks mdc
25371         dd if=/dev/urandom of=$tmp bs=1000 count=1
25372         dd if=$tmp of=$dom bs=1000 count=1
25373         cancel_lru_locks mdc
25374
25375         cat /etc/hosts >> $tmp
25376         lctl set_param -n mdc.*.stats=clear
25377
25378         # append data to the same file it should update local page
25379         echo "Append to the same page"
25380         cat /etc/hosts >> $dom
25381         local num=$(get_mdc_stats $mdtidx ost_read)
25382         local ra=$(get_mdc_stats $mdtidx req_active)
25383         local rw=$(get_mdc_stats $mdtidx req_waittime)
25384
25385         [ -z $num ] || error "$num READ RPC occured"
25386         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25387         echo "... DONE"
25388
25389         # compare content
25390         cmp $tmp $dom || error "file miscompare"
25391
25392         cancel_lru_locks mdc
25393         lctl set_param -n mdc.*.stats=clear
25394
25395         echo "Open and read file"
25396         cat $dom > /dev/null
25397         local num=$(get_mdc_stats $mdtidx ost_read)
25398         local ra=$(get_mdc_stats $mdtidx req_active)
25399         local rw=$(get_mdc_stats $mdtidx req_waittime)
25400
25401         [ -z $num ] || error "$num READ RPC occured"
25402         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25403         echo "... DONE"
25404
25405         # compare content
25406         cmp $tmp $dom || error "file miscompare"
25407
25408         return 0
25409 }
25410 run_test 271d "DoM: read on open (1K file in reply buffer)"
25411
25412 test_271f() {
25413         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
25414                 skip "Need MDS version at least 2.10.57"
25415
25416         local dom=$DIR/$tdir/dom
25417         local tmp=$TMP/$tfile
25418         trap "cleanup_271def_tests $tmp" EXIT
25419
25420         mkdir -p $DIR/$tdir
25421
25422         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25423
25424         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
25425
25426         cancel_lru_locks mdc
25427         dd if=/dev/urandom of=$tmp bs=265000 count=1
25428         dd if=$tmp of=$dom bs=265000 count=1
25429         cancel_lru_locks mdc
25430         cat /etc/hosts >> $tmp
25431         lctl set_param -n mdc.*.stats=clear
25432
25433         echo "Append to the same page"
25434         cat /etc/hosts >> $dom
25435         local num=$(get_mdc_stats $mdtidx ost_read)
25436         local ra=$(get_mdc_stats $mdtidx req_active)
25437         local rw=$(get_mdc_stats $mdtidx req_waittime)
25438
25439         [ -z $num ] || error "$num READ RPC occured"
25440         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25441         echo "... DONE"
25442
25443         # compare content
25444         cmp $tmp $dom || error "file miscompare"
25445
25446         cancel_lru_locks mdc
25447         lctl set_param -n mdc.*.stats=clear
25448
25449         echo "Open and read file"
25450         cat $dom > /dev/null
25451         local num=$(get_mdc_stats $mdtidx ost_read)
25452         local ra=$(get_mdc_stats $mdtidx req_active)
25453         local rw=$(get_mdc_stats $mdtidx req_waittime)
25454
25455         [ -z $num ] && num=0
25456         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
25457         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25458         echo "... DONE"
25459
25460         # compare content
25461         cmp $tmp $dom || error "file miscompare"
25462
25463         return 0
25464 }
25465 run_test 271f "DoM: read on open (200K file and read tail)"
25466
25467 test_271g() {
25468         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
25469                 skip "Skipping due to old client or server version"
25470
25471         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
25472         # to get layout
25473         $CHECKSTAT -t file $DIR1/$tfile
25474
25475         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
25476         MULTIOP_PID=$!
25477         sleep 1
25478         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
25479         $LCTL set_param fail_loc=0x80000314
25480         rm $DIR1/$tfile || error "Unlink fails"
25481         RC=$?
25482         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
25483         [ $RC -eq 0 ] || error "Failed write to stale object"
25484 }
25485 run_test 271g "Discard DoM data vs client flush race"
25486
25487 test_272a() {
25488         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25489                 skip "Need MDS version at least 2.11.50"
25490
25491         local dom=$DIR/$tdir/dom
25492         mkdir -p $DIR/$tdir
25493
25494         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
25495         dd if=/dev/urandom of=$dom bs=512K count=1 ||
25496                 error "failed to write data into $dom"
25497         local old_md5=$(md5sum $dom)
25498
25499         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
25500                 error "failed to migrate to the same DoM component"
25501
25502         local new_md5=$(md5sum $dom)
25503
25504         [ "$old_md5" == "$new_md5" ] ||
25505                 error "md5sum differ: $old_md5, $new_md5"
25506
25507         [ $($LFS getstripe -c $dom) -eq 2 ] ||
25508                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
25509 }
25510 run_test 272a "DoM migration: new layout with the same DOM component"
25511
25512 test_272b() {
25513         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25514                 skip "Need MDS version at least 2.11.50"
25515
25516         local dom=$DIR/$tdir/dom
25517         mkdir -p $DIR/$tdir
25518         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25519         stack_trap "rm -rf $DIR/$tdir"
25520
25521         local mdtidx=$($LFS getstripe -m $dom)
25522         local mdtname=MDT$(printf %04x $mdtidx)
25523         local facet=mds$((mdtidx + 1))
25524
25525         local mdtfree1=$(do_facet $facet \
25526                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25527         dd if=/dev/urandom of=$dom bs=2M count=1 ||
25528                 error "failed to write data into $dom"
25529         local old_md5=$(md5sum $dom)
25530         cancel_lru_locks mdc
25531         local mdtfree1=$(do_facet $facet \
25532                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25533
25534         $LFS migrate -c2 $dom ||
25535                 error "failed to migrate to the new composite layout"
25536         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
25537                 error "MDT stripe was not removed"
25538         ! getfattr -n trusted.dataver $dom &> /dev/null ||
25539                 error "$dir1 shouldn't have DATAVER EA"
25540
25541         cancel_lru_locks mdc
25542         local new_md5=$(md5sum $dom)
25543         [ "$old_md5" == "$new_md5" ] ||
25544                 error "$old_md5 != $new_md5"
25545
25546         # Skip free space checks with ZFS
25547         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25548                 local mdtfree2=$(do_facet $facet \
25549                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25550                 [ $mdtfree2 -gt $mdtfree1 ] ||
25551                         error "MDT space is not freed after migration"
25552         fi
25553         return 0
25554 }
25555 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
25556
25557 test_272c() {
25558         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25559                 skip "Need MDS version at least 2.11.50"
25560
25561         local dom=$DIR/$tdir/$tfile
25562         mkdir -p $DIR/$tdir
25563         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25564         stack_trap "rm -rf $DIR/$tdir"
25565
25566         local mdtidx=$($LFS getstripe -m $dom)
25567         local mdtname=MDT$(printf %04x $mdtidx)
25568         local facet=mds$((mdtidx + 1))
25569
25570         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25571                 error "failed to write data into $dom"
25572         local old_md5=$(md5sum $dom)
25573         cancel_lru_locks mdc
25574         local mdtfree1=$(do_facet $facet \
25575                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25576
25577         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
25578                 error "failed to migrate to the new composite layout"
25579         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
25580                 error "MDT stripe was not removed"
25581
25582         cancel_lru_locks mdc
25583         local new_md5=$(md5sum $dom)
25584         [ "$old_md5" == "$new_md5" ] ||
25585                 error "$old_md5 != $new_md5"
25586
25587         # Skip free space checks with ZFS
25588         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25589                 local mdtfree2=$(do_facet $facet \
25590                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25591                 [ $mdtfree2 -gt $mdtfree1 ] ||
25592                         error "MDS space is not freed after migration"
25593         fi
25594         return 0
25595 }
25596 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
25597
25598 test_272d() {
25599         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25600                 skip "Need MDS version at least 2.12.55"
25601
25602         local dom=$DIR/$tdir/$tfile
25603         mkdir -p $DIR/$tdir
25604         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25605
25606         local mdtidx=$($LFS getstripe -m $dom)
25607         local mdtname=MDT$(printf %04x $mdtidx)
25608         local facet=mds$((mdtidx + 1))
25609
25610         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25611                 error "failed to write data into $dom"
25612         local old_md5=$(md5sum $dom)
25613         cancel_lru_locks mdc
25614         local mdtfree1=$(do_facet $facet \
25615                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25616
25617         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
25618                 error "failed mirroring to the new composite layout"
25619         $LFS mirror resync $dom ||
25620                 error "failed mirror resync"
25621         $LFS mirror split --mirror-id 1 -d $dom ||
25622                 error "failed mirror split"
25623
25624         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
25625                 error "MDT stripe was not removed"
25626
25627         cancel_lru_locks mdc
25628         local new_md5=$(md5sum $dom)
25629         [ "$old_md5" == "$new_md5" ] ||
25630                 error "$old_md5 != $new_md5"
25631
25632         # Skip free space checks with ZFS
25633         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25634                 local mdtfree2=$(do_facet $facet \
25635                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25636                 [ $mdtfree2 -gt $mdtfree1 ] ||
25637                         error "MDS space is not freed after DOM mirror deletion"
25638         fi
25639         return 0
25640 }
25641 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
25642
25643 test_272e() {
25644         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25645                 skip "Need MDS version at least 2.12.55"
25646
25647         local dom=$DIR/$tdir/$tfile
25648         mkdir -p $DIR/$tdir
25649         $LFS setstripe -c 2 $dom
25650
25651         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25652                 error "failed to write data into $dom"
25653         local old_md5=$(md5sum $dom)
25654         cancel_lru_locks
25655
25656         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
25657                 error "failed mirroring to the DOM layout"
25658         $LFS mirror resync $dom ||
25659                 error "failed mirror resync"
25660         $LFS mirror split --mirror-id 1 -d $dom ||
25661                 error "failed mirror split"
25662
25663         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25664                 error "MDT stripe wasn't set"
25665
25666         cancel_lru_locks
25667         local new_md5=$(md5sum $dom)
25668         [ "$old_md5" == "$new_md5" ] ||
25669                 error "$old_md5 != $new_md5"
25670
25671         return 0
25672 }
25673 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
25674
25675 test_272f() {
25676         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25677                 skip "Need MDS version at least 2.12.55"
25678
25679         local dom=$DIR/$tdir/$tfile
25680         mkdir -p $DIR/$tdir
25681         $LFS setstripe -c 2 $dom
25682
25683         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25684                 error "failed to write data into $dom"
25685         local old_md5=$(md5sum $dom)
25686         cancel_lru_locks
25687
25688         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
25689                 error "failed migrating to the DOM file"
25690
25691         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25692                 error "MDT stripe wasn't set"
25693
25694         cancel_lru_locks
25695         local new_md5=$(md5sum $dom)
25696         [ "$old_md5" != "$new_md5" ] &&
25697                 error "$old_md5 != $new_md5"
25698
25699         return 0
25700 }
25701 run_test 272f "DoM migration: OST-striped file to DOM file"
25702
25703 test_273a() {
25704         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25705                 skip "Need MDS version at least 2.11.50"
25706
25707         # Layout swap cannot be done if either file has DOM component,
25708         # this will never be supported, migration should be used instead
25709
25710         local dom=$DIR/$tdir/$tfile
25711         mkdir -p $DIR/$tdir
25712
25713         $LFS setstripe -c2 ${dom}_plain
25714         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
25715         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
25716                 error "can swap layout with DoM component"
25717         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
25718                 error "can swap layout with DoM component"
25719
25720         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
25721         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
25722                 error "can swap layout with DoM component"
25723         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
25724                 error "can swap layout with DoM component"
25725         return 0
25726 }
25727 run_test 273a "DoM: layout swapping should fail with DOM"
25728
25729 test_273b() {
25730         mkdir -p $DIR/$tdir
25731         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
25732
25733 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
25734         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
25735
25736         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25737 }
25738 run_test 273b "DoM: race writeback and object destroy"
25739
25740 test_273c() {
25741         mkdir -p $DIR/$tdir
25742         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
25743
25744         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
25745         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
25746
25747         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25748 }
25749 run_test 273c "race writeback and object destroy"
25750
25751 test_275() {
25752         remote_ost_nodsh && skip "remote OST with nodsh"
25753         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
25754                 skip "Need OST version >= 2.10.57"
25755
25756         local file=$DIR/$tfile
25757         local oss
25758
25759         oss=$(comma_list $(osts_nodes))
25760
25761         dd if=/dev/urandom of=$file bs=1M count=2 ||
25762                 error "failed to create a file"
25763         stack_trap "rm -f $file"
25764         cancel_lru_locks osc
25765
25766         #lock 1
25767         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25768                 error "failed to read a file"
25769
25770 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
25771         $LCTL set_param fail_loc=0x8000031f
25772
25773         cancel_lru_locks osc &
25774         sleep 1
25775
25776 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
25777         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
25778         #IO takes another lock, but matches the PENDING one
25779         #and places it to the IO RPC
25780         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25781                 error "failed to read a file with PENDING lock"
25782 }
25783 run_test 275 "Read on a canceled duplicate lock"
25784
25785 test_276() {
25786         remote_ost_nodsh && skip "remote OST with nodsh"
25787         local pid
25788
25789         do_facet ost1 "(while true; do \
25790                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
25791                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
25792         pid=$!
25793
25794         for LOOP in $(seq 20); do
25795                 stop ost1
25796                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
25797         done
25798         kill -9 $pid
25799         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
25800                 rm $TMP/sanity_276_pid"
25801 }
25802 run_test 276 "Race between mount and obd_statfs"
25803
25804 test_277() {
25805         $LCTL set_param ldlm.namespaces.*.lru_size=0
25806         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25807         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25808                           awk '/^used_mb/ { print $2 }')
25809         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
25810         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
25811                 oflag=direct conv=notrunc
25812         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25813                     awk '/^used_mb/ { print $2 }')
25814         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
25815 }
25816 run_test 277 "Direct IO shall drop page cache"
25817
25818 test_278() {
25819         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
25820         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25821         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
25822                 skip "needs the same host for mdt1 mdt2" && return
25823
25824         local pid1
25825         local pid2
25826
25827 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
25828         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
25829         stop mds2 &
25830         pid2=$!
25831
25832         stop mds1
25833
25834         echo "Starting MDTs"
25835         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
25836         wait $pid2
25837 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
25838 #will return NULL
25839         do_facet mds2 $LCTL set_param fail_loc=0
25840
25841         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
25842         wait_recovery_complete mds2
25843 }
25844 run_test 278 "Race starting MDS between MDTs stop/start"
25845
25846 test_280() {
25847         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
25848                 skip "Need MGS version at least 2.13.52"
25849         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25850         combined_mgs_mds || skip "needs combined MGS/MDT"
25851
25852         umount_client $MOUNT
25853 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
25854         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
25855
25856         mount_client $MOUNT &
25857         sleep 1
25858         stop mgs || error "stop mgs failed"
25859         #for a race mgs would crash
25860         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
25861         # make sure we unmount client before remounting
25862         wait
25863         umount_client $MOUNT
25864         mount_client $MOUNT || error "mount client failed"
25865 }
25866 run_test 280 "Race between MGS umount and client llog processing"
25867
25868 cleanup_test_300() {
25869         trap 0
25870         umask $SAVE_UMASK
25871 }
25872
25873 test_striped_dir() {
25874         local mdt_index=$1
25875         local stripe_count=$2
25876         local overstriping=$3
25877         local stripe_index
25878         local getstripe_count
25879
25880         mkdir -p $DIR/$tdir
25881
25882         SAVE_UMASK=$(umask)
25883         trap cleanup_test_300 RETURN EXIT
25884
25885         if [ -z $overstriping ]; then
25886                 $LFS setdirstripe -i $mdt_index -c $stripe_count -H all_char \
25887                                         -o 755 $DIR/$tdir/striped_dir ||
25888                         error "set striped dir error"
25889         else
25890                 $LFS setdirstripe -i $mdt_index -C $stripe_count -H all_char \
25891                                         -o 755 $DIR/$tdir/striped_dir ||
25892                         error "set striped dir error"
25893         fi
25894
25895         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
25896         [ "$mode" = "755" ] || error "expect 755 got $mode"
25897
25898         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
25899                 error "getdirstripe failed"
25900         getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
25901         if [ "$getstripe_count" != "$stripe_count" ]; then
25902                 error "1:stripe_count is $getstripe_count, expect $stripe_count"
25903         fi
25904         getstripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
25905         if [ "$getstripe_count" != "$stripe_count" ]; then
25906                 error "2:stripe_count is $getstripe_count, expect $stripe_count"
25907         fi
25908
25909         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
25910         if [ "$stripe_index" != "$mdt_index" ]; then
25911                 error "stripe_index is $stripe_index, expect $mdt_index"
25912         fi
25913
25914         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25915                 error "nlink error after create striped dir"
25916
25917         mkdir $DIR/$tdir/striped_dir/a
25918         mkdir $DIR/$tdir/striped_dir/b
25919
25920         stat $DIR/$tdir/striped_dir/a ||
25921                 error "create dir under striped dir failed"
25922         stat $DIR/$tdir/striped_dir/b ||
25923                 error "create dir under striped dir failed"
25924
25925         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
25926                 error "nlink error after mkdir"
25927
25928         rmdir $DIR/$tdir/striped_dir/a
25929         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
25930                 error "nlink error after rmdir"
25931
25932         rmdir $DIR/$tdir/striped_dir/b
25933         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25934                 error "nlink error after rmdir"
25935
25936         chattr +i $DIR/$tdir/striped_dir
25937         createmany -o $DIR/$tdir/striped_dir/f 10 &&
25938                 error "immutable flags not working under striped dir!"
25939         chattr -i $DIR/$tdir/striped_dir
25940
25941         rmdir $DIR/$tdir/striped_dir ||
25942                 error "rmdir striped dir error"
25943
25944         cleanup_test_300
25945
25946         true
25947 }
25948
25949 test_300a() {
25950         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25951                 skip "skipped for lustre < 2.7.0"
25952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25953         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25954
25955         test_striped_dir 0 2 || error "failed on striped dir on MDT0"
25956         test_striped_dir 1 2 || error "failed on striped dir on MDT0"
25957 }
25958 run_test 300a "basic striped dir sanity test"
25959
25960 test_300b() {
25961         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25962                 skip "skipped for lustre < 2.7.0"
25963         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25964         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25965
25966         local i
25967         local mtime1
25968         local mtime2
25969         local mtime3
25970
25971         test_mkdir $DIR/$tdir || error "mkdir fail"
25972         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25973                 error "set striped dir error"
25974         for i in {0..9}; do
25975                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
25976                 sleep 1
25977                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
25978                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
25979                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
25980                 sleep 1
25981                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
25982                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
25983                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
25984         done
25985         true
25986 }
25987 run_test 300b "check ctime/mtime for striped dir"
25988
25989 test_300c() {
25990         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25991                 skip "skipped for lustre < 2.7.0"
25992         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25993         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25994
25995         local file_count
25996
25997         mkdir_on_mdt0 $DIR/$tdir
25998         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
25999                 error "set striped dir error"
26000
26001         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
26002                 error "chown striped dir failed"
26003
26004         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
26005                 error "create 5k files failed"
26006
26007         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
26008
26009         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
26010
26011         rm -rf $DIR/$tdir
26012 }
26013 run_test 300c "chown && check ls under striped directory"
26014
26015 test_300d() {
26016         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
26017                 skip "skipped for lustre < 2.7.0"
26018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26019         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26020
26021         local stripe_count
26022         local file
26023
26024         mkdir -p $DIR/$tdir
26025         $LFS setstripe -c 2 $DIR/$tdir
26026
26027         #local striped directory
26028         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
26029                 error "set striped dir error"
26030         #look at the directories for debug purposes
26031         ls -l $DIR/$tdir
26032         $LFS getdirstripe $DIR/$tdir
26033         ls -l $DIR/$tdir/striped_dir
26034         $LFS getdirstripe $DIR/$tdir/striped_dir
26035         createmany -o $DIR/$tdir/striped_dir/f 10 ||
26036                 error "create 10 files failed"
26037
26038         #remote striped directory
26039         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
26040                 error "set striped dir error"
26041         #look at the directories for debug purposes
26042         ls -l $DIR/$tdir
26043         $LFS getdirstripe $DIR/$tdir
26044         ls -l $DIR/$tdir/remote_striped_dir
26045         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
26046         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
26047                 error "create 10 files failed"
26048
26049         for file in $(find $DIR/$tdir); do
26050                 stripe_count=$($LFS getstripe -c $file)
26051                 [ $stripe_count -eq 2 ] ||
26052                         error "wrong stripe $stripe_count for $file"
26053         done
26054
26055         rm -rf $DIR/$tdir
26056 }
26057 run_test 300d "check default stripe under striped directory"
26058
26059 test_300e() {
26060         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26061                 skip "Need MDS version at least 2.7.55"
26062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26063         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26064
26065         local stripe_count
26066         local file
26067
26068         mkdir -p $DIR/$tdir
26069
26070         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
26071                 error "set striped dir error"
26072
26073         touch $DIR/$tdir/striped_dir/a
26074         touch $DIR/$tdir/striped_dir/b
26075         touch $DIR/$tdir/striped_dir/c
26076
26077         mkdir $DIR/$tdir/striped_dir/dir_a
26078         mkdir $DIR/$tdir/striped_dir/dir_b
26079         mkdir $DIR/$tdir/striped_dir/dir_c
26080
26081         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
26082                 error "set striped adir under striped dir error"
26083
26084         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
26085                 error "set striped bdir under striped dir error"
26086
26087         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
26088                 error "set striped cdir under striped dir error"
26089
26090         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
26091                 error "rename dir under striped dir fails"
26092
26093         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
26094                 error "rename dir under different stripes fails"
26095
26096         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
26097                 error "rename file under striped dir should succeed"
26098
26099         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
26100                 error "rename dir under striped dir should succeed"
26101
26102         rm -rf $DIR/$tdir
26103 }
26104 run_test 300e "check rename under striped directory"
26105
26106 test_300f() {
26107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26108         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26109         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26110                 skip "Need MDS version at least 2.7.55"
26111
26112         local stripe_count
26113         local file
26114
26115         rm -rf $DIR/$tdir
26116         mkdir -p $DIR/$tdir
26117
26118         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
26119                 error "set striped dir error"
26120
26121         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
26122                 error "set striped dir error"
26123
26124         touch $DIR/$tdir/striped_dir/a
26125         mkdir $DIR/$tdir/striped_dir/dir_a
26126         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
26127                 error "create striped dir under striped dir fails"
26128
26129         touch $DIR/$tdir/striped_dir1/b
26130         mkdir $DIR/$tdir/striped_dir1/dir_b
26131         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
26132                 error "create striped dir under striped dir fails"
26133
26134         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
26135                 error "rename dir under different striped dir should fail"
26136
26137         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
26138                 error "rename striped dir under diff striped dir should fail"
26139
26140         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
26141                 error "rename file under diff striped dirs fails"
26142
26143         rm -rf $DIR/$tdir
26144 }
26145 run_test 300f "check rename cross striped directory"
26146
26147 test_300_check_default_striped_dir()
26148 {
26149         local dirname=$1
26150         local default_count=$2
26151         local default_index=$3
26152         local stripe_count
26153         local stripe_index
26154         local dir_stripe_index
26155         local dir
26156
26157         echo "checking $dirname $default_count $default_index"
26158         $LFS setdirstripe -D -c $default_count -i $default_index \
26159                                 -H all_char $DIR/$tdir/$dirname ||
26160                 error "set default stripe on striped dir error"
26161         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
26162         [ $stripe_count -eq $default_count ] ||
26163                 error "expect $default_count get $stripe_count for $dirname"
26164
26165         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
26166         [ $stripe_index -eq $default_index ] ||
26167                 error "expect $default_index get $stripe_index for $dirname"
26168
26169         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
26170                                                 error "create dirs failed"
26171
26172         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
26173         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
26174         for dir in $(find $DIR/$tdir/$dirname/*); do
26175                 stripe_count=$($LFS getdirstripe -c $dir)
26176                 (( $stripe_count == $default_count )) ||
26177                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
26178                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
26179                 error "stripe count $default_count != $stripe_count for $dir"
26180
26181                 stripe_index=$($LFS getdirstripe -i $dir)
26182                 [ $default_index -eq -1 ] ||
26183                         [ $stripe_index -eq $default_index ] ||
26184                         error "$stripe_index != $default_index for $dir"
26185
26186                 #check default stripe
26187                 stripe_count=$($LFS getdirstripe -D -c $dir)
26188                 [ $stripe_count -eq $default_count ] ||
26189                 error "default count $default_count != $stripe_count for $dir"
26190
26191                 stripe_index=$($LFS getdirstripe -D -i $dir)
26192                 [ $stripe_index -eq $default_index ] ||
26193                 error "default index $default_index != $stripe_index for $dir"
26194         done
26195         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
26196 }
26197
26198 test_300g() {
26199         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26200         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26201                 skip "Need MDS version at least 2.7.55"
26202
26203         local dir
26204         local stripe_count
26205         local stripe_index
26206
26207         mkdir_on_mdt0 $DIR/$tdir
26208         mkdir $DIR/$tdir/normal_dir
26209
26210         #Checking when client cache stripe index
26211         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26212         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
26213                 error "create striped_dir failed"
26214
26215         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
26216                 error "create dir0 fails"
26217         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
26218         [ $stripe_index -eq 0 ] ||
26219                 error "dir0 expect index 0 got $stripe_index"
26220
26221         mkdir $DIR/$tdir/striped_dir/dir1 ||
26222                 error "create dir1 fails"
26223         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
26224         [ $stripe_index -eq 1 ] ||
26225                 error "dir1 expect index 1 got $stripe_index"
26226
26227         #check default stripe count/stripe index
26228         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
26229         test_300_check_default_striped_dir normal_dir 1 0
26230         test_300_check_default_striped_dir normal_dir -1 1
26231         test_300_check_default_striped_dir normal_dir 2 -1
26232
26233         #delete default stripe information
26234         echo "delete default stripeEA"
26235         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
26236                 error "set default stripe on striped dir error"
26237
26238         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
26239         for dir in $(find $DIR/$tdir/normal_dir/*); do
26240                 stripe_count=$($LFS getdirstripe -c $dir)
26241                 [ $stripe_count -eq 0 ] ||
26242                         error "expect 1 get $stripe_count for $dir"
26243         done
26244 }
26245 run_test 300g "check default striped directory for normal directory"
26246
26247 test_300h() {
26248         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26249         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26250                 skip "Need MDS version at least 2.7.55"
26251
26252         local dir
26253         local stripe_count
26254
26255         mkdir $DIR/$tdir
26256         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
26257                 error "set striped dir error"
26258
26259         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
26260         test_300_check_default_striped_dir striped_dir 1 0
26261         test_300_check_default_striped_dir striped_dir -1 1
26262         test_300_check_default_striped_dir striped_dir 2 -1
26263
26264         #delete default stripe information
26265         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
26266                 error "set default stripe on striped dir error"
26267
26268         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
26269         for dir in $(find $DIR/$tdir/striped_dir/*); do
26270                 stripe_count=$($LFS getdirstripe -c $dir)
26271                 [ $stripe_count -eq 0 ] ||
26272                         error "expect 1 get $stripe_count for $dir"
26273         done
26274 }
26275 run_test 300h "check default striped directory for striped directory"
26276
26277 test_300i() {
26278         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
26279         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
26280         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
26281                 skip "Need MDS version at least 2.7.55"
26282
26283         local stripe_count
26284         local file
26285
26286         mkdir $DIR/$tdir
26287
26288         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
26289                 error "set striped dir error"
26290
26291         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
26292                 error "create files under striped dir failed"
26293
26294         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
26295                 error "set striped hashdir error"
26296
26297         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
26298                 error "create dir0 under hash dir failed"
26299         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
26300                 error "create dir1 under hash dir failed"
26301         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
26302                 error "create dir2 under hash dir failed"
26303
26304         # unfortunately, we need to umount to clear dir layout cache for now
26305         # once we fully implement dir layout, we can drop this
26306         umount_client $MOUNT || error "umount failed"
26307         mount_client $MOUNT || error "mount failed"
26308
26309         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
26310         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
26311         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
26312
26313         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
26314                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
26315                         error "create crush2 dir $tdir/hashdir/d3 failed"
26316                 $LFS find -H crush2 $DIR/$tdir/hashdir
26317                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
26318                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
26319
26320                 # mkdir with an invalid hash type (hash=fail_val) from client
26321                 # should be replaced on MDS with a valid (default) hash type
26322                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
26323                 $LCTL set_param fail_loc=0x1901 fail_val=99
26324                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
26325
26326                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
26327                 local expect=$(do_facet mds1 \
26328                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
26329                 [[ $hash == $expect ]] ||
26330                         error "d99 hash '$hash' != expected hash '$expect'"
26331         fi
26332
26333         #set the stripe to be unknown hash type on read
26334         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
26335         $LCTL set_param fail_loc=0x1901 fail_val=99
26336         for ((i = 0; i < 10; i++)); do
26337                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
26338                         error "stat f-$i failed"
26339                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
26340         done
26341
26342         touch $DIR/$tdir/striped_dir/f0 &&
26343                 error "create under striped dir with unknown hash should fail"
26344
26345         $LCTL set_param fail_loc=0
26346
26347         umount_client $MOUNT || error "umount failed"
26348         mount_client $MOUNT || error "mount failed"
26349
26350         return 0
26351 }
26352 run_test 300i "client handle unknown hash type striped directory"
26353
26354 test_300j() {
26355         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26356         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26357         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26358                 skip "Need MDS version at least 2.7.55"
26359
26360         local stripe_count
26361         local file
26362
26363         mkdir $DIR/$tdir
26364
26365         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
26366         $LCTL set_param fail_loc=0x1702
26367         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
26368                 error "set striped dir error"
26369
26370         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
26371                 error "create files under striped dir failed"
26372
26373         $LCTL set_param fail_loc=0
26374
26375         rm -rf $DIR/$tdir || error "unlink striped dir fails"
26376
26377         return 0
26378 }
26379 run_test 300j "test large update record"
26380
26381 test_300k() {
26382         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26383         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26384         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26385                 skip "Need MDS version at least 2.7.55"
26386
26387         # this test needs a huge transaction
26388         local kb
26389         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
26390              osd*.$FSNAME-MDT0000.kbytestotal")
26391         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
26392
26393         local stripe_count
26394         local file
26395
26396         mkdir $DIR/$tdir
26397
26398         #define OBD_FAIL_LARGE_STRIPE   0x1703
26399         $LCTL set_param fail_loc=0x1703
26400         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
26401                 error "set striped dir error"
26402         $LCTL set_param fail_loc=0
26403
26404         $LFS getdirstripe $DIR/$tdir/striped_dir ||
26405                 error "getstripeddir fails"
26406         rm -rf $DIR/$tdir/striped_dir ||
26407                 error "unlink striped dir fails"
26408
26409         return 0
26410 }
26411 run_test 300k "test large striped directory"
26412
26413 test_300l() {
26414         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26415         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26416         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26417                 skip "Need MDS version at least 2.7.55"
26418
26419         local stripe_index
26420
26421         test_mkdir -p $DIR/$tdir/striped_dir
26422         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
26423                         error "chown $RUNAS_ID failed"
26424         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
26425                 error "set default striped dir failed"
26426
26427         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
26428         $LCTL set_param fail_loc=0x80000158
26429         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
26430
26431         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
26432         [ $stripe_index -eq 1 ] ||
26433                 error "expect 1 get $stripe_index for $dir"
26434 }
26435 run_test 300l "non-root user to create dir under striped dir with stale layout"
26436
26437 test_300m() {
26438         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26439         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
26440         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26441                 skip "Need MDS version at least 2.7.55"
26442
26443         mkdir -p $DIR/$tdir/striped_dir
26444         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
26445                 error "set default stripes dir error"
26446
26447         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
26448
26449         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
26450         [ $stripe_count -eq 0 ] ||
26451                         error "expect 0 get $stripe_count for a"
26452
26453         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
26454                 error "set default stripes dir error"
26455
26456         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
26457
26458         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
26459         [ $stripe_count -eq 0 ] ||
26460                         error "expect 0 get $stripe_count for b"
26461
26462         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
26463                 error "set default stripes dir error"
26464
26465         mkdir $DIR/$tdir/striped_dir/c &&
26466                 error "default stripe_index is invalid, mkdir c should fails"
26467
26468         rm -rf $DIR/$tdir || error "rmdir fails"
26469 }
26470 run_test 300m "setstriped directory on single MDT FS"
26471
26472 cleanup_300n() {
26473         local list=$(comma_list $(mdts_nodes))
26474
26475         trap 0
26476         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26477 }
26478
26479 test_300n() {
26480         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26481         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26482         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26483                 skip "Need MDS version at least 2.7.55"
26484         remote_mds_nodsh && skip "remote MDS with nodsh"
26485
26486         local stripe_index
26487         local list=$(comma_list $(mdts_nodes))
26488
26489         trap cleanup_300n RETURN EXIT
26490         mkdir -p $DIR/$tdir
26491         chmod 777 $DIR/$tdir
26492         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
26493                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
26494                 error "create striped dir succeeds with gid=0"
26495
26496         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
26497         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
26498                 error "create striped dir fails with gid=-1"
26499
26500         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26501         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
26502                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
26503                 error "set default striped dir succeeds with gid=0"
26504
26505
26506         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
26507         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
26508                 error "set default striped dir fails with gid=-1"
26509
26510
26511         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26512         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
26513                                         error "create test_dir fails"
26514         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
26515                                         error "create test_dir1 fails"
26516         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
26517                                         error "create test_dir2 fails"
26518         cleanup_300n
26519 }
26520 run_test 300n "non-root user to create dir under striped dir with default EA"
26521
26522 test_300o() {
26523         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26524         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26525         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26526                 skip "Need MDS version at least 2.7.55"
26527
26528         local numfree1
26529         local numfree2
26530
26531         mkdir -p $DIR/$tdir
26532
26533         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
26534         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
26535         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
26536                 skip "not enough free inodes $numfree1 $numfree2"
26537         fi
26538
26539         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
26540         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
26541         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
26542                 skip "not enough free space $numfree1 $numfree2"
26543         fi
26544
26545         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
26546                 error "setdirstripe fails"
26547
26548         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
26549                 error "create dirs fails"
26550
26551         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
26552         ls $DIR/$tdir/striped_dir > /dev/null ||
26553                 error "ls striped dir fails"
26554         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
26555                 error "unlink big striped dir fails"
26556 }
26557 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
26558
26559 test_300p() {
26560         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26561         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26562         remote_mds_nodsh && skip "remote MDS with nodsh"
26563
26564         mkdir_on_mdt0 $DIR/$tdir
26565
26566         #define OBD_FAIL_OUT_ENOSPC     0x1704
26567         do_facet mds2 lctl set_param fail_loc=0x80001704
26568         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
26569                  && error "create striped directory should fail"
26570
26571         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
26572
26573         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
26574         true
26575 }
26576 run_test 300p "create striped directory without space"
26577
26578 test_300q() {
26579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26580         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26581
26582         local fd=$(free_fd)
26583         local cmd="exec $fd<$tdir"
26584         cd $DIR
26585         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
26586         eval $cmd
26587         cmd="exec $fd<&-"
26588         trap "eval $cmd" EXIT
26589         cd $tdir || error "cd $tdir fails"
26590         rmdir  ../$tdir || error "rmdir $tdir fails"
26591         mkdir local_dir && error "create dir succeeds"
26592         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
26593         eval $cmd
26594         return 0
26595 }
26596 run_test 300q "create remote directory under orphan directory"
26597
26598 test_300r() {
26599         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26600                 skip "Need MDS version at least 2.7.55" && return
26601         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
26602
26603         mkdir $DIR/$tdir
26604
26605         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
26606                 error "set striped dir error"
26607
26608         $LFS getdirstripe $DIR/$tdir/striped_dir ||
26609                 error "getstripeddir fails"
26610
26611         local stripe_count
26612         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
26613                       awk '/lmv_stripe_count:/ { print $2 }')
26614
26615         [ $MDSCOUNT -ne $stripe_count ] &&
26616                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
26617
26618         rm -rf $DIR/$tdir/striped_dir ||
26619                 error "unlink striped dir fails"
26620 }
26621 run_test 300r "test -1 striped directory"
26622
26623 test_300s_helper() {
26624         local count=$1
26625
26626         local stripe_dir=$DIR/$tdir/striped_dir.$count
26627
26628         $LFS mkdir -c $count $stripe_dir ||
26629                 error "lfs mkdir -c error"
26630
26631         $LFS getdirstripe $stripe_dir ||
26632                 error "lfs getdirstripe fails"
26633
26634         local stripe_count
26635         stripe_count=$($LFS getdirstripe $stripe_dir |
26636                       awk '/lmv_stripe_count:/ { print $2 }')
26637
26638         [ $count -ne $stripe_count ] &&
26639                 error_noexit "bad stripe count $stripe_count expected $count"
26640
26641         local dupe_stripes
26642         dupe_stripes=$($LFS getdirstripe $stripe_dir |
26643                 awk '/0x/ {count[$1] += 1}; END {
26644                         for (idx in count) {
26645                                 if (count[idx]>1) {
26646                                         print "index " idx " count " count[idx]
26647                                 }
26648                         }
26649                 }')
26650
26651         if [[ -n "$dupe_stripes" ]] ; then
26652                 lfs getdirstripe $stripe_dir
26653                 error_noexit "Dupe MDT above: $dupe_stripes "
26654         fi
26655
26656         rm -rf $stripe_dir ||
26657                 error_noexit "unlink $stripe_dir fails"
26658 }
26659
26660 test_300s() {
26661         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26662                 skip "Need MDS version at least 2.7.55" && return
26663         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
26664
26665         mkdir $DIR/$tdir
26666         for count in $(seq 2 $MDSCOUNT); do
26667                 test_300s_helper $count
26668         done
26669 }
26670 run_test 300s "test lfs mkdir -c without -i"
26671
26672 test_300t() {
26673         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
26674                 skip "need MDS 2.14.55 or later"
26675         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
26676
26677         local testdir="$DIR/$tdir/striped_dir"
26678         local dir1=$testdir/dir1
26679         local dir2=$testdir/dir2
26680
26681         mkdir -p $testdir
26682
26683         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
26684                 error "failed to set default stripe count for $testdir"
26685
26686         mkdir $dir1
26687         local stripe_count=$($LFS getdirstripe -c $dir1)
26688
26689         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
26690
26691         local max_count=$((MDSCOUNT - 1))
26692         local mdts=$(comma_list $(mdts_nodes))
26693
26694         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
26695         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
26696
26697         mkdir $dir2
26698         stripe_count=$($LFS getdirstripe -c $dir2)
26699
26700         (( $stripe_count == $max_count )) || error "wrong stripe count"
26701 }
26702 run_test 300t "test max_mdt_stripecount"
26703
26704 MDT_OVSTRP_VER="2.15.60"
26705 # 300u family tests MDT overstriping
26706 test_300ua() {
26707         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26708
26709         local setcount=$((MDSCOUNT * 2))
26710
26711         local expected_count
26712
26713         mkdir $DIR/$tdir
26714         $LFS setdirstripe -C $setcount $DIR/$tdir/${tdir}.0 ||
26715                 error "(0) failed basic overstriped dir creation test"
26716         local getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.0)
26717
26718         # This does a basic interop test - if the MDS does not support mdt
26719         # overstriping, we should get stripes == number of MDTs
26720         if (( $MDS1_VERSION < $(version_code $MDT_OVSTRP_VER) )); then
26721                 expected_count=$MDSCOUNT
26722         else
26723                 expected_count=$setcount
26724         fi
26725         (( getstripe_count == expected_count )) ||
26726                 error "(1) incorrect stripe count for simple overstriped dir"
26727
26728         rm -rf $DIR/$tdir/${tdir}.0 ||
26729                 error "(2) unable to rm overstriped dir"
26730
26731         # Tests after this require overstriping support
26732         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26733                 { echo "skipped for MDS < $MDT_OVSTRP_VER"; return 0; }
26734
26735         test_striped_dir 0 $setcount true ||
26736                 error "(3)failed on overstriped dir"
26737         test_striped_dir 1 $setcount true ||
26738                 error "(4)failed on overstriped dir"
26739
26740         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26741
26742         test_striped_dir 0 $setcount true ||
26743                 error "(5)failed on overstriped dir"
26744 }
26745 run_test 300ua "basic overstriped dir sanity test"
26746
26747 test_300ub() {
26748         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26749                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26750         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26751
26752         mkdir $DIR/$tdir
26753
26754         echo "Testing invalid stripe count, failure expected"
26755         local setcount=$((MDSCOUNT * 2))
26756
26757         $LFS setdirstripe -c $setcount $DIR/$tdir/${tdir}.0
26758         local getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.0)
26759
26760         (( getstripe_count <= MDSCOUNT )) ||
26761                 error "(0)stripe count ($setcount) > MDT count ($MDSCOUNT) succeeded with -c"
26762
26763         # When a user requests > LMV_MAX_STRIPES_PER_MDT, we reduce to that
26764         setcount=$((MDSCOUNT * 2 * LMV_MAX_STRIPES_PER_MDT))
26765         $LFS setdirstripe -C $setcount $DIR/$tdir/${tdir}.1
26766
26767         local maxcount=$((MDSCOUNT * LMV_MAX_STRIPES_PER_MDT))
26768
26769         getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.1)
26770         (( getstripe_count == maxcount )) ||
26771                 error "(1)stripe_count is $getstripe_count, expect $maxcount"
26772
26773         # Test specific striping with -i
26774         $LFS setdirstripe -i 0,0,0,0 $DIR/$tdir/${tdir}.2
26775
26776         getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.2)
26777         (( getstripe_count == 4 )) ||
26778                 error "(2)stripe_count is $getstripe_count, expect 4"
26779
26780         local nonzeroindices=$($LFS getdirstripe $DIR/$tdir/${tdir}.2 | grep "\[" | \
26781                                grep -v mdtidx | awk '{print $1}' | grep -c -v 0)
26782
26783         [[ -n "$nonzeroindices" ]] ||
26784                 error "(3) stripes indices not all 0: $nonzeroindices"
26785
26786         # Test specific striping with too many stripes on one MDT
26787         echo "Testing invalid striping, failure expected"
26788         $LFS setdirstripe -i 0,1,0,1,0,1,0,1,0,1,0 $DIR/$tdir/${tdir}.3
26789         $LFS getdirstripe $DIR/$tdir/${tdir}.3
26790         getstripe_count=$($LFS getdirstripe $DIR/$tdir/${tdir}.3 | grep "\[" | \
26791                           grep -v mdtidx | awk '{print $1}' | grep -c '0')
26792         echo "stripes on MDT0: $getstripe_count"
26793         (( getstripe_count <= LMV_MAX_STRIPES_PER_MDT )) ||
26794                 error "(4) setstripe with too many stripes on MDT0 succeeded"
26795
26796         setcount=$((MDSCOUNT * 2))
26797         $LFS setdirstripe -C $setcount -H all_char $DIR/${tdir}.4 ||
26798                 error "(5) can't setdirstripe with manually set hash function"
26799
26800         getstripe_count=$($LFS getdirstripe -c $DIR/${tdir}.4)
26801         (( getstripe_count == setcount )) ||
26802                 error "(6)stripe_count is $getstripe_count, expect $setcount"
26803
26804         setcount=$((MDSCOUNT * 2))
26805         mkdir $DIR/${tdir}.5
26806         $LFS setdirstripe -C $setcount -D -H crush $DIR/${tdir}.5 ||
26807                 error "(7) can't setdirstripe with manually set hash function"
26808         mkdir $DIR/${tdir}.5/${tdir}.6
26809
26810         getstripe_count=$($LFS getdirstripe -c $DIR/${tdir}.5/${tdir}.6)
26811         (( getstripe_count == setcount )) ||
26812                 error "(8)stripe_count is $getstripe_count, expect $setcount"
26813 }
26814 run_test 300ub "test MDT overstriping interface & limits"
26815
26816 test_300uc() {
26817         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26818                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26819         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26820
26821         mkdir $DIR/$tdir
26822
26823         local setcount=$((MDSCOUNT * 2))
26824
26825         $LFS setdirstripe -D -C $setcount $DIR/$tdir
26826
26827         mkdir $DIR/$tdir/${tdir}.1
26828
26829         local getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.1)
26830
26831         (( getstripe_count == setcount )) ||
26832                 error "(0)stripe_count is $getstripe_count, expect $setcount"
26833
26834         mkdir $DIR/$tdir/${tdir}.1/${tdir}.2
26835
26836         local getstripe_count=$($LFS getdirstripe -c \
26837                                 $DIR/$tdir/${tdir}.1/${tdir}.2)
26838
26839         (( getstripe_count == setcount )) ||
26840                 error "(1)stripe_count is $getstripe_count, expect $setcount"
26841 }
26842 run_test 300uc "test MDT overstriping as default & inheritance"
26843
26844 test_300ud() {
26845         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26846                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26847         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26848
26849         local mdts=$(comma_list $(mdts_nodes))
26850         local timeout=100
26851
26852         local restripe_status
26853         local delta
26854         local i
26855
26856         [[ $mds1_FSTYPE == zfs ]] && timeout=300
26857
26858         # in case "crush" hash type is not set
26859         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
26860
26861         restripe_status=$(do_facet mds1 $LCTL get_param -n \
26862                            mdt.*MDT0000.enable_dir_restripe)
26863         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
26864         stack_trap "do_nodes $mdts $LCTL set_param \
26865                     mdt.*.enable_dir_restripe=$restripe_status"
26866
26867         mkdir $DIR/$tdir
26868         createmany -m $DIR/$tdir/f $((50 * MDSCOUNT)) ||
26869                 error "create files under remote dir failed $i"
26870         createmany -d $DIR/$tdir/d $((50 * MDSCOUNT)) ||
26871                 error "create dirs under remote dir failed $i"
26872
26873         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26874
26875         (( setcount < 13 )) || setcount=12
26876         for i in $(seq 2 $setcount); do
26877                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
26878                 $LFS setdirstripe -C $i $DIR/$tdir ||
26879                         error "split -C $i $tdir failed"
26880                 wait_update $HOSTNAME \
26881                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
26882                         error "dir split not finished"
26883                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
26884                         awk '/migrate/ {sum += $2} END { print sum }')
26885                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
26886                 # delta is around total_files/stripe_count, deviation 3%
26887                 (( delta < 100 * MDSCOUNT / i + 3 * MDSCOUNT )) ||
26888                         error "$delta files migrated >= $((100 * MDSCOUNT / i + 3 * MDSCOUNT))"
26889         done
26890 }
26891 run_test 300ud "dir split"
26892
26893 test_300ue() {
26894         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26895                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26896         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26897
26898         local mdts=$(comma_list $(mdts_nodes))
26899         local timeout=100
26900
26901         local restripe_status
26902         local delta
26903         local c
26904
26905         [[ $mds1_FSTYPE == zfs ]] && timeout=300
26906
26907         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
26908
26909         restripe_status=$(do_facet mds1 $LCTL get_param -n \
26910                            mdt.*MDT0000.enable_dir_restripe)
26911         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
26912         stack_trap "do_nodes $mdts $LCTL set_param \
26913                     mdt.*.enable_dir_restripe=$restripe_status"
26914
26915         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26916
26917         (( setcount < 13 )) || setcount=12
26918         test_mkdir -C $setcount -H crush $DIR/$tdir
26919         createmany -m $DIR/$tdir/f $((50 * MDSCOUNT)) ||
26920                 error "create files under remote dir failed"
26921         createmany -d $DIR/$tdir/d $((50 * MDSCOUNT)) ||
26922                 error "create dirs under remote dir failed"
26923
26924         for c in $(seq $((setcount - 1)) -1 1); do
26925                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
26926                 $LFS setdirstripe -C $c $DIR/$tdir ||
26927                         error "split -C $c $tdir failed"
26928                 wait_update $HOSTNAME \
26929                         "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" $timeout ||
26930                         error "dir merge not finished"
26931                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
26932                         awk '/migrate/ {sum += $2} END { print sum }')
26933                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
26934                 # delta is around total_files/stripe_count, deviation 3%
26935                 (( delta < 100 * MDSCOUNT / c + 3 * MDSCOUNT )) ||
26936                         error "$delta files migrated >= $((100 * MDSCOUNT / c + 3 * MDSCOUNT))"
26937         done
26938 }
26939 run_test 300ue "dir merge"
26940
26941 test_300uf() {
26942         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26943                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26944         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26945
26946         # maximum amount of local locks:
26947         # parent striped dir - 2 locks
26948         # new stripe in parent to migrate to - 1 lock
26949         # source and target - 2 locks
26950         # Total 5 locks for regular file
26951         #
26952         # NB: Overstriping should add several extra local locks
26953         # FIXME: Remove this once understood
26954         #lctl set_param *debug=-1 debug_mb=10000
26955         lctl clear
26956         lctl mark "touch/create"
26957         mkdir -p $DIR/$tdir
26958         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26959         local setcount=$((MDSCOUNT * 5))
26960
26961         $LFS mkdir -i1 -C $setcount $DIR/$tdir/dir1
26962         touch $DIR/$tdir/dir1/eee
26963
26964         lctl mark "hardlinks"
26965         # create 4 hardlink for 4 more locks
26966         # Total: 9 locks > RS_MAX_LOCKS (8)
26967         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
26968         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
26969         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
26970         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
26971         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
26972         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
26973         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
26974         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
26975
26976         lctl mark "cancel lru"
26977         cancel_lru_locks mdc
26978
26979         lctl mark "migrate"
26980         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
26981                 error "migrate dir fails"
26982
26983         rm -rf $DIR/$tdir || error "rm dir failed after migration"
26984 }
26985 run_test 300uf "migrate with too many local locks"
26986
26987 test_300ug() {
26988         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26989                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26990         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26991
26992         mkdir -p $DIR/$tdir
26993         local migrate_dir=$DIR/$tdir/migrate_dir
26994         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26995         local setcount2=$((setcount - 2))
26996
26997         $LFS setdirstripe -c 2 $migrate_dir ||
26998                 error "(0) failed to create striped directory"
26999
27000         $LFS migrate -m 0 -C $setcount $migrate_dir ||
27001                 error "(1)failed to migrate to overstriped directory"
27002         local getstripe_count=$($LFS getdirstripe -c $migrate_dir)
27003
27004         (( getstripe_count == setcount )) ||
27005                 error "(2)stripe_count is $getstripe_count, expect $setcount"
27006         touch $DIR/$tdir/migrate_dir/$tfile ||
27007                 error "(3)failed to create file in overstriped directory"
27008         $LFS migrate -m 0 -C $setcount2 $migrate_dir ||
27009                 error "(4)failed to migrate overstriped directory"
27010         # Check stripe count after migration
27011         $LFS getdirstripe $migrate_dir
27012         getstripe_count=$($LFS getdirstripe -c $migrate_dir)
27013         (( getstripe_count == setcount2 )) ||
27014                 error "(5)stripe_count is $getstripe_count, expect $setcount2"
27015
27016         rm -rf $migrate_dir || error "(6) unable to rm overstriped dir"
27017 }
27018 run_test 300ug "migrate overstriped dirs"
27019
27020 prepare_remote_file() {
27021         mkdir $DIR/$tdir/src_dir ||
27022                 error "create remote source failed"
27023
27024         cp /etc/hosts $DIR/$tdir/src_dir/a ||
27025                  error "cp to remote source failed"
27026         touch $DIR/$tdir/src_dir/a
27027
27028         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
27029                 error "create remote target dir failed"
27030
27031         touch $DIR/$tdir/tgt_dir/b
27032
27033         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
27034                 error "rename dir cross MDT failed!"
27035
27036         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
27037                 error "src_child still exists after rename"
27038
27039         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
27040                 error "missing file(a) after rename"
27041
27042         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
27043                 error "diff after rename"
27044 }
27045
27046 test_310a() {
27047         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
27048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27049
27050         local remote_file=$DIR/$tdir/tgt_dir/b
27051
27052         mkdir -p $DIR/$tdir
27053
27054         prepare_remote_file || error "prepare remote file failed"
27055
27056         #open-unlink file
27057         $OPENUNLINK $remote_file $remote_file ||
27058                 error "openunlink $remote_file failed"
27059         $CHECKSTAT -a $remote_file || error "$remote_file exists"
27060 }
27061 run_test 310a "open unlink remote file"
27062
27063 test_310b() {
27064         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
27065         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27066
27067         local remote_file=$DIR/$tdir/tgt_dir/b
27068
27069         mkdir -p $DIR/$tdir
27070
27071         prepare_remote_file || error "prepare remote file failed"
27072
27073         ln $remote_file $DIR/$tfile || error "link failed for remote file"
27074         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
27075         $CHECKSTAT -t file $remote_file || error "check file failed"
27076 }
27077 run_test 310b "unlink remote file with multiple links while open"
27078
27079 test_310c() {
27080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27081         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
27082
27083         local remote_file=$DIR/$tdir/tgt_dir/b
27084
27085         mkdir -p $DIR/$tdir
27086
27087         prepare_remote_file || error "prepare remote file failed"
27088
27089         ln $remote_file $DIR/$tfile || error "link failed for remote file"
27090         multiop_bg_pause $remote_file O_uc ||
27091                         error "mulitop failed for remote file"
27092         MULTIPID=$!
27093         $MULTIOP $DIR/$tfile Ouc
27094         kill -USR1 $MULTIPID
27095         wait $MULTIPID
27096 }
27097 run_test 310c "open-unlink remote file with multiple links"
27098
27099 #LU-4825
27100 test_311() {
27101         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27102         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
27103         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
27104                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
27105         remote_mds_nodsh && skip "remote MDS with nodsh"
27106
27107         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
27108         local mdts=$(comma_list $(mdts_nodes))
27109
27110         mkdir -p $DIR/$tdir
27111         $LFS setstripe -i 0 -c 1 $DIR/$tdir
27112         createmany -o $DIR/$tdir/$tfile. 1000
27113
27114         # statfs data is not real time, let's just calculate it
27115         old_iused=$((old_iused + 1000))
27116
27117         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27118                         osp.*OST0000*MDT0000.create_count")
27119         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27120                                 osp.*OST0000*MDT0000.max_create_count")
27121         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
27122
27123         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
27124         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
27125         [ $index -ne 0 ] || error "$tfile stripe index is 0"
27126
27127         unlinkmany $DIR/$tdir/$tfile. 1000
27128
27129         do_nodes $mdts "$LCTL set_param -n \
27130                         osp.*OST0000*.max_create_count=$max_count"
27131         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
27132                 do_nodes $mdts "$LCTL set_param -n \
27133                                 osp.*OST0000*.create_count=$count"
27134         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
27135                         grep "=0" && error "create_count is zero"
27136
27137         local new_iused
27138         for i in $(seq 120); do
27139                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
27140                 # system may be too busy to destroy all objs in time, use
27141                 # a somewhat small value to not fail autotest
27142                 [ $((old_iused - new_iused)) -gt 400 ] && break
27143                 sleep 1
27144         done
27145
27146         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
27147         [ $((old_iused - new_iused)) -gt 400 ] ||
27148                 error "objs not destroyed after unlink"
27149 }
27150 run_test 311 "disable OSP precreate, and unlink should destroy objs"
27151
27152 zfs_get_objid()
27153 {
27154         local ost=$1
27155         local tf=$2
27156         local fid=($($LFS getstripe $tf | grep 0x))
27157         local seq=${fid[3]#0x}
27158         local objid=${fid[1]}
27159
27160         local vdevdir=$(dirname $(facet_vdevice $ost))
27161         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
27162         local zfs_zapid=$(do_facet $ost $cmd |
27163                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
27164                           awk '/Object/{getline; print $1}')
27165         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
27166                           awk "/$objid = /"'{printf $3}')
27167
27168         echo $zfs_objid
27169 }
27170
27171 zfs_object_blksz() {
27172         local ost=$1
27173         local objid=$2
27174
27175         local vdevdir=$(dirname $(facet_vdevice $ost))
27176         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
27177         local blksz=$(do_facet $ost $cmd $objid |
27178                       awk '/dblk/{getline; printf $4}')
27179
27180         case "${blksz: -1}" in
27181                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
27182                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
27183                 *) ;;
27184         esac
27185
27186         echo $blksz
27187 }
27188
27189 test_312() { # LU-4856
27190         remote_ost_nodsh && skip "remote OST with nodsh"
27191         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
27192
27193         local max_blksz=$(do_facet ost1 \
27194                           $ZFS get -p recordsize $(facet_device ost1) |
27195                           awk '!/VALUE/{print $3}')
27196         local tf=$DIR/$tfile
27197
27198         $LFS setstripe -c1 $tf
27199         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
27200
27201         # Get ZFS object id
27202         local zfs_objid=$(zfs_get_objid $facet $tf)
27203         # block size change by sequential overwrite
27204         local bs
27205
27206         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
27207                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
27208
27209                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
27210                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
27211         done
27212         rm -f $tf
27213
27214         $LFS setstripe -c1 $tf
27215         facet="ost$(($($LFS getstripe -i $tf) + 1))"
27216
27217         # block size change by sequential append write
27218         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
27219         zfs_objid=$(zfs_get_objid $facet $tf)
27220         local count
27221
27222         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
27223                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
27224                         oflag=sync conv=notrunc
27225
27226                 blksz=$(zfs_object_blksz $facet $zfs_objid)
27227                 (( $blksz == 2 * count * PAGE_SIZE )) ||
27228                         error "blksz error, actual $blksz, " \
27229                                 "expected: 2 * $count * $PAGE_SIZE"
27230         done
27231         rm -f $tf
27232
27233         # random write
27234         $LFS setstripe -c1 $tf
27235         facet="ost$(($($LFS getstripe -i $tf) + 1))"
27236         zfs_objid=$(zfs_get_objid $facet $tf)
27237
27238         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
27239         blksz=$(zfs_object_blksz $facet $zfs_objid)
27240         (( blksz == PAGE_SIZE )) ||
27241                 error "blksz error: $blksz, expected: $PAGE_SIZE"
27242
27243         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
27244         blksz=$(zfs_object_blksz $facet $zfs_objid)
27245         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
27246
27247         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
27248         blksz=$(zfs_object_blksz $facet $zfs_objid)
27249         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
27250 }
27251 run_test 312 "make sure ZFS adjusts its block size by write pattern"
27252
27253 test_313() {
27254         remote_ost_nodsh && skip "remote OST with nodsh"
27255
27256         local file=$DIR/$tfile
27257
27258         rm -f $file
27259         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
27260
27261         # define OBD_FAIL_TGT_RCVD_EIO           0x720
27262         do_facet ost1 "$LCTL set_param fail_loc=0x720"
27263         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
27264                 error "write should failed"
27265         do_facet ost1 "$LCTL set_param fail_loc=0"
27266         rm -f $file
27267 }
27268 run_test 313 "io should fail after last_rcvd update fail"
27269
27270 test_314() {
27271         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
27272
27273         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
27274         do_facet ost1 "$LCTL set_param fail_loc=0x720"
27275         rm -f $DIR/$tfile
27276         wait_delete_completed
27277         do_facet ost1 "$LCTL set_param fail_loc=0"
27278 }
27279 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
27280
27281 test_315() { # LU-618
27282         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
27283
27284         local file=$DIR/$tfile
27285         rm -f $file
27286
27287         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
27288                 error "multiop file write failed"
27289         $MULTIOP $file oO_RDONLY:r4063232_c &
27290         PID=$!
27291
27292         sleep 2
27293
27294         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
27295         kill -USR1 $PID
27296
27297         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
27298         rm -f $file
27299 }
27300 run_test 315 "read should be accounted"
27301
27302 test_316() {
27303         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
27304         large_xattr_enabled || skip "ea_inode feature disabled"
27305
27306         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27307         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
27308         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
27309         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
27310
27311         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
27312 }
27313 run_test 316 "lfs migrate of file with large_xattr enabled"
27314
27315 test_317() {
27316         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
27317                 skip "Need MDS version at least 2.11.53"
27318         if [ "$ost1_FSTYPE" == "zfs" ]; then
27319                 skip "LU-10370: no implementation for ZFS"
27320         fi
27321
27322         local trunc_sz
27323         local grant_blk_size
27324
27325         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
27326                         awk '/grant_block_size:/ { print $2; exit; }')
27327         #
27328         # Create File of size 5M. Truncate it to below size's and verify
27329         # blocks count.
27330         #
27331         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
27332                 error "Create file $DIR/$tfile failed"
27333         stack_trap "rm -f $DIR/$tfile" EXIT
27334
27335         for trunc_sz in 2097152 4097 4000 509 0; do
27336                 $TRUNCATE $DIR/$tfile $trunc_sz ||
27337                         error "truncate $tfile to $trunc_sz failed"
27338                 local sz=$(stat --format=%s $DIR/$tfile)
27339                 local blk=$(stat --format=%b $DIR/$tfile)
27340                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
27341                                      grant_blk_size) * 8))
27342
27343                 if [[ $blk -ne $trunc_blk ]]; then
27344                         $(which stat) $DIR/$tfile
27345                         error "Expected Block $trunc_blk got $blk for $tfile"
27346                 fi
27347
27348                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
27349                         error "Expected Size $trunc_sz got $sz for $tfile"
27350         done
27351
27352         #
27353         # sparse file test
27354         # Create file with a hole and write actual 65536 bytes which aligned
27355         # with 4K and 64K PAGE_SIZE. Block count must be 128.
27356         #
27357         local bs=65536
27358         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
27359                 error "Create file : $DIR/$tfile"
27360
27361         #
27362         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
27363         # blocks. The block count must drop to 8.
27364         #
27365         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
27366                 ((bs - grant_blk_size) + 1)))
27367         $TRUNCATE $DIR/$tfile $trunc_sz ||
27368                 error "truncate $tfile to $trunc_sz failed"
27369
27370         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
27371         sz=$(stat --format=%s $DIR/$tfile)
27372         blk=$(stat --format=%b $DIR/$tfile)
27373
27374         if [[ $blk -ne $trunc_bsz ]]; then
27375                 $(which stat) $DIR/$tfile
27376                 error "Expected Block $trunc_bsz got $blk for $tfile"
27377         fi
27378
27379         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
27380                 error "Expected Size $trunc_sz got $sz for $tfile"
27381 }
27382 run_test 317 "Verify blocks get correctly update after truncate"
27383
27384 test_318() {
27385         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
27386         local old_max_active=$($LCTL get_param -n \
27387                             ${llite_name}.max_read_ahead_async_active \
27388                             2>/dev/null)
27389
27390         $LCTL set_param llite.*.max_read_ahead_async_active=256
27391         local max_active=$($LCTL get_param -n \
27392                            ${llite_name}.max_read_ahead_async_active \
27393                            2>/dev/null)
27394         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
27395
27396         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
27397                 error "set max_read_ahead_async_active should succeed"
27398
27399         $LCTL set_param llite.*.max_read_ahead_async_active=512
27400         max_active=$($LCTL get_param -n \
27401                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
27402         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
27403
27404         # restore @max_active
27405         [ $old_max_active -ne 0 ] && $LCTL set_param \
27406                 llite.*.max_read_ahead_async_active=$old_max_active
27407
27408         local old_threshold=$($LCTL get_param -n \
27409                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
27410         local max_per_file_mb=$($LCTL get_param -n \
27411                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
27412
27413         local invalid=$(($max_per_file_mb + 1))
27414         $LCTL set_param \
27415                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
27416                         && error "set $invalid should fail"
27417
27418         local valid=$(($invalid - 1))
27419         $LCTL set_param \
27420                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
27421                         error "set $valid should succeed"
27422         local threshold=$($LCTL get_param -n \
27423                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
27424         [ $threshold -eq $valid ] || error \
27425                 "expect threshold $valid got $threshold"
27426         $LCTL set_param \
27427                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
27428 }
27429 run_test 318 "Verify async readahead tunables"
27430
27431 test_319() {
27432         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
27433
27434         local before=$(date +%s)
27435         local evict
27436         local mdir=$DIR/$tdir
27437         local file=$mdir/xxx
27438
27439         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
27440         touch $file
27441
27442 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
27443         $LCTL set_param fail_val=5 fail_loc=0x8000032c
27444         $LFS migrate -m1 $mdir &
27445
27446         sleep 1
27447         dd if=$file of=/dev/null
27448         wait
27449         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
27450           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
27451
27452         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
27453 }
27454 run_test 319 "lost lease lock on migrate error"
27455
27456 test_350() {
27457         local mdts=$(comma_list $(mdts_nodes))
27458
27459         mkdir $DIR/$tdir || error "mkdir $DIR/$tdir failed"
27460         stack_trap "rm -r $DIR/$tdir"
27461
27462         #force 1/100 of replies to take "NID mismatch" codepath
27463         #define CFS_FAIL_MATCH_MD_NID 0xe001  CFS_FAIL_SOME 0x10000000
27464         do_nodes $mdts $LCTL set_param fail_loc=0x1000e001 fail_val=100
27465
27466         while ls -lR $DIR/$tdir > /dev/null; do :; done &
27467         stack_trap "killall -9 ls || killall -9 ls"
27468
27469         cp -a /etc $DIR/$tdir || error "cp failed"
27470 }
27471 run_test 350 "force NID mismatch path to be exercised"
27472
27473 test_360() {
27474         (( $OST1_VERSION >= $(version_code 2.15.58.96) )) ||
27475                 skip "Need OST version at least 2.15.58.96"
27476         [[ "$ost1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
27477
27478         check_set_fallocate_or_skip
27479         local param="osd-ldiskfs.delayed_unlink_mb"
27480         local old=($(do_facet ost1 "$LCTL get_param -n $param"))
27481
27482         do_facet ost1 "$LCTL set_param $param=1MiB"
27483         stack_trap "do_facet ost1 $LCTL set_param $param=${old[0]}"
27484
27485         mkdir $DIR/$tdir/
27486         do_facet ost1 $LCTL set_param debug=+inode
27487         do_facet ost1 $LCTL clear
27488         local files=100
27489
27490         for ((i = 0; i < $files; i++)); do
27491                 fallocate -l 1280k $DIR/$tdir/$tfile.$i ||
27492                         error "fallocate 1280k $DIR/$tdir/$tfile.$i failed"
27493         done
27494         local min=$(($($LFS find $DIR/$tdir --ost 0 | wc -l) / 2))
27495
27496         for ((i = 0; i < $files; i++)); do
27497                 unlink $DIR/$tdir/$tfile.$i ||
27498                         error "unlink $DIR/$tdir/$tfile.$i failed"
27499         done
27500
27501         local count=0
27502         local loop
27503
27504         for (( loop = 0; loop < 30 && count < min; loop++)); do
27505                 sleep 1
27506                 (( count += $(do_facet ost1 $LCTL dk | grep -c "delayed iput")))
27507                 echo "Count[$loop]: $count"
27508         done
27509         (( count >= min )) || error "$count < $min delayed iput after $loop s"
27510 }
27511 run_test 360 "ldiskfs unlink in a separate thread"
27512
27513 test_398a() { # LU-4198
27514         local ost1_imp=$(get_osc_import_name client ost1)
27515         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27516                          cut -d'.' -f2)
27517
27518         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27519         stack_trap "rm -f $DIR/$tfile"
27520         $LCTL set_param ldlm.namespaces.*.lru_size=clear
27521
27522         # request a new lock on client
27523         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27524
27525         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
27526         local lock_count=$($LCTL get_param -n \
27527                            ldlm.namespaces.$imp_name.lru_size)
27528         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
27529
27530         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
27531
27532         # no lock cached, should use lockless DIO and not enqueue new lock
27533         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
27534         lock_count=$($LCTL get_param -n \
27535                      ldlm.namespaces.$imp_name.lru_size)
27536         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
27537
27538         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
27539
27540         # no lock cached, should use locked DIO append
27541         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
27542                 conv=notrunc || error "DIO append failed"
27543         lock_count=$($LCTL get_param -n \
27544                      ldlm.namespaces.$imp_name.lru_size)
27545         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
27546 }
27547 run_test 398a "direct IO should cancel lock otherwise lockless"
27548
27549 test_398b() { # LU-4198
27550         local before=$(date +%s)
27551         local njobs=4
27552         local size=48
27553
27554         which fio || skip_env "no fio installed"
27555         $LFS setstripe -c -1 -S 1M $DIR/$tfile
27556         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
27557
27558         # Single page, multiple pages, stripe size, 4*stripe size
27559         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
27560                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
27561                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
27562                         --numjobs=$njobs --fallocate=none \
27563                         --iodepth=16 --allow_file_create=0 \
27564                         --size=$((size/njobs))M \
27565                         --filename=$DIR/$tfile &
27566                 bg_pid=$!
27567
27568                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
27569                 fio --name=rand-rw --rw=randrw --bs=$bsize \
27570                         --numjobs=$njobs --fallocate=none \
27571                         --iodepth=16 --allow_file_create=0 \
27572                         --size=$((size/njobs))M \
27573                         --filename=$DIR/$tfile || true
27574                 wait $bg_pid
27575         done
27576
27577         evict=$(do_facet client $LCTL get_param \
27578                 osc.$FSNAME-OST*-osc-*/state |
27579             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
27580
27581         [ -z "$evict" ] || [[ $evict -le $before ]] ||
27582                 (do_facet client $LCTL get_param \
27583                         osc.$FSNAME-OST*-osc-*/state;
27584                     error "eviction happened: $evict before:$before")
27585
27586         rm -f $DIR/$tfile
27587 }
27588 run_test 398b "DIO and buffer IO race"
27589
27590 test_398c() { # LU-4198
27591         local ost1_imp=$(get_osc_import_name client ost1)
27592         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27593                          cut -d'.' -f2)
27594
27595         which fio || skip_env "no fio installed"
27596
27597         saved_debug=$($LCTL get_param -n debug)
27598         $LCTL set_param debug=0
27599
27600         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
27601         ((size /= 1024)) # by megabytes
27602         ((size /= 2)) # write half of the OST at most
27603         [ $size -gt 40 ] && size=40 #reduce test time anyway
27604
27605         $LFS setstripe -c 1 $DIR/$tfile
27606
27607         # it seems like ldiskfs reserves more space than necessary if the
27608         # writing blocks are not mapped, so it extends the file firstly
27609         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
27610         cancel_lru_locks osc
27611
27612         # clear and verify rpc_stats later
27613         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
27614
27615         local njobs=4
27616         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
27617         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
27618                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
27619                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
27620                 --filename=$DIR/$tfile
27621         [ $? -eq 0 ] || error "fio write error"
27622
27623         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
27624                 error "Locks were requested while doing AIO"
27625
27626         # get the percentage of 1-page I/O
27627         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
27628                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
27629                 awk '{print $7}')
27630         (( $pct <= 50 )) || {
27631                 $LCTL get_param osc.${imp_name}.rpc_stats
27632                 error "$pct% of I/O are 1-page"
27633         }
27634
27635         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
27636         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
27637                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
27638                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
27639                 --filename=$DIR/$tfile
27640         [ $? -eq 0 ] || error "fio mixed read write error"
27641
27642         echo "AIO with large block size ${size}M"
27643         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
27644                 --numjobs=1 --fallocate=none --ioengine=libaio \
27645                 --iodepth=16 --allow_file_create=0 --size=${size}M \
27646                 --filename=$DIR/$tfile
27647         [ $? -eq 0 ] || error "fio large block size failed"
27648
27649         rm -f $DIR/$tfile
27650         $LCTL set_param debug="$saved_debug"
27651 }
27652 run_test 398c "run fio to test AIO"
27653
27654 test_398d() { #  LU-13846
27655         which aiocp || skip_env "no aiocp installed"
27656         local aio_file=$DIR/$tfile.aio
27657
27658         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
27659
27660         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
27661         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
27662         stack_trap "rm -f $DIR/$tfile $aio_file"
27663
27664         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
27665
27666         # test memory unaligned aio
27667         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file ||
27668                 error "unaligned aio failed"
27669         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
27670
27671         rm -f $DIR/$tfile $aio_file
27672 }
27673 run_test 398d "run aiocp to verify block size > stripe size"
27674
27675 test_398e() {
27676         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
27677         touch $DIR/$tfile.new
27678         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
27679 }
27680 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
27681
27682 test_398f() { #  LU-14687
27683         which aiocp || skip_env "no aiocp installed"
27684         local aio_file=$DIR/$tfile.aio
27685
27686         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
27687
27688         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
27689         stack_trap "rm -f $DIR/$tfile $aio_file"
27690
27691         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
27692         $LCTL set_param fail_loc=0x1418
27693         # make sure we don't crash and fail properly
27694         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
27695                 error "aio with page allocation failure succeeded"
27696         $LCTL set_param fail_loc=0
27697         diff $DIR/$tfile $aio_file
27698         [[ $? != 0 ]] || error "no diff after failed aiocp"
27699 }
27700 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
27701
27702 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
27703 # stripe and i/o size must be > stripe size
27704 # Old style synchronous DIO waits after submitting each chunk, resulting in a
27705 # single RPC in flight.  This test shows async DIO submission is working by
27706 # showing multiple RPCs in flight.
27707 test_398g() { #  LU-13798
27708         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
27709
27710         # We need to do some i/o first to acquire enough grant to put our RPCs
27711         # in flight; otherwise a new connection may not have enough grant
27712         # available
27713         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27714                 error "parallel dio failed"
27715         stack_trap "rm -f $DIR/$tfile"
27716
27717         # Reduce RPC size to 1M to avoid combination in to larger RPCs
27718         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
27719         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
27720         stack_trap "$LCTL set_param -n $pages_per_rpc"
27721
27722         # Recreate file so it's empty
27723         rm -f $DIR/$tfile
27724         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
27725         #Pause rpc completion to guarantee we see multiple rpcs in flight
27726         #define OBD_FAIL_OST_BRW_PAUSE_BULK
27727         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
27728         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
27729
27730         # Clear rpc stats
27731         $LCTL set_param osc.*.rpc_stats=c
27732
27733         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27734                 error "parallel dio failed"
27735         stack_trap "rm -f $DIR/$tfile"
27736
27737         $LCTL get_param osc.*-OST0000-*.rpc_stats
27738         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
27739                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
27740                 grep "8:" | awk '{print $8}')
27741         # We look at the "8 rpcs in flight" field, and verify A) it is present
27742         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
27743         # as expected for an 8M DIO to a file with 1M stripes.
27744         # NB: There is occasionally a mystery extra write RPC to a different
27745         # file.  I can't identify why that's happening, so we set up a margin
27746         # of 1 RPC here, ie, 8/9 RPCs at this size, or ~88%
27747         [ $pct -gt 87 ] || error "we should see 8 RPCs in flight"
27748
27749         # Verify turning off parallel dio works as expected
27750         # Clear rpc stats
27751         $LCTL set_param osc.*.rpc_stats=c
27752         $LCTL set_param llite.*.parallel_dio=0
27753         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
27754
27755         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27756                 error "dio with parallel dio disabled failed"
27757
27758         # Ideally, we would see only one RPC in flight here, but there is an
27759         # unavoidable race between i/o completion and RPC in flight counting,
27760         # so while only 1 i/o is in flight at a time, the RPC in flight counter
27761         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
27762         # So instead we just verify it's always < 8.
27763         $LCTL get_param osc.*-OST0000-*.rpc_stats
27764         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
27765                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
27766                 grep '^$' -B1 | grep . | awk '{print $1}')
27767         [ $ret != "8:" ] ||
27768                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
27769 }
27770 run_test 398g "verify parallel dio async RPC submission"
27771
27772 test_398h() { #  LU-13798
27773         local dio_file=$DIR/$tfile.dio
27774
27775         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
27776
27777         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27778         stack_trap "rm -f $DIR/$tfile $dio_file"
27779
27780         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
27781                 error "parallel dio failed"
27782         diff $DIR/$tfile $dio_file
27783         [[ $? == 0 ]] || error "file diff after aiocp"
27784 }
27785 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
27786
27787 test_398i() { #  LU-13798
27788         local dio_file=$DIR/$tfile.dio
27789
27790         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
27791
27792         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27793         stack_trap "rm -f $DIR/$tfile $dio_file"
27794
27795         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
27796         $LCTL set_param fail_loc=0x1418
27797         # make sure we don't crash and fail properly
27798         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
27799                 error "parallel dio page allocation failure succeeded"
27800         diff $DIR/$tfile $dio_file
27801         [[ $? != 0 ]] || error "no diff after failed aiocp"
27802 }
27803 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
27804
27805 test_398j() { #  LU-13798
27806         # Stripe size > RPC size but less than i/o size tests split across
27807         # stripes and RPCs for individual i/o op
27808         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
27809
27810         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
27811         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
27812         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
27813         stack_trap "$LCTL set_param -n $pages_per_rpc"
27814
27815         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27816                 error "parallel dio write failed"
27817         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
27818
27819         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
27820                 error "parallel dio read failed"
27821         diff $DIR/$tfile $DIR/$tfile.2
27822         [[ $? == 0 ]] || error "file diff after parallel dio read"
27823 }
27824 run_test 398j "test parallel dio where stripe size > rpc_size"
27825
27826 test_398k() { #  LU-13798
27827         wait_delete_completed
27828         wait_mds_ost_sync
27829
27830         # 4 stripe file; we will cause out of space on OST0
27831         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
27832
27833         # Fill OST0 (if it's not too large)
27834         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
27835                    head -n1)
27836         if [[ $ORIGFREE -gt $MAXFREE ]]; then
27837                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
27838         fi
27839         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
27840         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
27841                 error "dd should fill OST0"
27842         stack_trap "rm -f $DIR/$tfile.1"
27843
27844         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27845         err=$?
27846
27847         ls -la $DIR/$tfile
27848         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
27849                 error "file is not 0 bytes in size"
27850
27851         # dd above should not succeed, but don't error until here so we can
27852         # get debug info above
27853         [[ $err != 0 ]] ||
27854                 error "parallel dio write with enospc succeeded"
27855         stack_trap "rm -f $DIR/$tfile"
27856 }
27857 run_test 398k "test enospc on first stripe"
27858
27859 test_398l() { #  LU-13798
27860         wait_delete_completed
27861         wait_mds_ost_sync
27862
27863         # 4 stripe file; we will cause out of space on OST0
27864         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
27865         # happens on the second i/o chunk we issue
27866         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
27867
27868         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
27869         stack_trap "rm -f $DIR/$tfile"
27870
27871         # Fill OST0 (if it's not too large)
27872         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
27873                    head -n1)
27874         if [[ $ORIGFREE -gt $MAXFREE ]]; then
27875                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
27876         fi
27877         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
27878         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
27879                 error "dd should fill OST0"
27880         stack_trap "rm -f $DIR/$tfile.1"
27881
27882         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
27883         err=$?
27884         stack_trap "rm -f $DIR/$tfile.2"
27885
27886         # Check that short write completed as expected
27887         ls -la $DIR/$tfile.2
27888         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
27889                 error "file is not 1M in size"
27890
27891         # dd above should not succeed, but don't error until here so we can
27892         # get debug info above
27893         [[ $err != 0 ]] ||
27894                 error "parallel dio write with enospc succeeded"
27895
27896         # Truncate source file to same length as output file and diff them
27897         $TRUNCATE $DIR/$tfile 1048576
27898         diff $DIR/$tfile $DIR/$tfile.2
27899         [[ $? == 0 ]] || error "data incorrect after short write"
27900 }
27901 run_test 398l "test enospc on intermediate stripe/RPC"
27902
27903 test_398m() { #  LU-13798
27904         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
27905
27906         # Set up failure on OST0, the first stripe:
27907         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
27908         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
27909         # OST0 is on ost1, OST1 is on ost2.
27910         # So this fail_val specifies OST0
27911         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
27912         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
27913
27914         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
27915                 error "parallel dio write with failure on first stripe succeeded"
27916         stack_trap "rm -f $DIR/$tfile"
27917         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
27918
27919         # Place data in file for read
27920         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27921                 error "parallel dio write failed"
27922
27923         # Fail read on OST0, first stripe
27924         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
27925         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
27926         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
27927                 error "parallel dio read with error on first stripe succeeded"
27928         rm -f $DIR/$tfile.2
27929         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
27930
27931         # Switch to testing on OST1, second stripe
27932         # Clear file contents, maintain striping
27933         echo > $DIR/$tfile
27934         # Set up failure on OST1, second stripe:
27935         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
27936         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
27937
27938         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
27939                 error "parallel dio write with failure on second stripe succeeded"
27940         stack_trap "rm -f $DIR/$tfile"
27941         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
27942
27943         # Place data in file for read
27944         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27945                 error "parallel dio write failed"
27946
27947         # Fail read on OST1, second stripe
27948         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
27949         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
27950         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
27951                 error "parallel dio read with error on second stripe succeeded"
27952         rm -f $DIR/$tfile.2
27953         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
27954 }
27955 run_test 398m "test RPC failures with parallel dio"
27956
27957 # Parallel submission of DIO should not cause problems for append, but it's
27958 # important to verify.
27959 test_398n() { #  LU-13798
27960         $LFS setstripe -C 2 -S 1M $DIR/$tfile
27961
27962         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
27963                 error "dd to create source file failed"
27964         stack_trap "rm -f $DIR/$tfile"
27965
27966         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
27967                 error "parallel dio write with failure on second stripe succeeded"
27968         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
27969         diff $DIR/$tfile $DIR/$tfile.1
27970         [[ $? == 0 ]] || error "data incorrect after append"
27971
27972 }
27973 run_test 398n "test append with parallel DIO"
27974
27975 test_398o() {
27976         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
27977 }
27978 run_test 398o "right kms with DIO"
27979
27980 test_398p()
27981 {
27982         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
27983         which aiocp || skip_env "no aiocp installed"
27984
27985         local stripe_size=$((1024 * 1024)) #1 MiB
27986         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
27987         local file_size=$((25 * stripe_size))
27988
27989         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
27990         stack_trap "rm -f $DIR/$tfile*"
27991         # Just a bit bigger than the largest size in the test set below
27992         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
27993                 error "buffered i/o to create file failed"
27994
27995         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
27996                 $((stripe_size * 4)); do
27997
27998                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
27999
28000                 echo "bs: $bs, file_size $file_size"
28001                 aiocp -a $PAGE_SIZE -b $bs -s $file_size -f O_DIRECT \
28002                         $DIR/$tfile.1 $DIR/$tfile.2 &
28003                 pid_dio1=$!
28004                 # Buffered I/O with similar but not the same block size
28005                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
28006                         conv=notrunc &
28007                 pid_bio2=$!
28008                 wait $pid_dio1
28009                 rc1=$?
28010                 wait $pid_bio2
28011                 rc2=$?
28012                 if (( rc1 != 0 )); then
28013                         error "aio copy 1 w/bsize $bs failed: $rc1"
28014                 fi
28015                 if (( rc2 != 0 )); then
28016                         error "buffered copy 2 w/bsize $bs failed: $rc2"
28017                 fi
28018
28019                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
28020                         error "size incorrect"
28021                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
28022                         error "files differ, bsize $bs"
28023                 rm -f $DIR/$tfile.2
28024         done
28025 }
28026 run_test 398p "race aio with buffered i/o"
28027
28028 test_398q()
28029 {
28030         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
28031
28032         local stripe_size=$((1024 * 1024)) #1 MiB
28033         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
28034         local file_size=$((25 * stripe_size))
28035
28036         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
28037         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
28038
28039         # Just a bit bigger than the largest size in the test set below
28040         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
28041                 error "buffered i/o to create file failed"
28042
28043         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
28044                 $((stripe_size * 4)); do
28045
28046                 echo "bs: $bs, file_size $file_size"
28047                 dd if=$DIR/$tfile.1 bs=$((bs *2 )) of=$DIR/$tfile.2 \
28048                         conv=notrunc oflag=direct iflag=direct &
28049                 pid_dio1=$!
28050                 # Buffered I/O with similar but not the same block size
28051                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
28052                         conv=notrunc &
28053                 pid_bio2=$!
28054                 wait $pid_dio1
28055                 rc1=$?
28056                 wait $pid_bio2
28057                 rc2=$?
28058                 if (( rc1 != 0 )); then
28059                         error "dio copy 1 w/bsize $bs failed: $rc1"
28060                 fi
28061                 if (( rc2 != 0 )); then
28062                         error "buffered copy 2 w/bsize $bs failed: $rc2"
28063                 fi
28064
28065                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
28066                         error "size incorrect"
28067                 diff $DIR/$tfile.1 $DIR/$tfile.2 ||
28068                         error "files differ, bsize $bs"
28069         done
28070
28071         rm -f $DIR/$tfile*
28072 }
28073 run_test 398q "race dio with buffered i/o"
28074
28075 test_398r() {
28076         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
28077         echo "hello, world" > $DIR/$tfile
28078
28079         cancel_lru_locks osc
28080
28081 #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
28082         do_facet ost1 $LCTL set_param fail_loc=0x20f
28083         cat $DIR/$tfile > /dev/null && error "cat should fail"
28084         return 0
28085 }
28086 run_test 398r "i/o error on file read"
28087
28088 test_398s() {
28089         [[ $OSTCOUNT -ge 2 && "$ost1_HOST" = "$ost2_HOST" ]] ||
28090                 skip "remote OST"
28091
28092         $LFS mirror create -N -i 0 -c 1 -N -i 1 -c 1 $DIR/$tfile ||
28093                 error "mirror create failed"
28094
28095         echo "hello, world" > $DIR/$tfile
28096         $LFS mirror resync $DIR/$tfile || error "mirror resync failed"
28097
28098         cancel_lru_locks osc
28099
28100 #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
28101         do_facet ost1 $LCTL set_param fail_loc=0x20f
28102         cat $DIR/$tfile > /dev/null && error "cat should fail"
28103         return 0
28104 }
28105 run_test 398s "i/o error on mirror file read"
28106
28107 test_fake_rw() {
28108         local read_write=$1
28109         if [ "$read_write" = "write" ]; then
28110                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
28111         elif [ "$read_write" = "read" ]; then
28112                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
28113         else
28114                 error "argument error"
28115         fi
28116
28117         # turn off debug for performance testing
28118         local saved_debug=$($LCTL get_param -n debug)
28119         $LCTL set_param debug=0
28120
28121         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28122
28123         # get ost1 size - $FSNAME-OST0000
28124         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
28125         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
28126         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
28127
28128         if [ "$read_write" = "read" ]; then
28129                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
28130         fi
28131
28132         local start_time=$(date +%s.%N)
28133         $dd_cmd bs=1M count=$blocks oflag=sync ||
28134                 error "real dd $read_write error"
28135         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
28136
28137         if [ "$read_write" = "write" ]; then
28138                 rm -f $DIR/$tfile
28139         fi
28140
28141         # define OBD_FAIL_OST_FAKE_RW           0x238
28142         do_facet ost1 $LCTL set_param fail_loc=0x238
28143
28144         local start_time=$(date +%s.%N)
28145         $dd_cmd bs=1M count=$blocks oflag=sync ||
28146                 error "fake dd $read_write error"
28147         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
28148
28149         if [ "$read_write" = "write" ]; then
28150                 # verify file size
28151                 cancel_lru_locks osc
28152                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
28153                         error "$tfile size not $blocks MB"
28154         fi
28155         do_facet ost1 $LCTL set_param fail_loc=0
28156
28157         echo "fake $read_write $duration_fake vs. normal $read_write" \
28158                 "$duration in seconds"
28159         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
28160                 error_not_in_vm "fake write is slower"
28161
28162         $LCTL set_param -n debug="$saved_debug"
28163         rm -f $DIR/$tfile
28164 }
28165 test_399a() { # LU-7655 for OST fake write
28166         remote_ost_nodsh && skip "remote OST with nodsh"
28167
28168         test_fake_rw write
28169 }
28170 run_test 399a "fake write should not be slower than normal write"
28171
28172 test_399b() { # LU-8726 for OST fake read
28173         remote_ost_nodsh && skip "remote OST with nodsh"
28174         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
28175                 skip_env "ldiskfs only test"
28176         fi
28177
28178         test_fake_rw read
28179 }
28180 run_test 399b "fake read should not be slower than normal read"
28181
28182 test_400a() { # LU-1606, was conf-sanity test_74
28183         if ! which $CC > /dev/null 2>&1; then
28184                 skip_env "$CC is not installed"
28185         fi
28186
28187         local extra_flags=''
28188         local out=$TMP/$tfile
28189         local prefix=/usr/include/lustre
28190         local prog
28191
28192         # Oleg removes .c files in his test rig so test if any c files exist
28193         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
28194                 skip_env "Needed .c test files are missing"
28195
28196         if ! [[ -d $prefix ]]; then
28197                 # Assume we're running in tree and fixup the include path.
28198                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
28199                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
28200                 extra_flags+=" -L$LUSTRE/utils/.libs"
28201         fi
28202
28203         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
28204                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
28205                         error "client api broken"
28206         done
28207         rm -f $out
28208 }
28209 run_test 400a "Lustre client api program can compile and link"
28210
28211 test_400b() { # LU-1606, LU-5011
28212         local header
28213         local out=$TMP/$tfile
28214         local prefix=/usr/include/linux/lustre
28215
28216         # We use a hard coded prefix so that this test will not fail
28217         # when run in tree. There are headers in lustre/include/lustre/
28218         # that are not packaged (like lustre_idl.h) and have more
28219         # complicated include dependencies (like config.h and lnet/types.h).
28220         # Since this test about correct packaging we just skip them when
28221         # they don't exist (see below) rather than try to fixup cppflags.
28222
28223         if ! which $CC > /dev/null 2>&1; then
28224                 skip_env "$CC is not installed"
28225         fi
28226
28227         for header in $prefix/*.h; do
28228                 if ! [[ -f "$header" ]]; then
28229                         continue
28230                 fi
28231
28232                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
28233                         continue # lustre_ioctl.h is internal header
28234                 fi
28235
28236                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
28237                         error "cannot compile '$header'"
28238         done
28239         rm -f $out
28240 }
28241 run_test 400b "packaged headers can be compiled"
28242
28243 test_401a() { #LU-7437
28244         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
28245         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
28246
28247         #count the number of parameters by "list_param -R"
28248         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
28249         #count the number of parameters by listing proc files
28250         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
28251         echo "proc_dirs='$proc_dirs'"
28252         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
28253         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
28254                       sort -u | wc -l)
28255
28256         [ $params -eq $procs ] ||
28257                 error "found $params parameters vs. $procs proc files"
28258
28259         # test the list_param -D option only returns directories
28260         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
28261         #count the number of parameters by listing proc directories
28262         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
28263                 sort -u | wc -l)
28264
28265         [ $params -eq $procs ] ||
28266                 error "found $params parameters vs. $procs proc files"
28267 }
28268 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
28269
28270 test_401b() {
28271         # jobid_var may not allow arbitrary values, so use jobid_name
28272         # if available
28273         if $LCTL list_param jobid_name > /dev/null 2>&1; then
28274                 local testname=jobid_name tmp='testing%p'
28275         else
28276                 local testname=jobid_var tmp=testing
28277         fi
28278
28279         local save=$($LCTL get_param -n $testname)
28280
28281         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
28282                 error "no error returned when setting bad parameters"
28283
28284         local jobid_new=$($LCTL get_param -n foe $testname baz)
28285         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
28286
28287         $LCTL set_param -n fog=bam $testname=$save bat=fog
28288         local jobid_old=$($LCTL get_param -n foe $testname bag)
28289         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
28290 }
28291 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
28292
28293 test_401c() {
28294         # jobid_var may not allow arbitrary values, so use jobid_name
28295         # if available
28296         if $LCTL list_param jobid_name > /dev/null 2>&1; then
28297                 local testname=jobid_name
28298         else
28299                 local testname=jobid_var
28300         fi
28301
28302         local jobid_var_old=$($LCTL get_param -n $testname)
28303         local jobid_var_new
28304
28305         $LCTL set_param $testname= &&
28306                 error "no error returned for 'set_param a='"
28307
28308         jobid_var_new=$($LCTL get_param -n $testname)
28309         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
28310                 error "$testname was changed by setting without value"
28311
28312         $LCTL set_param $testname &&
28313                 error "no error returned for 'set_param a'"
28314
28315         jobid_var_new=$($LCTL get_param -n $testname)
28316         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
28317                 error "$testname was changed by setting without value"
28318 }
28319 run_test 401c "Verify 'lctl set_param' without value fails in either format."
28320
28321 test_401d() {
28322         # jobid_var may not allow arbitrary values, so use jobid_name
28323         # if available
28324         if $LCTL list_param jobid_name > /dev/null 2>&1; then
28325                 local testname=jobid_name new_value='foo=bar%p'
28326         else
28327                 local testname=jobid_var new_valuie=foo=bar
28328         fi
28329
28330         local jobid_var_old=$($LCTL get_param -n $testname)
28331         local jobid_var_new
28332
28333         $LCTL set_param $testname=$new_value ||
28334                 error "'set_param a=b' did not accept a value containing '='"
28335
28336         jobid_var_new=$($LCTL get_param -n $testname)
28337         [[ "$jobid_var_new" == "$new_value" ]] ||
28338                 error "'set_param a=b' failed on a value containing '='"
28339
28340         # Reset the $testname to test the other format
28341         $LCTL set_param $testname=$jobid_var_old
28342         jobid_var_new=$($LCTL get_param -n $testname)
28343         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
28344                 error "failed to reset $testname"
28345
28346         $LCTL set_param $testname $new_value ||
28347                 error "'set_param a b' did not accept a value containing '='"
28348
28349         jobid_var_new=$($LCTL get_param -n $testname)
28350         [[ "$jobid_var_new" == "$new_value" ]] ||
28351                 error "'set_param a b' failed on a value containing '='"
28352
28353         $LCTL set_param $testname $jobid_var_old
28354         jobid_var_new=$($LCTL get_param -n $testname)
28355         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
28356                 error "failed to reset $testname"
28357 }
28358 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
28359
28360 test_401e() { # LU-14779
28361         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
28362                 error "lctl list_param MGC* failed"
28363         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
28364         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
28365                 error "lctl get_param lru_size failed"
28366 }
28367 run_test 401e "verify 'lctl get_param' works with NID in parameter"
28368
28369 test_402() {
28370         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
28371         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
28372                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
28373         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
28374                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
28375                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
28376         remote_mds_nodsh && skip "remote MDS with nodsh"
28377
28378         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
28379 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
28380         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
28381         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
28382                 echo "Touch failed - OK"
28383 }
28384 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
28385
28386 test_403() {
28387         local file1=$DIR/$tfile.1
28388         local file2=$DIR/$tfile.2
28389         local tfile=$TMP/$tfile
28390
28391         rm -f $file1 $file2 $tfile
28392
28393         touch $file1
28394         ln $file1 $file2
28395
28396         # 30 sec OBD_TIMEOUT in ll_getattr()
28397         # right before populating st_nlink
28398         $LCTL set_param fail_loc=0x80001409
28399         stat -c %h $file1 > $tfile &
28400
28401         # create an alias, drop all locks and reclaim the dentry
28402         < $file2
28403         cancel_lru_locks mdc
28404         cancel_lru_locks osc
28405         sysctl -w vm.drop_caches=2
28406
28407         wait
28408
28409         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
28410
28411         rm -f $tfile $file1 $file2
28412 }
28413 run_test 403 "i_nlink should not drop to zero due to aliasing"
28414
28415 test_404() { # LU-6601
28416         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
28417                 skip "Need server version newer than 2.8.52"
28418         remote_mds_nodsh && skip "remote MDS with nodsh"
28419
28420         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
28421                 awk '/osp .*-osc-MDT/ { print $4}')
28422
28423         local osp
28424         for osp in $mosps; do
28425                 echo "Deactivate: " $osp
28426                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
28427                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
28428                         awk -vp=$osp '$4 == p { print $2 }')
28429                 [ $stat = IN ] || {
28430                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
28431                         error "deactivate error"
28432                 }
28433                 echo "Activate: " $osp
28434                 do_facet $SINGLEMDS $LCTL --device %$osp activate
28435                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
28436                         awk -vp=$osp '$4 == p { print $2 }')
28437                 [ $stat = UP ] || {
28438                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
28439                         error "activate error"
28440                 }
28441         done
28442 }
28443 run_test 404 "validate manual {de}activated works properly for OSPs"
28444
28445 test_405() {
28446         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
28447         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
28448                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
28449                         skip "Layout swap lock is not supported"
28450
28451         check_swap_layouts_support
28452         check_swap_layout_no_dom $DIR
28453
28454         test_mkdir $DIR/$tdir
28455         swap_lock_test -d $DIR/$tdir ||
28456                 error "One layout swap locked test failed"
28457 }
28458 run_test 405 "Various layout swap lock tests"
28459
28460 test_406() {
28461         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
28462         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
28463         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
28464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28465         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
28466                 skip "Need MDS version at least 2.8.50"
28467
28468         local def_stripe_size=$($LFS getstripe -S $MOUNT)
28469         local test_pool=$TESTNAME
28470
28471         pool_add $test_pool || error "pool_add failed"
28472         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
28473                 error "pool_add_targets failed"
28474
28475         save_layout_restore_at_exit $MOUNT
28476
28477         # parent set default stripe count only, child will stripe from both
28478         # parent and fs default
28479         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
28480                 error "setstripe $MOUNT failed"
28481         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
28482         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
28483         for i in $(seq 10); do
28484                 local f=$DIR/$tdir/$tfile.$i
28485                 touch $f || error "touch failed"
28486                 local count=$($LFS getstripe -c $f)
28487                 [ $count -eq $OSTCOUNT ] ||
28488                         error "$f stripe count $count != $OSTCOUNT"
28489                 local offset=$($LFS getstripe -i $f)
28490                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
28491                 local size=$($LFS getstripe -S $f)
28492                 [ $size -eq $((def_stripe_size * 2)) ] ||
28493                         error "$f stripe size $size != $((def_stripe_size * 2))"
28494                 local pool=$($LFS getstripe -p $f)
28495                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
28496         done
28497
28498         # change fs default striping, delete parent default striping, now child
28499         # will stripe from new fs default striping only
28500         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
28501                 error "change $MOUNT default stripe failed"
28502         $LFS setstripe -c 0 $DIR/$tdir ||
28503                 error "delete $tdir default stripe failed"
28504         for i in $(seq 11 20); do
28505                 local f=$DIR/$tdir/$tfile.$i
28506                 touch $f || error "touch $f failed"
28507                 local count=$($LFS getstripe -c $f)
28508                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
28509                 local offset=$($LFS getstripe -i $f)
28510                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
28511                 local size=$($LFS getstripe -S $f)
28512                 [ $size -eq $def_stripe_size ] ||
28513                         error "$f stripe size $size != $def_stripe_size"
28514                 local pool=$($LFS getstripe -p $f)
28515                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
28516         done
28517
28518         unlinkmany $DIR/$tdir/$tfile. 1 20
28519
28520         local f=$DIR/$tdir/$tfile
28521         pool_remove_all_targets $test_pool $f
28522         pool_remove $test_pool $f
28523 }
28524 run_test 406 "DNE support fs default striping"
28525
28526 test_407() {
28527         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
28528         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
28529                 skip "Need MDS version at least 2.8.55"
28530         remote_mds_nodsh && skip "remote MDS with nodsh"
28531
28532         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
28533                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
28534         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
28535                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
28536         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
28537
28538         #define OBD_FAIL_DT_TXN_STOP    0x2019
28539         for idx in $(seq $MDSCOUNT); do
28540                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
28541         done
28542         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
28543         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
28544                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
28545         true
28546 }
28547 run_test 407 "transaction fail should cause operation fail"
28548
28549 test_408() {
28550         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
28551
28552         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
28553         lctl set_param fail_loc=0x8000040a
28554         # let ll_prepare_partial_page() fail
28555         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
28556
28557         rm -f $DIR/$tfile
28558
28559         # create at least 100 unused inodes so that
28560         # shrink_icache_memory(0) should not return 0
28561         touch $DIR/$tfile-{0..100}
28562         rm -f $DIR/$tfile-{0..100}
28563         sync
28564
28565         echo 2 > /proc/sys/vm/drop_caches
28566 }
28567 run_test 408 "drop_caches should not hang due to page leaks"
28568
28569 test_409()
28570 {
28571         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28572
28573         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
28574         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
28575         touch $DIR/$tdir/guard || error "(2) Fail to create"
28576
28577         local PREFIX=$(str_repeat 'A' 128)
28578         echo "Create 1K hard links start at $(date)"
28579         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
28580                 error "(3) Fail to hard link"
28581
28582         echo "Links count should be right although linkEA overflow"
28583         stat $DIR/$tdir/guard || error "(4) Fail to stat"
28584         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
28585         [ $linkcount -eq 1001 ] ||
28586                 error "(5) Unexpected hard links count: $linkcount"
28587
28588         echo "List all links start at $(date)"
28589         ls -l $DIR/$tdir/foo > /dev/null ||
28590                 error "(6) Fail to list $DIR/$tdir/foo"
28591
28592         echo "Unlink hard links start at $(date)"
28593         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
28594                 error "(7) Fail to unlink"
28595         echo "Unlink hard links finished at $(date)"
28596 }
28597 run_test 409 "Large amount of cross-MDTs hard links on the same file"
28598
28599 test_410()
28600 {
28601         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
28602                 skip "Need client version at least 2.9.59"
28603
28604         # Create a file, and stat it from the kernel
28605         local testfile=$DIR/$tfile
28606         touch $testfile
28607
28608         local run_id=$RANDOM
28609         local my_ino=$(stat --format "%i" $testfile)
28610
28611         # Try to insert the module.
28612         load_module kunit/kinode run_id=$run_id fname=$testfile ||
28613                 error "load_module failed"
28614
28615         # Anything but success is a test failure
28616         dmesg | grep -q \
28617             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
28618             error "no inode match"
28619
28620         # Remove the test module
28621         rmmod -v kinode ||
28622                 error "rmmod failed (may trigger a failure in a later test)"
28623 }
28624 run_test 410 "Test inode number returned from kernel thread"
28625
28626 cleanup_test411_cgroup() {
28627         trap 0
28628         cat $1/memory.stat
28629         rmdir "$1"
28630 }
28631
28632 test_411a() {
28633         local cg_basedir=/sys/fs/cgroup/memory
28634         # LU-9966
28635         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
28636                 skip "no setup for cgroup"
28637
28638         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
28639                 error "test file creation failed"
28640         cancel_lru_locks osc
28641
28642         # Create a very small memory cgroup to force a slab allocation error
28643         local cgdir=$cg_basedir/osc_slab_alloc
28644         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
28645         trap "cleanup_test411_cgroup $cgdir" EXIT
28646         echo 2M > $cgdir/memory.kmem.limit_in_bytes
28647         echo 1M > $cgdir/memory.limit_in_bytes
28648
28649         # Should not LBUG, just be killed by oom-killer
28650         # dd will return 0 even allocation failure in some environment.
28651         # So don't check return value
28652         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
28653         cleanup_test411_cgroup $cgdir
28654
28655         return 0
28656 }
28657 run_test 411a "Slab allocation error with cgroup does not LBUG"
28658
28659 test_411b() {
28660         local cg_basedir=/sys/fs/cgroup/memory
28661         # LU-9966
28662         [ -e "$cg_basedir/memory.kmem.limit_in_bytes" ] ||
28663                 skip "no setup for cgroup"
28664         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
28665         # (x86) testing suggests we can't reliably avoid OOM with a 64M-256M
28666         # limit, so we have 384M in cgroup
28667         # (arm) this seems to hit OOM more often than x86, so 1024M
28668         if [[ $(uname -m) = aarch64 ]]; then
28669                 local memlimit_mb=1024
28670         else
28671                 local memlimit_mb=384
28672         fi
28673
28674         # Create a cgroup and set memory limit
28675         # (tfile is used as an easy way to get a recognizable cgroup name)
28676         local cgdir=$cg_basedir/$tfile
28677         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
28678         stack_trap "cleanup_test411_cgroup $cgdir" EXIT
28679         echo $((memlimit_mb * 1024 * 1024)) > $cgdir/memory.limit_in_bytes
28680
28681         echo "writing first file"
28682         # Write a file 4x the memory limit in size
28683         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=1M count=$((memlimit_mb * 4))" ||
28684                 error "(1) failed to write successfully"
28685
28686         sync
28687         cancel_lru_locks osc
28688
28689         rm -f $DIR/$tfile
28690         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
28691
28692         # Try writing at a larger block size
28693         # NB: if block size is >= 1/2 cgroup size, we sometimes get OOM killed
28694         # so test with 1/4 cgroup size (this seems reasonable to me - we do
28695         # need *some* memory to do IO in)
28696         echo "writing at larger block size"
28697         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=64M count=$((memlimit_mb * 4 / 128))" ||
28698                 error "(3) failed to write successfully"
28699
28700         sync
28701         cancel_lru_locks osc
28702         rm -f $DIR/$tfile
28703         $LFS setstripe -c 2 $DIR/$tfile.{1..4} || error "unable to setstripe"
28704
28705         # Try writing multiple files at once
28706         echo "writing multiple files"
28707         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.1 bs=32M count=$((memlimit_mb * 4 / 64))" &
28708         local pid1=$!
28709         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.2 bs=32M count=$((memlimit_mb * 4 / 64))" &
28710         local pid2=$!
28711         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.3 bs=32M count=$((memlimit_mb * 4 / 64))" &
28712         local pid3=$!
28713         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.4 bs=32M count=$((memlimit_mb * 4 / 64))" &
28714         local pid4=$!
28715
28716         wait $pid1
28717         local rc1=$?
28718         wait $pid2
28719         local rc2=$?
28720         wait $pid3
28721         local rc3=$?
28722         wait $pid4
28723         local rc4=$?
28724         if (( rc1 != 0)); then
28725                 error "error $rc1 writing to file from $pid1"
28726         fi
28727         if (( rc2 != 0)); then
28728                 error "error $rc2 writing to file from $pid2"
28729         fi
28730         if (( rc3 != 0)); then
28731                 error "error $rc3 writing to file from $pid3"
28732         fi
28733         if (( rc4 != 0)); then
28734                 error "error $rc4 writing to file from $pid4"
28735         fi
28736
28737         sync
28738         cancel_lru_locks osc
28739
28740         # These files can be large-ish (~1 GiB total), so delete them rather
28741         # than leave for later cleanup
28742         rm -f $DIR/$tfile.*
28743         return 0
28744 }
28745 run_test 411b "confirm Lustre can avoid OOM with reasonable cgroups limits"
28746
28747 test_412() {
28748         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
28749         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
28750                 skip "Need server version at least 2.10.55"
28751
28752         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
28753                 error "mkdir failed"
28754         $LFS getdirstripe $DIR/$tdir
28755         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
28756         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
28757                 error "expect $((MDSCOUT - 1)) get $stripe_index"
28758         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
28759         [ $stripe_count -eq 2 ] ||
28760                 error "expect 2 get $stripe_count"
28761
28762         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
28763
28764         local index
28765         local index2
28766
28767         # subdirs should be on the same MDT as parent
28768         for i in $(seq 0 $((MDSCOUNT - 1))); do
28769                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
28770                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
28771                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
28772                 (( index == i )) || error "mdt$i/sub on MDT$index"
28773         done
28774
28775         # stripe offset -1, ditto
28776         for i in {1..10}; do
28777                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
28778                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
28779                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
28780                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
28781                 (( index == index2 )) ||
28782                         error "qos$i on MDT$index, sub on MDT$index2"
28783         done
28784
28785         local testdir=$DIR/$tdir/inherit
28786
28787         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
28788         # inherit 2 levels
28789         for i in 1 2; do
28790                 testdir=$testdir/s$i
28791                 mkdir $testdir || error "mkdir $testdir failed"
28792                 index=$($LFS getstripe -m $testdir)
28793                 (( index == 1 )) ||
28794                         error "$testdir on MDT$index"
28795         done
28796
28797         # not inherit any more
28798         testdir=$testdir/s3
28799         mkdir $testdir || error "mkdir $testdir failed"
28800         getfattr -d -m dmv $testdir | grep dmv &&
28801                 error "default LMV set on $testdir" || true
28802 }
28803 run_test 412 "mkdir on specific MDTs"
28804
28805 TEST413_COUNT=${TEST413_COUNT:-200}
28806
28807 #
28808 # set_maxage() is used by test_413 only.
28809 # This is a helper function to set maxage. Does not return any value.
28810 # Input: maxage to set
28811 #
28812 set_maxage() {
28813         local lmv_qos_maxage
28814         local lod_qos_maxage
28815         local new_maxage=$1
28816
28817         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
28818         $LCTL set_param lmv.*.qos_maxage=$new_maxage
28819         stack_trap "$LCTL set_param \
28820                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
28821         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
28822                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
28823         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28824                 lod.*.mdt_qos_maxage=$new_maxage
28825         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28826                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
28827 }
28828
28829 generate_uneven_mdts() {
28830         local threshold=$1
28831         local ffree
28832         local bavail
28833         local max
28834         local min
28835         local max_index
28836         local min_index
28837         local tmp
28838         local i
28839
28840         echo
28841         echo "Check for uneven MDTs: "
28842
28843         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28844         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28845         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28846
28847         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28848         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28849         max_index=0
28850         min_index=0
28851         for ((i = 1; i < ${#ffree[@]}; i++)); do
28852                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28853                 if [ $tmp -gt $max ]; then
28854                         max=$tmp
28855                         max_index=$i
28856                 fi
28857                 if [ $tmp -lt $min ]; then
28858                         min=$tmp
28859                         min_index=$i
28860                 fi
28861         done
28862
28863         (( min > 0 )) || skip "low space on MDT$min_index"
28864         (( ${ffree[min_index]} > 0 )) ||
28865                 skip "no free files on MDT$min_index"
28866         (( ${ffree[min_index]} < 10000000 )) ||
28867                 skip "too many free files on MDT$min_index"
28868
28869         # Check if we need to generate uneven MDTs
28870         local diff=$(((max - min) * 100 / min))
28871         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
28872         local testdir # individual folder within $testdirp
28873         local start
28874         local cmd
28875
28876         # fallocate is faster to consume space on MDT, if available
28877         if check_fallocate_supported mds$((min_index + 1)); then
28878                 cmd="fallocate -l 128K "
28879         else
28880                 cmd="dd if=/dev/zero bs=128K count=1 of="
28881         fi
28882
28883         echo "using cmd $cmd"
28884         for (( i = 0; diff < threshold; i++ )); do
28885                 testdir=${testdirp}/$i
28886                 [ -d $testdir ] && continue
28887
28888                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
28889
28890                 mkdir -p $testdirp
28891                 # generate uneven MDTs, create till $threshold% diff
28892                 echo -n "weight diff=$diff% must be > $threshold% ..."
28893                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
28894                 $LFS mkdir -i $min_index $testdir ||
28895                         error "mkdir $testdir failed"
28896                 $LFS setstripe -E 1M -L mdt $testdir ||
28897                         error "setstripe $testdir failed"
28898                 start=$SECONDS
28899                 for (( f = 0; f < TEST413_COUNT; f++ )); do
28900                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
28901                 done
28902                 sync; sleep 1; sync
28903
28904                 # wait for QOS to update
28905                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
28906
28907                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
28908                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
28909                 max=$(((${ffree[max_index]} >> 8) *
28910                         (${bavail[max_index]} * bsize >> 16)))
28911                 min=$(((${ffree[min_index]} >> 8) *
28912                         (${bavail[min_index]} * bsize >> 16)))
28913                 (( min > 0 )) || skip "low space on MDT$min_index"
28914                 diff=$(((max - min) * 100 / min))
28915         done
28916
28917         echo "MDT filesfree available: ${ffree[*]}"
28918         echo "MDT blocks available: ${bavail[*]}"
28919         echo "weight diff=$diff%"
28920 }
28921
28922 test_qos_mkdir() {
28923         local mkdir_cmd=$1
28924         local stripe_count=$2
28925         local mdts=$(comma_list $(mdts_nodes))
28926
28927         local testdir
28928         local lmv_qos_prio_free
28929         local lmv_qos_threshold_rr
28930         local lod_qos_prio_free
28931         local lod_qos_threshold_rr
28932         local total
28933         local count
28934         local i
28935
28936         # @total is total directories created if it's testing plain
28937         # directories, otherwise it's total stripe object count for
28938         # striped directories test.
28939         # remote/striped directory unlinking is slow on zfs and may
28940         # timeout, test with fewer directories
28941         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
28942
28943         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
28944         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
28945         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
28946                 head -n1)
28947         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
28948         stack_trap "$LCTL set_param \
28949                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
28950         stack_trap "$LCTL set_param \
28951                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
28952
28953         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
28954                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
28955         lod_qos_prio_free=${lod_qos_prio_free%%%}
28956         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
28957                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
28958         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
28959         stack_trap "do_nodes $mdts $LCTL set_param \
28960                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
28961         stack_trap "do_nodes $mdts $LCTL set_param \
28962                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
28963
28964         # decrease statfs age, so that it can be updated in time
28965         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
28966         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
28967
28968         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
28969         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
28970
28971         testdir=$DIR/$tdir-s$stripe_count/rr
28972
28973         local stripe_index=$($LFS getstripe -m $testdir)
28974         local test_mkdir_rr=true
28975
28976         getfattr -d -m dmv -e hex $testdir | grep dmv
28977         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
28978                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
28979                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
28980                         test_mkdir_rr=false
28981         fi
28982
28983         echo
28984         $test_mkdir_rr &&
28985                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
28986                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
28987
28988         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
28989         for (( i = 0; i < total / stripe_count; i++ )); do
28990                 eval $mkdir_cmd $testdir/subdir$i ||
28991                         error "$mkdir_cmd subdir$i failed"
28992         done
28993
28994         for (( i = 0; i < $MDSCOUNT; i++ )); do
28995                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
28996                 echo "$count directories created on MDT$i"
28997                 if $test_mkdir_rr; then
28998                         (( count == total / stripe_count / MDSCOUNT )) ||
28999                                 error "subdirs are not evenly distributed"
29000                 elif (( i == stripe_index )); then
29001                         (( count == total / stripe_count )) ||
29002                                 error "$count subdirs created on MDT$i"
29003                 else
29004                         (( count == 0 )) ||
29005                                 error "$count subdirs created on MDT$i"
29006                 fi
29007
29008                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
29009                         count=$($LFS getdirstripe $testdir/* |
29010                                 grep -c -P "^\s+$i\t")
29011                         echo "$count stripes created on MDT$i"
29012                         # deviation should < 5% of average
29013                         delta=$((count - total / MDSCOUNT))
29014                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
29015                                 error "stripes are not evenly distributed"
29016                 fi
29017         done
29018
29019         echo
29020         echo "Check for uneven MDTs: "
29021
29022         local ffree
29023         local bavail
29024         local max
29025         local min
29026         local max_index
29027         local min_index
29028         local tmp
29029
29030         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
29031         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
29032         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
29033
29034         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
29035         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
29036         max_index=0
29037         min_index=0
29038         for ((i = 1; i < ${#ffree[@]}; i++)); do
29039                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
29040                 if [ $tmp -gt $max ]; then
29041                         max=$tmp
29042                         max_index=$i
29043                 fi
29044                 if [ $tmp -lt $min ]; then
29045                         min=$tmp
29046                         min_index=$i
29047                 fi
29048         done
29049         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
29050
29051         (( min > 0 )) || skip "low space on MDT$min_index"
29052         (( ${ffree[min_index]} < 10000000 )) ||
29053                 skip "too many free files on MDT$min_index"
29054
29055         generate_uneven_mdts 120
29056
29057         echo "MDT filesfree available: ${ffree[*]}"
29058         echo "MDT blocks available: ${bavail[*]}"
29059         echo "weight diff=$(((max - min) * 100 / min))%"
29060         echo
29061         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
29062
29063         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
29064         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
29065         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
29066         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
29067
29068         sleep 1
29069
29070         testdir=$DIR/$tdir-s$stripe_count/qos
29071
29072         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
29073         for (( i = 0; i < total / stripe_count; i++ )); do
29074                 eval $mkdir_cmd $testdir/subdir$i ||
29075                         error "$mkdir_cmd subdir$i failed"
29076         done
29077
29078         max=0
29079         for (( i = 0; i < $MDSCOUNT; i++ )); do
29080                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
29081                 (( count > max )) && max=$count
29082                 echo "$count directories created on MDT$i : curmax=$max"
29083         done
29084
29085         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
29086
29087         # D-value should > 10% of average
29088         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
29089                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
29090
29091         # ditto for stripes
29092         if (( stripe_count > 1 )); then
29093                 max=0
29094                 for (( i = 0; i < $MDSCOUNT; i++ )); do
29095                         count=$($LFS getdirstripe $testdir/* |
29096                                 grep -c -P "^\s+$i\t")
29097                         (( count > max )) && max=$count
29098                         echo "$count stripes created on MDT$i"
29099                 done
29100
29101                 min=$($LFS getdirstripe $testdir/* |
29102                         grep -c -P "^\s+$min_index\t")
29103                 (( max - min > total / MDSCOUNT / 10 )) ||
29104                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
29105         fi
29106 }
29107
29108 most_full_mdt() {
29109         local ffree
29110         local bavail
29111         local bsize
29112         local min
29113         local min_index
29114         local tmp
29115
29116         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
29117         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
29118         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
29119
29120         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
29121         min_index=0
29122         for ((i = 1; i < ${#ffree[@]}; i++)); do
29123                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
29124                 (( tmp < min )) && min=$tmp && min_index=$i
29125         done
29126
29127         echo -n $min_index
29128 }
29129
29130 test_413a() {
29131         [ $MDSCOUNT -lt 2 ] &&
29132                 skip "We need at least 2 MDTs for this test"
29133
29134         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
29135                 skip "Need server version at least 2.12.52"
29136
29137         local stripe_max=$((MDSCOUNT - 1))
29138         local stripe_count
29139
29140         # let caller set maxage for latest result
29141         set_maxage 1
29142
29143         # fill MDT unevenly
29144         generate_uneven_mdts 120
29145
29146         # test 4-stripe directory at most, otherwise it's too slow
29147         # We are being very defensive. Although Autotest uses 4 MDTs.
29148         # We make sure stripe_max does not go over 4.
29149         (( stripe_max > 4 )) && stripe_max=4
29150         # unlinking striped directory is slow on zfs, and may timeout, only test
29151         # plain directory
29152         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
29153         for stripe_count in $(seq 1 $stripe_max); do
29154                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
29155                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
29156                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
29157                         error "mkdir failed"
29158                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
29159         done
29160 }
29161 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
29162
29163 test_413b() {
29164         [ $MDSCOUNT -lt 2 ] &&
29165                 skip "We need at least 2 MDTs for this test"
29166
29167         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
29168                 skip "Need server version at least 2.12.52"
29169
29170         local stripe_max=$((MDSCOUNT - 1))
29171         local testdir
29172         local stripe_count
29173
29174         # let caller set maxage for latest result
29175         set_maxage 1
29176
29177         # fill MDT unevenly
29178         generate_uneven_mdts 120
29179
29180         # test 4-stripe directory at most, otherwise it's too slow
29181         # We are being very defensive. Although Autotest uses 4 MDTs.
29182         # We make sure stripe_max does not go over 4.
29183         (( stripe_max > 4 )) && stripe_max=4
29184         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
29185         for stripe_count in $(seq 1 $stripe_max); do
29186                 testdir=$DIR/$tdir-s$stripe_count
29187                 mkdir $testdir || error "mkdir $testdir failed"
29188                 mkdir $testdir/rr || error "mkdir rr failed"
29189                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
29190                         error "mkdir qos failed"
29191                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
29192                         $testdir/rr || error "setdirstripe rr failed"
29193                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
29194                         error "setdirstripe failed"
29195                 test_qos_mkdir "mkdir" $stripe_count
29196         done
29197 }
29198 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
29199
29200 test_413c() {
29201         (( $MDSCOUNT >= 2 )) ||
29202                 skip "We need at least 2 MDTs for this test"
29203
29204         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
29205                 skip "Need server version at least 2.14.51"
29206
29207         local testdir
29208         local inherit
29209         local inherit_rr
29210         local lmv_qos_maxage
29211         local lod_qos_maxage
29212
29213         # let caller set maxage for latest result
29214         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
29215         $LCTL set_param lmv.*.qos_maxage=1
29216         stack_trap "$LCTL set_param \
29217                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
29218         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
29219                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
29220         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
29221                 lod.*.mdt_qos_maxage=1
29222         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
29223                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
29224
29225         # fill MDT unevenly
29226         generate_uneven_mdts 120
29227
29228         testdir=$DIR/${tdir}-s1
29229         mkdir $testdir || error "mkdir $testdir failed"
29230         mkdir $testdir/rr || error "mkdir rr failed"
29231         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
29232         # default max_inherit is -1, default max_inherit_rr is 0
29233         $LFS setdirstripe -D -c 1 $testdir/rr ||
29234                 error "setdirstripe rr failed"
29235         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
29236                 error "setdirstripe qos failed"
29237         test_qos_mkdir "mkdir" 1
29238
29239         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
29240         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
29241         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
29242         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
29243         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
29244
29245         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
29246         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
29247         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
29248         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
29249         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
29250         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
29251         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
29252                 error "level2 shouldn't have default LMV" || true
29253 }
29254 run_test 413c "mkdir with default LMV max inherit rr"
29255
29256 test_413d() {
29257         (( MDSCOUNT >= 2 )) ||
29258                 skip "We need at least 2 MDTs for this test"
29259
29260         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
29261                 skip "Need server version at least 2.14.51"
29262
29263         local lmv_qos_threshold_rr
29264
29265         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
29266                 head -n1)
29267         stack_trap "$LCTL set_param \
29268                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
29269
29270         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
29271         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
29272         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
29273                 error "$tdir shouldn't have default LMV"
29274         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
29275                 error "mkdir sub failed"
29276
29277         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
29278
29279         (( count == 100 )) || error "$count subdirs on MDT0"
29280 }
29281 run_test 413d "inherit ROOT default LMV"
29282
29283 test_413e() {
29284         (( MDSCOUNT >= 2 )) ||
29285                 skip "We need at least 2 MDTs for this test"
29286         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
29287                 skip "Need server version at least 2.14.55"
29288
29289         local testdir=$DIR/$tdir
29290         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
29291         local max_inherit
29292         local sub_max_inherit
29293
29294         mkdir -p $testdir || error "failed to create $testdir"
29295
29296         # set default max-inherit to -1 if stripe count is 0 or 1
29297         $LFS setdirstripe -D -c 1 $testdir ||
29298                 error "failed to set default LMV"
29299         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
29300         (( max_inherit == -1 )) ||
29301                 error "wrong max_inherit value $max_inherit"
29302
29303         # set default max_inherit to a fixed value if stripe count is not 0 or 1
29304         $LFS setdirstripe -D -c -1 $testdir ||
29305                 error "failed to set default LMV"
29306         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
29307         (( max_inherit > 0 )) ||
29308                 error "wrong max_inherit value $max_inherit"
29309
29310         # and the subdir will decrease the max_inherit by 1
29311         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
29312         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
29313         (( sub_max_inherit == max_inherit - 1)) ||
29314                 error "wrong max-inherit of subdir $sub_max_inherit"
29315
29316         # check specified --max-inherit and warning message
29317         stack_trap "rm -f $tmpfile"
29318         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
29319                 error "failed to set default LMV"
29320         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
29321         (( max_inherit == -1 )) ||
29322                 error "wrong max_inherit value $max_inherit"
29323
29324         # check the warning messages
29325         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
29326                 error "failed to detect warning string"
29327         fi
29328 }
29329 run_test 413e "check default max-inherit value"
29330
29331 test_fs_dmv_inherit()
29332 {
29333         local testdir=$DIR/$tdir
29334
29335         local count
29336         local inherit
29337         local inherit_rr
29338
29339         for i in 1 2; do
29340                 mkdir $testdir || error "mkdir $testdir failed"
29341                 count=$($LFS getdirstripe -D -c $testdir)
29342                 (( count == 1 )) ||
29343                         error "$testdir default LMV count mismatch $count != 1"
29344                 inherit=$($LFS getdirstripe -D -X $testdir)
29345                 (( inherit == 3 - i )) ||
29346                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
29347                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
29348                 (( inherit_rr == 3 - i )) ||
29349                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
29350                 testdir=$testdir/sub
29351         done
29352
29353         mkdir $testdir || error "mkdir $testdir failed"
29354         count=$($LFS getdirstripe -D -c $testdir)
29355         (( count == 0 )) ||
29356                 error "$testdir default LMV count not zero: $count"
29357 }
29358
29359 test_413f() {
29360         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
29361
29362         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
29363                 skip "Need server version at least 2.14.55"
29364
29365         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
29366                 error "dump $DIR default LMV failed"
29367         stack_trap "setfattr --restore=$TMP/dmv.ea"
29368
29369         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
29370                 error "set $DIR default LMV failed"
29371
29372         test_fs_dmv_inherit
29373 }
29374 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
29375
29376 test_413g() {
29377         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
29378
29379         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
29380         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
29381                 error "dump $DIR default LMV failed"
29382         stack_trap "setfattr --restore=$TMP/dmv.ea"
29383
29384         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
29385                 error "set $DIR default LMV failed"
29386
29387         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
29388                 error "mount $MOUNT2 failed"
29389         stack_trap "umount_client $MOUNT2"
29390
29391         local saved_DIR=$DIR
29392
29393         export DIR=$MOUNT2
29394
29395         stack_trap "export DIR=$saved_DIR"
29396
29397         # first check filesystem-wide default LMV inheritance
29398         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
29399
29400         # then check subdirs are spread to all MDTs
29401         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
29402
29403         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
29404
29405         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
29406 }
29407 run_test 413g "enforce ROOT default LMV on subdir mount"
29408
29409 test_413h() {
29410         (( MDSCOUNT >= 2 )) ||
29411                 skip "We need at least 2 MDTs for this test"
29412
29413         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
29414                 skip "Need server version at least 2.15.50.6"
29415
29416         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
29417
29418         stack_trap "$LCTL set_param \
29419                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
29420         $LCTL set_param lmv.*.qos_maxage=1
29421
29422         local depth=5
29423         local rr_depth=4
29424         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
29425         local count=$((MDSCOUNT * 20))
29426
29427         generate_uneven_mdts 50
29428
29429         mkdir -p $dir || error "mkdir $dir failed"
29430         stack_trap "rm -rf $dir"
29431         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
29432                 --max-inherit-rr=$rr_depth $dir
29433
29434         for ((d=0; d < depth + 2; d++)); do
29435                 log "dir=$dir:"
29436                 for ((sub=0; sub < count; sub++)); do
29437                         mkdir $dir/d$sub
29438                 done
29439                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
29440                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
29441                 # subdirs within $rr_depth should be created round-robin
29442                 if (( d < rr_depth )); then
29443                         (( ${num[0]} != count )) ||
29444                                 error "all objects created on MDT ${num[1]}"
29445                 fi
29446
29447                 dir=$dir/d0
29448         done
29449 }
29450 run_test 413h "don't stick to parent for round-robin dirs"
29451
29452 test_413i() {
29453         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
29454
29455         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
29456                 skip "Need server version at least 2.14.55"
29457
29458         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
29459                 error "dump $DIR default LMV failed"
29460         stack_trap "setfattr --restore=$TMP/dmv.ea"
29461
29462         local testdir=$DIR/$tdir
29463         local def_max_rr=1
29464         local def_max=3
29465         local count
29466
29467         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
29468                 --max-inherit-rr=$def_max_rr $DIR ||
29469                 error "set $DIR default LMV failed"
29470
29471         for i in $(seq 2 3); do
29472                 def_max=$((def_max - 1))
29473                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
29474
29475                 mkdir $testdir
29476                 # RR is decremented and keeps zeroed once exhausted
29477                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
29478                 (( count == def_max_rr )) ||
29479                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
29480
29481                 # max-inherit is decremented
29482                 count=$($LFS getdirstripe -D --max-inherit $testdir)
29483                 (( count == def_max )) ||
29484                         error_noexit "$testdir: max-inherit $count != $def_max"
29485
29486                 testdir=$testdir/d$i
29487         done
29488
29489         # d3 is the last inherited from ROOT, no inheritance anymore
29490         # i.e. no the default layout anymore
29491         mkdir -p $testdir/d4/d5
29492         count=$($LFS getdirstripe -D --max-inherit $testdir)
29493         (( count == -1 )) ||
29494                 error_noexit "$testdir: max-inherit $count != -1"
29495
29496         local p_count=$($LFS getdirstripe -i $testdir)
29497
29498         for i in $(seq 4 5); do
29499                 testdir=$testdir/d$i
29500
29501                 # the root default layout is not applied once exhausted
29502                 count=$($LFS getdirstripe -i $testdir)
29503                 (( count == p_count )) ||
29504                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
29505         done
29506
29507         $LFS setdirstripe -i 0 $DIR/d2
29508         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
29509         (( count == -1 )) ||
29510                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
29511 }
29512 run_test 413i "check default layout inheritance"
29513
29514 test_413j()
29515 {
29516         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
29517
29518         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
29519         $LFS setdirstripe -D -c2 --max-inherit=2 $DIR/$tdir ||
29520                 error "setdirstripe $tdir failed"
29521
29522         local value=$(getfattr -n trusted.dmv $DIR/$tdir | \
29523                       grep "trusted.dmv" |sed -e 's/[^=]\+=//')
29524
29525         mkdir -p $DIR/$tdir/sub || error "mkdir sub failed"
29526         # setfattr dmv calls setdirstripe -D
29527         setfattr -n trusted.dmv -v $value $DIR/$tdir/sub ||
29528                 error "setfattr sub failed"
29529         local value2=$(getfattr -n trusted.dmv $DIR/$tdir/sub | \
29530                        grep "trusted.dmv" |sed -e 's/[^=]\+=//')
29531
29532         [ $value == $value2 ] || error "dmv mismatch"
29533
29534         (( MDS1_VERSION >= $(version_code 2.15.58) )) || return 0
29535
29536         # do not allow remove dmv by setfattr -x
29537         do_nodes $(comma_list $(mdts_nodes)) \
29538                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=0"
29539         setfattr -x trusted.dmv $DIR/$tdir/sub || error "setfattr sub failed"
29540         getfattr -n trusted.dmv $DIR/$tdir/sub || error "default LMV deleted"
29541
29542         # allow remove dmv by setfattr -x
29543         do_nodes $(comma_list $(mdts_nodes)) \
29544                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=1"
29545         setfattr -x trusted.dmv $DIR/$tdir/sub || error "setfattr sub failed"
29546         getfattr -n trusted.dmv $DIR/$tdir/sub && error "default LMV exists"
29547         do_nodes $(comma_list $(mdts_nodes)) \
29548                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=0"
29549 }
29550 run_test 413j "set default LMV by setxattr"
29551
29552 test_413k() {
29553         (( $MDS1_VERSION >= $(version_code 2.15.60) )) ||
29554                 skip "Need server version at least 2.15.60"
29555
29556         local index1
29557         local index2
29558         local old=$($LCTL get_param -n lmv.*.qos_exclude_prefixes)
29559         local count=$($LCTL get_param -n lmv.*.qos_exclude_prefixes | wc -l)
29560         local prefixes="abc:123:foo bar"
29561
29562         # add prefixes
29563         stack_trap "$LCTL set_param lmv.*.qos_exclude_prefixes=\"$old\""
29564         $LCTL set_param lmv.*.qos_exclude_prefixes="+$prefixes"
29565
29566         mkdir $DIR/$tdir || error "mkdir $tdir failed"
29567         index1=$($LFS getstripe -m $DIR/$tdir)
29568         for dname in _temporary _temporary.XXXXXX abc 123 "foo bar"; do
29569                 mkdir "$DIR/$tdir/$dname" || error "mkdir $dname failed"
29570                 index2=$($LFS getstripe -m "$DIR/$tdir/$dname")
29571                 ((index1 == index2)) ||
29572                         error "$tdir on MDT$index1, $dname on MDT$index2"
29573         done
29574
29575         # remove prefixes
29576         $LCTL set_param lmv.*.qos_exclude_prefixes="-$prefixes"
29577
29578         # total prefixes length > PAGE_SIZE can be printed correctly
29579         for c in {a..z}; do
29580                 prefixes=$(str_repeat $c 255)
29581                 $LCTL set_param lmv.*.qos_exclude_prefixes="+$prefixes" >/dev/null
29582         done
29583         local count2=$($LCTL get_param -n lmv.*.qos_exclude_prefixes | wc -l)
29584         ((count2 == count + 26)) ||
29585                 error "prefixes count $count2 != $((count + 26))"
29586 }
29587 run_test 413k "QoS mkdir exclude prefixes"
29588
29589 test_413z() {
29590         local pids=""
29591         local subdir
29592         local pid
29593
29594         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
29595                 unlinkmany $subdir/f. $TEST413_COUNT &
29596                 pids="$pids $!"
29597         done
29598
29599         for pid in $pids; do
29600                 wait $pid
29601         done
29602
29603         true
29604 }
29605 run_test 413z "413 test cleanup"
29606
29607 test_414() {
29608 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
29609         $LCTL set_param fail_loc=0x80000521
29610         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
29611         rm -f $DIR/$tfile
29612         # This error path has sometimes left inflight requests dangling, so
29613         # test for this by remounting the client (umount will hang if there's
29614         # a dangling request)
29615         umount_client $MOUNT
29616         mount_client $MOUNT
29617 }
29618 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
29619
29620 test_415() {
29621         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
29622         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
29623                 skip "Need server version at least 2.11.52"
29624
29625         # LU-11102
29626         local total=500
29627         local max=120
29628
29629         # this test may be slow on ZFS
29630         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
29631
29632         # though this test is designed for striped directory, let's test normal
29633         # directory too since lock is always saved as CoS lock.
29634         test_mkdir $DIR/$tdir || error "mkdir $tdir"
29635         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
29636         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
29637         # if looping with ONLY_REPEAT, wait for previous deletions to finish
29638         wait_delete_completed_mds
29639
29640         # run a loop without concurrent touch to measure rename duration.
29641         # only for test debug/robustness, NOT part of COS functional test.
29642         local start_time=$SECONDS
29643         for ((i = 0; i < total; i++)); do
29644                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
29645                         > /dev/null
29646         done
29647         local baseline=$((SECONDS - start_time))
29648         echo "rename $total files without 'touch' took $baseline sec"
29649
29650         (
29651                 while true; do
29652                         touch $DIR/$tdir
29653                 done
29654         ) &
29655         local setattr_pid=$!
29656
29657         # rename files back to original name so unlinkmany works
29658         start_time=$SECONDS
29659         for ((i = 0; i < total; i++)); do
29660                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
29661                         > /dev/null
29662         done
29663         local duration=$((SECONDS - start_time))
29664
29665         kill -9 $setattr_pid
29666
29667         echo "rename $total files with 'touch' took $duration sec"
29668         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
29669         (( duration <= max )) ||
29670                 error_not_in_vm "rename took $duration > $max sec"
29671 }
29672 run_test 415 "lock revoke is not missing"
29673
29674 test_416() {
29675         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
29676                 skip "Need server version at least 2.11.55"
29677
29678         # define OBD_FAIL_OSD_TXN_START    0x19a
29679         do_facet mds1 lctl set_param fail_loc=0x19a
29680
29681         lfs mkdir -c $MDSCOUNT $DIR/$tdir
29682
29683         true
29684 }
29685 run_test 416 "transaction start failure won't cause system hung"
29686
29687 cleanup_417() {
29688         trap 0
29689         do_nodes $(comma_list $(mdts_nodes)) \
29690                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
29691         do_nodes $(comma_list $(mdts_nodes)) \
29692                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
29693         do_nodes $(comma_list $(mdts_nodes)) \
29694                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
29695 }
29696
29697 test_417() {
29698         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
29699         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
29700                 skip "Need MDS version at least 2.11.56"
29701
29702         trap cleanup_417 RETURN EXIT
29703
29704         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
29705         do_nodes $(comma_list $(mdts_nodes)) \
29706                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
29707         $LFS migrate -m 0 $DIR/$tdir.1 &&
29708                 error "migrate dir $tdir.1 should fail"
29709
29710         do_nodes $(comma_list $(mdts_nodes)) \
29711                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
29712         $LFS mkdir -i 1 $DIR/$tdir.2 &&
29713                 error "create remote dir $tdir.2 should fail"
29714
29715         do_nodes $(comma_list $(mdts_nodes)) \
29716                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
29717         $LFS mkdir -c 2 $DIR/$tdir.3 &&
29718                 error "create striped dir $tdir.3 should fail"
29719         true
29720 }
29721 run_test 417 "disable remote dir, striped dir and dir migration"
29722
29723 # Checks that the outputs of df [-i] and lfs df [-i] match
29724 #
29725 # usage: check_lfs_df <blocks | inodes> <mountpoint>
29726 check_lfs_df() {
29727         local dir=$2
29728         local inodes
29729         local df_out
29730         local lfs_df_out
29731         local count
29732         local passed=false
29733
29734         # blocks or inodes
29735         [ "$1" == "blocks" ] && inodes= || inodes="-i"
29736
29737         for count in {1..100}; do
29738                 do_nodes "$CLIENTS" \
29739                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
29740                 sync; sleep 0.2
29741
29742                 # read the lines of interest
29743                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
29744                         error "df $inodes $dir | tail -n +2 failed"
29745                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
29746                         error "lfs df $inodes $dir | grep summary: failed"
29747
29748                 # skip first substrings of each output as they are different
29749                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
29750                 # compare the two outputs
29751                 passed=true
29752                 #  skip "available" on MDT until LU-13997 is fixed.
29753                 #for i in {1..5}; do
29754                 for i in 1 2 4 5; do
29755                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
29756                 done
29757                 $passed && break
29758         done
29759
29760         if ! $passed; then
29761                 df -P $inodes $dir
29762                 echo
29763                 lfs df $inodes $dir
29764                 error "df and lfs df $1 output mismatch: "      \
29765                       "df ${inodes}: ${df_out[*]}, "            \
29766                       "lfs df ${inodes}: ${lfs_df_out[*]}"
29767         fi
29768 }
29769
29770 test_418() {
29771         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29772
29773         local dir=$DIR/$tdir
29774         local numfiles=$((RANDOM % 4096 + 2))
29775         local numblocks=$((RANDOM % 256 + 1))
29776
29777         wait_delete_completed
29778         test_mkdir $dir
29779
29780         # check block output
29781         check_lfs_df blocks $dir
29782         # check inode output
29783         check_lfs_df inodes $dir
29784
29785         # create a single file and retest
29786         echo "Creating a single file and testing"
29787         createmany -o $dir/$tfile- 1 &>/dev/null ||
29788                 error "creating 1 file in $dir failed"
29789         check_lfs_df blocks $dir
29790         check_lfs_df inodes $dir
29791
29792         # create a random number of files
29793         echo "Creating $((numfiles - 1)) files and testing"
29794         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
29795                 error "creating $((numfiles - 1)) files in $dir failed"
29796
29797         # write a random number of blocks to the first test file
29798         echo "Writing $numblocks 4K blocks and testing"
29799         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
29800                 count=$numblocks &>/dev/null ||
29801                 error "dd to $dir/${tfile}-0 failed"
29802
29803         # retest
29804         check_lfs_df blocks $dir
29805         check_lfs_df inodes $dir
29806
29807         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
29808                 error "unlinking $numfiles files in $dir failed"
29809 }
29810 run_test 418 "df and lfs df outputs match"
29811
29812 test_419()
29813 {
29814         local dir=$DIR/$tdir
29815
29816         mkdir -p $dir
29817         touch $dir/file
29818
29819         cancel_lru_locks mdc
29820
29821         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
29822         $LCTL set_param fail_loc=0x1410
29823         cat $dir/file
29824         $LCTL set_param fail_loc=0
29825         rm -rf $dir
29826 }
29827 run_test 419 "Verify open file by name doesn't crash kernel"
29828
29829 test_420()
29830 {
29831         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
29832                 skip "Need MDS version at least 2.12.53"
29833
29834         local SAVE_UMASK=$(umask)
29835         local dir=$DIR/$tdir
29836         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
29837
29838         mkdir -p $dir
29839         umask 0000
29840         mkdir -m03777 $dir/testdir
29841         ls -dn $dir/testdir
29842         # Need to remove trailing '.' when SELinux is enabled
29843         local dirperms=$(ls -dn $dir/testdir |
29844                          awk '{ sub(/\.$/, "", $1); print $1}')
29845         [ $dirperms == "drwxrwsrwt" ] ||
29846                 error "incorrect perms on $dir/testdir"
29847
29848         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
29849                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
29850         ls -n $dir/testdir/testfile
29851         local fileperms=$(ls -n $dir/testdir/testfile |
29852                           awk '{ sub(/\.$/, "", $1); print $1}')
29853         [ $fileperms == "-rwxr-xr-x" ] ||
29854                 error "incorrect perms on $dir/testdir/testfile"
29855
29856         umask $SAVE_UMASK
29857 }
29858 run_test 420 "clear SGID bit on non-directories for non-members"
29859
29860 test_421a() {
29861         local cnt
29862         local fid1
29863         local fid2
29864
29865         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29866                 skip "Need MDS version at least 2.12.54"
29867
29868         test_mkdir $DIR/$tdir
29869         createmany -o $DIR/$tdir/f 3
29870         cnt=$(ls -1 $DIR/$tdir | wc -l)
29871         [ $cnt != 3 ] && error "unexpected #files: $cnt"
29872
29873         fid1=$(lfs path2fid $DIR/$tdir/f1)
29874         fid2=$(lfs path2fid $DIR/$tdir/f2)
29875         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
29876
29877         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
29878         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
29879
29880         cnt=$(ls -1 $DIR/$tdir | wc -l)
29881         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
29882
29883         rm -f $DIR/$tdir/f3 || error "can't remove f3"
29884         createmany -o $DIR/$tdir/f 3
29885         cnt=$(ls -1 $DIR/$tdir | wc -l)
29886         [ $cnt != 3 ] && error "unexpected #files: $cnt"
29887
29888         fid1=$(lfs path2fid $DIR/$tdir/f1)
29889         fid2=$(lfs path2fid $DIR/$tdir/f2)
29890         echo "remove using fsname $FSNAME"
29891         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
29892
29893         cnt=$(ls -1 $DIR/$tdir | wc -l)
29894         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
29895 }
29896 run_test 421a "simple rm by fid"
29897
29898 test_421b() {
29899         local cnt
29900         local FID1
29901         local FID2
29902
29903         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29904                 skip "Need MDS version at least 2.12.54"
29905
29906         test_mkdir $DIR/$tdir
29907         createmany -o $DIR/$tdir/f 3
29908         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
29909         MULTIPID=$!
29910
29911         FID1=$(lfs path2fid $DIR/$tdir/f1)
29912         FID2=$(lfs path2fid $DIR/$tdir/f2)
29913         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
29914
29915         kill -USR1 $MULTIPID
29916         wait
29917
29918         cnt=$(ls $DIR/$tdir | wc -l)
29919         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
29920 }
29921 run_test 421b "rm by fid on open file"
29922
29923 test_421c() {
29924         local cnt
29925         local FIDS
29926
29927         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29928                 skip "Need MDS version at least 2.12.54"
29929
29930         test_mkdir $DIR/$tdir
29931         createmany -o $DIR/$tdir/f 3
29932         touch $DIR/$tdir/$tfile
29933         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
29934         cnt=$(ls -1 $DIR/$tdir | wc -l)
29935         [ $cnt != 184 ] && error "unexpected #files: $cnt"
29936
29937         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
29938         $LFS rmfid $DIR $FID1 || error "rmfid failed"
29939
29940         cnt=$(ls $DIR/$tdir | wc -l)
29941         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
29942 }
29943 run_test 421c "rm by fid against hardlinked files"
29944
29945 test_421d() {
29946         local cnt
29947         local FIDS
29948
29949         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29950                 skip "Need MDS version at least 2.12.54"
29951
29952         test_mkdir $DIR/$tdir
29953         createmany -o $DIR/$tdir/f 4097
29954         cnt=$(ls -1 $DIR/$tdir | wc -l)
29955         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
29956
29957         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
29958         $LFS rmfid $DIR $FIDS || error "rmfid failed"
29959
29960         cnt=$(ls $DIR/$tdir | wc -l)
29961         rm -rf $DIR/$tdir
29962         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
29963 }
29964 run_test 421d "rmfid en masse"
29965
29966 test_421e() {
29967         local cnt
29968         local FID
29969
29970         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
29971         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29972                 skip "Need MDS version at least 2.12.54"
29973
29974         mkdir -p $DIR/$tdir
29975         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
29976         createmany -o $DIR/$tdir/striped_dir/f 512
29977         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
29978         [ $cnt != 512 ] && error "unexpected #files: $cnt"
29979
29980         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
29981                 sed "s/[/][^:]*://g")
29982         $LFS rmfid $DIR $FIDS || error "rmfid failed"
29983
29984         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
29985         rm -rf $DIR/$tdir
29986         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
29987 }
29988 run_test 421e "rmfid in DNE"
29989
29990 test_421f() {
29991         local cnt
29992         local FID
29993
29994         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29995                 skip "Need MDS version at least 2.12.54"
29996
29997         test_mkdir $DIR/$tdir
29998         touch $DIR/$tdir/f
29999         cnt=$(ls -1 $DIR/$tdir | wc -l)
30000         [ $cnt != 1 ] && error "unexpected #files: $cnt"
30001
30002         FID=$(lfs path2fid $DIR/$tdir/f)
30003         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
30004         # rmfid should fail
30005         cnt=$(ls -1 $DIR/$tdir | wc -l)
30006         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
30007
30008         chmod a+rw $DIR/$tdir
30009         ls -la $DIR/$tdir
30010         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
30011         # rmfid should fail
30012         cnt=$(ls -1 $DIR/$tdir | wc -l)
30013         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
30014
30015         rm -f $DIR/$tdir/f
30016         $RUNAS touch $DIR/$tdir/f
30017         FID=$(lfs path2fid $DIR/$tdir/f)
30018         echo "rmfid as root"
30019         $LFS rmfid $DIR $FID || error "rmfid as root failed"
30020         cnt=$(ls -1 $DIR/$tdir | wc -l)
30021         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
30022
30023         rm -f $DIR/$tdir/f
30024         $RUNAS touch $DIR/$tdir/f
30025         cnt=$(ls -1 $DIR/$tdir | wc -l)
30026         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
30027         FID=$(lfs path2fid $DIR/$tdir/f)
30028         # rmfid w/o user_fid2path mount option should fail
30029         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
30030         cnt=$(ls -1 $DIR/$tdir | wc -l)
30031         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
30032
30033         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
30034         stack_trap "rmdir $tmpdir"
30035         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
30036                 error "failed to mount client'"
30037         stack_trap "umount_client $tmpdir"
30038
30039         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
30040         # rmfid should succeed
30041         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
30042         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
30043
30044         # rmfid shouldn't allow to remove files due to dir's permission
30045         chmod a+rwx $tmpdir/$tdir
30046         touch $tmpdir/$tdir/f
30047         ls -la $tmpdir/$tdir
30048         FID=$(lfs path2fid $tmpdir/$tdir/f)
30049         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
30050         return 0
30051 }
30052 run_test 421f "rmfid checks permissions"
30053
30054 test_421g() {
30055         local cnt
30056         local FIDS
30057
30058         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
30059         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
30060                 skip "Need MDS version at least 2.12.54"
30061
30062         mkdir -p $DIR/$tdir
30063         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
30064         createmany -o $DIR/$tdir/striped_dir/f 512
30065         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
30066         [ $cnt != 512 ] && error "unexpected #files: $cnt"
30067
30068         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
30069                 sed "s/[/][^:]*://g")
30070
30071         rm -f $DIR/$tdir/striped_dir/f1*
30072         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
30073         removed=$((512 - cnt))
30074
30075         # few files have been just removed, so we expect
30076         # rmfid to fail on their fids
30077         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
30078         [ $removed != $errors ] && error "$errors != $removed"
30079
30080         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
30081         rm -rf $DIR/$tdir
30082         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
30083 }
30084 run_test 421g "rmfid to return errors properly"
30085
30086 test_421h() {
30087         local mount_other
30088         local mount_ret
30089         local rmfid_ret
30090         local old_fid
30091         local fidA
30092         local fidB
30093         local fidC
30094         local fidD
30095
30096         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
30097                 skip "Need MDS version at least 2.15.53"
30098
30099         test_mkdir $DIR/$tdir
30100         test_mkdir $DIR/$tdir/subdir
30101         touch $DIR/$tdir/subdir/file0
30102         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
30103         echo File $DIR/$tdir/subdir/file0 FID $old_fid
30104         rm -f $DIR/$tdir/subdir/file0
30105         touch $DIR/$tdir/subdir/fileA
30106         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
30107         echo File $DIR/$tdir/subdir/fileA FID $fidA
30108         touch $DIR/$tdir/subdir/fileB
30109         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
30110         echo File $DIR/$tdir/subdir/fileB FID $fidB
30111         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
30112         touch $DIR/$tdir/subdir/fileC
30113         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
30114         echo File $DIR/$tdir/subdir/fileC FID $fidC
30115         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
30116         touch $DIR/$tdir/fileD
30117         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
30118         echo File $DIR/$tdir/fileD FID $fidD
30119
30120         # mount another client mount point with subdirectory mount
30121         export FILESET=/$tdir/subdir
30122         mount_other=${MOUNT}_other
30123         mount_client $mount_other ${MOUNT_OPTS}
30124         mount_ret=$?
30125         export FILESET=""
30126         (( mount_ret == 0 )) || error "mount $mount_other failed"
30127
30128         echo Removing FIDs:
30129         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
30130         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
30131         rmfid_ret=$?
30132
30133         umount_client $mount_other || error "umount $mount_other failed"
30134
30135         (( rmfid_ret != 0 )) || error "rmfid should have failed"
30136
30137         # fileA should have been deleted
30138         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
30139
30140         # fileB should have been deleted
30141         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
30142
30143         # fileC should not have been deleted, fid also exists outside of fileset
30144         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
30145
30146         # fileD should not have been deleted, it exists outside of fileset
30147         stat $DIR/$tdir/fileD || error "fileD deleted"
30148 }
30149 run_test 421h "rmfid with fileset mount"
30150
30151 test_422() {
30152         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
30153         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
30154         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
30155         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
30156         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
30157
30158         local amc=$(at_max_get client)
30159         local amo=$(at_max_get mds1)
30160         local timeout=`lctl get_param -n timeout`
30161
30162         at_max_set 0 client
30163         at_max_set 0 mds1
30164
30165 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
30166         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
30167                         fail_val=$(((2*timeout + 10)*1000))
30168         touch $DIR/$tdir/d3/file &
30169         sleep 2
30170 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
30171         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
30172                         fail_val=$((2*timeout + 5))
30173         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
30174         local pid=$!
30175         sleep 1
30176         kill -9 $pid
30177         sleep $((2 * timeout))
30178         echo kill $pid
30179         kill -9 $pid
30180         lctl mark touch
30181         touch $DIR/$tdir/d2/file3
30182         touch $DIR/$tdir/d2/file4
30183         touch $DIR/$tdir/d2/file5
30184
30185         wait
30186         at_max_set $amc client
30187         at_max_set $amo mds1
30188
30189         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
30190         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
30191                 error "Watchdog is always throttled"
30192 }
30193 run_test 422 "kill a process with RPC in progress"
30194
30195 stat_test() {
30196     df -h $MOUNT &
30197     df -h $MOUNT &
30198     df -h $MOUNT &
30199     df -h $MOUNT &
30200     df -h $MOUNT &
30201     df -h $MOUNT &
30202 }
30203
30204 test_423() {
30205     local _stats
30206     # ensure statfs cache is expired
30207     sleep 2;
30208
30209     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
30210     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
30211
30212     return 0
30213 }
30214 run_test 423 "statfs should return a right data"
30215
30216 test_424() {
30217 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | CFS_FAIL_ONCE
30218         $LCTL set_param fail_loc=0x80000522
30219         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
30220         rm -f $DIR/$tfile
30221 }
30222 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
30223
30224 test_425() {
30225         test_mkdir -c -1 $DIR/$tdir
30226         $LFS setstripe -c -1 $DIR/$tdir
30227
30228         lru_resize_disable "" 100
30229         stack_trap "lru_resize_enable" EXIT
30230
30231         sleep 5
30232
30233         for i in $(seq $((MDSCOUNT * 125))); do
30234                 local t=$DIR/$tdir/$tfile_$i
30235
30236                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
30237                         error_noexit "Create file $t"
30238         done
30239         stack_trap "rm -rf $DIR/$tdir" EXIT
30240
30241         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
30242                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
30243                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
30244
30245                 [ $lock_count -le $lru_size ] ||
30246                         error "osc lock count $lock_count > lru size $lru_size"
30247         done
30248
30249         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
30250                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
30251                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
30252
30253                 [ $lock_count -le $lru_size ] ||
30254                         error "mdc lock count $lock_count > lru size $lru_size"
30255         done
30256 }
30257 run_test 425 "lock count should not exceed lru size"
30258
30259 test_426() {
30260         splice-test -r $DIR/$tfile
30261         splice-test -rd $DIR/$tfile
30262         splice-test $DIR/$tfile
30263         splice-test -d $DIR/$tfile
30264 }
30265 run_test 426 "splice test on Lustre"
30266
30267 test_427() {
30268         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
30269         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
30270                 skip "Need MDS version at least 2.12.4"
30271         local log
30272
30273         mkdir $DIR/$tdir
30274         mkdir $DIR/$tdir/1
30275         mkdir $DIR/$tdir/2
30276         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
30277         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
30278
30279         $LFS getdirstripe $DIR/$tdir/1/dir
30280
30281         #first setfattr for creating updatelog
30282         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
30283
30284 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
30285         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
30286         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
30287         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
30288
30289         sleep 2
30290         fail mds2
30291         wait_recovery_complete mds2 $((2*TIMEOUT))
30292
30293         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
30294         echo $log | grep "get update log failed" &&
30295                 error "update log corruption is detected" || true
30296 }
30297 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
30298
30299 test_428() {
30300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30301         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
30302                               awk '/^max_cached_mb/ { print $2 }')
30303         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
30304
30305         $LCTL set_param -n llite.*.max_cached_mb=64
30306
30307         mkdir $DIR/$tdir
30308         $LFS setstripe -c 1 $DIR/$tdir
30309         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
30310         stack_trap "rm -f $DIR/$tdir/$tfile.*"
30311         #test write
30312         for f in $(seq 4); do
30313                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
30314         done
30315         wait
30316
30317         cancel_lru_locks osc
30318         # Test read
30319         for f in $(seq 4); do
30320                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
30321         done
30322         wait
30323 }
30324 run_test 428 "large block size IO should not hang"
30325
30326 test_429() { # LU-7915 / LU-10948
30327         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
30328         local testfile=$DIR/$tfile
30329         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
30330         local new_flag=1
30331         local first_rpc
30332         local second_rpc
30333         local third_rpc
30334
30335         $LCTL get_param $ll_opencache_threshold_count ||
30336                 skip "client does not have opencache parameter"
30337
30338         set_opencache $new_flag
30339         stack_trap "restore_opencache"
30340         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
30341                 error "enable opencache failed"
30342         touch $testfile
30343         # drop MDC DLM locks
30344         cancel_lru_locks mdc
30345         # clear MDC RPC stats counters
30346         $LCTL set_param $mdc_rpcstats=clear
30347
30348         # According to the current implementation, we need to run 3 times
30349         # open & close file to verify if opencache is enabled correctly.
30350         # 1st, RPCs are sent for lookup/open and open handle is released on
30351         #      close finally.
30352         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
30353         #      so open handle won't be released thereafter.
30354         # 3rd, No RPC is sent out.
30355         $MULTIOP $testfile oc || error "multiop failed"
30356         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
30357         echo "1st: $first_rpc RPCs in flight"
30358
30359         $MULTIOP $testfile oc || error "multiop failed"
30360         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
30361         echo "2nd: $second_rpc RPCs in flight"
30362
30363         $MULTIOP $testfile oc || error "multiop failed"
30364         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
30365         echo "3rd: $third_rpc RPCs in flight"
30366
30367         #verify no MDC RPC is sent
30368         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
30369 }
30370 run_test 429 "verify if opencache flag on client side does work"
30371
30372 lseek_test_430() {
30373         local offset
30374         local file=$1
30375
30376         # data at [200K, 400K)
30377         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
30378                 error "256K->512K dd fails"
30379         # data at [2M, 3M)
30380         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
30381                 error "2M->3M dd fails"
30382         # data at [4M, 5M)
30383         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
30384                 error "4M->5M dd fails"
30385         echo "Data at 256K...512K, 2M...3M and 4M...5M"
30386         # start at first component hole #1
30387         printf "Seeking hole from 1000 ... "
30388         offset=$(lseek_test -l 1000 $file)
30389         echo $offset
30390         [[ $offset == 1000 ]] || error "offset $offset != 1000"
30391         printf "Seeking data from 1000 ... "
30392         offset=$(lseek_test -d 1000 $file)
30393         echo $offset
30394         [[ $offset == 262144 ]] || error "offset $offset != 262144"
30395
30396         # start at first component data block
30397         printf "Seeking hole from 300000 ... "
30398         offset=$(lseek_test -l 300000 $file)
30399         echo $offset
30400         [[ $offset == 524288 ]] || error "offset $offset != 524288"
30401         printf "Seeking data from 300000 ... "
30402         offset=$(lseek_test -d 300000 $file)
30403         echo $offset
30404         [[ $offset == 300000 ]] || error "offset $offset != 300000"
30405
30406         # start at the first component but beyond end of object size
30407         printf "Seeking hole from 1000000 ... "
30408         offset=$(lseek_test -l 1000000 $file)
30409         echo $offset
30410         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
30411         printf "Seeking data from 1000000 ... "
30412         offset=$(lseek_test -d 1000000 $file)
30413         echo $offset
30414         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
30415
30416         # start at second component stripe 2 (empty file)
30417         printf "Seeking hole from 1500000 ... "
30418         offset=$(lseek_test -l 1500000 $file)
30419         echo $offset
30420         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
30421         printf "Seeking data from 1500000 ... "
30422         offset=$(lseek_test -d 1500000 $file)
30423         echo $offset
30424         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
30425
30426         # start at second component stripe 1 (all data)
30427         printf "Seeking hole from 3000000 ... "
30428         offset=$(lseek_test -l 3000000 $file)
30429         echo $offset
30430         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
30431         printf "Seeking data from 3000000 ... "
30432         offset=$(lseek_test -d 3000000 $file)
30433         echo $offset
30434         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
30435
30436         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
30437                 error "2nd dd fails"
30438         echo "Add data block at 640K...1280K"
30439
30440         # start at before new data block, in hole
30441         printf "Seeking hole from 600000 ... "
30442         offset=$(lseek_test -l 600000 $file)
30443         echo $offset
30444         [[ $offset == 600000 ]] || error "offset $offset != 600000"
30445         printf "Seeking data from 600000 ... "
30446         offset=$(lseek_test -d 600000 $file)
30447         echo $offset
30448         [[ $offset == 655360 ]] || error "offset $offset != 655360"
30449
30450         # start at the first component new data block
30451         printf "Seeking hole from 1000000 ... "
30452         offset=$(lseek_test -l 1000000 $file)
30453         echo $offset
30454         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
30455         printf "Seeking data from 1000000 ... "
30456         offset=$(lseek_test -d 1000000 $file)
30457         echo $offset
30458         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
30459
30460         # start at second component stripe 2, new data
30461         printf "Seeking hole from 1200000 ... "
30462         offset=$(lseek_test -l 1200000 $file)
30463         echo $offset
30464         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
30465         printf "Seeking data from 1200000 ... "
30466         offset=$(lseek_test -d 1200000 $file)
30467         echo $offset
30468         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
30469
30470         # start beyond file end
30471         printf "Using offset > filesize ... "
30472         lseek_test -l 4000000 $file && error "lseek should fail"
30473         printf "Using offset > filesize ... "
30474         lseek_test -d 4000000 $file && error "lseek should fail"
30475
30476         printf "Done\n\n"
30477 }
30478
30479 test_430a() {
30480         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
30481                 skip "MDT does not support SEEK_HOLE"
30482
30483         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
30484                 skip "OST does not support SEEK_HOLE"
30485
30486         local file=$DIR/$tdir/$tfile
30487
30488         mkdir -p $DIR/$tdir
30489
30490         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
30491         # OST stripe #1 will have continuous data at [1M, 3M)
30492         # OST stripe #2 is empty
30493         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
30494         lseek_test_430 $file
30495         rm $file
30496         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
30497         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
30498         lseek_test_430 $file
30499         rm $file
30500         $LFS setstripe -c2 -S 512K $file
30501         echo "Two stripes, stripe size 512K"
30502         lseek_test_430 $file
30503         rm $file
30504         # FLR with stale mirror
30505         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
30506                        -N -c2 -S 1M $file
30507         echo "Mirrored file:"
30508         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
30509         echo "Plain 2 stripes 1M"
30510         lseek_test_430 $file
30511         rm $file
30512 }
30513 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
30514
30515 test_430b() {
30516         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
30517                 skip "OST does not support SEEK_HOLE"
30518
30519         local offset
30520         local file=$DIR/$tdir/$tfile
30521
30522         mkdir -p $DIR/$tdir
30523         # Empty layout lseek should fail
30524         $MCREATE $file
30525         # seek from 0
30526         printf "Seeking hole from 0 ... "
30527         lseek_test -l 0 $file && error "lseek should fail"
30528         printf "Seeking data from 0 ... "
30529         lseek_test -d 0 $file && error "lseek should fail"
30530         rm $file
30531
30532         # 1M-hole file
30533         $LFS setstripe -E 1M -c2 -E eof $file
30534         $TRUNCATE $file 1048576
30535         printf "Seeking hole from 1000000 ... "
30536         offset=$(lseek_test -l 1000000 $file)
30537         echo $offset
30538         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
30539         printf "Seeking data from 1000000 ... "
30540         lseek_test -d 1000000 $file && error "lseek should fail"
30541         rm $file
30542
30543         # full component followed by non-inited one
30544         $LFS setstripe -E 1M -c2 -E eof $file
30545         dd if=/dev/urandom of=$file bs=1M count=1
30546         printf "Seeking hole from 1000000 ... "
30547         offset=$(lseek_test -l 1000000 $file)
30548         echo $offset
30549         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
30550         printf "Seeking hole from 1048576 ... "
30551         lseek_test -l 1048576 $file && error "lseek should fail"
30552         # init second component and truncate back
30553         echo "123" >> $file
30554         $TRUNCATE $file 1048576
30555         printf "Seeking hole from 1000000 ... "
30556         offset=$(lseek_test -l 1000000 $file)
30557         echo $offset
30558         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
30559         printf "Seeking hole from 1048576 ... "
30560         lseek_test -l 1048576 $file && error "lseek should fail"
30561         # boundary checks for big values
30562         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
30563         offset=$(lseek_test -d 0 $file.10g)
30564         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
30565         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
30566         offset=$(lseek_test -d 0 $file.100g)
30567         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
30568         return 0
30569 }
30570 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
30571
30572 test_430c() {
30573         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
30574                 skip "OST does not support SEEK_HOLE"
30575
30576         local file=$DIR/$tdir/$tfile
30577         local start
30578
30579         mkdir -p $DIR/$tdir
30580         stack_trap "rm -f $file $file.tmp"
30581         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M || error "dd failed"
30582
30583         # cp version 8.33+ prefers lseek over fiemap
30584         local ver=$(cp --version | awk '{ print $4; exit; }')
30585
30586         echo "cp $ver installed"
30587         if (( $(version_code $ver) >= $(version_code 8.33) )); then
30588                 start=$SECONDS
30589                 time cp -v $file $file.tmp || error "cp $file failed"
30590                 (( SECONDS - start < 5 )) || {
30591                         strace cp $file $file.tmp |&
30592                                 grep -E "open|read|seek|FIEMAP" |
30593                                 grep -A 100 $file
30594                         error "cp: too long runtime $((SECONDS - start))"
30595                 }
30596         else
30597                 echo "cp test skipped due to $ver < 8.33"
30598         fi
30599
30600         # tar version 1.29+ supports SEEK_HOLE/DATA
30601         ver=$(tar --version | awk '{ print $4; exit; }')
30602         echo "tar $ver installed"
30603         if (( $(version_code $ver) >= $(version_code 1.29) )); then
30604                 start=$SECONDS
30605                 time tar cvf $file.tmp --sparse $file || error "tar $file error"
30606                 (( SECONDS - start < 5 )) || {
30607                         strace tar cf $file.tmp --sparse $file |&
30608                                 grep -E "open|read|seek|FIEMAP" |
30609                                 grep -A 100 $file
30610                         error "tar: too long runtime $((SECONDS - start))"
30611                 }
30612         else
30613                 echo "tar test skipped due to $ver < 1.29"
30614         fi
30615 }
30616 run_test 430c "lseek: external tools check"
30617
30618 test_431() { # LU-14187
30619         local file=$DIR/$tdir/$tfile
30620
30621         mkdir -p $DIR/$tdir
30622         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
30623         dd if=/dev/urandom of=$file bs=4k count=1
30624         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
30625         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
30626         #define OBD_FAIL_OST_RESTART_IO 0x251
30627         do_facet ost1 "$LCTL set_param fail_loc=0x251"
30628         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
30629         cp $file $file.0
30630         cancel_lru_locks
30631         sync_all_data
30632         echo 3 > /proc/sys/vm/drop_caches
30633         diff  $file $file.0 || error "data diff"
30634 }
30635 run_test 431 "Restart transaction for IO"
30636
30637 cleanup_test_432() {
30638         do_facet mgs $LCTL nodemap_activate 0
30639         wait_nm_sync active
30640 }
30641
30642 test_432() {
30643         local tmpdir=$TMP/dir432
30644
30645         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
30646                 skip "Need MDS version at least 2.14.52"
30647
30648         stack_trap cleanup_test_432 EXIT
30649         mkdir $DIR/$tdir
30650         mkdir $tmpdir
30651
30652         do_facet mgs $LCTL nodemap_activate 1
30653         wait_nm_sync active
30654         do_facet mgs $LCTL nodemap_modify --name default \
30655                 --property admin --value 1
30656         do_facet mgs $LCTL nodemap_modify --name default \
30657                 --property trusted --value 1
30658         cancel_lru_locks mdc
30659         wait_nm_sync default admin_nodemap
30660         wait_nm_sync default trusted_nodemap
30661
30662         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
30663                grep -ci "Operation not permitted") -ne 0 ]; then
30664                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
30665         fi
30666 }
30667 run_test 432 "mv dir from outside Lustre"
30668
30669 test_433() {
30670         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30671
30672         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
30673                 skip "inode cache not supported"
30674
30675         $LCTL set_param llite.*.inode_cache=0
30676         stack_trap "$LCTL set_param llite.*.inode_cache=1"
30677
30678         local count=256
30679         local before
30680         local after
30681
30682         cancel_lru_locks mdc
30683         test_mkdir $DIR/$tdir || error "mkdir $tdir"
30684         createmany -m $DIR/$tdir/f $count
30685         createmany -d $DIR/$tdir/d $count
30686         ls -l $DIR/$tdir > /dev/null
30687         stack_trap "rm -rf $DIR/$tdir"
30688
30689         before=$(num_objects)
30690         cancel_lru_locks mdc
30691         after=$(num_objects)
30692
30693         # sometimes even @before is less than 2 * count
30694         while (( before - after < count )); do
30695                 sleep 1
30696                 after=$(num_objects)
30697                 wait=$((wait + 1))
30698                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
30699                 if (( wait > 60 )); then
30700                         error "inode slab grew from $before to $after"
30701                 fi
30702         done
30703
30704         echo "lustre_inode_cache $before objs before lock cancel, $after after"
30705 }
30706 run_test 433 "ldlm lock cancel releases dentries and inodes"
30707
30708 test_434() {
30709         local file
30710         local getxattr_count
30711         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
30712         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30713
30714         [[ $(getenforce) == "Disabled" ]] ||
30715                 skip "lsm selinux module have to be disabled for this test"
30716
30717         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
30718                 error "fail to create $DIR/$tdir/ on MDT0000"
30719
30720         touch $DIR/$tdir/$tfile-{001..100}
30721
30722         # disable the xattr cache
30723         save_lustre_params client "llite.*.xattr_cache" > $p
30724         lctl set_param llite.*.xattr_cache=0
30725         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
30726
30727         # clear clients mdc stats
30728         clear_stats $mdc_stat_param ||
30729                 error "fail to clear stats on mdc MDT0000"
30730
30731         for file in $DIR/$tdir/$tfile-{001..100}; do
30732                 getfattr -n security.selinux $file |&
30733                         grep -q "Operation not supported" ||
30734                         error "getxattr on security.selinux should return EOPNOTSUPP"
30735         done
30736
30737         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
30738         (( getxattr_count < 100 )) ||
30739                 error "client sent $getxattr_count getxattr RPCs to the MDS"
30740 }
30741 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
30742
30743 test_440() {
30744         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
30745                 source $LUSTRE/scripts/bash-completion/lustre
30746         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
30747                 source /usr/share/bash-completion/completions/lustre
30748         else
30749                 skip "bash completion scripts not found"
30750         fi
30751
30752         local lctl_completions
30753         local lfs_completions
30754
30755         lctl_completions=$(_lustre_cmds lctl)
30756         if [[ ! $lctl_completions =~ "get_param" ]]; then
30757                 error "lctl bash completion failed"
30758         fi
30759
30760         lfs_completions=$(_lustre_cmds lfs)
30761         if [[ ! $lfs_completions =~ "setstripe" ]]; then
30762                 error "lfs bash completion failed"
30763         fi
30764 }
30765 run_test 440 "bash completion for lfs, lctl"
30766
30767 test_442() {
30768         local pid1
30769         local pid2
30770         mkdir -p $DIR/$tdir
30771         multiop $DIR/$tdir/$tfile.1 O_w1 & pid1=$!
30772         multiop $DIR/$tdir/$tfile.1 O_w1 & pid2=$!
30773         sleep 1
30774         touch $DIR/$tdir/$tfile.2
30775         $LFS swap_layouts -n $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
30776         $LCTL set_param fail_loc=0x1430
30777         kill -USR1 $pid1
30778         sleep 1
30779         kill -USR1 $pid2
30780         wait
30781 }
30782 run_test 442 "truncate vs read/write should not panic"
30783
30784 test_460d() {
30785         verify_yaml_available || skip_env "YAML verification not installed"
30786         $LCTL get_param -n sptlrpc.page_pools
30787         $LCTL get_param -n sptlrpc.page_pools | verify_yaml ||
30788                 error "The output of encrypt_page_pools is not an valid YAML"
30789 }
30790 run_test 460d "Check encrypt pools output"
30791
30792 prep_801() {
30793         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
30794         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
30795                 skip "Need server version at least 2.9.55"
30796
30797         start_full_debug_logging
30798 }
30799
30800 post_801() {
30801         stop_full_debug_logging
30802 }
30803
30804 barrier_stat() {
30805         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
30806                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
30807                            awk '/The barrier for/ { print $7 }')
30808                 echo $st
30809         else
30810                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
30811                 echo \'$st\'
30812         fi
30813 }
30814
30815 barrier_expired() {
30816         local expired
30817
30818         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
30819                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
30820                           awk '/will be expired/ { print $7 }')
30821         else
30822                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
30823         fi
30824
30825         echo $expired
30826 }
30827
30828 test_801a() {
30829         prep_801
30830
30831         echo "Start barrier_freeze at: $(date)"
30832         #define OBD_FAIL_BARRIER_DELAY          0x2202
30833         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
30834         # Do not reduce barrier time - See LU-11873
30835         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
30836
30837         sleep 2
30838         local b_status=$(barrier_stat)
30839         echo "Got barrier status at: $(date)"
30840         [ "$b_status" = "'freezing_p1'" ] ||
30841                 error "(1) unexpected barrier status $b_status"
30842
30843         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
30844         wait
30845         b_status=$(barrier_stat)
30846         [ "$b_status" = "'frozen'" ] ||
30847                 error "(2) unexpected barrier status $b_status"
30848
30849         local expired=$(barrier_expired)
30850         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
30851         sleep $((expired + 3))
30852
30853         b_status=$(barrier_stat)
30854         [ "$b_status" = "'expired'" ] ||
30855                 error "(3) unexpected barrier status $b_status"
30856
30857         # Do not reduce barrier time - See LU-11873
30858         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
30859                 error "(4) fail to freeze barrier"
30860
30861         b_status=$(barrier_stat)
30862         [ "$b_status" = "'frozen'" ] ||
30863                 error "(5) unexpected barrier status $b_status"
30864
30865         echo "Start barrier_thaw at: $(date)"
30866         #define OBD_FAIL_BARRIER_DELAY          0x2202
30867         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
30868         do_facet mgs $LCTL barrier_thaw $FSNAME &
30869
30870         sleep 2
30871         b_status=$(barrier_stat)
30872         echo "Got barrier status at: $(date)"
30873         [ "$b_status" = "'thawing'" ] ||
30874                 error "(6) unexpected barrier status $b_status"
30875
30876         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
30877         wait
30878         b_status=$(barrier_stat)
30879         [ "$b_status" = "'thawed'" ] ||
30880                 error "(7) unexpected barrier status $b_status"
30881
30882         #define OBD_FAIL_BARRIER_FAILURE        0x2203
30883         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
30884         do_facet mgs $LCTL barrier_freeze $FSNAME
30885
30886         b_status=$(barrier_stat)
30887         [ "$b_status" = "'failed'" ] ||
30888                 error "(8) unexpected barrier status $b_status"
30889
30890         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
30891         do_facet mgs $LCTL barrier_thaw $FSNAME
30892
30893         post_801
30894 }
30895 run_test 801a "write barrier user interfaces and stat machine"
30896
30897 test_801b() {
30898         prep_801
30899
30900         mkdir $DIR/$tdir || error "(1) fail to mkdir"
30901         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
30902         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
30903         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
30904         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
30905
30906         cancel_lru_locks mdc
30907
30908         # 180 seconds should be long enough
30909         do_facet mgs $LCTL barrier_freeze $FSNAME 180
30910
30911         local b_status=$(barrier_stat)
30912         [ "$b_status" = "'frozen'" ] ||
30913                 error "(6) unexpected barrier status $b_status"
30914
30915         mkdir $DIR/$tdir/d0/d10 &
30916         mkdir_pid=$!
30917
30918         touch $DIR/$tdir/d1/f13 &
30919         touch_pid=$!
30920
30921         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
30922         ln_pid=$!
30923
30924         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
30925         mv_pid=$!
30926
30927         rm -f $DIR/$tdir/d4/f12 &
30928         rm_pid=$!
30929
30930         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
30931
30932         # To guarantee taht the 'stat' is not blocked
30933         b_status=$(barrier_stat)
30934         [ "$b_status" = "'frozen'" ] ||
30935                 error "(8) unexpected barrier status $b_status"
30936
30937         # let above commands to run at background
30938         sleep 5
30939
30940         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
30941         ps -p $touch_pid || error "(10) touch should be blocked"
30942         ps -p $ln_pid || error "(11) link should be blocked"
30943         ps -p $mv_pid || error "(12) rename should be blocked"
30944         ps -p $rm_pid || error "(13) unlink should be blocked"
30945
30946         b_status=$(barrier_stat)
30947         [ "$b_status" = "'frozen'" ] ||
30948                 error "(14) unexpected barrier status $b_status"
30949
30950         do_facet mgs $LCTL barrier_thaw $FSNAME
30951         b_status=$(barrier_stat)
30952         [ "$b_status" = "'thawed'" ] ||
30953                 error "(15) unexpected barrier status $b_status"
30954
30955         wait $mkdir_pid || error "(16) mkdir should succeed"
30956         wait $touch_pid || error "(17) touch should succeed"
30957         wait $ln_pid || error "(18) link should succeed"
30958         wait $mv_pid || error "(19) rename should succeed"
30959         wait $rm_pid || error "(20) unlink should succeed"
30960
30961         post_801
30962 }
30963 run_test 801b "modification will be blocked by write barrier"
30964
30965 test_801c() {
30966         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30967
30968         prep_801
30969
30970         stop mds2 || error "(1) Fail to stop mds2"
30971
30972         do_facet mgs $LCTL barrier_freeze $FSNAME 30
30973
30974         local b_status=$(barrier_stat)
30975         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
30976                 do_facet mgs $LCTL barrier_thaw $FSNAME
30977                 error "(2) unexpected barrier status $b_status"
30978         }
30979
30980         do_facet mgs $LCTL barrier_rescan $FSNAME ||
30981                 error "(3) Fail to rescan barrier bitmap"
30982
30983         # Do not reduce barrier time - See LU-11873
30984         do_facet mgs $LCTL barrier_freeze $FSNAME 20
30985
30986         b_status=$(barrier_stat)
30987         [ "$b_status" = "'frozen'" ] ||
30988                 error "(4) unexpected barrier status $b_status"
30989
30990         do_facet mgs $LCTL barrier_thaw $FSNAME
30991         b_status=$(barrier_stat)
30992         [ "$b_status" = "'thawed'" ] ||
30993                 error "(5) unexpected barrier status $b_status"
30994
30995         local devname=$(mdsdevname 2)
30996
30997         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
30998
30999         do_facet mgs $LCTL barrier_rescan $FSNAME ||
31000                 error "(7) Fail to rescan barrier bitmap"
31001
31002         post_801
31003 }
31004 run_test 801c "rescan barrier bitmap"
31005
31006 test_802b() {
31007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31008         remote_mds_nodsh && skip "remote MDS with nodsh"
31009
31010         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
31011                 skip "readonly option not available"
31012
31013         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
31014
31015         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
31016                 error "(2) Fail to copy"
31017
31018         # write back all cached data before setting MDT to readonly
31019         cancel_lru_locks
31020         sync_all_data
31021
31022         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
31023         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
31024
31025         echo "Modify should be refused"
31026         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
31027
31028         echo "Read should be allowed"
31029         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
31030                 error "(7) Read should succeed under ro mode"
31031
31032         # disable readonly
31033         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
31034 }
31035 run_test 802b "be able to set MDTs to readonly"
31036
31037 test_803a() {
31038         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
31039         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
31040                 skip "MDS needs to be newer than 2.10.54"
31041
31042         mkdir_on_mdt0 $DIR/$tdir
31043         # Create some objects on all MDTs to trigger related logs objects
31044         for idx in $(seq $MDSCOUNT); do
31045                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
31046                         $DIR/$tdir/dir${idx} ||
31047                         error "Fail to create $DIR/$tdir/dir${idx}"
31048         done
31049
31050         wait_delete_completed # ensure old test cleanups are finished
31051         sleep 3
31052         echo "before create:"
31053         $LFS df -i $MOUNT
31054         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
31055
31056         for i in {1..10}; do
31057                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
31058                         error "Fail to create $DIR/$tdir/foo$i"
31059         done
31060
31061         # sync ZFS-on-MDS to refresh statfs data
31062         wait_zfs_commit mds1
31063         sleep 3
31064         echo "after create:"
31065         $LFS df -i $MOUNT
31066         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
31067
31068         # allow for an llog to be cleaned up during the test
31069         [ $after_used -ge $((before_used + 10 - 1)) ] ||
31070                 error "before ($before_used) + 10 > after ($after_used)"
31071
31072         for i in {1..10}; do
31073                 rm -rf $DIR/$tdir/foo$i ||
31074                         error "Fail to remove $DIR/$tdir/foo$i"
31075         done
31076
31077         # sync ZFS-on-MDS to refresh statfs data
31078         wait_zfs_commit mds1
31079         wait_delete_completed
31080         sleep 3 # avoid MDT return cached statfs
31081         echo "after unlink:"
31082         $LFS df -i $MOUNT
31083         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
31084
31085         # allow for an llog to be created during the test
31086         [ $after_used -le $((before_used + 1)) ] ||
31087                 error "after ($after_used) > before ($before_used) + 1"
31088 }
31089 run_test 803a "verify agent object for remote object"
31090
31091 test_803b() {
31092         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
31093         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
31094                 skip "MDS needs to be newer than 2.13.56"
31095         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31096
31097         for i in $(seq 0 $((MDSCOUNT - 1))); do
31098                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
31099         done
31100
31101         local before=0
31102         local after=0
31103
31104         local tmp
31105
31106         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
31107         for i in $(seq 0 $((MDSCOUNT - 1))); do
31108                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
31109                         awk '/getattr/ { print $2 }')
31110                 before=$((before + tmp))
31111         done
31112         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
31113         for i in $(seq 0 $((MDSCOUNT - 1))); do
31114                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
31115                         awk '/getattr/ { print $2 }')
31116                 after=$((after + tmp))
31117         done
31118
31119         [ $before -eq $after ] || error "getattr count $before != $after"
31120 }
31121 run_test 803b "remote object can getattr from cache"
31122
31123 test_804() {
31124         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
31125         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
31126                 skip "MDS needs to be newer than 2.10.54"
31127         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
31128
31129         mkdir -p $DIR/$tdir
31130         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
31131                 error "Fail to create $DIR/$tdir/dir0"
31132
31133         local fid=$($LFS path2fid $DIR/$tdir/dir0)
31134         local dev=$(mdsdevname 2)
31135
31136         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
31137                 grep ${fid} || error "NOT found agent entry for dir0"
31138
31139         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
31140                 error "Fail to create $DIR/$tdir/dir1"
31141
31142         touch $DIR/$tdir/dir1/foo0 ||
31143                 error "Fail to create $DIR/$tdir/dir1/foo0"
31144         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
31145         local rc=0
31146
31147         for idx in $(seq $MDSCOUNT); do
31148                 dev=$(mdsdevname $idx)
31149                 do_facet mds${idx} \
31150                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
31151                         grep ${fid} && rc=$idx
31152         done
31153
31154         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
31155                 error "Fail to rename foo0 to foo1"
31156         if [ $rc -eq 0 ]; then
31157                 for idx in $(seq $MDSCOUNT); do
31158                         dev=$(mdsdevname $idx)
31159                         do_facet mds${idx} \
31160                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
31161                         grep ${fid} && rc=$idx
31162                 done
31163         fi
31164
31165         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
31166                 error "Fail to rename foo1 to foo2"
31167         if [ $rc -eq 0 ]; then
31168                 for idx in $(seq $MDSCOUNT); do
31169                         dev=$(mdsdevname $idx)
31170                         do_facet mds${idx} \
31171                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
31172                         grep ${fid} && rc=$idx
31173                 done
31174         fi
31175
31176         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
31177
31178         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
31179                 error "Fail to link to $DIR/$tdir/dir1/foo2"
31180         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
31181                 error "Fail to rename foo2 to foo0"
31182         unlink $DIR/$tdir/dir1/foo0 ||
31183                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
31184         rm -rf $DIR/$tdir/dir0 ||
31185                 error "Fail to rm $DIR/$tdir/dir0"
31186
31187         for idx in $(seq $MDSCOUNT); do
31188                 rc=0
31189
31190                 stop mds${idx}
31191                 dev=$(mdsdevname $idx)
31192                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
31193                         rc=$?
31194                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
31195                         error "mount mds$idx failed"
31196                 df $MOUNT > /dev/null 2>&1
31197
31198                 # e2fsck should not return error
31199                 [ $rc -eq 0 ] ||
31200                         error "e2fsck detected error on MDT${idx}: rc=$rc"
31201         done
31202 }
31203 run_test 804 "verify agent entry for remote entry"
31204
31205 cleanup_805() {
31206         do_facet $SINGLEMDS zfs set quota=$old $fsset
31207         unlinkmany $DIR/$tdir/f- 1000000
31208         trap 0
31209 }
31210
31211 test_805() {
31212         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
31213         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
31214         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
31215                 skip "netfree not implemented before 0.7"
31216         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
31217                 skip "Need MDS version at least 2.10.57"
31218
31219         local fsset
31220         local freekb
31221         local usedkb
31222         local old
31223         local quota
31224         local pref="osd-zfs.$FSNAME-MDT0000."
31225
31226         # limit available space on MDS dataset to meet nospace issue
31227         # quickly. then ZFS 0.7.2 can use reserved space if asked
31228         # properly (using netfree flag in osd_declare_destroy()
31229         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
31230         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
31231                 gawk '{print $3}')
31232         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
31233         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
31234         let "usedkb=usedkb-freekb"
31235         let "freekb=freekb/2"
31236         if let "freekb > 5000"; then
31237                 let "freekb=5000"
31238         fi
31239         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
31240         trap cleanup_805 EXIT
31241         mkdir_on_mdt0 $DIR/$tdir
31242         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
31243                 error "Can't set PFL layout"
31244         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
31245         rm -rf $DIR/$tdir || error "not able to remove"
31246         do_facet $SINGLEMDS zfs set quota=$old $fsset
31247         trap 0
31248 }
31249 run_test 805 "ZFS can remove from full fs"
31250
31251 # Size-on-MDS test
31252 check_lsom_data()
31253 {
31254         local file=$1
31255         local expect=$(stat -c %s $file)
31256         local msg=$2
31257
31258         check_lsom_size $1 $expect $msg
31259
31260         local blocks=$($LFS getsom -b $file)
31261         expect=$(stat -c %b $file)
31262         [[ $blocks == $expect ]] ||
31263                 error "$msg $file expected blocks: $expect, got: $blocks"
31264 }
31265
31266 check_lsom_size()
31267 {
31268         local size
31269         local expect=$2
31270         local msg=$3
31271
31272         cancel_lru_locks mdc
31273
31274         size=$($LFS getsom -s $1)
31275         [[ $size == $expect ]] ||
31276                 error "$msg $file expected size: $expect, got: $size"
31277 }
31278
31279 test_806() {
31280         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
31281                 skip "Need MDS version at least 2.11.52"
31282
31283         local bs=1048576
31284
31285         $LFS setstripe -c-1 $DIR/$tfile || error "setstripe $tfile failed"
31286
31287         disable_opencache
31288         stack_trap "restore_opencache"
31289
31290         # single-threaded write
31291         echo "Test SOM for single-threaded write"
31292         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
31293                 error "write $tfile failed"
31294         check_lsom_size $DIR/$tfile $bs "(0)"
31295         # Test SOM with DIO write (dd truncates to 0)
31296         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 oflag=direct ||
31297                 error "write $tfile failed"
31298         check_lsom_size $DIR/$tfile $bs "(1)"
31299
31300         local num=32
31301         local size=$(($num * $bs))
31302         local offset=0
31303         local i
31304
31305         echo "Test SOM for single client multi-threaded($num) write"
31306         $TRUNCATE $DIR/$tfile 0
31307         for ((i = 0; i < $num; i++)); do
31308                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31309                 local pids[$i]=$!
31310                 offset=$((offset + $bs))
31311         done
31312         for (( i=0; i < $num; i++ )); do
31313                 wait ${pids[$i]}
31314         done
31315         check_lsom_size $DIR/$tfile $size "(2)"
31316
31317         $TRUNCATE $DIR/$tfile 0
31318         for ((i = 0; i < $num; i++)); do
31319                 offset=$((offset - $bs))
31320                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31321                 local pids[$i]=$!
31322         done
31323         for (( i=0; i < $num; i++ )); do
31324                 wait ${pids[$i]}
31325         done
31326         check_lsom_size $DIR/$tfile $size "(3)"
31327
31328         # multi-client writes
31329         num=$(get_node_count ${CLIENTS//,/ })
31330         size=$(($num * $bs))
31331         offset=0
31332         i=0
31333
31334         echo "Test SOM for multi-client ($num) writes"
31335         $TRUNCATE $DIR/$tfile 0
31336         for client in ${CLIENTS//,/ }; do
31337                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31338                 local pids[$i]=$!
31339                 i=$((i + 1))
31340                 offset=$((offset + $bs))
31341         done
31342         for (( i=0; i < $num; i++ )); do
31343                 wait ${pids[$i]}
31344         done
31345         check_lsom_size $DIR/$tfile $offset "(4)"
31346
31347         i=0
31348         $TRUNCATE $DIR/$tfile 0
31349         for client in ${CLIENTS//,/ }; do
31350                 offset=$((offset - $bs))
31351                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31352                 local pids[$i]=$!
31353                 i=$((i + 1))
31354         done
31355         for (( i=0; i < $num; i++ )); do
31356                 wait ${pids[$i]}
31357         done
31358         check_lsom_size $DIR/$tfile $size "(5)"
31359
31360         # verify SOM blocks count
31361         echo "Verify SOM block count"
31362         $TRUNCATE $DIR/$tfile 0
31363         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs))YSc ||
31364                 error "failed to write file $tfile with fdatasync and fstat"
31365         check_lsom_data $DIR/$tfile "(6)"
31366
31367         $TRUNCATE $DIR/$tfile 0
31368         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs * 2))Yc ||
31369                 error "failed to write file $tfile with fdatasync"
31370         check_lsom_data $DIR/$tfile "(7)"
31371
31372         $TRUNCATE $DIR/$tfile 0
31373         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:O_SYNC:w$((bs * 3))c ||
31374                 error "failed to write file $tfile with sync IO"
31375         check_lsom_data $DIR/$tfile "(8)"
31376
31377         # verify truncate
31378         echo "Test SOM for truncate"
31379         # use ftruncate to sync blocks on close request
31380         $MULTIOP $DIR/$tfile oO_WRONLY:T16384c
31381         check_lsom_size $DIR/$tfile 16384 "(9)"
31382         check_lsom_data $DIR/$tfile "(10)"
31383
31384         $TRUNCATE $DIR/$tfile 1234
31385         check_lsom_size $DIR/$tfile 1234 "(11)"
31386         # sync blocks on the MDT
31387         $MULTIOP $DIR/$tfile oc
31388         check_lsom_data $DIR/$tfile "(12)"
31389 }
31390 run_test 806 "Verify Lazy Size on MDS"
31391
31392 test_807() {
31393         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
31394         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
31395                 skip "Need MDS version at least 2.11.52"
31396
31397         # Registration step
31398         changelog_register || error "changelog_register failed"
31399         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
31400         changelog_users $SINGLEMDS | grep -q $cl_user ||
31401                 error "User $cl_user not found in changelog_users"
31402
31403         rm -rf $DIR/$tdir || error "rm $tdir failed"
31404         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
31405         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
31406         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
31407         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
31408                 error "truncate $tdir/trunc failed"
31409
31410         local bs=1048576
31411         echo "Test SOM for single-threaded write with fsync"
31412         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
31413                 error "write $tfile failed"
31414         sync;sync;sync
31415
31416         # multi-client wirtes
31417         local num=$(get_node_count ${CLIENTS//,/ })
31418         local offset=0
31419         local i=0
31420
31421         echo "Test SOM for multi-client ($num) writes"
31422         touch $DIR/$tfile || error "touch $tfile failed"
31423         $TRUNCATE $DIR/$tfile 0
31424         for client in ${CLIENTS//,/ }; do
31425                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31426                 local pids[$i]=$!
31427                 i=$((i + 1))
31428                 offset=$((offset + $bs))
31429         done
31430         for (( i=0; i < $num; i++ )); do
31431                 wait ${pids[$i]}
31432         done
31433
31434         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
31435         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
31436         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
31437         check_lsom_data $DIR/$tdir/trunc "(0)"
31438         check_lsom_data $DIR/$tdir/single_dd "(1)"
31439         check_lsom_data $DIR/$tfile "(2)"
31440
31441         rm -rf $DIR/$tdir
31442         # Deregistration step
31443         changelog_deregister || error "changelog_deregister failed"
31444 }
31445 run_test 807 "verify LSOM syncing tool"
31446
31447 check_som_nologged()
31448 {
31449         local lines=$($LFS changelog $FSNAME-MDT0000 |
31450                 grep 'x=trusted.som' | wc -l)
31451         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
31452 }
31453
31454 test_808() {
31455         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
31456                 skip "Need MDS version at least 2.11.55"
31457
31458         # Registration step
31459         changelog_register || error "changelog_register failed"
31460
31461         touch $DIR/$tfile || error "touch $tfile failed"
31462         check_som_nologged
31463
31464         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
31465                 error "write $tfile failed"
31466         check_som_nologged
31467
31468         $TRUNCATE $DIR/$tfile 1234
31469         check_som_nologged
31470
31471         $TRUNCATE $DIR/$tfile 1048576
31472         check_som_nologged
31473
31474         # Deregistration step
31475         changelog_deregister || error "changelog_deregister failed"
31476 }
31477 run_test 808 "Check trusted.som xattr not logged in Changelogs"
31478
31479 check_som_nodata()
31480 {
31481         $LFS getsom $1
31482         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
31483 }
31484
31485 test_809() {
31486         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
31487                 skip "Need MDS version at least 2.11.56"
31488
31489         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
31490                 error "failed to create DoM-only file $DIR/$tfile"
31491         touch $DIR/$tfile || error "touch $tfile failed"
31492         check_som_nodata $DIR/$tfile
31493
31494         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
31495                 error "write $tfile failed"
31496         check_som_nodata $DIR/$tfile
31497
31498         $TRUNCATE $DIR/$tfile 1234
31499         check_som_nodata $DIR/$tfile
31500
31501         $TRUNCATE $DIR/$tfile 4097
31502         check_som_nodata $DIR/$file
31503 }
31504 run_test 809 "Verify no SOM xattr store for DoM-only files"
31505
31506 test_810() {
31507         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31508         $GSS && skip_env "could not run with gss"
31509         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
31510                 skip "OST < 2.12.58 doesn't align checksum"
31511
31512         set_checksums 1
31513         stack_trap "set_checksums $ORIG_CSUM" EXIT
31514         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
31515
31516         local csum
31517         local before
31518         local after
31519         for csum in $CKSUM_TYPES; do
31520                 #define OBD_FAIL_OSC_NO_GRANT   0x411
31521                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
31522                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
31523                         eval set -- $i
31524                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
31525                         before=$(md5sum $DIR/$tfile)
31526                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
31527                         after=$(md5sum $DIR/$tfile)
31528                         [ "$before" == "$after" ] ||
31529                                 error "$csum: $before != $after bs=$1 seek=$2"
31530                 done
31531         done
31532 }
31533 run_test 810 "partial page writes on ZFS (LU-11663)"
31534
31535 test_812a() {
31536         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
31537                 skip "OST < 2.12.51 doesn't support this fail_loc"
31538         local old
31539
31540         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
31541         $LCTL set_param osc.*.idle_timeout=10
31542         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
31543
31544         $LFS setstripe -c 1 -i 0 $DIR/$tfile
31545         # ensure ost1 is connected
31546         stat $DIR/$tfile >/dev/null || error "can't stat"
31547         wait_osc_import_state client ost1 FULL
31548         # no locks, no reqs to let the connection idle
31549         cancel_lru_locks osc
31550
31551         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
31552 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
31553         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
31554         wait_osc_import_state client ost1 CONNECTING
31555         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
31556
31557         stat $DIR/$tfile >/dev/null || error "can't stat file"
31558 }
31559 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
31560
31561 test_812b() { # LU-12378
31562         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
31563                 skip "OST < 2.12.51 doesn't support this fail_loc"
31564         local old
31565
31566         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
31567         $LCTL set_param osc.*.idle_timeout=10
31568         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
31569
31570         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
31571         # ensure ost1 is connected
31572         stat $DIR/$tfile >/dev/null || error "can't stat"
31573         wait_osc_import_state client ost1 FULL
31574         # no locks, no reqs to let the connection idle
31575         cancel_lru_locks osc
31576
31577         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
31578 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
31579         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
31580         wait_osc_import_state client ost1 CONNECTING
31581         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
31582
31583         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
31584         wait_osc_import_state client ost1 IDLE
31585 }
31586 run_test 812b "do not drop no resend request for idle connect"
31587
31588 test_812c() {
31589         local old
31590
31591         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
31592
31593         $LFS setstripe -c 1 -o 0 $DIR/$tfile
31594         $LFS getstripe $DIR/$tfile
31595         $LCTL set_param osc.*.idle_timeout=10
31596         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
31597         # ensure ost1 is connected
31598         stat $DIR/$tfile >/dev/null || error "can't stat"
31599         wait_osc_import_state client ost1 FULL
31600         # no locks, no reqs to let the connection idle
31601         cancel_lru_locks osc
31602
31603 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
31604         $LCTL set_param fail_loc=0x80000533
31605         sleep 15
31606         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
31607 }
31608 run_test 812c "idle import vs lock enqueue race"
31609
31610 test_813() {
31611         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
31612         [ -z "$file_heat_sav" ] && skip "no file heat support"
31613
31614         local readsample
31615         local writesample
31616         local readbyte
31617         local writebyte
31618         local readsample1
31619         local writesample1
31620         local readbyte1
31621         local writebyte1
31622
31623         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
31624         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
31625
31626         $LCTL set_param -n llite.*.file_heat=1
31627         echo "Turn on file heat"
31628         echo "Period second: $period_second, Decay percentage: $decay_pct"
31629
31630         echo "QQQQ" > $DIR/$tfile
31631         echo "QQQQ" > $DIR/$tfile
31632         echo "QQQQ" > $DIR/$tfile
31633         cat $DIR/$tfile > /dev/null
31634         cat $DIR/$tfile > /dev/null
31635         cat $DIR/$tfile > /dev/null
31636         cat $DIR/$tfile > /dev/null
31637
31638         local out=$($LFS heat_get $DIR/$tfile)
31639
31640         $LFS heat_get $DIR/$tfile
31641         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31642         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31643         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31644         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31645
31646         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
31647         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
31648         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
31649         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
31650
31651         sleep $((period_second + 3))
31652         echo "Sleep $((period_second + 3)) seconds..."
31653         # The recursion formula to calculate the heat of the file f is as
31654         # follow:
31655         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
31656         # Where Hi is the heat value in the period between time points i*I and
31657         # (i+1)*I; Ci is the access count in the period; the symbol P refers
31658         # to the weight of Ci.
31659         out=$($LFS heat_get $DIR/$tfile)
31660         $LFS heat_get $DIR/$tfile
31661         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31662         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31663         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31664         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31665
31666         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
31667                 error "read sample ($readsample) is wrong"
31668         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
31669                 error "write sample ($writesample) is wrong"
31670         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
31671                 error "read bytes ($readbyte) is wrong"
31672         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
31673                 error "write bytes ($writebyte) is wrong"
31674
31675         echo "QQQQ" > $DIR/$tfile
31676         echo "QQQQ" > $DIR/$tfile
31677         echo "QQQQ" > $DIR/$tfile
31678         cat $DIR/$tfile > /dev/null
31679         cat $DIR/$tfile > /dev/null
31680         cat $DIR/$tfile > /dev/null
31681         cat $DIR/$tfile > /dev/null
31682
31683         sleep $((period_second + 3))
31684         echo "Sleep $((period_second + 3)) seconds..."
31685
31686         out=$($LFS heat_get $DIR/$tfile)
31687         $LFS heat_get $DIR/$tfile
31688         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31689         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31690         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31691         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31692
31693         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
31694                 4 * $decay_pct) / 100") -eq 1 ] ||
31695                 error "read sample ($readsample1) is wrong"
31696         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
31697                 3 * $decay_pct) / 100") -eq 1 ] ||
31698                 error "write sample ($writesample1) is wrong"
31699         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
31700                 20 * $decay_pct) / 100") -eq 1 ] ||
31701                 error "read bytes ($readbyte1) is wrong"
31702         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
31703                 15 * $decay_pct) / 100") -eq 1 ] ||
31704                 error "write bytes ($writebyte1) is wrong"
31705
31706         echo "Turn off file heat for the file $DIR/$tfile"
31707         $LFS heat_set -o $DIR/$tfile
31708
31709         echo "QQQQ" > $DIR/$tfile
31710         echo "QQQQ" > $DIR/$tfile
31711         echo "QQQQ" > $DIR/$tfile
31712         cat $DIR/$tfile > /dev/null
31713         cat $DIR/$tfile > /dev/null
31714         cat $DIR/$tfile > /dev/null
31715         cat $DIR/$tfile > /dev/null
31716
31717         out=$($LFS heat_get $DIR/$tfile)
31718         $LFS heat_get $DIR/$tfile
31719         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31720         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31721         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31722         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31723
31724         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
31725         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
31726         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
31727         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
31728
31729         echo "Trun on file heat for the file $DIR/$tfile"
31730         $LFS heat_set -O $DIR/$tfile
31731
31732         echo "QQQQ" > $DIR/$tfile
31733         echo "QQQQ" > $DIR/$tfile
31734         echo "QQQQ" > $DIR/$tfile
31735         cat $DIR/$tfile > /dev/null
31736         cat $DIR/$tfile > /dev/null
31737         cat $DIR/$tfile > /dev/null
31738         cat $DIR/$tfile > /dev/null
31739
31740         out=$($LFS heat_get $DIR/$tfile)
31741         $LFS heat_get $DIR/$tfile
31742         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31743         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31744         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31745         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31746
31747         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
31748         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
31749         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
31750         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
31751
31752         $LFS heat_set -c $DIR/$tfile
31753         $LCTL set_param -n llite.*.file_heat=0
31754         echo "Turn off file heat support for the Lustre filesystem"
31755
31756         echo "QQQQ" > $DIR/$tfile
31757         echo "QQQQ" > $DIR/$tfile
31758         echo "QQQQ" > $DIR/$tfile
31759         cat $DIR/$tfile > /dev/null
31760         cat $DIR/$tfile > /dev/null
31761         cat $DIR/$tfile > /dev/null
31762         cat $DIR/$tfile > /dev/null
31763
31764         out=$($LFS heat_get $DIR/$tfile)
31765         $LFS heat_get $DIR/$tfile
31766         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31767         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31768         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31769         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31770
31771         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
31772         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
31773         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
31774         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
31775
31776         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
31777         rm -f $DIR/$tfile
31778 }
31779 run_test 813 "File heat verfication"
31780
31781 test_814()
31782 {
31783         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
31784         echo -n y >> $DIR/$tfile
31785         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
31786         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
31787 }
31788 run_test 814 "sparse cp works as expected (LU-12361)"
31789
31790 test_815()
31791 {
31792         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
31793         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
31794 }
31795 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
31796
31797 test_816() {
31798         local ost1_imp=$(get_osc_import_name client ost1)
31799         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
31800                          cut -d'.' -f2)
31801         local old
31802
31803         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
31804         $LCTL set_param osc.*.idle_timeout=10
31805         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
31806
31807         $LFS setstripe -c 1 -i 0 $DIR/$tfile
31808         # ensure ost1 is connected
31809
31810         stat $DIR/$tfile >/dev/null || error "can't stat"
31811         wait_osc_import_state client ost1 FULL
31812         # no locks, no reqs to let the connection idle
31813         cancel_lru_locks osc
31814         lru_resize_disable osc
31815         local before
31816         local now
31817         before=$($LCTL get_param -n \
31818                  ldlm.namespaces.$imp_name.lru_size)
31819
31820         wait_osc_import_state client ost1 IDLE
31821         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
31822         now=$($LCTL get_param -n \
31823               ldlm.namespaces.$imp_name.lru_size)
31824         [ $before == $now ] || error "lru_size changed $before != $now"
31825 }
31826 run_test 816 "do not reset lru_resize on idle reconnect"
31827
31828 cleanup_817() {
31829         umount $tmpdir
31830         exportfs -u localhost:$DIR/nfsexp
31831         rm -rf $DIR/nfsexp
31832 }
31833
31834 test_817() {
31835         systemctl restart nfs-server.service || skip "failed to restart nfsd"
31836
31837         mkdir -p $DIR/nfsexp
31838         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
31839                 error "failed to export nfs"
31840
31841         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
31842         stack_trap cleanup_817 EXIT
31843
31844         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
31845                 error "failed to mount nfs to $tmpdir"
31846
31847         cp /bin/true $tmpdir
31848         $DIR/nfsexp/true || error "failed to execute 'true' command"
31849 }
31850 run_test 817 "nfsd won't cache write lock for exec file"
31851
31852 test_818() {
31853         test_mkdir -i0 -c1 $DIR/$tdir
31854         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
31855         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
31856         stop $SINGLEMDS
31857
31858         # restore osp-syn threads
31859         stack_trap "fail $SINGLEMDS"
31860
31861         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
31862         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
31863         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
31864                 error "start $SINGLEMDS failed"
31865         rm -rf $DIR/$tdir
31866
31867         local testid=$(echo $TESTNAME | tr '_' ' ')
31868
31869         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
31870                 grep "run LFSCK" || error "run LFSCK is not suggested"
31871 }
31872 run_test 818 "unlink with failed llog"
31873
31874 test_819a() {
31875         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
31876         cancel_lru_locks osc
31877         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
31878         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
31879         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
31880         rm -f $TDIR/$tfile
31881 }
31882 run_test 819a "too big niobuf in read"
31883
31884 test_819b() {
31885         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
31886         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
31887         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
31888         cancel_lru_locks osc
31889         sleep 1
31890         rm -f $TDIR/$tfile
31891 }
31892 run_test 819b "too big niobuf in write"
31893
31894
31895 function test_820_start_ost() {
31896         sleep 5
31897
31898         for num in $(seq $OSTCOUNT); do
31899                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
31900         done
31901 }
31902
31903 test_820() {
31904         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
31905
31906         mkdir $DIR/$tdir
31907         umount_client $MOUNT || error "umount failed"
31908         for num in $(seq $OSTCOUNT); do
31909                 stop ost$num
31910         done
31911
31912         # mount client with no active OSTs
31913         # so that the client can't initialize max LOV EA size
31914         # from OSC notifications
31915         mount_client $MOUNT || error "mount failed"
31916         # delay OST starting to keep this 0 max EA size for a while
31917         test_820_start_ost &
31918
31919         # create a directory on MDS2
31920         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
31921                 error "Failed to create directory"
31922         # open intent should update default EA size
31923         # see mdc_update_max_ea_from_body()
31924         # notice this is the very first RPC to MDS2
31925         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
31926         ret=$?
31927         echo $out
31928         # With SSK, this situation can lead to -EPERM being returned.
31929         # In that case, simply retry.
31930         if [ $ret -ne 0 ] && $SHARED_KEY; then
31931                 if echo "$out" | grep -q "not permitted"; then
31932                         cp /etc/services $DIR/$tdir/mds2
31933                         ret=$?
31934                 fi
31935         fi
31936         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
31937 }
31938 run_test 820 "update max EA from open intent"
31939
31940 test_823() {
31941         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
31942         local OST_MAX_PRECREATE=20000
31943
31944         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
31945                 skip "Need MDS version at least 2.14.56"
31946
31947         save_lustre_params mds1 \
31948                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
31949         do_facet $SINGLEMDS "$LCTL set_param -n \
31950                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
31951         do_facet $SINGLEMDS "$LCTL set_param -n \
31952                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
31953
31954         stack_trap "restore_lustre_params < $p; rm $p"
31955
31956         do_facet $SINGLEMDS "$LCTL set_param -n \
31957                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
31958
31959         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
31960                       osp.$FSNAME-OST0000*MDT0000.create_count")
31961         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
31962                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
31963         local expect_count=$(((($max/2)/256) * 256))
31964
31965         log "setting create_count to 100200:"
31966         log " -result- count: $count with max: $max, expecting: $expect_count"
31967
31968         [[ $count -eq expect_count ]] ||
31969                 error "Create count not set to max precreate."
31970 }
31971 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
31972
31973 test_831() {
31974         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
31975                 skip "Need MDS version 2.14.56"
31976
31977         local sync_changes=$(do_facet $SINGLEMDS \
31978                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
31979
31980         [ "$sync_changes" -gt 100 ] &&
31981                 skip "Sync changes $sync_changes > 100 already"
31982
31983         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
31984
31985         $LFS mkdir -i 0 $DIR/$tdir
31986         $LFS setstripe -c 1 -i 0 $DIR/$tdir
31987
31988         save_lustre_params mds1 \
31989                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
31990         save_lustre_params mds1 \
31991                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
31992
31993         do_facet mds1 "$LCTL set_param -n \
31994                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
31995                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
31996         stack_trap "restore_lustre_params < $p" EXIT
31997
31998         createmany -o $DIR/$tdir/f- 1000
31999         unlinkmany $DIR/$tdir/f- 1000 &
32000         local UNLINK_PID=$!
32001
32002         while sleep 1; do
32003                 sync_changes=$(do_facet mds1 \
32004                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
32005                 # the check in the code is racy, fail the test
32006                 # if the value above the limit by 10.
32007                 [ $sync_changes -gt 110 ] && {
32008                         kill -2 $UNLINK_PID
32009                         wait
32010                         error "osp changes throttling failed, $sync_changes>110"
32011                 }
32012                 kill -0 $UNLINK_PID 2> /dev/null || break
32013         done
32014         wait
32015 }
32016 run_test 831 "throttling unlink/setattr queuing on OSP"
32017
32018 test_832() {
32019         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
32020         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
32021                 skip "Need MDS version 2.15.52+"
32022         is_rmentry_supported || skip "rm_entry not supported"
32023
32024         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
32025         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
32026         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
32027                 error "mkdir remote_dir failed"
32028         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
32029                 error "mkdir striped_dir failed"
32030         touch $DIR/$tdir/file || error "touch file failed"
32031         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
32032         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
32033 }
32034 run_test 832 "lfs rm_entry"
32035
32036 test_833() {
32037         local file=$DIR/$tfile
32038
32039         stack_trap "rm -f $file" EXIT
32040         dd if=/dev/zero of=$file bs=1M count=50 || error "Write $file failed"
32041
32042         local wpid
32043         local rpid
32044         local rpid2
32045
32046         # Buffered I/O write
32047         (
32048                 while [ ! -e $DIR/sanity.833.lck ]; do
32049                         dd if=/dev/zero of=$file bs=1M count=50 conv=notrunc ||
32050                                 error "failed to write $file"
32051                         sleep 0.$((RANDOM % 4 + 1))
32052                 done
32053         )&
32054         wpid=$!
32055
32056         # Buffered I/O read
32057         (
32058                 while [ ! -e $DIR/sanity.833.lck ]; do
32059                         dd if=$file of=/dev/null bs=1M count=50 ||
32060                                 error "failed to read $file"
32061                         sleep 0.$((RANDOM % 4 + 1))
32062                 done
32063         )&
32064         rpid=$!
32065
32066         # Direct I/O read
32067         (
32068                 while [ ! -e $DIR/sanity.833.lck ]; do
32069                         dd if=$file of=/dev/null bs=1M count=50 iflag=direct ||
32070                                 error "failed to read $file in direct I/O mode"
32071                         sleep 0.$((RANDOM % 4 + 1))
32072                 done
32073         )&
32074         rpid2=$!
32075
32076         sleep 30
32077         touch $DIR/sanity.833.lck
32078         wait $wpid || error "$?: buffered write failed"
32079         wait $rpid || error "$?: buffered read failed"
32080         wait $rpid2 || error "$?: direct read failed"
32081 }
32082 run_test 833 "Mixed buffered/direct read and write should not return -EIO"
32083
32084 test_842() {
32085         local oss1=$(facet_host ost1)
32086
32087         # Try to insert the module.  This will leave results in dmesg
32088         now=$(date +%s)
32089         log "STAMP $now" > /dev/kmsg
32090         do_rpc_nodes $oss1 load_module kunit/ldlm_extent ||
32091                 error "$oss1 load_module ldlm_extent failed"
32092
32093         do_node $oss1 dmesg | sed -n -e "1,/STAMP $now/d" -e '/ldlm_extent:/p'
32094         do_node $oss1 rmmod -v ldlm_extent ||
32095                 error "rmmod failed (may trigger a failure in a later test)"
32096 }
32097 run_test 842 "Measure ldlm_extent performance"
32098
32099 test_850() {
32100         local dir=$DIR/$tdir
32101         local file=$dir/$tfile
32102         local statsfile=$dir/all_job_stats.txt
32103
32104         test_mkdir -p $dir || error "failed to create dir $dir"
32105         echo "abcdefg" > $file || error "failed to create file $file"
32106
32107         # read job_stats in the living system
32108         lljobstat -n 1 ||
32109                 error "failed to run lljobstat on living system"
32110
32111         $LCTL get_param *.*.job_stats > $statsfile
32112         lljobstat --statsfile=$statsfile ||
32113                 error "failed to run lljobstat on file $statsfile"
32114 }
32115 run_test 850 "lljobstat can parse living and aggregated job_stats"
32116
32117 test_851() {
32118         local dir=$DIR/$tdir
32119         local file=$dir/f_test_851_$$
32120         local report=/tmp/report_test_851_$$
32121         local fanotify_prog=monitor_lustrefs
32122         local pid
32123
32124         test_mkdir $dir || error "failed to create dir $dir"
32125
32126         $fanotify_prog $DIR > $report &
32127         pid=$!
32128
32129         sleep 1
32130         if ! kill -0 $pid; then
32131                 error "failed to start $fanoify_prog"
32132         fi
32133
32134         stack_trap "kill $pid"
32135         stack_trap "rm -f $report"
32136
32137         echo "1234567890" > $file
32138         wait_update_cond localhost "stat -c %s $report" "-gt" "0" 30 ||
32139                 error "fanotify did not report anything after 30 seconds"
32140         grep -a -E "open.*:$file:" $report ||
32141                 error "no open event for writing $file"
32142         grep -a -E "write.*:$file:" $report ||
32143                 error "no write event for writing $file"
32144         grep -a -E "close.*:$file:" $report ||
32145                 error "no close event for writing $file"
32146
32147         > $report
32148         cat $file
32149         wait_update_cond localhost "stat -c %s $report" "-gt" "0" 30 ||
32150                 error "fanotify did not report anything after 30 seconds"
32151         grep -a -E "open.*:$file:" $report ||
32152                 error "no open event for reading $file"
32153         grep -a -E "read.*:$file:" $report ||
32154                 error "no write event for reading $file"
32155         grep -a -E "close.*:$file:" $report ||
32156                 error "no close event for reading $file"
32157 }
32158 run_test 851 "fanotify can monitor open/read/write/close events for lustre fs"
32159
32160 #
32161 # tests that do cleanup/setup should be run at the end
32162 #
32163
32164 test_900() {
32165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
32166         local ls
32167
32168         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
32169         $LCTL set_param fail_loc=0x903
32170
32171         cancel_lru_locks MGC
32172
32173         FAIL_ON_ERROR=true cleanup
32174         FAIL_ON_ERROR=true setup
32175 }
32176 run_test 900 "umount should not race with any mgc requeue thread"
32177
32178 # LUS-6253/LU-11185
32179 test_901() {
32180         local old
32181         local count
32182         local oldc
32183         local newc
32184         local olds
32185         local news
32186         [ $PARALLEL == "yes" ] && skip "skip parallel run"
32187
32188         # some get_param have a bug to handle dot in param name
32189         cancel_lru_locks MGC
32190         old=$(mount -t lustre | wc -l)
32191         # 1 config+sptlrpc
32192         # 2 params
32193         # 3 nodemap
32194         # 4 IR
32195         old=$((old * 4))
32196         oldc=0
32197         count=0
32198         while [ $old -ne $oldc ]; do
32199                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
32200                 sleep 1
32201                 ((count++))
32202                 if [ $count -ge $TIMEOUT ]; then
32203                         error "too large timeout"
32204                 fi
32205         done
32206         umount_client $MOUNT || error "umount failed"
32207         mount_client $MOUNT || error "mount failed"
32208         cancel_lru_locks MGC
32209         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
32210
32211         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
32212
32213         return 0
32214 }
32215 run_test 901 "don't leak a mgc lock on client umount"
32216
32217 # LU-13377
32218 test_902() {
32219         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
32220                 skip "client does not have LU-13377 fix"
32221         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
32222         $LCTL set_param fail_loc=0x1415
32223         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
32224         cancel_lru_locks osc
32225         rm -f $DIR/$tfile
32226 }
32227 run_test 902 "test short write doesn't hang lustre"
32228
32229 # LU-14711
32230 test_903() {
32231         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
32232         echo "blah" > $DIR/${tfile}-2
32233         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
32234         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
32235         $LCTL set_param fail_loc=0x417 fail_val=20
32236
32237         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
32238         sleep 1 # To start the destroy
32239         wait_destroy_complete 150 || error "Destroy taking too long"
32240         cat $DIR/$tfile > /dev/null || error "Evicted"
32241 }
32242 run_test 903 "Test long page discard does not cause evictions"
32243
32244 test_904() {
32245         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
32246         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
32247                 grep -q project || skip "skip project quota not supported"
32248
32249         local testfile="$DIR/$tdir/$tfile"
32250         local xattr="trusted.projid"
32251         local projid
32252         local mdts=$(comma_list $(mdts_nodes))
32253         local saved=$(do_facet mds1 $LCTL get_param -n \
32254                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
32255
32256         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
32257         stack_trap "do_nodes $mdts $LCTL set_param \
32258                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
32259
32260         mkdir -p $DIR/$tdir
32261         touch $testfile
32262         #hide projid xattr on server
32263         $LFS project -p 1 $testfile ||
32264                 error "set $testfile project id failed"
32265         getfattr -m - $testfile | grep $xattr &&
32266                 error "do not show trusted.projid when disabled on server"
32267         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
32268         #should be hidden when projid is 0
32269         $LFS project -p 0 $testfile ||
32270                 error "set $testfile project id failed"
32271         getfattr -m - $testfile | grep $xattr &&
32272                 error "do not show trusted.projid with project ID 0"
32273
32274         #still can getxattr explicitly
32275         projid=$(getfattr -n $xattr $testfile |
32276                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
32277         [ $projid == "0" ] ||
32278                 error "projid expected 0 not $projid"
32279
32280         #set the projid via setxattr
32281         setfattr -n $xattr -v "1000" $testfile ||
32282                 error "setattr failed with $?"
32283         projid=($($LFS project $testfile))
32284         [ ${projid[0]} == "1000" ] ||
32285                 error "projid expected 1000 not $projid"
32286
32287         #check the new projid via getxattr
32288         $LFS project -p 1001 $testfile ||
32289                 error "set $testfile project id failed"
32290         getfattr -m - $testfile | grep $xattr ||
32291                 error "should show trusted.projid when project ID != 0"
32292         projid=$(getfattr -n $xattr $testfile |
32293                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
32294         [ $projid == "1001" ] ||
32295                 error "projid expected 1001 not $projid"
32296
32297         #try to set invalid projid
32298         setfattr -n $xattr -v "4294967295" $testfile &&
32299                 error "set invalid projid should fail"
32300
32301         #remove the xattr means setting projid to 0
32302         setfattr -x $xattr $testfile ||
32303                 error "setfattr failed with $?"
32304         projid=($($LFS project $testfile))
32305         [ ${projid[0]} == "0" ] ||
32306                 error "projid expected 0 not $projid"
32307
32308         #should be hidden when parent has inherit flag and same projid
32309         $LFS project -srp 1002 $DIR/$tdir ||
32310                 error "set $tdir project id failed"
32311         getfattr -m - $testfile | grep $xattr &&
32312                 error "do not show trusted.projid with inherit flag"
32313
32314         #still can getxattr explicitly
32315         projid=$(getfattr -n $xattr $testfile |
32316                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
32317         [ $projid == "1002" ] ||
32318                 error "projid expected 1002 not $projid"
32319 }
32320 run_test 904 "virtual project ID xattr"
32321
32322 # LU-8582
32323 test_905() {
32324         (( $OST1_VERSION >= $(version_code 2.15.50.220) )) ||
32325                 skip "need OST version >= 2.15.50.220 for fail_loc"
32326
32327         remote_ost_nodsh && skip "remote OST with nodsh"
32328         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
32329
32330         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
32331
32332         #define OBD_FAIL_OST_OPCODE 0x253
32333         # OST_LADVISE = 21
32334         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
32335         $LFS ladvise -a willread $DIR/$tfile &&
32336                 error "unexpected success of ladvise with fault injection"
32337         $LFS ladvise -a willread $DIR/$tfile |&
32338                 grep -q "Operation not supported"
32339         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
32340 }
32341 run_test 905 "bad or new opcode should not stuck client"
32342
32343 test_906() {
32344         grep -q io_uring_setup /proc/kallsyms ||
32345                 skip "Client OS does not support io_uring I/O engine"
32346         io_uring_probe || skip "kernel does not support io_uring fully"
32347         which fio || skip_env "no fio installed"
32348         fio --enghelp | grep -q io_uring ||
32349                 skip_env "fio does not support io_uring I/O engine"
32350
32351         local file=$DIR/$tfile
32352         local ioengine="io_uring"
32353         local numjobs=2
32354         local size=50M
32355
32356         fio --name=seqwrite --ioengine=$ioengine        \
32357                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
32358                 --iodepth=64 --size=$size --filename=$file --rw=write ||
32359                 error "fio seqwrite $file failed"
32360
32361         fio --name=seqread --ioengine=$ioengine \
32362                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
32363                 --iodepth=64 --size=$size --filename=$file --rw=read ||
32364                 error "fio seqread $file failed"
32365
32366         rm -f $file || error "rm -f $file failed"
32367 }
32368 run_test 906 "Simple test for io_uring I/O engine via fio"
32369
32370 test_907() {
32371         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
32372
32373         # set stripe size to max rpc size
32374         $LFS setstripe -i 0 -c 2 -S $((max_pages * PAGE_SIZE)) $DIR/$tfile
32375         $LFS getstripe $DIR/$tfile
32376 #define OBD_FAIL_OST_EROFS               0x216
32377         do_facet ost1 "$LCTL set_param fail_val=3 fail_loc=0x80000216"
32378
32379         local bs=$((max_pages * PAGE_SIZE / 16))
32380
32381         # write full one stripe and one block
32382         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=17 || error "dd failed"
32383
32384         rm $DIR/$tfile || error "rm failed"
32385 }
32386 run_test 907 "write rpc error during unlink"
32387
32388 complete_test $SECONDS
32389 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
32390 check_and_cleanup_lustre
32391 if [ "$I_MOUNTED" != "yes" ]; then
32392         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
32393 fi
32394 exit_status