Whamcloud - gitweb
LU-17571 tests: set idle_timeout in sanity 77l, 812[ab], 816
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 SOCKETSERVER=${SOCKETSERVER:-socketserver}
23 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
24 MEMHOG=${MEMHOG:-memhog}
25 DIRECTIO=${DIRECTIO:-directio}
26 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
27 DEF_STRIPE_COUNT=-1
28 CHECK_GRANT=${CHECK_GRANT:-"yes"}
29 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
30
31 TRACE=${TRACE:-""}
32 LUSTRE=${LUSTRE:-$(dirname $0)/..}
33 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
34 . $LUSTRE/tests/test-framework.sh
35 init_test_env "$@"
36
37 init_logging
38
39 ALWAYS_EXCEPT="$SANITY_EXCEPT "
40 always_except LU-9693  42a 42c
41 always_except LU-6493  42b
42 always_except LU-16515 118c 118d
43 always_except LU-8411  407
44
45 if $SHARED_KEY; then
46         always_except LU-14181 64e 64f
47         always_except LU-17127 39o
48 fi
49
50 # skip the grant tests for ARM until they are fixed
51 if [[ $(uname -m) = aarch64 ]]; then
52         always_except LU-11671 45
53 fi
54
55 # skip nfs tests on kernels >= 4.12.0 until they are fixed
56 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
57         always_except LU-12661 817
58 fi
59 # skip cgroup tests on RHEL8.1 kernels until they are fixed
60 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
61       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
62         always_except LU-13063 411a
63 fi
64
65 # skip cgroup tests for kernels < v4.18.0
66 if (( $LINUX_VERSION_CODE < $(version_code 4.18.0) )); then
67         always_except LU-13063 411b
68 fi
69
70 #                                  5              12     8   12  15   (min)"
71 [[ "$SLOW" = "no" ]] && EXCEPT_SLOW="27m 60i 64b 68 71 135 136 230d 300o"
72
73 if [[ "$mds1_FSTYPE" == "zfs" ]]; then
74         #                                               13    (min)"
75         [[ "$SLOW" == "no" ]] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
76 fi
77
78 if [[ "$ost1_FSTYPE" = "zfs" ]]; then
79         always_except LU-1941 130b 130c 130d 130e 130f 130g
80         always_except LU-9054 312
81 fi
82
83 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
84
85 # Get the SLES distro version
86 #
87 # Returns a version string that should only be used in comparing
88 # strings returned by version_code()
89 sles_version_code()
90 {
91         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
92
93         # All SuSE Linux versions have one decimal. version_code expects two
94         local sles_version=$version.0
95         version_code $sles_version
96 }
97
98 # Check if we are running on Ubuntu or SLES so we can make decisions on
99 # what tests to run
100 if [ -r /etc/SuSE-release ] || [ -r /etc/SUSE-brand ]; then
101         sles_version=$(sles_version_code)
102         (( $sles_version >= $(version_code 11.4.0) )) ||
103                 always_except LU-4341 170
104
105         (( $sles_version >= $(version_code 12.0.0) )) ||
106                 always_except LU-3703 234
107 elif [ -r /etc/redhat-release ]; then
108         rhel_version=$(cat /etc/redhat-release |
109                 sed -e 's/^[^0-9.]*//g' | sed -e 's/[ ].*//')
110         if (( $(version_code $rhel_version) >= $(version_code 9.3.0) )); then
111                 # disable test_906 temporarily until rhel9.3 solves the
112                 # failure on fio io_uring I/O engine.
113                 always_except LU-17289 906
114         fi
115 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         LANG=C perl -MSocket -e ';' || skip "no Socket perl module installed"
6343
6344         LANG=C $SOCKETSERVER $DIR/socket ||
6345                 error "$SOCKETSERVER $DIR/socket failed: $?"
6346         LANG=C $SOCKETCLIENT $DIR/socket ||
6347                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6348         unlink $DIR/socket || error "unlink $DIR/socket failed: $?"
6349 }
6350 run_test 54a "unix domain socket test =========================="
6351
6352 test_54b() {
6353         f="$DIR/f54b"
6354         mknod $f c 1 3
6355         chmod 0666 $f
6356         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6357 }
6358 run_test 54b "char device works in lustre ======================"
6359
6360 find_loop_dev() {
6361         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6362         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6363         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6364
6365         for i in $(seq 3 7); do
6366                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6367                 LOOPDEV=$LOOPBASE$i
6368                 LOOPNUM=$i
6369                 break
6370         done
6371 }
6372
6373 cleanup_54c() {
6374         local rc=0
6375         loopdev="$DIR/loop54c"
6376
6377         trap 0
6378         $UMOUNT $DIR/$tdir || rc=$?
6379         losetup -d $loopdev || true
6380         losetup -d $LOOPDEV || true
6381         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6382         return $rc
6383 }
6384
6385 test_54c() {
6386         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6387
6388         loopdev="$DIR/loop54c"
6389
6390         find_loop_dev
6391         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6392         trap cleanup_54c EXIT
6393         mknod $loopdev b 7 $LOOPNUM
6394         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6395         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6396         losetup $loopdev $DIR/$tfile ||
6397                 error "can't set up $loopdev for $DIR/$tfile"
6398         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6399         test_mkdir $DIR/$tdir
6400         mount -t ext2 $loopdev $DIR/$tdir ||
6401                 error "error mounting $loopdev on $DIR/$tdir"
6402         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6403                 error "dd write"
6404         df $DIR/$tdir
6405         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6406                 error "dd read"
6407         cleanup_54c
6408 }
6409 run_test 54c "block device works in lustre ====================="
6410
6411 test_54d() {
6412         local pipe="$DIR/$tfile.pipe"
6413         local string="aaaaaa"
6414
6415         mknod $pipe p
6416         echo -n "$string" > $pipe &
6417         local result=$(cat $pipe)
6418         [[ "$result" == "$string" ]] || error "$result != $string"
6419 }
6420 run_test 54d "fifo device works in lustre ======================"
6421
6422 test_54e() {
6423         f="$DIR/f54e"
6424         string="aaaaaa"
6425         cp -aL /dev/console $f
6426         echo $string > $f || error "echo $string to $f failed"
6427 }
6428 run_test 54e "console/tty device works in lustre ======================"
6429
6430 test_55a() {
6431         local dev_path="/sys/kernel/debug/lustre/devices"
6432
6433         load_module kunit/obd_test verbose=2 || error "load_module failed"
6434
6435         # This must be run in iteractive mode, since attach and setup
6436         # are stateful
6437         eval "$LCTL <<-EOF || error 'OBD device creation failed'
6438                 attach obd_test obd_name obd_uuid
6439                 setup obd_test
6440         EOF"
6441
6442         echo "Devices:"
6443         cat "$dev_path" | tail -n 10
6444
6445         $LCTL --device "obd_name" cleanup
6446         $LCTL --device "obd_name" detach
6447
6448         dmesg | tail -n 25 | grep "Lustre: OBD:.*FAIL" &&
6449                 error "OBD unit test failed"
6450
6451         rmmod -v obd_test ||
6452                 error "rmmod failed (may trigger a failure in a later test)"
6453 }
6454 run_test 55a "OBD device life cycle unit tests"
6455
6456 test_55b() {
6457         local dev_path="/sys/kernel/debug/lustre/devices"
6458         local dev_count="$(wc -l $dev_path | awk '{print $1}')"
6459
6460         # Set up a large number of devices, using the number
6461         # that can be set up in about a minute (based on prior
6462         # testing). We don't want to run this test forever.
6463         local num_dev_to_create="$(( 24000 - $dev_count))"
6464
6465         load_module kunit/obd_test || error "load_module failed"
6466
6467         local start=$SECONDS
6468
6469         # This must be run in iteractive mode, since attach and setup
6470         # are stateful
6471         for ((i = 1; i <= num_dev_to_create; i++)); do
6472                 echo "attach obd_test obd_name_$i obd_uuid_$i"
6473                 echo "setup obd_test_$i"
6474         done | $LCTL || error "OBD device creation failed"
6475
6476         echo "Load time: $((SECONDS - start))"
6477         echo "Devices:"
6478         cat "$dev_path" | tail -n 10
6479
6480         for ((i = 1; i <= num_dev_to_create; i++)); do
6481                 echo "--device obd_name_$i cleanup"
6482                 echo "--device obd_name_$i detach"
6483         done | $LCTL || error "OBD device cleanup failed"
6484
6485         echo "Unload time: $((SECONDS - start))"
6486
6487         rmmod -v obd_test ||
6488                 error "rmmod failed (may trigger a failure in a later test)"
6489 }
6490 run_test 55b "Load and unload max OBD devices"
6491
6492 test_56a() {
6493         local numfiles=3
6494         local numdirs=2
6495         local dir=$DIR/$tdir
6496
6497         rm -rf $dir
6498         test_mkdir -p $dir/dir
6499         for i in $(seq $numfiles); do
6500                 touch $dir/file$i
6501                 touch $dir/dir/file$i
6502         done
6503
6504         local numcomp=$($LFS getstripe --component-count $dir)
6505
6506         [[ $numcomp == 0 ]] && numcomp=1
6507
6508         # test lfs getstripe with --recursive
6509         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6510
6511         [[ $filenum -eq $((numfiles * 2)) ]] ||
6512                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6513         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6514         [[ $filenum -eq $numfiles ]] ||
6515                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6516         echo "$LFS getstripe showed obdidx or l_ost_idx"
6517
6518         # test lfs getstripe with file instead of dir
6519         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6520         [[ $filenum -eq 1 ]] ||
6521                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6522         echo "$LFS getstripe file1 passed"
6523
6524         #test lfs getstripe with --verbose
6525         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6526         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6527                 error "$LFS getstripe --verbose $dir: "\
6528                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6529         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6530                 error "$LFS getstripe $dir: showed lmm_magic"
6531
6532         #test lfs getstripe with -v prints lmm_fid
6533         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6534         local countfids=$((numdirs + numfiles * numcomp))
6535         [[ $filenum -eq $countfids ]] ||
6536                 error "$LFS getstripe -v $dir: "\
6537                       "got $filenum want $countfids lmm_fid"
6538         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6539                 error "$LFS getstripe $dir: showed lmm_fid by default"
6540         echo "$LFS getstripe --verbose passed"
6541
6542         #check for FID information
6543         local fid1=$($LFS getstripe --fid $dir/file1)
6544         local fid2=$($LFS getstripe --verbose $dir/file1 |
6545                      awk '/lmm_fid: / { print $2; exit; }')
6546         local fid3=$($LFS path2fid $dir/file1)
6547
6548         [ "$fid1" != "$fid2" ] &&
6549                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6550         [ "$fid1" != "$fid3" ] &&
6551                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6552         echo "$LFS getstripe --fid passed"
6553
6554         #test lfs getstripe with --obd
6555         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6556                 error "$LFS getstripe --obd wrong_uuid: should return error"
6557
6558         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6559
6560         local ostidx=1
6561         local obduuid=$(ostuuid_from_index $ostidx)
6562         local found=$($LFS getstripe -r --obd $obduuid $dir |
6563                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6564
6565         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6566         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6567                 ((filenum--))
6568         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6569                 ((filenum--))
6570
6571         [[ $found -eq $filenum ]] ||
6572                 error "$LFS getstripe --obd: found $found expect $filenum"
6573         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6574                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6575                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6576                 error "$LFS getstripe --obd: should not show file on other obd"
6577         echo "$LFS getstripe --obd passed"
6578 }
6579 run_test 56a "check $LFS getstripe"
6580
6581 test_56b() {
6582         local dir=$DIR/$tdir
6583         local numdirs=3
6584
6585         test_mkdir $dir
6586         for i in $(seq $numdirs); do
6587                 test_mkdir $dir/dir$i
6588         done
6589
6590         # test lfs getdirstripe default mode is non-recursion, which is
6591         # different from lfs getstripe
6592         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6593
6594         [[ $dircnt -eq 1 ]] ||
6595                 error "$LFS getdirstripe: found $dircnt, not 1"
6596         dircnt=$($LFS getdirstripe --recursive $dir |
6597                 grep -c lmv_stripe_count)
6598         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6599                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6600 }
6601 run_test 56b "check $LFS getdirstripe"
6602
6603 test_56bb() {
6604         verify_yaml_available || skip_env "YAML verification not installed"
6605         local output_file=$DIR/$tfile.out
6606
6607         $LFS getdirstripe -v -D -y $DIR 1> $output_file
6608
6609         cat $output_file
6610         cat $output_file | verify_yaml || error "layout is not valid YAML"
6611 }
6612 run_test 56bb "check $LFS getdirstripe layout is YAML"
6613
6614 test_56c() {
6615         remote_ost_nodsh && skip "remote OST with nodsh"
6616
6617         local ost_idx=0
6618         local ost_name=$(ostname_from_index $ost_idx)
6619         local old_status=$(ost_dev_status $ost_idx)
6620         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6621
6622         [[ -z "$old_status" ]] ||
6623                 skip_env "OST $ost_name is in $old_status status"
6624
6625         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6626         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6627                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6628         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6629                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6630                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6631         fi
6632
6633         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6634                 error "$LFS df -v showing inactive devices"
6635         sleep_maxage
6636
6637         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6638
6639         [[ "$new_status" =~ "D" ]] ||
6640                 error "$ost_name status is '$new_status', missing 'D'"
6641         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6642                 [[ "$new_status" =~ "N" ]] ||
6643                         error "$ost_name status is '$new_status', missing 'N'"
6644         fi
6645         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6646                 [[ "$new_status" =~ "f" ]] ||
6647                         error "$ost_name status is '$new_status', missing 'f'"
6648         fi
6649
6650         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6651         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6652                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6653         [[ -z "$p" ]] && restore_lustre_params < $p || true
6654         sleep_maxage
6655
6656         new_status=$(ost_dev_status $ost_idx)
6657         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6658                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6659         # can't check 'f' as devices may actually be on flash
6660 }
6661 run_test 56c "check 'lfs df' showing device status"
6662
6663 test_56d() {
6664         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6665         local osts=$($LFS df -v $MOUNT | grep -c OST)
6666
6667         $LFS df $MOUNT
6668
6669         (( mdts == MDSCOUNT )) ||
6670                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6671         (( osts == OSTCOUNT )) ||
6672                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6673 }
6674 run_test 56d "'lfs df -v' prints only configured devices"
6675
6676 test_56e() {
6677         err_enoent=2 # No such file or directory
6678         err_eopnotsupp=95 # Operation not supported
6679
6680         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6681         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6682
6683         # Check for handling of path not exists
6684         output=$($LFS df $enoent_mnt 2>&1)
6685         ret=$?
6686
6687         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6688         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6689                 error "expect failure $err_enoent, not $ret"
6690
6691         # Check for handling of non-Lustre FS
6692         output=$($LFS df $notsup_mnt)
6693         ret=$?
6694
6695         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6696         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6697                 error "expect success $err_eopnotsupp, not $ret"
6698
6699         # Check for multiple LustreFS argument
6700         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6701         ret=$?
6702
6703         [[ $output -eq 3 && $ret -eq 0 ]] ||
6704                 error "expect success 3, not $output, rc = $ret"
6705
6706         # Check for correct non-Lustre FS handling among multiple
6707         # LustreFS argument
6708         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6709                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6710         ret=$?
6711
6712         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6713                 error "expect success 2, not $output, rc = $ret"
6714 }
6715 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6716
6717 NUMFILES=3
6718 NUMDIRS=3
6719 setup_56() {
6720         local local_tdir="$1"
6721         local local_numfiles="$2"
6722         local local_numdirs="$3"
6723         local dir_params="$4"
6724         local dir_stripe_params="$5"
6725
6726         if [ ! -d "$local_tdir" ] ; then
6727                 test_mkdir -p $dir_stripe_params $local_tdir
6728                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6729                 for i in $(seq $local_numfiles) ; do
6730                         touch $local_tdir/file$i
6731                 done
6732                 for i in $(seq $local_numdirs) ; do
6733                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6734                         for j in $(seq $local_numfiles) ; do
6735                                 touch $local_tdir/dir$i/file$j
6736                         done
6737                 done
6738         fi
6739 }
6740
6741 setup_56_special() {
6742         local local_tdir=$1
6743         local local_numfiles=$2
6744         local local_numdirs=$3
6745
6746         setup_56 $local_tdir $local_numfiles $local_numdirs
6747
6748         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6749                 for i in $(seq $local_numfiles) ; do
6750                         mknod $local_tdir/loop${i}b b 7 $i
6751                         mknod $local_tdir/null${i}c c 1 3
6752                         ln -s $local_tdir/file1 $local_tdir/link${i}
6753                 done
6754                 for i in $(seq $local_numdirs) ; do
6755                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6756                         mknod $local_tdir/dir$i/null${i}c c 1 3
6757                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6758                 done
6759         fi
6760 }
6761
6762 test_56g() {
6763         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6764         local expected=$(($NUMDIRS + 2))
6765
6766         setup_56 $dir $NUMFILES $NUMDIRS
6767
6768         # test lfs find with -name
6769         for i in $(seq $NUMFILES) ; do
6770                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6771
6772                 [ $nums -eq $expected ] ||
6773                         error "lfs find -name '*$i' $dir wrong: "\
6774                               "found $nums, expected $expected"
6775         done
6776 }
6777 run_test 56g "check lfs find -name"
6778
6779 test_56h() {
6780         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6781         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6782
6783         setup_56 $dir $NUMFILES $NUMDIRS
6784
6785         # test lfs find with ! -name
6786         for i in $(seq $NUMFILES) ; do
6787                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6788
6789                 [ $nums -eq $expected ] ||
6790                         error "lfs find ! -name '*$i' $dir wrong: "\
6791                               "found $nums, expected $expected"
6792         done
6793 }
6794 run_test 56h "check lfs find ! -name"
6795
6796 test_56i() {
6797         local dir=$DIR/$tdir
6798
6799         test_mkdir $dir
6800
6801         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6802         local out=$($cmd)
6803
6804         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6805 }
6806 run_test 56i "check 'lfs find -ost UUID' skips directories"
6807
6808 test_56j() {
6809         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6810
6811         setup_56_special $dir $NUMFILES $NUMDIRS
6812
6813         local expected=$((NUMDIRS + 1))
6814         local cmd="$LFS find -type d $dir"
6815         local nums=$($cmd | wc -l)
6816
6817         [ $nums -eq $expected ] ||
6818                 error "'$cmd' wrong: found $nums, expected $expected"
6819 }
6820 run_test 56j "check lfs find -type d"
6821
6822 test_56k() {
6823         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6824
6825         setup_56_special $dir $NUMFILES $NUMDIRS
6826
6827         local expected=$(((NUMDIRS + 1) * NUMFILES))
6828         local cmd="$LFS find -type f $dir"
6829         local nums=$($cmd | wc -l)
6830
6831         [ $nums -eq $expected ] ||
6832                 error "'$cmd' wrong: found $nums, expected $expected"
6833 }
6834 run_test 56k "check lfs find -type f"
6835
6836 test_56l() {
6837         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6838
6839         setup_56_special $dir $NUMFILES $NUMDIRS
6840
6841         local expected=$((NUMDIRS + NUMFILES))
6842         local cmd="$LFS find -type b $dir"
6843         local nums=$($cmd | wc -l)
6844
6845         [ $nums -eq $expected ] ||
6846                 error "'$cmd' wrong: found $nums, expected $expected"
6847 }
6848 run_test 56l "check lfs find -type b"
6849
6850 test_56m() {
6851         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6852
6853         setup_56_special $dir $NUMFILES $NUMDIRS
6854
6855         local expected=$((NUMDIRS + NUMFILES))
6856         local cmd="$LFS find -type c $dir"
6857         local nums=$($cmd | wc -l)
6858         [ $nums -eq $expected ] ||
6859                 error "'$cmd' wrong: found $nums, expected $expected"
6860 }
6861 run_test 56m "check lfs find -type c"
6862
6863 test_56n() {
6864         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6865         setup_56_special $dir $NUMFILES $NUMDIRS
6866
6867         local expected=$((NUMDIRS + NUMFILES))
6868         local cmd="$LFS find -type l $dir"
6869         local nums=$($cmd | wc -l)
6870
6871         [ $nums -eq $expected ] ||
6872                 error "'$cmd' wrong: found $nums, expected $expected"
6873 }
6874 run_test 56n "check lfs find -type l"
6875
6876 test_56o() {
6877         local dir=$DIR/$tdir
6878
6879         setup_56 $dir $NUMFILES $NUMDIRS
6880         utime $dir/file1 > /dev/null || error "utime (1)"
6881         utime $dir/file2 > /dev/null || error "utime (2)"
6882         utime $dir/dir1 > /dev/null || error "utime (3)"
6883         utime $dir/dir2 > /dev/null || error "utime (4)"
6884         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6885         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6886
6887         local expected=4
6888         local nums=$($LFS find -mtime +0 $dir | wc -l)
6889
6890         [ $nums -eq $expected ] ||
6891                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6892
6893         expected=12
6894         cmd="$LFS find -mtime 0 $dir"
6895         nums=$($cmd | wc -l)
6896         [ $nums -eq $expected ] ||
6897                 error "'$cmd' wrong: found $nums, expected $expected"
6898 }
6899 run_test 56o "check lfs find -mtime for old files"
6900
6901 test_56ob() {
6902         local dir=$DIR/$tdir
6903         local expected=1
6904         local count=0
6905
6906         # just to make sure there is something that won't be found
6907         test_mkdir $dir
6908         touch $dir/$tfile.now
6909
6910         for age in year week day hour min; do
6911                 count=$((count + 1))
6912
6913                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6914                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6915                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6916
6917                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6918                 local nums=$($cmd | wc -l)
6919                 [ $nums -eq $expected ] ||
6920                         error "'$cmd' wrong: found $nums, expected $expected"
6921
6922                 cmd="$LFS find $dir -atime $count${age:0:1}"
6923                 nums=$($cmd | wc -l)
6924                 [ $nums -eq $expected ] ||
6925                         error "'$cmd' wrong: found $nums, expected $expected"
6926         done
6927
6928         sleep 2
6929         cmd="$LFS find $dir -ctime +1s -type f"
6930         nums=$($cmd | wc -l)
6931         (( $nums == $count * 2 + 1)) ||
6932                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6933 }
6934 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6935
6936 test_newerXY_base() {
6937         local x=$1
6938         local y=$2
6939         local dir=$DIR/$tdir
6940         local ref
6941         local negref
6942
6943         if [ $y == "t" ]; then
6944                 if [ $x == "b" ]; then
6945                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6946                 else
6947                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6948                 fi
6949         else
6950                 ref=$DIR/$tfile.newer.$x$y
6951                 touch $ref || error "touch $ref failed"
6952         fi
6953
6954         echo "before = $ref"
6955         sleep 2
6956         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6957         sleep 2
6958         if [ $y == "t" ]; then
6959                 if [ $x == "b" ]; then
6960                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6961                 else
6962                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6963                 fi
6964         else
6965                 negref=$DIR/$tfile.negnewer.$x$y
6966                 touch $negref || error "touch $negref failed"
6967         fi
6968
6969         echo "after = $negref"
6970         local cmd="$LFS find $dir -newer$x$y $ref"
6971         local nums=$(eval $cmd | wc -l)
6972         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6973
6974         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6975                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6976
6977         cmd="$LFS find $dir ! -newer$x$y $negref"
6978         nums=$(eval $cmd | wc -l)
6979         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6980                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6981
6982         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6983         nums=$(eval $cmd | wc -l)
6984         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6985                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6986
6987         rm -rf $DIR/*
6988 }
6989
6990 test_56oc() {
6991         test_newerXY_base "a" "a"
6992         test_newerXY_base "a" "m"
6993         test_newerXY_base "a" "c"
6994         test_newerXY_base "m" "a"
6995         test_newerXY_base "m" "m"
6996         test_newerXY_base "m" "c"
6997         test_newerXY_base "c" "a"
6998         test_newerXY_base "c" "m"
6999         test_newerXY_base "c" "c"
7000
7001         test_newerXY_base "a" "t"
7002         test_newerXY_base "m" "t"
7003         test_newerXY_base "c" "t"
7004
7005         (( $MDS1_VERSION >= $(version_code v2_13_53-145-g186b97e68a) &&
7006            $CLIENT_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
7007                 { echo "btime needs v2_13_53-145-g186b97e68a"; return 0; }
7008
7009         test_newerXY_base "b" "b"
7010         test_newerXY_base "b" "t"
7011 }
7012 run_test 56oc "check lfs find -newerXY work"
7013
7014 test_56od() {
7015         (( $MDS1_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
7016                 skip "btime unsupported on MDS < v2_13_53-145-g186b97e68a"
7017
7018         (( $CLIENT_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
7019                 skip "btime unsupported on clients < v2_13_53-145-g186b97e68a"
7020
7021         local dir=$DIR/$tdir
7022         local ref=$DIR/$tfile.ref
7023         local negref=$DIR/$tfile.negref
7024
7025         mkdir $dir || error "mkdir $dir failed"
7026         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
7027         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
7028         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
7029         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
7030         touch $ref || error "touch $ref failed"
7031         # sleep 3 seconds at least
7032         sleep 3
7033
7034         local before=$(do_facet mds1 date +%s)
7035         local skew=$(($(date +%s) - before + 1))
7036
7037         if (( skew < 0 && skew > -5 )); then
7038                 sleep $((0 - skew + 1))
7039                 skew=0
7040         fi
7041
7042         # Set the dir stripe params to limit files all on MDT0,
7043         # otherwise we need to calc the max clock skew between
7044         # the client and MDTs.
7045         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
7046         sleep 2
7047         touch $negref || error "touch $negref failed"
7048
7049         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
7050         local nums=$($cmd | wc -l)
7051         local expected=$(((NUMFILES + 1) * NUMDIRS))
7052
7053         [ $nums -eq $expected ] ||
7054                 error "'$cmd' wrong: found $nums, expected $expected"
7055
7056         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
7057         nums=$($cmd | wc -l)
7058         expected=$((NUMFILES + 1))
7059         [ $nums -eq $expected ] ||
7060                 error "'$cmd' wrong: found $nums, expected $expected"
7061
7062         [ $skew -lt 0 ] && return
7063
7064         local after=$(do_facet mds1 date +%s)
7065         local age=$((after - before + 1 + skew))
7066
7067         cmd="$LFS find $dir -btime -${age}s -type f"
7068         nums=$($cmd | wc -l)
7069         expected=$(((NUMFILES + 1) * NUMDIRS))
7070
7071         echo "Clock skew between client and server: $skew, age:$age"
7072         [ $nums -eq $expected ] ||
7073                 error "'$cmd' wrong: found $nums, expected $expected"
7074
7075         expected=$(($NUMDIRS + 1))
7076         cmd="$LFS find $dir -btime -${age}s -type d"
7077         nums=$($cmd | wc -l)
7078         [ $nums -eq $expected ] ||
7079                 error "'$cmd' wrong: found $nums, expected $expected"
7080         rm -f $ref $negref || error "Failed to remove $ref $negref"
7081 }
7082 run_test 56od "check lfs find -btime with units"
7083
7084 test_56p() {
7085         [ $RUNAS_ID -eq $UID ] &&
7086                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7087
7088         local dir=$DIR/$tdir
7089
7090         setup_56 $dir $NUMFILES $NUMDIRS
7091         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
7092
7093         local expected=$NUMFILES
7094         local cmd="$LFS find -uid $RUNAS_ID $dir"
7095         local nums=$($cmd | wc -l)
7096
7097         [ $nums -eq $expected ] ||
7098                 error "'$cmd' wrong: found $nums, expected $expected"
7099
7100         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
7101         cmd="$LFS find ! -uid $RUNAS_ID $dir"
7102         nums=$($cmd | wc -l)
7103         [ $nums -eq $expected ] ||
7104                 error "'$cmd' wrong: found $nums, expected $expected"
7105 }
7106 run_test 56p "check lfs find -uid and ! -uid"
7107
7108 test_56q() {
7109         [ $RUNAS_ID -eq $UID ] &&
7110                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7111
7112         local dir=$DIR/$tdir
7113
7114         setup_56 $dir $NUMFILES $NUMDIRS
7115         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
7116
7117         local expected=$NUMFILES
7118         local cmd="$LFS find -gid $RUNAS_GID $dir"
7119         local nums=$($cmd | wc -l)
7120
7121         [ $nums -eq $expected ] ||
7122                 error "'$cmd' wrong: found $nums, expected $expected"
7123
7124         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
7125         cmd="$LFS find ! -gid $RUNAS_GID $dir"
7126         nums=$($cmd | wc -l)
7127         [ $nums -eq $expected ] ||
7128                 error "'$cmd' wrong: found $nums, expected $expected"
7129 }
7130 run_test 56q "check lfs find -gid and ! -gid"
7131
7132 test_56r() {
7133         local dir=$DIR/$tdir
7134
7135         setup_56 $dir $NUMFILES $NUMDIRS
7136
7137         local expected=12
7138         local cmd="$LFS find -size 0 -type f -lazy $dir"
7139         local nums=$($cmd | wc -l)
7140
7141         [ $nums -eq $expected ] ||
7142                 error "'$cmd' wrong: found $nums, expected $expected"
7143         cmd="$LFS find -size 0 -type f $dir"
7144         nums=$($cmd | wc -l)
7145         [ $nums -eq $expected ] ||
7146                 error "'$cmd' wrong: found $nums, expected $expected"
7147
7148         expected=0
7149         cmd="$LFS find ! -size 0 -type f -lazy $dir"
7150         nums=$($cmd | wc -l)
7151         [ $nums -eq $expected ] ||
7152                 error "'$cmd' wrong: found $nums, expected $expected"
7153         cmd="$LFS find ! -size 0 -type f $dir"
7154         nums=$($cmd | wc -l)
7155         [ $nums -eq $expected ] ||
7156                 error "'$cmd' wrong: found $nums, expected $expected"
7157
7158         echo "test" > $dir/$tfile
7159         echo "test2" > $dir/$tfile.2 && sync
7160         expected=1
7161         cmd="$LFS find -size 5c -type f -lazy $dir"
7162         nums=$($cmd | wc -l)
7163         [ $nums -eq $expected ] ||
7164                 error "'$cmd' wrong: found $nums, expected $expected"
7165         cmd="$LFS find -size 5c -type f $dir"
7166         nums=$($cmd | wc -l)
7167         [ $nums -eq $expected ] ||
7168                 error "'$cmd' wrong: found $nums, expected $expected"
7169
7170         expected=1
7171         cmd="$LFS find -size +5c -type f -lazy $dir"
7172         nums=$($cmd | wc -l)
7173         [ $nums -eq $expected ] ||
7174                 error "'$cmd' wrong: found $nums, expected $expected"
7175         cmd="$LFS find -size +5c -type f $dir"
7176         nums=$($cmd | wc -l)
7177         [ $nums -eq $expected ] ||
7178                 error "'$cmd' wrong: found $nums, expected $expected"
7179
7180         expected=2
7181         cmd="$LFS find -size +0 -type f -lazy $dir"
7182         nums=$($cmd | wc -l)
7183         [ $nums -eq $expected ] ||
7184                 error "'$cmd' wrong: found $nums, expected $expected"
7185         cmd="$LFS find -size +0 -type f $dir"
7186         nums=$($cmd | wc -l)
7187         [ $nums -eq $expected ] ||
7188                 error "'$cmd' wrong: found $nums, expected $expected"
7189
7190         expected=2
7191         cmd="$LFS find ! -size -5c -type f -lazy $dir"
7192         nums=$($cmd | wc -l)
7193         [ $nums -eq $expected ] ||
7194                 error "'$cmd' wrong: found $nums, expected $expected"
7195         cmd="$LFS find ! -size -5c -type f $dir"
7196         nums=$($cmd | wc -l)
7197         [ $nums -eq $expected ] ||
7198                 error "'$cmd' wrong: found $nums, expected $expected"
7199
7200         expected=12
7201         cmd="$LFS find -size -5c -type f -lazy $dir"
7202         nums=$($cmd | wc -l)
7203         [ $nums -eq $expected ] ||
7204                 error "'$cmd' wrong: found $nums, expected $expected"
7205         cmd="$LFS find -size -5c -type f $dir"
7206         nums=$($cmd | wc -l)
7207         [ $nums -eq $expected ] ||
7208                 error "'$cmd' wrong: found $nums, expected $expected"
7209 }
7210 run_test 56r "check lfs find -size works"
7211
7212 test_56ra_sub() {
7213         local expected=$1
7214         local glimpses=$2
7215         local cmd="$3"
7216
7217         cancel_lru_locks $OSC
7218
7219         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7220         local nums=$($cmd | wc -l)
7221
7222         [ $nums -eq $expected ] ||
7223                 error "'$cmd' wrong: found $nums, expected $expected"
7224
7225         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7226
7227         if (( rpcs_before + glimpses != rpcs_after )); then
7228                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
7229                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
7230
7231                 if [[ $glimpses == 0 ]]; then
7232                         error "'$cmd' should not send glimpse RPCs to OST"
7233                 else
7234                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
7235                 fi
7236         fi
7237 }
7238
7239 test_56ra() {
7240         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
7241                 skip "MDS < 2.12.58 doesn't return LSOM data"
7242         local dir=$DIR/$tdir
7243         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
7244
7245         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
7246
7247         # statahead_agl may cause extra glimpse which confuses results. LU-13017
7248         $LCTL set_param -n llite.*.statahead_agl=0
7249         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
7250
7251         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7252         # open and close all files to ensure LSOM is updated
7253         cancel_lru_locks $OSC
7254         find $dir -type f | xargs cat > /dev/null
7255
7256         #   expect_found  glimpse_rpcs  command_to_run
7257         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
7258         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
7259         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
7260         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
7261
7262         echo "test" > $dir/$tfile
7263         echo "test2" > $dir/$tfile.2 && sync
7264         cancel_lru_locks $OSC
7265         cat $dir/$tfile $dir/$tfile.2 > /dev/null
7266
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         test_56ra_sub  1  0 "$LFS find -size +5c -type f -lazy $dir"
7270         test_56ra_sub  1 14 "$LFS find -size +5c -type f $dir"
7271
7272         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
7273         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
7274         test_56ra_sub  2  0 "$LFS find ! -size -5c -type f -lazy $dir"
7275         test_56ra_sub  2 14 "$LFS find ! -size -5c -type f $dir"
7276         test_56ra_sub 12  0 "$LFS find -size -5c -type f -lazy $dir"
7277         test_56ra_sub 12 14 "$LFS find -size -5c -type f $dir"
7278 }
7279 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
7280
7281 test_56rb() {
7282         local dir=$DIR/$tdir
7283         local tmp=$TMP/$tfile.log
7284         local mdt_idx;
7285
7286         test_mkdir -p $dir || error "failed to mkdir $dir"
7287         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
7288                 error "failed to setstripe $dir/$tfile"
7289         mdt_idx=$($LFS getdirstripe -i $dir)
7290         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
7291
7292         stack_trap "rm -f $tmp" EXIT
7293         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7294         ! grep -q obd_uuid $tmp ||
7295                 error "failed to find --size +100K --ost 0 $dir"
7296         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7297         ! grep -q obd_uuid $tmp ||
7298                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7299 }
7300 run_test 56rb "check lfs find --size --ost/--mdt works"
7301
7302 test_56rc() {
7303         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7304         local dir=$DIR/$tdir
7305         local found
7306
7307         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7308         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7309         (( $MDSCOUNT > 2 )) &&
7310                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7311         mkdir $dir/$tdir-{1..10}
7312         touch $dir/$tfile-{1..10}
7313
7314         found=$($LFS find $dir --mdt-count 2 | wc -l)
7315         expect=11
7316         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7317
7318         found=$($LFS find $dir -T +1 | wc -l)
7319         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7320         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7321
7322         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7323         expect=11
7324         (( $found == $expect )) || error "found $found all_char, expect $expect"
7325
7326         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7327         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7328         (( $found == $expect )) || error "found $found all_char, expect $expect"
7329 }
7330 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7331
7332 test_56rd() {
7333         local dir=$DIR/$tdir
7334
7335         test_mkdir $dir
7336         rm -f $dir/*
7337
7338         mkfifo $dir/fifo || error "failed to create fifo file"
7339         $LFS find $dir -t p --printf "%p %y %LP\n" ||
7340                 error "should not fail even cannot get projid from pipe file"
7341         found=$($LFS find $dir -t p --printf "%y")
7342         [[ "p" == $found ]] || error "found $found, expect p"
7343
7344         mknod $dir/chardev c 1 5 ||
7345                 error "failed to create character device file"
7346         $LFS find $dir -t c --printf "%p %y %LP\n" ||
7347                 error "should not fail even cannot get projid from chardev file"
7348         found=$($LFS find $dir -t c --printf "%y")
7349         [[ "c" == $found ]] || error "found $found, expect c"
7350
7351         found=$($LFS find $dir ! -type d --printf "%p %y %LP\n" | wc -l)
7352         (( found == 2 )) || error "unable to list all files"
7353 }
7354 run_test 56rd "check lfs find --printf special files"
7355
7356 test_56s() { # LU-611 #LU-9369
7357         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7358
7359         local dir=$DIR/$tdir
7360         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7361
7362         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7363         for i in $(seq $NUMDIRS); do
7364                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7365         done
7366
7367         local expected=$NUMDIRS
7368         local cmd="$LFS find -c $OSTCOUNT $dir"
7369         local nums=$($cmd | wc -l)
7370
7371         [ $nums -eq $expected ] || {
7372                 $LFS getstripe -R $dir
7373                 error "'$cmd' wrong: found $nums, expected $expected"
7374         }
7375
7376         expected=$((NUMDIRS + onestripe))
7377         cmd="$LFS find -stripe-count +0 -type f $dir"
7378         nums=$($cmd | wc -l)
7379         [ $nums -eq $expected ] || {
7380                 $LFS getstripe -R $dir
7381                 error "'$cmd' wrong: found $nums, expected $expected"
7382         }
7383
7384         expected=$onestripe
7385         cmd="$LFS find -stripe-count 1 -type f $dir"
7386         nums=$($cmd | wc -l)
7387         [ $nums -eq $expected ] || {
7388                 $LFS getstripe -R $dir
7389                 error "'$cmd' wrong: found $nums, expected $expected"
7390         }
7391
7392         cmd="$LFS find -stripe-count -2 -type f $dir"
7393         nums=$($cmd | wc -l)
7394         [ $nums -eq $expected ] || {
7395                 $LFS getstripe -R $dir
7396                 error "'$cmd' wrong: found $nums, expected $expected"
7397         }
7398
7399         expected=0
7400         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7401         nums=$($cmd | wc -l)
7402         [ $nums -eq $expected ] || {
7403                 $LFS getstripe -R $dir
7404                 error "'$cmd' wrong: found $nums, expected $expected"
7405         }
7406 }
7407 run_test 56s "check lfs find -stripe-count works"
7408
7409 test_56t() { # LU-611 #LU-9369
7410         local dir=$DIR/$tdir
7411
7412         setup_56 $dir 0 $NUMDIRS
7413         for i in $(seq $NUMDIRS); do
7414                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7415         done
7416
7417         local expected=$NUMDIRS
7418         local cmd="$LFS find -S 8M $dir"
7419         local nums=$($cmd | wc -l)
7420
7421         [ $nums -eq $expected ] || {
7422                 $LFS getstripe -R $dir
7423                 error "'$cmd' wrong: found $nums, expected $expected"
7424         }
7425         rm -rf $dir
7426
7427         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7428
7429         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7430
7431         expected=$(((NUMDIRS + 1) * NUMFILES))
7432         cmd="$LFS find -stripe-size 512k -type f $dir"
7433         nums=$($cmd | wc -l)
7434         [ $nums -eq $expected ] ||
7435                 error "'$cmd' wrong: found $nums, expected $expected"
7436
7437         cmd="$LFS find -stripe-size +320k -type f $dir"
7438         nums=$($cmd | wc -l)
7439         [ $nums -eq $expected ] ||
7440                 error "'$cmd' wrong: found $nums, expected $expected"
7441
7442         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7443         cmd="$LFS find -stripe-size +200k -type f $dir"
7444         nums=$($cmd | wc -l)
7445         [ $nums -eq $expected ] ||
7446                 error "'$cmd' wrong: found $nums, expected $expected"
7447
7448         cmd="$LFS find -stripe-size -640k -type f $dir"
7449         nums=$($cmd | wc -l)
7450         [ $nums -eq $expected ] ||
7451                 error "'$cmd' wrong: found $nums, expected $expected"
7452
7453         expected=4
7454         cmd="$LFS find -stripe-size 256k -type f $dir"
7455         nums=$($cmd | wc -l)
7456         [ $nums -eq $expected ] ||
7457                 error "'$cmd' wrong: found $nums, expected $expected"
7458
7459         cmd="$LFS find -stripe-size -320k -type f $dir"
7460         nums=$($cmd | wc -l)
7461         [ $nums -eq $expected ] ||
7462                 error "'$cmd' wrong: found $nums, expected $expected"
7463
7464         expected=0
7465         cmd="$LFS find -stripe-size 1024k -type f $dir"
7466         nums=$($cmd | wc -l)
7467         [ $nums -eq $expected ] ||
7468                 error "'$cmd' wrong: found $nums, expected $expected"
7469 }
7470 run_test 56t "check lfs find -stripe-size works"
7471
7472 test_56u() { # LU-611
7473         local dir=$DIR/$tdir
7474
7475         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7476
7477         if [[ $OSTCOUNT -gt 1 ]]; then
7478                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7479                 onestripe=4
7480         else
7481                 onestripe=0
7482         fi
7483
7484         local expected=$(((NUMDIRS + 1) * NUMFILES))
7485         local cmd="$LFS find -stripe-index 0 -type f $dir"
7486         local nums=$($cmd | wc -l)
7487
7488         [ $nums -eq $expected ] ||
7489                 error "'$cmd' wrong: found $nums, expected $expected"
7490
7491         expected=$onestripe
7492         cmd="$LFS find -stripe-index 1 -type f $dir"
7493         nums=$($cmd | wc -l)
7494         [ $nums -eq $expected ] ||
7495                 error "'$cmd' wrong: found $nums, expected $expected"
7496
7497         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7498         nums=$($cmd | wc -l)
7499         [ $nums -eq $expected ] ||
7500                 error "'$cmd' wrong: found $nums, expected $expected"
7501
7502         expected=0
7503         # This should produce an error and not return any files
7504         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7505         nums=$($cmd 2>/dev/null | wc -l)
7506         [ $nums -eq $expected ] ||
7507                 error "'$cmd' wrong: found $nums, expected $expected"
7508
7509         if [[ $OSTCOUNT -gt 1 ]]; then
7510                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7511                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7512                 nums=$($cmd | wc -l)
7513                 [ $nums -eq $expected ] ||
7514                         error "'$cmd' wrong: found $nums, expected $expected"
7515         fi
7516 }
7517 run_test 56u "check lfs find -stripe-index works"
7518
7519 test_56v() {
7520         local mdt_idx=0
7521         local dir=$DIR/$tdir
7522
7523         setup_56 $dir $NUMFILES $NUMDIRS
7524
7525         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7526         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7527
7528         for file in $($LFS find -m $UUID $dir); do
7529                 file_midx=$($LFS getstripe -m $file)
7530                 [ $file_midx -eq $mdt_idx ] ||
7531                         error "lfs find -m $UUID != getstripe -m $file_midx"
7532         done
7533 }
7534 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7535
7536 test_56wa() {
7537         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7539
7540         local dir=$DIR/$tdir
7541
7542         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7543         stack_trap "rm -rf $dir"
7544
7545         local stripe_size=$($LFS getstripe -S -d $dir) ||
7546                 error "$LFS getstripe -S -d $dir failed"
7547         stripe_size=${stripe_size%% *}
7548
7549         local file_size=$((stripe_size * OSTCOUNT))
7550         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7551         local required_space=$((file_num * file_size))
7552         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7553                            head -n1)
7554         (( free_space >= required_space / 1024 )) ||
7555                 skip_env "need $required_space, have $free_space kbytes"
7556
7557         local dd_bs=65536
7558         local dd_count=$((file_size / dd_bs))
7559
7560         # write data into the files
7561         local i
7562         local j
7563         local file
7564
7565         for ((i = 1; i <= NUMFILES; i++ )); do
7566                 file=$dir/file$i
7567                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7568                         error "write data into $file failed"
7569         done
7570         for ((i = 1; i <= NUMDIRS; i++ )); do
7571                 for ((j = 1; j <= NUMFILES; j++ )); do
7572                         file=$dir/dir$i/file$j
7573                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7574                                 error "write data into $file failed"
7575                 done
7576         done
7577
7578         # $LFS_MIGRATE will fail if hard link migration is unsupported
7579         if (( MDS1_VERSION > $(version_code 2.5.55) )); then
7580                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7581                         error "creating links to $dir/dir1/file1 failed"
7582         fi
7583
7584         local expected=-1
7585
7586         (( OSTCOUNT <= 1 )) || expected=$((OSTCOUNT - 1))
7587
7588         # lfs_migrate file
7589         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7590
7591         echo "$cmd"
7592         eval $cmd || error "$cmd failed"
7593
7594         check_stripe_count $dir/file1 $expected
7595
7596         if (( $MDS1_VERSION >= $(version_code 2.6.90) )); then
7597                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7598                 # OST 1 if it is on OST 0. This file is small enough to
7599                 # be on only one stripe.
7600                 file=$dir/migr_1_ost
7601                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7602                         error "write data into $file failed"
7603                 local obdidx=$($LFS getstripe -i $file)
7604                 local oldmd5=$(md5sum $file)
7605                 local newobdidx=0
7606
7607                 (( obdidx != 0 )) || newobdidx=1
7608                 cmd="$LFS migrate -i $newobdidx $file"
7609                 echo $cmd
7610                 eval $cmd || error "$cmd failed"
7611
7612                 local realobdix=$($LFS getstripe -i $file)
7613                 local newmd5=$(md5sum $file)
7614
7615                 (( $newobdidx == $realobdix )) ||
7616                         error "new OST is different (was=$obdidx, wanted=$newobdidx, got=$realobdix)"
7617                 [[ "$oldmd5" == "$newmd5" ]] ||
7618                         error "md5sum differ: $oldmd5, $newmd5"
7619         fi
7620
7621         # lfs_migrate dir
7622         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7623         echo "$cmd"
7624         eval $cmd || error "$cmd failed"
7625
7626         for (( j = 1; j <= NUMFILES; j++ )); do
7627                 check_stripe_count $dir/dir1/file$j $expected
7628         done
7629
7630         # lfs_migrate works with lfs find
7631         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7632              $LFS_MIGRATE -y -c $expected"
7633         echo "$cmd"
7634         eval $cmd || error "$cmd failed"
7635
7636         for (( i = 2; i <= NUMFILES; i++ )); do
7637                 check_stripe_count $dir/file$i $expected
7638         done
7639         for (( i = 2; i <= NUMDIRS; i++ )); do
7640                 for (( j = 1; j <= NUMFILES; j++ )); do
7641                         check_stripe_count $dir/dir$i/file$j $expected
7642                 done
7643         done
7644 }
7645 run_test 56wa "check lfs_migrate -c stripe_count works"
7646
7647 test_56wb() {
7648         local file1=$DIR/$tdir/file1
7649         local create_pool=false
7650         local initial_pool=$($LFS getstripe -p $DIR)
7651         local pool_list=()
7652         local pool=""
7653
7654         echo -n "Creating test dir..."
7655         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7656         echo "done."
7657
7658         echo -n "Creating test file..."
7659         touch $file1 || error "cannot create file"
7660         echo "done."
7661
7662         echo -n "Detecting existing pools..."
7663         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7664
7665         if [ ${#pool_list[@]} -gt 0 ]; then
7666                 echo "${pool_list[@]}"
7667                 for thispool in "${pool_list[@]}"; do
7668                         if [[ -z "$initial_pool" ||
7669                               "$initial_pool" != "$thispool" ]]; then
7670                                 pool="$thispool"
7671                                 echo "Using existing pool '$pool'"
7672                                 break
7673                         fi
7674                 done
7675         else
7676                 echo "none detected."
7677         fi
7678         if [ -z "$pool" ]; then
7679                 pool=${POOL:-testpool}
7680                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7681                 echo -n "Creating pool '$pool'..."
7682                 create_pool=true
7683                 pool_add $pool &> /dev/null ||
7684                         error "pool_add failed"
7685                 echo "done."
7686
7687                 echo -n "Adding target to pool..."
7688                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7689                         error "pool_add_targets failed"
7690                 echo "done."
7691         fi
7692
7693         echo -n "Setting pool using -p option..."
7694         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7695                 error "migrate failed rc = $?"
7696         echo "done."
7697
7698         echo -n "Verifying test file is in pool after migrating..."
7699         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7700                 error "file was not migrated to pool $pool"
7701         echo "done."
7702
7703         echo -n "Removing test file from pool '$pool'..."
7704         # "lfs migrate $file" won't remove the file from the pool
7705         # until some striping information is changed.
7706         $LFS migrate -c 1 $file1 &> /dev/null ||
7707                 error "cannot remove from pool"
7708         [ "$($LFS getstripe -p $file1)" ] &&
7709                 error "pool still set"
7710         echo "done."
7711
7712         echo -n "Setting pool using --pool option..."
7713         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7714                 error "migrate failed rc = $?"
7715         echo "done."
7716
7717         # Clean up
7718         rm -f $file1
7719         if $create_pool; then
7720                 destroy_test_pools 2> /dev/null ||
7721                         error "destroy test pools failed"
7722         fi
7723 }
7724 run_test 56wb "check lfs_migrate pool support"
7725
7726 test_56wc() {
7727         local file1="$DIR/$tdir/$tfile"
7728         local md5
7729         local parent_ssize
7730         local parent_scount
7731         local cur_ssize
7732         local cur_scount
7733         local orig_ssize
7734         local new_scount
7735         local cur_comp
7736
7737         echo -n "Creating test dir..."
7738         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7739         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7740                 error "cannot set stripe by '-S 1M -c 1'"
7741         echo "done"
7742
7743         echo -n "Setting initial stripe for test file..."
7744         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7745                 error "cannot set stripe"
7746         cur_ssize=$($LFS getstripe -S "$file1")
7747         (( cur_ssize == 524288 )) || error "setstripe -S $cur_ssize != 524288"
7748         echo "done."
7749
7750         dd if=/dev/urandom of=$file1 bs=1M count=12 || error "dd $file1 failed"
7751         stack_trap "rm -f $file1"
7752         md5="$(md5sum $file1)"
7753
7754         # File currently set to -S 512K -c 1
7755
7756         # Ensure -c and -S options are rejected when -R is set
7757         echo -n "Verifying incompatible options are detected..."
7758         $LFS_MIGRATE -R -c 1 "$file1" &&
7759                 error "incompatible -R and -c options not detected"
7760         $LFS_MIGRATE -R -S 1M "$file1" &&
7761                 error "incompatible -R and -S options not detected"
7762         $LFS_MIGRATE -R -p pool "$file1" &&
7763                 error "incompatible -R and -p options not detected"
7764         $LFS_MIGRATE -R -E eof -c 1 "$file1" &&
7765                 error "incompatible -R and -E options not detected"
7766         $LFS_MIGRATE -R -A "$file1" &&
7767                 error "incompatible -R and -A options not detected"
7768         $LFS_MIGRATE -A -c 1 "$file1" &&
7769                 error "incompatible -A and -c options not detected"
7770         $LFS_MIGRATE -A -S 1M "$file1" &&
7771                 error "incompatible -A and -S options not detected"
7772         $LFS_MIGRATE -A -p pool "$file1" &&
7773                 error "incompatible -A and -p options not detected"
7774         $LFS_MIGRATE -A -E eof -c 1 "$file1" &&
7775                 error "incompatible -A and -E options not detected"
7776         echo "done."
7777
7778         # Ensure unrecognized options are passed through to 'lfs migrate'
7779         echo -n "Verifying -S option is passed through to lfs migrate..."
7780         $LFS_MIGRATE -y -S 1M "$file1" || error "migration failed"
7781         cur_ssize=$($LFS getstripe -S "$file1")
7782         (( cur_ssize == 1048576 )) || error "migrate -S $cur_ssize != 1048576"
7783         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (1)"
7784         echo "done."
7785
7786         # File currently set to -S 1M -c 1
7787
7788         # Ensure long options are supported
7789         echo -n "Verifying long options supported..."
7790         $LFS_MIGRATE --non-block "$file1" ||
7791                 error "long option without argument not supported"
7792         $LFS_MIGRATE --stripe-size 512K "$file1" ||
7793                 error "long option with argument not supported"
7794         cur_ssize=$($LFS getstripe -S "$file1")
7795         (( cur_ssize == 524288 )) ||
7796                 error "migrate --stripe-size $cur_ssize != 524288"
7797         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (2)"
7798         echo "done."
7799
7800         # File currently set to -S 512K -c 1
7801
7802         if (( OSTCOUNT > 1 )); then
7803                 echo -n "Verifying explicit stripe count can be set..."
7804                 $LFS_MIGRATE -c 2 "$file1" || error "migrate failed"
7805                 cur_scount=$($LFS getstripe -c "$file1")
7806                 (( cur_scount == 2 )) || error "migrate -c $cur_scount != 2"
7807                 [[ "$(md5sum $file1)" == "$md5" ]] ||
7808                         error "file data has changed (3)"
7809                 echo "done."
7810         fi
7811
7812         # File currently set to -S 512K -c 1 or -S 512K -c 2
7813
7814         # Ensure parent striping is used if -R is set, and no stripe
7815         # count or size is specified
7816         echo -n "Setting stripe for parent directory..."
7817         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7818                 error "cannot set stripe '-S 2M -c 1'"
7819         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (4)"
7820         echo "done."
7821
7822         echo -n "Verifying restripe option uses parent stripe settings..."
7823         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7824         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7825         $LFS_MIGRATE -R "$file1" || error "migrate failed"
7826         cur_ssize=$($LFS getstripe -S "$file1")
7827         (( cur_ssize == parent_ssize )) ||
7828                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7829         cur_scount=$($LFS getstripe -c "$file1")
7830         (( cur_scount == parent_scount )) ||
7831                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7832         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (5)"
7833         echo "done."
7834
7835         # File currently set to -S 1M -c 1
7836
7837         # Ensure striping is preserved if -R is not set, and no stripe
7838         # count or size is specified
7839         echo -n "Verifying striping size preserved when not specified..."
7840         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7841         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7842                 error "cannot set stripe on parent directory"
7843         $LFS_MIGRATE "$file1" || error "migrate failed"
7844         cur_ssize=$($LFS getstripe -S "$file1")
7845         (( cur_ssize == orig_ssize )) ||
7846                 error "migrate by default $cur_ssize != $orig_ssize"
7847         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (6)"
7848         echo "done."
7849
7850         # Ensure file name properly detected when final option has no argument
7851         echo -n "Verifying file name properly detected..."
7852         $LFS_MIGRATE "$file1" ||
7853                 error "file name interpreted as option argument"
7854         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (7)"
7855         echo "done."
7856
7857         # Ensure PFL arguments are passed through properly
7858         echo -n "Verifying PFL options passed through..."
7859         new_scount=$(((OSTCOUNT + 1) / 2))
7860         $LFS_MIGRATE -E 1M -c 1 -E 16M -c $new_scount -E eof -c -1 "$file1" ||
7861                 error "migrate PFL arguments failed"
7862         cur_comp=$($LFS getstripe --comp-count $file1)
7863         (( cur_comp == 3 )) || error "component count '$cur_comp' != 3"
7864         cur_scount=$($LFS getstripe --stripe-count $file1)
7865         (( cur_scount == new_scount)) ||
7866                 error "PFL stripe count $cur_scount != $new_scount"
7867         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (8)"
7868         echo "done."
7869 }
7870 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7871
7872 test_56wd() {
7873         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7874
7875         local file1=$DIR/$tdir/$tfile
7876
7877         echo -n "Creating test dir..."
7878         test_mkdir $DIR/$tdir || error "cannot create dir"
7879         echo "done."
7880
7881         echo -n "Creating test file..."
7882         echo "$tfile" > $file1
7883         echo "done."
7884
7885         # Ensure 'lfs migrate' will fail by using a non-existent option,
7886         # and make sure rsync is not called to recover
7887         echo -n "Make sure --no-rsync option works..."
7888         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7889                 grep -q 'refusing to fall back to rsync' ||
7890                 error "rsync was called with --no-rsync set"
7891         echo "done."
7892
7893         # Ensure rsync is called without trying 'lfs migrate' first
7894         echo -n "Make sure --rsync option works..."
7895         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7896                 grep -q 'falling back to rsync' &&
7897                 error "lfs migrate was called with --rsync set"
7898         echo "done."
7899 }
7900 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7901
7902 test_56we() {
7903         local td=$DIR/$tdir
7904         local tf=$td/$tfile
7905
7906         test_mkdir $td || error "cannot create $td"
7907         touch $tf || error "cannot touch $tf"
7908
7909         echo -n "Make sure --non-direct|-D works..."
7910         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7911                 grep -q "lfs migrate --non-direct" ||
7912                 error "--non-direct option cannot work correctly"
7913         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7914                 grep -q "lfs migrate -D" ||
7915                 error "-D option cannot work correctly"
7916         echo "done."
7917 }
7918 run_test 56we "check lfs_migrate --non-direct|-D support"
7919
7920 test_56x() {
7921         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7922         check_swap_layouts_support
7923
7924         local dir=$DIR/$tdir
7925         local ref1=/etc/passwd
7926         local file1=$dir/file1
7927
7928         test_mkdir $dir || error "creating dir $dir"
7929         $LFS setstripe -c 2 $file1
7930         cp $ref1 $file1
7931         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7932         stripe=$($LFS getstripe -c $file1)
7933         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7934         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7935
7936         # clean up
7937         rm -f $file1
7938 }
7939 run_test 56x "lfs migration support"
7940
7941 test_56xa() {
7942         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7943         check_swap_layouts_support
7944
7945         local dir=$DIR/$tdir/$testnum
7946
7947         test_mkdir -p $dir
7948
7949         local ref1=/etc/passwd
7950         local file1=$dir/file1
7951
7952         $LFS setstripe -c 2 $file1
7953         cp $ref1 $file1
7954         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7955
7956         local stripe=$($LFS getstripe -c $file1)
7957
7958         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7959         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7960
7961         # clean up
7962         rm -f $file1
7963 }
7964 run_test 56xa "lfs migration --block support"
7965
7966 check_migrate_links() {
7967         [[ "$1" == "--rsync" ]] && local opts="--rsync -y" && shift
7968         local dir="$1"
7969         local file1="$dir/file1"
7970         local begin="$2"
7971         local count="$3"
7972         local runas="$4"
7973         local total_count=$(($begin + $count - 1))
7974         local symlink_count=10
7975         local uniq_count=10
7976
7977         if [ ! -f "$file1" ]; then
7978                 echo -n "creating initial file..."
7979                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7980                         error "cannot setstripe initial file"
7981                 echo "done"
7982
7983                 echo -n "creating symlinks..."
7984                 for s in $(seq 1 $symlink_count); do
7985                         ln -s "$file1" "$dir/slink$s" ||
7986                                 error "cannot create symlinks"
7987                 done
7988                 echo "done"
7989
7990                 echo -n "creating nonlinked files..."
7991                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7992                         error "cannot create nonlinked files"
7993                 echo "done"
7994         fi
7995
7996         # create hard links
7997         if [ ! -f "$dir/file$total_count" ]; then
7998                 echo -n "creating hard links $begin:$total_count..."
7999                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
8000                         /dev/null || error "cannot create hard links"
8001                 echo "done"
8002         fi
8003
8004         echo -n "checking number of hard links listed in xattrs..."
8005         local fid=$($LFS getstripe -F "$file1")
8006         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
8007
8008         echo "${#paths[*]}"
8009         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
8010                         skip "hard link list has unexpected size, skipping test"
8011         fi
8012         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
8013                         error "link names should exceed xattrs size"
8014         fi
8015
8016         echo -n "migrating files..."
8017         local migrate_out=$($runas $LFS_MIGRATE $opts -S '1m' $dir)
8018         local rc=$?
8019         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
8020         echo "done"
8021
8022         # make sure all links have been properly migrated
8023         echo -n "verifying files..."
8024         fid=$($LFS getstripe -F "$file1") ||
8025                 error "cannot get fid for file $file1"
8026         for i in $(seq 2 $total_count); do
8027                 local fid2=$($LFS getstripe -F $dir/file$i)
8028
8029                 [ "$fid2" == "$fid" ] ||
8030                         error "migrated hard link has mismatched FID"
8031         done
8032
8033         # make sure hard links were properly detected, and migration was
8034         # performed only once for the entire link set; nonlinked files should
8035         # also be migrated
8036         local actual=$(grep -c 'done' <<< "$migrate_out")
8037         local expected=$(($uniq_count + 1))
8038
8039         [ "$actual" -eq  "$expected" ] ||
8040                 error "hard links individually migrated ($actual != $expected)"
8041
8042         # make sure the correct number of hard links are present
8043         local hardlinks=$(stat -c '%h' "$file1")
8044
8045         [ $hardlinks -eq $total_count ] ||
8046                 error "num hard links $hardlinks != $total_count"
8047         echo "done"
8048
8049         return 0
8050 }
8051
8052 test_56xb() {
8053         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
8054                 skip "Need MDS version at least 2.10.55"
8055
8056         local dir="$DIR/$tdir"
8057
8058         test_mkdir "$dir" || error "cannot create dir $dir"
8059
8060         echo "testing lfs migrate mode when all links fit within xattrs"
8061         check_migrate_links "$dir" 2 99
8062
8063         echo "testing rsync mode when all links fit within xattrs"
8064         check_migrate_links --rsync "$dir" 2 99
8065
8066         echo "testing lfs migrate mode when all links do not fit within xattrs"
8067         check_migrate_links "$dir" 101 100
8068
8069         echo "testing rsync mode when all links do not fit within xattrs"
8070         check_migrate_links --rsync "$dir" 101 100
8071
8072         chown -R $RUNAS_ID $dir
8073         echo "testing non-root lfs migrate mode when not all links are in xattr"
8074         check_migrate_links "$dir" 101 100 "$RUNAS"
8075
8076         # clean up
8077         rm -rf $dir
8078 }
8079 run_test 56xb "lfs migration hard link support"
8080
8081 test_56xc() {
8082         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8083
8084         local dir="$DIR/$tdir"
8085
8086         test_mkdir "$dir" || error "cannot create dir $dir"
8087
8088         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
8089         echo -n "Setting initial stripe for 20MB test file..."
8090         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
8091                 error "cannot setstripe 20MB file"
8092         echo "done"
8093         echo -n "Sizing 20MB test file..."
8094         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
8095         echo "done"
8096         echo -n "Verifying small file autostripe count is 1..."
8097         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
8098                 error "cannot migrate 20MB file"
8099         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
8100                 error "cannot get stripe for $dir/20mb"
8101         [ $stripe_count -eq 1 ] ||
8102                 error "unexpected stripe count $stripe_count for 20MB file"
8103         rm -f "$dir/20mb"
8104         echo "done"
8105
8106         # Test 2: File is small enough to fit within the available space on
8107         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
8108         # have at least an additional 1KB for each desired stripe for test 3
8109         echo -n "Setting stripe for 1GB test file..."
8110         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
8111         echo "done"
8112         echo -n "Sizing 1GB test file..."
8113         # File size is 1GB + 3KB
8114         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
8115         echo "done"
8116
8117         # need at least 512MB per OST for 1GB file to fit in 2 stripes
8118         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
8119         if (( avail > 524288 * OSTCOUNT )); then
8120                 echo -n "Migrating 1GB file..."
8121                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
8122                         error "cannot migrate 1GB file"
8123                 echo "done"
8124                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
8125                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
8126                         error "cannot getstripe for 1GB file"
8127                 [ $stripe_count -eq 2 ] ||
8128                         error "unexpected stripe count $stripe_count != 2"
8129                 echo "done"
8130         fi
8131
8132         # Test 3: File is too large to fit within the available space on
8133         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
8134         if [ $OSTCOUNT -ge 3 ]; then
8135                 # The required available space is calculated as
8136                 # file size (1GB + 3KB) / OST count (3).
8137                 local kb_per_ost=349526
8138
8139                 echo -n "Migrating 1GB file with limit..."
8140                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
8141                         error "cannot migrate 1GB file with limit"
8142                 echo "done"
8143
8144                 stripe_count=$($LFS getstripe -c "$dir/1gb")
8145                 echo -n "Verifying 1GB autostripe count with limited space..."
8146                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
8147                         error "unexpected stripe count $stripe_count (min 3)"
8148                 echo "done"
8149         fi
8150
8151         # clean up
8152         rm -rf $dir
8153 }
8154 run_test 56xc "lfs migration autostripe"
8155
8156 test_56xd() {
8157         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8158
8159         local dir=$DIR/$tdir
8160         local f_mgrt=$dir/$tfile.mgrt
8161         local f_yaml=$dir/$tfile.yaml
8162         local f_copy=$dir/$tfile.copy
8163         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8164         local layout_copy="-c 2 -S 2M -i 1"
8165         local yamlfile=$dir/yamlfile
8166         local layout_before;
8167         local layout_after;
8168
8169         test_mkdir "$dir" || error "cannot create dir $dir"
8170         stack_trap "rm -rf $dir"
8171         $LFS setstripe $layout_yaml $f_yaml ||
8172                 error "cannot setstripe $f_yaml with layout $layout_yaml"
8173         $LFS getstripe --yaml $f_yaml > $yamlfile
8174         $LFS setstripe $layout_copy $f_copy ||
8175                 error "cannot setstripe $f_copy with layout $layout_copy"
8176         touch $f_mgrt
8177         dd if=/dev/zero of=$f_mgrt bs=1M count=4
8178
8179         # 1. test option --yaml
8180         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
8181                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
8182         layout_before=$(get_layout_param $f_yaml)
8183         layout_after=$(get_layout_param $f_mgrt)
8184         [ "$layout_after" == "$layout_before" ] ||
8185                 error "lfs_migrate --yaml: $layout_after != $layout_before"
8186
8187         # 2. test option --copy
8188         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
8189                 error "cannot migrate $f_mgrt with --copy $f_copy"
8190         layout_before=$(SKIP_INDEX=yes get_layout_param $f_copy)
8191         layout_after=$(SKIP_INDEX=yes get_layout_param $f_mgrt)
8192         [ "$layout_after" == "$layout_before" ] ||
8193                 error "lfs_migrate --copy: $layout_after != $layout_before"
8194 }
8195 run_test 56xd "check lfs_migrate --yaml and --copy support"
8196
8197 test_56xe() {
8198         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8199
8200         local dir=$DIR/$tdir
8201         local f_comp=$dir/$tfile
8202         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8203         local layout_before=""
8204         local layout_after=""
8205
8206         test_mkdir "$dir" || error "cannot create dir $dir"
8207         stack_trap "rm -rf $dir"
8208         $LFS setstripe $layout $f_comp ||
8209                 error "cannot setstripe $f_comp with layout $layout"
8210         layout_before=$(SKIP_INDEX=yes get_layout_param $f_comp)
8211         dd if=/dev/zero of=$f_comp bs=1M count=4
8212
8213         # 1. migrate a comp layout file by lfs_migrate
8214         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
8215         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
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         [ "$layout_before" == "$layout_after" ] ||
8223                 error "lfs migrate: $layout_before != $layout_after"
8224 }
8225 run_test 56xe "migrate a composite layout file"
8226
8227 test_56xf() {
8228         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8229
8230         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
8231                 skip "Need server version at least 2.13.53"
8232
8233         local dir=$DIR/$tdir
8234         local f_comp=$dir/$tfile
8235         local layout="-E 1M -c1 -E -1 -c2"
8236         local fid_before=""
8237         local fid_after=""
8238
8239         test_mkdir "$dir" || error "cannot create dir $dir"
8240         stack_trap "rm -rf $dir"
8241         $LFS setstripe $layout $f_comp ||
8242                 error "cannot setstripe $f_comp with layout $layout"
8243         fid_before=$($LFS getstripe --fid $f_comp)
8244         dd if=/dev/zero of=$f_comp bs=1M count=4
8245
8246         # 1. migrate a comp layout file to a comp layout
8247         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8248         fid_after=$($LFS getstripe --fid $f_comp)
8249         [ "$fid_before" == "$fid_after" ] ||
8250                 error "comp-to-comp migrate: $fid_before != $fid_after"
8251
8252         # 2. migrate a comp layout file to a plain layout
8253         $LFS migrate -c2 $f_comp ||
8254                 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-plain migrate: $fid_before != $fid_after"
8258
8259         # 3. migrate a plain layout file to a comp layout
8260         $LFS migrate $layout $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 "plain-to-comp migrate: $fid_before != $fid_after"
8265 }
8266 run_test 56xf "FID is not lost during migration of a composite layout file"
8267
8268 check_file_ost_range() {
8269         local file="$1"
8270         shift
8271         local range="$*"
8272         local -a file_range
8273         local idx
8274
8275         file_range=($($LFS getstripe -y "$file" |
8276                 awk '/l_ost_idx:/ { print $NF }'))
8277
8278         if [[ "${#file_range[@]}" = 0 ]]; then
8279                 echo "No osts found for $file"
8280                 return 1
8281         fi
8282
8283         for idx in "${file_range[@]}"; do
8284                 [[ " $range " =~ " $idx " ]] ||
8285                         return 1
8286         done
8287
8288         return 0
8289 }
8290
8291 sub_test_56xg() {
8292         local stripe_opt="$1"
8293         local pool="$2"
8294         shift 2
8295         local pool_ostidx="$(seq $* | tr '\n' ' ')"
8296
8297         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
8298                 error "Fail to migrate $tfile on $pool"
8299         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
8300                 error "$tfile is not in pool $pool"
8301         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
8302                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
8303 }
8304
8305 test_56xg() {
8306         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8307         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
8308         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
8309                 skip "Need MDS version newer than 2.14.52"
8310
8311         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
8312         local -a pool_ranges=("0 0" "1 1" "0 1")
8313
8314         # init pools
8315         for i in "${!pool_names[@]}"; do
8316                 pool_add ${pool_names[$i]} ||
8317                         error "pool_add failed (pool: ${pool_names[$i]})"
8318                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
8319                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
8320         done
8321
8322         # init the file to migrate
8323         $LFS setstripe -c1 -i1 $DIR/$tfile ||
8324                 error "Unable to create $tfile on OST1"
8325         stack_trap "rm -f $DIR/$tfile"
8326         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
8327                 error "Unable to write on $tfile"
8328
8329         echo "1. migrate $tfile on pool ${pool_names[0]}"
8330         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
8331
8332         echo "2. migrate $tfile on pool ${pool_names[2]}"
8333         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
8334
8335         echo "3. migrate $tfile on pool ${pool_names[1]}"
8336         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
8337
8338         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
8339         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
8340         echo
8341
8342         # Clean pools
8343         destroy_test_pools ||
8344                 error "pool_destroy failed"
8345 }
8346 run_test 56xg "lfs migrate pool support"
8347
8348 test_56xh() {
8349         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8350
8351         local size_mb=25
8352         local file1=$DIR/$tfile
8353         local tmp1=$TMP/$tfile.tmp
8354
8355         $LFS setstripe -c 2 $file1
8356
8357         stack_trap "rm -f $file1 $tmp1"
8358         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8359                         error "error creating $tmp1"
8360         ls -lsh $tmp1
8361         cp $tmp1 $file1
8362
8363         local start=$SECONDS
8364
8365         $LFS migrate --stats --stats-interval=1 -W 1M -c 1 $file1 ||
8366                 error "migrate failed rc = $?"
8367
8368         local elapsed=$((SECONDS - start))
8369
8370         # with 1MB/s, elapsed should equal size_mb
8371         (( elapsed >= size_mb * 95 / 100 )) ||
8372                 error "'lfs migrate -W' too fast ($elapsed < 0.95 * $size_mb)?"
8373
8374         (( elapsed <= size_mb * 120 / 100 )) ||
8375                 error_not_in_vm "'lfs migrate -W' slow ($elapsed > 1.2 * $size_mb)"
8376
8377         (( elapsed <= size_mb * 350 / 100 )) ||
8378                 error "'lfs migrate -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8379
8380         stripe=$($LFS getstripe -c $file1)
8381         (( $stripe == 1 )) || error "stripe of $file1 is $stripe != 1"
8382         cmp $file1 $tmp1 || error "content mismatch $file1 differs from $tmp1"
8383
8384         # Clean up file (since it is multiple MB)
8385         rm -f $file1 $tmp1
8386 }
8387 run_test 56xh "lfs migrate bandwidth limitation support"
8388
8389 test_56xi() {
8390         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8391         verify_yaml_available || skip_env "YAML verification not installed"
8392
8393         local size_mb=5
8394         local file1=$DIR/$tfile.1
8395         local file2=$DIR/$tfile.2
8396         local file3=$DIR/$tfile.3
8397         local output_file=$DIR/$tfile.out
8398         local tmp1=$TMP/$tfile.tmp
8399
8400         $LFS setstripe -c 2 $file1
8401         $LFS setstripe -c 2 $file2
8402         $LFS setstripe -c 2 $file3
8403
8404         stack_trap "rm -f $file1 $file2 $file3 $tmp1 $output_file"
8405         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8406                         error "error creating $tmp1"
8407         ls -lsh $tmp1
8408         cp $tmp1 $file1
8409         cp $tmp1 $file2
8410         cp $tmp1 $file3
8411
8412         $LFS migrate --stats --stats-interval=1 \
8413                 -c 1 $file1 $file2 $file3 1> $output_file ||
8414                 error "migrate failed rc = $?"
8415
8416         cat $output_file
8417         cat $output_file | verify_yaml || error "rename_stats is not valid YAML"
8418
8419         # Clean up file (since it is multiple MB)
8420         rm -f $file1 $file2 $file3 $tmp1 $output_file
8421 }
8422 run_test 56xi "lfs migrate stats support"
8423
8424 test_56xj() { # LU-16571 "lfs migrate -b" can cause thread starvation on OSS
8425         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8426
8427         local file=$DIR/$tfile
8428         local linkdir=$DIR/$tdir
8429
8430         test_mkdir $linkdir || error "fail to create $linkdir"
8431         $LFS setstripe -i 0 -c 1 -S1M $file
8432         stack_trap "rm -rf $file $linkdir"
8433         dd if=/dev/urandom of=$file bs=1M count=10 ||
8434                 error "fail to create $file"
8435
8436         # Create file links
8437         local cpts
8438         local threads_max
8439         local nlinks
8440
8441         thread_max=$(do_facet ost1 "$LCTL get_param -n ost.OSS.ost.threads_max")
8442         cpts=$(do_facet ost1 "$LCTL get_param -n cpu_partition_table | wc -l")
8443         (( nlinks = thread_max * 3 / 2 / cpts))
8444
8445         echo "create $nlinks hard links of $file"
8446         createmany -l $file $linkdir/link $nlinks
8447
8448         # Parallel migrates (should not block)
8449         local i
8450         for ((i = 0; i < nlinks; i++)); do
8451                 echo $linkdir/link$i
8452         done | xargs -n1 -P $nlinks $LFS migrate -c2
8453
8454         local stripe_count
8455         stripe_count=$($LFS getstripe -c $file) ||
8456                 error "fail to get stripe count on $file"
8457
8458         ((stripe_count == 2)) ||
8459                 error "fail to migrate $file (stripe_count = $stripe_count)"
8460 }
8461 run_test 56xj "lfs migrate -b should not cause starvation of threads on OSS"
8462
8463 test_56xk() {
8464         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8465
8466         local size_mb=5
8467         local file1=$DIR/$tfile
8468
8469         stack_trap "rm -f $file1"
8470         $LFS setstripe -c 1 $file1
8471         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8472                 error "error creating $file1"
8473         $LFS mirror extend -N $file1 || error "can't mirror"
8474         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8475                 error "can't dd"
8476         $LFS getstripe $file1 | grep stale ||
8477                 error "one component must be stale"
8478
8479         local start=$SECONDS
8480         $LFS mirror resync --stats --stats-interval=1 -W 1M $file1 ||
8481                 error "migrate failed rc = $?"
8482         local elapsed=$((SECONDS - start))
8483         $LFS getstripe $file1 | grep stale &&
8484                 error "all components must be sync"
8485
8486         # with 1MB/s, elapsed should equal size_mb
8487         (( elapsed >= size_mb * 95 / 100 )) ||
8488                 error "'lfs mirror resync -W' too fast ($elapsed < 0.95 * $size_mb)?"
8489
8490         (( elapsed <= size_mb * 120 / 100 )) ||
8491                 error_not_in_vm "'lfs mirror resync -W' slow ($elapsed > 1.2 * $size_mb)"
8492
8493         (( elapsed <= size_mb * 350 / 100 )) ||
8494                 error "'lfs mirror resync -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8495 }
8496 run_test 56xk "lfs mirror resync bandwidth limitation support"
8497
8498 test_56xl() {
8499         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8500         verify_yaml_available || skip_env "YAML verification not installed"
8501
8502         local size_mb=5
8503         local file1=$DIR/$tfile.1
8504         local output_file=$DIR/$tfile.out
8505
8506         stack_trap "rm -f $file1"
8507         $LFS setstripe -c 1 $file1
8508         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8509                 error "error creating $file1"
8510         $LFS mirror extend -N $file1 || error "can't mirror"
8511         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8512                 error "can't dd"
8513         $LFS getstripe $file1 | grep stale ||
8514                 error "one component must be stale"
8515         $LFS getstripe $file1
8516
8517         $LFS mirror resync --stats --stats-interval=1 $file1 >$output_file ||
8518                 error "resync failed rc = $?"
8519         $LFS getstripe $file1 | grep stale &&
8520                 error "all components must be sync"
8521
8522         cat $output_file
8523         cat $output_file | verify_yaml || error "stats is not valid YAML"
8524 }
8525 run_test 56xl "lfs mirror resync stats support"
8526
8527 test_56y() {
8528         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8529                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8530
8531         local res=""
8532         local dir=$DIR/$tdir
8533         local f1=$dir/file1
8534         local f2=$dir/file2
8535
8536         test_mkdir -p $dir || error "creating dir $dir"
8537         touch $f1 || error "creating std file $f1"
8538         $MULTIOP $f2 H2c || error "creating released file $f2"
8539
8540         # a directory can be raid0, so ask only for files
8541         res=$($LFS find $dir -L raid0 -type f | wc -l)
8542         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8543
8544         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8545         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8546
8547         # only files can be released, so no need to force file search
8548         res=$($LFS find $dir -L released)
8549         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8550
8551         res=$($LFS find $dir -type f \! -L released)
8552         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8553 }
8554 run_test 56y "lfs find -L raid0|released"
8555
8556 test_56z() { # LU-4824
8557         # This checks to make sure 'lfs find' continues after errors
8558         # There are two classes of errors that should be caught:
8559         # - If multiple paths are provided, all should be searched even if one
8560         #   errors out
8561         # - If errors are encountered during the search, it should not terminate
8562         #   early
8563         local dir=$DIR/$tdir
8564         local i
8565
8566         test_mkdir $dir
8567         for i in d{0..9}; do
8568                 test_mkdir $dir/$i
8569                 touch $dir/$i/$tfile
8570         done
8571         $LFS find $DIR/non_existent_dir $dir &&
8572                 error "$LFS find did not return an error"
8573         # Make a directory unsearchable. This should NOT be the last entry in
8574         # directory order.  Arbitrarily pick the 6th entry
8575         chmod 700 $($LFS find $dir -type d | sed '6!d')
8576
8577         $RUNAS $LFS find $DIR/non_existent $dir
8578         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8579
8580         # The user should be able to see 10 directories and 9 files
8581         (( count == 19 )) ||
8582                 error "$LFS find found $count != 19 entries after error"
8583 }
8584 run_test 56z "lfs find should continue after an error"
8585
8586 test_56aa() { # LU-5937
8587         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8588
8589         local dir=$DIR/$tdir
8590
8591         mkdir $dir
8592         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8593
8594         createmany -o $dir/striped_dir/${tfile}- 1024
8595         local dirs=$($LFS find --size +8k $dir/)
8596
8597         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8598 }
8599 run_test 56aa "lfs find --size under striped dir"
8600
8601 test_56ab() { # LU-10705
8602         test_mkdir $DIR/$tdir
8603         dd if=/dev/urandom of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8604         dd if=/dev/urandom of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8605         dd if=/dev/urandom of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8606         # Flush writes to ensure valid blocks.  Need to be more thorough for
8607         # ZFS, since blocks are not allocated/returned to client immediately.
8608         sync_all_data
8609         wait_zfs_commit ost1 2
8610         cancel_lru_locks osc
8611         ls -ls $DIR/$tdir
8612
8613         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8614
8615         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8616
8617         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8618         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8619
8620         rm -f $DIR/$tdir/$tfile.[123]
8621 }
8622 run_test 56ab "lfs find --blocks"
8623
8624 # LU-11188
8625 test_56aca() {
8626         local dir="$DIR/$tdir"
8627         local perms=(001 002 003 004 005 006 007
8628                      010 020 030 040 050 060 070
8629                      100 200 300 400 500 600 700
8630                      111 222 333 444 555 666 777)
8631         local perm_minus=(8 8 4 8 4 4 2
8632                           8 8 4 8 4 4 2
8633                           8 8 4 8 4 4 2
8634                           4 4 2 4 2 2 1)
8635         local perm_slash=(8  8 12  8 12 12 14
8636                           8  8 12  8 12 12 14
8637                           8  8 12  8 12 12 14
8638                          16 16 24 16 24 24 28)
8639
8640         test_mkdir "$dir"
8641         for perm in ${perms[*]}; do
8642                 touch "$dir/$tfile.$perm"
8643                 chmod $perm "$dir/$tfile.$perm"
8644         done
8645
8646         for ((i = 0; i < ${#perms[*]}; i++)); do
8647                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8648                 (( $num == 1 )) ||
8649                         error "lfs find -perm ${perms[i]}:"\
8650                               "$num != 1"
8651
8652                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8653                 (( $num == ${perm_minus[i]} )) ||
8654                         error "lfs find -perm -${perms[i]}:"\
8655                               "$num != ${perm_minus[i]}"
8656
8657                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8658                 (( $num == ${perm_slash[i]} )) ||
8659                         error "lfs find -perm /${perms[i]}:"\
8660                               "$num != ${perm_slash[i]}"
8661         done
8662 }
8663 run_test 56aca "check lfs find -perm with octal representation"
8664
8665 test_56acb() {
8666         local dir=$DIR/$tdir
8667         # p is the permission of write and execute for user, group and other
8668         # without the umask. It is used to test +wx.
8669         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8670         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8671         local symbolic=(+t  a+t u+t g+t o+t
8672                         g+s u+s o+s +s o+sr
8673                         o=r,ug+o,u+w
8674                         u+ g+ o+ a+ ugo+
8675                         u- g- o- a- ugo-
8676                         u= g= o= a= ugo=
8677                         o=r,ug+o,u+w u=r,a+u,u+w
8678                         g=r,ugo=g,u+w u+x,+X +X
8679                         u+x,u+X u+X u+x,g+X o+r,+X
8680                         u+x,go+X +wx +rwx)
8681
8682         test_mkdir $dir
8683         for perm in ${perms[*]}; do
8684                 touch "$dir/$tfile.$perm"
8685                 chmod $perm "$dir/$tfile.$perm"
8686         done
8687
8688         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8689                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8690
8691                 (( $num == 1 )) ||
8692                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8693         done
8694 }
8695 run_test 56acb "check lfs find -perm with symbolic representation"
8696
8697 test_56acc() {
8698         local dir=$DIR/$tdir
8699         local tests="17777 787 789 abcd
8700                 ug=uu ug=a ug=gu uo=ou urw
8701                 u+xg+x a=r,u+x,"
8702
8703         test_mkdir $dir
8704         for err in $tests; do
8705                 if $LFS find $dir -perm $err 2>/dev/null; then
8706                         error "lfs find -perm $err: parsing should have failed"
8707                 fi
8708         done
8709 }
8710 run_test 56acc "check parsing error for lfs find -perm"
8711
8712 test_56ba() {
8713         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8714                 skip "Need MDS version at least 2.10.50"
8715
8716         # Create composite files with one component
8717         local dir=$DIR/$tdir
8718
8719         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8720         # Create composite files with three components
8721         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8722         # LU-16904 Create plain layout files
8723         lfs setstripe -c 1 $dir/$tfile-{1..10}
8724
8725         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8726
8727         [[ $nfiles == 10 ]] ||
8728                 error "lfs find -E 1M found $nfiles != 10 files"
8729
8730         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8731         [[ $nfiles == 25 ]] ||
8732                 error "lfs find ! -E 1M found $nfiles != 25 files"
8733
8734         # All files have a component that starts at 0
8735         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8736         [[ $nfiles == 35 ]] ||
8737                 error "lfs find --component-start 0 - $nfiles != 35 files"
8738
8739         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8740         [[ $nfiles == 15 ]] ||
8741                 error "lfs find --component-start 2M - $nfiles != 15 files"
8742
8743         # All files created here have a componenet that does not starts at 2M
8744         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8745         [[ $nfiles == 35 ]] ||
8746                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8747
8748         # Find files with a specified number of components
8749         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8750         [[ $nfiles == 15 ]] ||
8751                 error "lfs find --component-count 3 - $nfiles != 15 files"
8752
8753         # Remember non-composite files have a component count of zero
8754         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8755         [[ $nfiles == 10 ]] ||
8756                 error "lfs find --component-count 0 - $nfiles != 10 files"
8757
8758         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8759         [[ $nfiles == 20 ]] ||
8760                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8761
8762         # All files have a flag called "init"
8763         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8764         [[ $nfiles == 35 ]] ||
8765                 error "lfs find --component-flags init - $nfiles != 35 files"
8766
8767         # Multi-component files will have a component not initialized
8768         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8769         [[ $nfiles == 15 ]] ||
8770                 error "lfs find !--component-flags init - $nfiles != 15 files"
8771
8772         rm -rf $dir
8773
8774 }
8775 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8776
8777 test_56ca() {
8778         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8779                 skip "Need MDS version at least 2.10.57"
8780
8781         local td=$DIR/$tdir
8782         local tf=$td/$tfile
8783         local dir
8784         local nfiles
8785         local cmd
8786         local i
8787         local j
8788
8789         # create mirrored directories and mirrored files
8790         mkdir $td || error "mkdir $td failed"
8791         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8792         createmany -o $tf- 10 || error "create $tf- failed"
8793
8794         for i in $(seq 2); do
8795                 dir=$td/dir$i
8796                 mkdir $dir || error "mkdir $dir failed"
8797                 $LFS mirror create -N$((3 + i)) $dir ||
8798                         error "create mirrored dir $dir failed"
8799                 createmany -o $dir/$tfile- 10 ||
8800                         error "create $dir/$tfile- failed"
8801         done
8802
8803         # change the states of some mirrored files
8804         echo foo > $tf-6
8805         for i in $(seq 2); do
8806                 dir=$td/dir$i
8807                 for j in $(seq 4 9); do
8808                         echo foo > $dir/$tfile-$j
8809                 done
8810         done
8811
8812         # find mirrored files with specific mirror count
8813         cmd="$LFS find --mirror-count 3 --type f $td"
8814         nfiles=$($cmd | wc -l)
8815         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8816
8817         cmd="$LFS find ! --mirror-count 3 --type f $td"
8818         nfiles=$($cmd | wc -l)
8819         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8820
8821         cmd="$LFS find --mirror-count +2 --type f $td"
8822         nfiles=$($cmd | wc -l)
8823         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8824
8825         cmd="$LFS find --mirror-count -6 --type f $td"
8826         nfiles=$($cmd | wc -l)
8827         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8828
8829         # find mirrored files with specific file state
8830         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8831         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8832
8833         cmd="$LFS find --mirror-state=ro --type f $td"
8834         nfiles=$($cmd | wc -l)
8835         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8836
8837         cmd="$LFS find ! --mirror-state=ro --type f $td"
8838         nfiles=$($cmd | wc -l)
8839         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8840
8841         cmd="$LFS find --mirror-state=wp --type f $td"
8842         nfiles=$($cmd | wc -l)
8843         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8844
8845         cmd="$LFS find ! --mirror-state=sp --type f $td"
8846         nfiles=$($cmd | wc -l)
8847         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8848 }
8849 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8850
8851 test_56da() { # LU-14179
8852         local path=$DIR/$tdir
8853
8854         test_mkdir $path
8855         cd $path
8856
8857         local longdir=$(str_repeat 'a' 255)
8858
8859         for i in {1..15}; do
8860                 path=$path/$longdir
8861                 test_mkdir $longdir
8862                 cd $longdir
8863         done
8864
8865         local len=${#path}
8866         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8867
8868         test_mkdir $lastdir
8869         cd $lastdir
8870         # PATH_MAX-1
8871         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8872
8873         # NAME_MAX
8874         touch $(str_repeat 'f' 255)
8875
8876         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8877                 error "lfs find reported an error"
8878
8879         rm -rf $DIR/$tdir
8880 }
8881 run_test 56da "test lfs find with long paths"
8882
8883 test_56ea() { #LU-10378
8884         local path=$DIR/$tdir
8885         local pool=$TESTNAME
8886
8887         # Create ost pool
8888         pool_add $pool || error "pool_add $pool failed"
8889         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8890                 error "adding targets to $pool failed"
8891
8892         # Set default pool on directory before creating file
8893         mkdir $path || error "mkdir $path failed"
8894         $LFS setstripe -p $pool $path ||
8895                 error "set OST pool on $pool failed"
8896         touch $path/$tfile || error "touch $path/$tfile failed"
8897
8898         # Compare basic file attributes from -printf and stat
8899         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G %n")
8900         local attr_stat=$(stat -c "%X %Y %Z %u %g %h" $path/$tfile)
8901
8902         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8903                 error "Attrs from lfs find and stat don't match"
8904
8905         # Compare Lustre attributes from lfs find and lfs getstripe
8906         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8907         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8908         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8909         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8910         local fpool=$($LFS getstripe --pool $path/$tfile)
8911         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8912
8913         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8914                 error "Attrs from lfs find and lfs getstripe don't match"
8915
8916         # Verify behavior for unknown escape/format sequences
8917         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8918
8919         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8920                 error "Escape/format codes don't match"
8921 }
8922 run_test 56ea "test lfs find -printf option"
8923
8924 test_56eb() {
8925         local dir=$DIR/$tdir
8926         local subdir_1=$dir/subdir_1
8927
8928         test_mkdir -p $subdir_1
8929         ln -s subdir_1 $dir/link_1
8930
8931         $LFS getstripe $dir | grep "^$dir/link_1$" -A1 ||
8932                 error "symlink is not followed"
8933
8934         $LFS getstripe --no-follow $dir |
8935                 grep "^$dir/link_1 has no stripe info$" ||
8936                 error "symlink should not have stripe info"
8937
8938         touch $dir/testfile
8939         ln -s testfile $dir/file_link_2
8940
8941         $LFS getstripe $dir | grep "^$dir/file_link_2$" -A1 ||
8942                 error "symlink is not followed"
8943
8944         $LFS getstripe --no-follow $dir |
8945                 grep "^$dir/file_link_2 has no stripe info$" ||
8946                 error "symlink should not have stripe info"
8947 }
8948 run_test 56eb "check lfs getstripe on symlink"
8949
8950 test_56ec() {
8951         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8952         local dir=$DIR/$tdir
8953         local srcfile=$dir/srcfile
8954         local srcyaml=$dir/srcyaml
8955         local destfile=$dir/destfile
8956
8957         test_mkdir -p $dir
8958
8959         $LFS setstripe -i 1 $srcfile
8960         $LFS getstripe --hex-idx --yaml $srcfile > $srcyaml
8961         # if the setstripe yaml parsing fails for any reason, the command can
8962         # randomly assign the correct OST index, leading to an erroneous
8963         # success. but the chance of false success is low enough that a
8964         # regression should still be quickly caught.
8965         $LFS setstripe --yaml=$srcyaml $destfile
8966
8967         local srcindex=$($LFS getstripe -i $srcfile)
8968         local destindex=$($LFS getstripe -i $destfile)
8969
8970         if [[ ! $srcindex -eq $destindex ]]; then
8971                 error "setstripe did not set OST index correctly"
8972         fi
8973 }
8974 run_test 56ec "check lfs getstripe,setstripe --hex --yaml"
8975
8976 test_56eda() {
8977         local dir=$DIR/$tdir
8978         local subdir=$dir/subdir
8979         local file1=$dir/$tfile
8980         local file2=$dir/$tfile\2
8981         local link=$dir/$tfile-link
8982         local nfiles
8983
8984         test_mkdir -p $dir
8985         $LFS setdirstripe -c1 $subdir
8986         touch $file1
8987         touch $file2
8988         ln $file2 $link
8989
8990         nfiles=$($LFS find --links 1 $dir | wc -l)
8991         (( $nfiles == 1 )) ||
8992                 error "lfs find --links expected 1 file, got $nfiles"
8993
8994         nfiles=$($LFS find --type f --links 2 $dir | wc -l)
8995         (( $nfiles == 2 )) ||
8996                 error "lfs find --links expected 2 files, got $nfiles"
8997
8998         nfiles=$($LFS find --type d --links 2 $dir | wc -l)
8999         (( $nfiles == 1 )) ||
9000                 error "lfs find --links expected 1 directory, got $nfiles"
9001 }
9002 run_test 56eda "check lfs find --links"
9003
9004 test_56edb() {
9005         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
9006
9007         local dir=$DIR/$tdir
9008         local stripedir=$dir/stripedir
9009         local nfiles
9010
9011         test_mkdir -p $dir
9012
9013         $LFS setdirstripe -c2 $stripedir
9014
9015         $LFS getdirstripe $stripedir
9016
9017         nfiles=$($LFS find --type d --links 2 $stripedir | wc -l)
9018         (( $nfiles == 1 )) ||
9019                 error "lfs find --links expected 1 directory, got $nfiles"
9020 }
9021 run_test 56edb "check lfs find --links for directory striped on multiple MDTs"
9022
9023 test_56ef() {
9024         local dir=$DIR/$tdir
9025         local dir1=$dir/d1
9026         local dir2=$dir/d2
9027         local nfiles
9028         local err_msg
9029
9030         test_mkdir -p $dir
9031
9032         mkdir $dir1
9033         mkdir $dir2
9034
9035         touch $dir1/f
9036         touch $dir2/f
9037
9038         nfiles=$($LFS find $dir1 $dir2 ! -type d | wc -l)
9039         (( $nfiles == 2 )) ||
9040                 error "(1) lfs find expected 2 files, got $nfiles"
9041
9042         nfiles=$($LFS find $dir1 $dir2 -type f | wc -l)
9043         (( $nfiles == 2 )) ||
9044                 error "(2) lfs find expected 2 files, got $nfiles"
9045
9046         nfiles=$($LFS find -type f $dir1 $dir2 | wc -l)
9047         (( $nfiles == 2 )) ||
9048                 error "(3) lfs find expected 2 files, got $nfiles"
9049
9050         err_msg=$($LFS find $dir1/typo $dir1/f 2>&1 > /dev/null)
9051         [[ $err_msg =~ "No such file or directory" ]] ||
9052                 error "expected standard error message, got: '$err_msg'"
9053 }
9054 run_test 56ef "lfs find with multiple paths"
9055
9056 test_56eg() {
9057         local dir=$DIR/$tdir
9058         local found
9059
9060         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9061
9062         test_mkdir -p $dir
9063
9064         touch $dir/$tfile
9065         ln -s $dir/$tfile $dir/$tfile.symlink
9066         setfattr -n "trusted.test" -v "test_target" $dir/$tfile
9067         setfattr --no-dereference -n "trusted.test" -v "test_link" \
9068                 $dir/$tfile.symlink
9069         setfattr --no-dereference -n "trusted.common" \
9070                 $dir/{$tfile,$tfile.symlink}
9071
9072         found=$($LFS find -xattr "trusted.*=test_target" \
9073                 -xattr "trusted.common" $dir)
9074         [[ "$found" == "$dir/$tfile" ]] || {
9075                 getfattr -d -m trusted.* $dir/$tfile
9076                 error "should have found '$tfile' with xattr 'trusted.test=test_target', got '$found'"
9077         }
9078
9079         found=$($LFS find -xattr "trusted.*=test_link" \
9080                 -xattr "trusted.common" $dir)
9081         [[ "$found" == "$dir/$tfile.symlink" ]] || {
9082                 getfattr --no-dereference -d -m trusted.* $dir/$tfile.symlink
9083                 error "should have found '$tfile.symlink' with xattr 'trusted.test=test_link', got '$found'"
9084         }
9085
9086         rm -f $dir/*
9087
9088         touch $dir/$tfile.1
9089         touch $dir/$tfile.2
9090         setfattr -n "user.test" -v "1" $dir/$tfile.1
9091         setfattr -n "user.test" -v "2" $dir/$tfile.2
9092         setfattr -n "user.test2" -v "common" $dir/$tfile.{1,2}
9093
9094         found=$($LFS find -xattr "user.*=common" -xattr "user.test=1" $dir)
9095         [[ "$found" == "$dir/$tfile.1" ]] || {
9096                 getfattr -d $dir/$tfile.1
9097                 error "should have found '$tfile.1' with xattr user.test=1', got '$found'"
9098         }
9099
9100         found=$($LFS find -xattr "user.*=common" ! -xattr "user.test=1" $dir)
9101         [[ "$found" == "$dir/$tfile.2" ]] || {
9102                 getfattr -d $dir/$tfile.2
9103                 error "should have found '$tfile.2' without xattr 'user.test=1', got '$found'"
9104         }
9105
9106         setfattr -n "user.empty" $dir/$tfile.1
9107         found=$($LFS find -xattr "user.empty" $dir)
9108         [[ "$found" == "$dir/$tfile.1" ]] || {
9109                 getfattr -d $dir/$tfile.1
9110                 error "should have found '$tfile.1' with xattr 'user.empty=', got '$found'"
9111         }
9112
9113         # setfattr command normally does not store terminating null byte
9114         # when writing a string as an xattr value.
9115         #
9116         # In order to test matching a value string that includes a terminating
9117         # null, explicitly encode the string "test\0" with the null terminator.
9118         setfattr -n "user.test" -v "0x7465737400" $dir/$tfile.1
9119         found=$($LFS find -xattr "user.test=test" $dir)
9120         [[ "$found" == "$dir/$tfile.1" ]] || {
9121                 getfattr -d --encoding=hex $dir/$tfile.1
9122                 error "should have found '$tfile.1' with xattr 'user.test=0x7465737400', got '$found'"
9123         }
9124 }
9125 run_test 56eg "lfs find -xattr"
9126
9127 test_57a() {
9128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9129         # note test will not do anything if MDS is not local
9130         if [ "$mds1_FSTYPE" != ldiskfs ]; then
9131                 skip_env "ldiskfs only test"
9132         fi
9133         remote_mds_nodsh && skip "remote MDS with nodsh"
9134
9135         local MNTDEV="osd*.*MDT*.mntdev"
9136         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
9137         [ -z "$DEV" ] && error "can't access $MNTDEV"
9138         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
9139                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
9140                         error "can't access $DEV"
9141                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
9142                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
9143                 rm $TMP/t57a.dump
9144         done
9145 }
9146 run_test 57a "verify MDS filesystem created with large inodes =="
9147
9148 test_57b() {
9149         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9150         if [ "$mds1_FSTYPE" != ldiskfs ]; then
9151                 skip_env "ldiskfs only test"
9152         fi
9153         remote_mds_nodsh && skip "remote MDS with nodsh"
9154
9155         local dir=$DIR/$tdir
9156         local filecount=100
9157         local file1=$dir/f1
9158         local fileN=$dir/f$filecount
9159
9160         rm -rf $dir || error "removing $dir"
9161         test_mkdir -c1 $dir
9162         local mdtidx=$($LFS getstripe -m $dir)
9163         local mdtname=MDT$(printf %04x $mdtidx)
9164         local facet=mds$((mdtidx + 1))
9165
9166         echo "mcreating $filecount files"
9167         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
9168
9169         # verify that files do not have EAs yet
9170         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
9171                 error "$file1 has an EA"
9172         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
9173                 error "$fileN has an EA"
9174
9175         sync
9176         sleep 1
9177         df $dir  #make sure we get new statfs data
9178         local mdsfree=$(do_facet $facet \
9179                         lctl get_param -n osd*.*$mdtname.kbytesfree)
9180         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
9181         local file
9182
9183         echo "opening files to create objects/EAs"
9184         for file in $(seq -f $dir/f%g 1 $filecount); do
9185                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
9186                         error "opening $file"
9187         done
9188
9189         # verify that files have EAs now
9190         $LFS getstripe -y $file1 | grep -q "l_ost_idx" ||
9191                 error "$file1 missing EA"
9192         $LFS getstripe -y $fileN | grep -q "l_ost_idx" ||
9193                 error "$fileN missing EA"
9194
9195         sleep 1  #make sure we get new statfs data
9196         df $dir
9197         local mdsfree2=$(do_facet $facet \
9198                          lctl get_param -n osd*.*$mdtname.kbytesfree)
9199         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
9200
9201         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
9202                 if [ "$mdsfree" != "$mdsfree2" ]; then
9203                         error "MDC before $mdcfree != after $mdcfree2"
9204                 else
9205                         echo "MDC before $mdcfree != after $mdcfree2"
9206                         echo "unable to confirm if MDS has large inodes"
9207                 fi
9208         fi
9209         rm -rf $dir
9210 }
9211 run_test 57b "default LOV EAs are stored inside large inodes ==="
9212
9213 test_58() {
9214         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9215         [ -z "$(which wiretest 2>/dev/null)" ] &&
9216                         skip_env "could not find wiretest"
9217
9218         wiretest
9219 }
9220 run_test 58 "verify cross-platform wire constants =============="
9221
9222 test_59() {
9223         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9224
9225         echo "touch 130 files"
9226         createmany -o $DIR/f59- 130
9227         echo "rm 130 files"
9228         unlinkmany $DIR/f59- 130
9229         sync
9230         # wait for commitment of removal
9231         wait_delete_completed
9232 }
9233 run_test 59 "verify cancellation of llog records async ========="
9234
9235 TEST60_HEAD="test_60 run $RANDOM"
9236 test_60a() {
9237         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9238         remote_mgs_nodsh && skip "remote MGS with nodsh"
9239         do_facet mgs "! which run-llog.sh &> /dev/null" &&
9240                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
9241                         skip_env "missing subtest run-llog.sh"
9242
9243         log "$TEST60_HEAD - from kernel mode"
9244         do_facet mgs "$LCTL dk > /dev/null"
9245         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
9246         do_facet mgs $LCTL dk > $TMP/$tfile
9247
9248         # LU-6388: test llog_reader
9249         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
9250         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
9251         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
9252                         skip_env "missing llog_reader"
9253         local fstype=$(facet_fstype mgs)
9254         [ $fstype != ldiskfs -a $fstype != zfs ] &&
9255                 skip_env "Only for ldiskfs or zfs type mgs"
9256
9257         local mntpt=$(facet_mntpt mgs)
9258         local mgsdev=$(mgsdevname 1)
9259         local fid_list
9260         local fid
9261         local rec_list
9262         local rec
9263         local rec_type
9264         local obj_file
9265         local path
9266         local seq
9267         local oid
9268         local pass=true
9269
9270         #get fid and record list
9271         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
9272                 tail -n 4))
9273         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
9274                 tail -n 4))
9275         #remount mgs as ldiskfs or zfs type
9276         stop mgs || error "stop mgs failed"
9277         mount_fstype mgs || error "remount mgs failed"
9278         for ((i = 0; i < ${#fid_list[@]}; i++)); do
9279                 fid=${fid_list[i]}
9280                 rec=${rec_list[i]}
9281                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
9282                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
9283                 oid=$((16#$oid))
9284
9285                 case $fstype in
9286                         ldiskfs )
9287                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
9288                         zfs )
9289                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
9290                 esac
9291                 echo "obj_file is $obj_file"
9292                 do_facet mgs $llog_reader $obj_file
9293
9294                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
9295                         awk '{ print $3 }' | sed -e "s/^type=//g")
9296                 if [ $rec_type != $rec ]; then
9297                         echo "FAILED test_60a wrong record type $rec_type," \
9298                               "should be $rec"
9299                         pass=false
9300                         break
9301                 fi
9302
9303                 #check obj path if record type is LLOG_LOGID_MAGIC
9304                 if [ "$rec" == "1064553b" ]; then
9305                         path=$(do_facet mgs $llog_reader $obj_file |
9306                                 grep "path=" | awk '{ print $NF }' |
9307                                 sed -e "s/^path=//g")
9308                         if [ $obj_file != $mntpt/$path ]; then
9309                                 echo "FAILED test_60a wrong obj path" \
9310                                       "$montpt/$path, should be $obj_file"
9311                                 pass=false
9312                                 break
9313                         fi
9314                 fi
9315         done
9316         rm -f $TMP/$tfile
9317         #restart mgs before "error", otherwise it will block the next test
9318         stop mgs || error "stop mgs failed"
9319         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
9320         $pass || error "test failed, see FAILED test_60a messages for specifics"
9321 }
9322 run_test 60a "llog_test run from kernel module and test llog_reader"
9323
9324 test_60b() { # bug 6411
9325         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9326
9327         dmesg > $DIR/$tfile
9328         LLOG_COUNT=$(do_facet mgs dmesg |
9329                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
9330                           /llog_[a-z]*.c:[0-9]/ {
9331                                 if (marker)
9332                                         from_marker++
9333                                 from_begin++
9334                           }
9335                           END {
9336                                 if (marker)
9337                                         print from_marker
9338                                 else
9339                                         print from_begin
9340                           }")
9341
9342         [[ $LLOG_COUNT -gt 120 ]] &&
9343                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
9344 }
9345 run_test 60b "limit repeated messages from CERROR/CWARN"
9346
9347 test_60c() {
9348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9349
9350         echo "create 5000 files"
9351         createmany -o $DIR/f60c- 5000
9352 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
9353         lctl set_param fail_loc=0x80000137
9354         unlinkmany $DIR/f60c- 5000
9355         lctl set_param fail_loc=0
9356 }
9357 run_test 60c "unlink file when mds full"
9358
9359 test_60d() {
9360         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9361
9362         SAVEPRINTK=$(lctl get_param -n printk)
9363         # verify "lctl mark" is even working"
9364         MESSAGE="test message ID $RANDOM $$"
9365         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9366         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
9367
9368         lctl set_param printk=0 || error "set lnet.printk failed"
9369         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
9370         MESSAGE="new test message ID $RANDOM $$"
9371         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
9372         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9373         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
9374
9375         lctl set_param -n printk="$SAVEPRINTK"
9376 }
9377 run_test 60d "test printk console message masking"
9378
9379 test_60e() {
9380         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9381         remote_mds_nodsh && skip "remote MDS with nodsh"
9382
9383         touch $DIR/$tfile
9384 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
9385         do_facet mds1 lctl set_param fail_loc=0x15b
9386         rm $DIR/$tfile
9387 }
9388 run_test 60e "no space while new llog is being created"
9389
9390 test_60f() {
9391         local old_path=$($LCTL get_param -n debug_path)
9392
9393         stack_trap "$LCTL set_param debug_path=$old_path"
9394         stack_trap "rm -f $TMP/$tfile*"
9395         rm -f $TMP/$tfile* 2> /dev/null
9396         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
9397         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
9398         test_mkdir $DIR/$tdir
9399         # retry in case the open is cached and not released
9400         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
9401                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
9402                 sleep 0.1
9403         done
9404         ls $TMP/$tfile*
9405         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
9406 }
9407 run_test 60f "change debug_path works"
9408
9409 test_60g() {
9410         local pid
9411         local i
9412
9413         test_mkdir -c $MDSCOUNT $DIR/$tdir
9414
9415         (
9416                 local index=0
9417                 while true; do
9418                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
9419                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
9420                                 2>/dev/null
9421                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
9422                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
9423                         index=$((index + 1))
9424                 done
9425         ) &
9426
9427         pid=$!
9428
9429         for i in {0..100}; do
9430                 # define OBD_FAIL_OSD_TXN_START    0x19a
9431                 local index=$((i % MDSCOUNT + 1))
9432
9433                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
9434                         > /dev/null
9435                 sleep 0.01
9436         done
9437
9438         kill -9 $pid
9439
9440         for i in $(seq $MDSCOUNT); do
9441                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
9442         done
9443
9444         mkdir $DIR/$tdir/new || error "mkdir failed"
9445         rmdir $DIR/$tdir/new || error "rmdir failed"
9446
9447         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
9448                 -t namespace
9449         for i in $(seq $MDSCOUNT); do
9450                 wait_update_facet mds$i "$LCTL get_param -n \
9451                         mdd.$(facet_svc mds$i).lfsck_namespace |
9452                         awk '/^status/ { print \\\$2 }'" "completed"
9453         done
9454
9455         ls -R $DIR/$tdir
9456         rm -rf $DIR/$tdir || error "rmdir failed"
9457 }
9458 run_test 60g "transaction abort won't cause MDT hung"
9459
9460 test_60h() {
9461         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
9462                 skip "Need MDS version at least 2.12.52"
9463         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
9464
9465         local f
9466
9467         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
9468         #define OBD_FAIL_MDS_STRIPE_FID          0x189
9469         for fail_loc in 0x80000188 0x80000189; do
9470                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
9471                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
9472                         error "mkdir $dir-$fail_loc failed"
9473                 for i in {0..10}; do
9474                         # create may fail on missing stripe
9475                         echo $i > $DIR/$tdir-$fail_loc/$i
9476                 done
9477                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9478                         error "getdirstripe $tdir-$fail_loc failed"
9479                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
9480                         error "migrate $tdir-$fail_loc failed"
9481                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9482                         error "getdirstripe $tdir-$fail_loc failed"
9483                 pushd $DIR/$tdir-$fail_loc
9484                 for f in *; do
9485                         echo $f | cmp $f - || error "$f data mismatch"
9486                 done
9487                 popd
9488                 rm -rf $DIR/$tdir-$fail_loc
9489         done
9490 }
9491 run_test 60h "striped directory with missing stripes can be accessed"
9492
9493 function t60i_load() {
9494         mkdir $DIR/$tdir
9495         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
9496         $LCTL set_param fail_loc=0x131c fail_val=1
9497         for ((i=0; i<5000; i++)); do
9498                 touch $DIR/$tdir/f$i
9499         done
9500 }
9501
9502 test_60i() {
9503         changelog_register || error "changelog_register failed"
9504         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
9505         changelog_users $SINGLEMDS | grep -q $cl_user ||
9506                 error "User $cl_user not found in changelog_users"
9507         changelog_chmask "ALL"
9508         t60i_load &
9509         local PID=$!
9510         for((i=0; i<100; i++)); do
9511                 changelog_dump >/dev/null ||
9512                         error "can't read changelog"
9513         done
9514         kill $PID
9515         wait $PID
9516         changelog_deregister || error "changelog_deregister failed"
9517         $LCTL set_param fail_loc=0
9518 }
9519 run_test 60i "llog: new record vs reader race"
9520
9521 test_60j() {
9522         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
9523                 skip "need MDS version at least 2.15.50"
9524         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9525         remote_mds_nodsh && skip "remote MDS with nodsh"
9526         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
9527
9528         changelog_users $SINGLEMDS | grep "^cl" &&
9529                 skip "active changelog user"
9530
9531         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
9532
9533         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
9534                 skip_env "missing llog_reader"
9535
9536         mkdir_on_mdt0 $DIR/$tdir
9537
9538         local f=$DIR/$tdir/$tfile
9539         local mdt_dev
9540         local tmpfile
9541         local plain
9542
9543         changelog_register || error "cannot register changelog user"
9544
9545         # set changelog_mask to ALL
9546         changelog_chmask "ALL"
9547         changelog_clear
9548
9549         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
9550         unlinkmany ${f}- 100 || error "unlinkmany failed"
9551
9552         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
9553         mdt_dev=$(facet_device $SINGLEMDS)
9554
9555         do_facet $SINGLEMDS sync
9556         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
9557                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
9558                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
9559
9560         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
9561
9562         # if $tmpfile is not on EXT3 filesystem for some reason
9563         [[ ${plain:0:1} == 'O' ]] ||
9564                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
9565
9566         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
9567                 $mdt_dev; stat -c %s $tmpfile")
9568         echo "Truncate llog from $size to $((size - size % 8192))"
9569         size=$((size - size % 8192))
9570         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
9571         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9572                 grep -c 'in bitmap only')
9573         (( $errs > 0 )) || error "llog_reader didn't find lost records"
9574
9575         size=$((size - 9000))
9576         echo "Corrupt llog in the middle at $size"
9577         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
9578                 count=333 conv=notrunc
9579         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9580                 grep -c 'next chunk')
9581         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
9582 }
9583 run_test 60j "llog_reader reports corruptions"
9584
9585 test_61a() {
9586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9587
9588         f="$DIR/f61"
9589         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
9590         cancel_lru_locks osc
9591         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
9592         sync
9593 }
9594 run_test 61a "mmap() writes don't make sync hang ================"
9595
9596 test_61b() {
9597         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
9598 }
9599 run_test 61b "mmap() of unstriped file is successful"
9600
9601 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
9602 # Though this test is irrelevant anymore, it helped to reveal some
9603 # other grant bugs (LU-4482), let's keep it.
9604 test_63a() {   # was test_63
9605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9606
9607         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
9608
9609         for i in `seq 10` ; do
9610                 dd if=/dev/zero of=$DIR/f63 bs=8k &
9611                 sleep 5
9612                 kill $!
9613                 sleep 1
9614         done
9615
9616         rm -f $DIR/f63 || true
9617 }
9618 run_test 63a "Verify oig_wait interruption does not crash ======="
9619
9620 # bug 2248 - async write errors didn't return to application on sync
9621 # bug 3677 - async write errors left page locked
9622 test_63b() {
9623         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9624
9625         debugsave
9626         lctl set_param debug=-1
9627
9628         # ensure we have a grant to do async writes
9629         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
9630         rm $DIR/$tfile
9631
9632         sync    # sync lest earlier test intercept the fail_loc
9633
9634         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9635         lctl set_param fail_loc=0x80000406
9636         $MULTIOP $DIR/$tfile Owy && \
9637                 error "sync didn't return ENOMEM"
9638         sync; sleep 2; sync     # do a real sync this time to flush page
9639         lctl get_param -n llite.*.dump_page_cache | grep locked && \
9640                 error "locked page left in cache after async error" || true
9641         debugrestore
9642 }
9643 run_test 63b "async write errors should be returned to fsync ==="
9644
9645 test_64a () {
9646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9647
9648         lfs df $DIR
9649         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
9650 }
9651 run_test 64a "verify filter grant calculations (in kernel) ====="
9652
9653 test_64b () {
9654         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9655
9656         bash oos.sh $MOUNT || error "oos.sh failed: $?"
9657 }
9658 run_test 64b "check out-of-space detection on client"
9659
9660 test_64c() {
9661         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
9662 }
9663 run_test 64c "verify grant shrink"
9664
9665 import_param() {
9666         local tgt=$1
9667         local param=$2
9668
9669         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
9670 }
9671
9672 # this does exactly what osc_request.c:osc_announce_cached() does in
9673 # order to calculate max amount of grants to ask from server
9674 want_grant() {
9675         local tgt=$1
9676
9677         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
9678         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
9679
9680         ((rpc_in_flight++));
9681         nrpages=$((nrpages * rpc_in_flight))
9682
9683         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
9684
9685         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
9686
9687         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
9688         local undirty=$((nrpages * PAGE_SIZE))
9689
9690         local max_extent_pages
9691         max_extent_pages=$(import_param $tgt grant_max_extent_size)
9692         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
9693         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
9694         local grant_extent_tax
9695         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9696
9697         undirty=$((undirty + nrextents * grant_extent_tax))
9698
9699         echo $undirty
9700 }
9701
9702 # this is size of unit for grant allocation. It should be equal to
9703 # what tgt_grant.c:tgt_grant_chunk() calculates
9704 grant_chunk() {
9705         local tgt=$1
9706         local max_brw_size
9707         local grant_extent_tax
9708
9709         max_brw_size=$(import_param $tgt max_brw_size)
9710
9711         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9712
9713         echo $(((max_brw_size + grant_extent_tax) * 2))
9714 }
9715
9716 test_64d() {
9717         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
9718                 skip "OST < 2.10.55 doesn't limit grants enough"
9719
9720         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9721
9722         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9723                 skip "no grant_param connect flag"
9724
9725         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9726
9727         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9728         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9729
9730
9731         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9732         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9733
9734         $LFS setstripe $DIR/$tfile -i 0 -c 1
9735         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9736         ddpid=$!
9737
9738         while kill -0 $ddpid; do
9739                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9740
9741                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9742                         kill $ddpid
9743                         error "cur_grant $cur_grant > $max_cur_granted"
9744                 fi
9745
9746                 sleep 1
9747         done
9748 }
9749 run_test 64d "check grant limit exceed"
9750
9751 check_grants() {
9752         local tgt=$1
9753         local expected=$2
9754         local msg=$3
9755         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9756
9757         ((cur_grants == expected)) ||
9758                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9759 }
9760
9761 round_up_p2() {
9762         echo $((($1 + $2 - 1) & ~($2 - 1)))
9763 }
9764
9765 test_64e() {
9766         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9767         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9768                 skip "Need OSS version at least 2.11.56"
9769
9770         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9771         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9772         $LCTL set_param debug=+cache
9773
9774         # Remount client to reset grant
9775         remount_client $MOUNT || error "failed to remount client"
9776         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9777
9778         local init_grants=$(import_param $osc_tgt initial_grant)
9779
9780         check_grants $osc_tgt $init_grants "init grants"
9781
9782         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9783         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9784         local gbs=$(import_param $osc_tgt grant_block_size)
9785
9786         # write random number of bytes from max_brw_size / 4 to max_brw_size
9787         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9788         # align for direct io
9789         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9790         # round to grant consumption unit
9791         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9792
9793         local grants=$((wb_round_up + extent_tax))
9794
9795         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9796         stack_trap "rm -f $DIR/$tfile"
9797
9798         # define OBD_FAIL_TGT_NO_GRANT 0x725
9799         # make the server not grant more back
9800         do_facet ost1 $LCTL set_param fail_loc=0x725
9801         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9802
9803         do_facet ost1 $LCTL set_param fail_loc=0
9804
9805         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9806
9807         rm -f $DIR/$tfile || error "rm failed"
9808
9809         # Remount client to reset grant
9810         remount_client $MOUNT || error "failed to remount client"
9811         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9812
9813         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9814
9815         # define OBD_FAIL_TGT_NO_GRANT 0x725
9816         # make the server not grant more back
9817         do_facet ost1 $LCTL set_param fail_loc=0x725
9818         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9819         do_facet ost1 $LCTL set_param fail_loc=0
9820
9821         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9822 }
9823 run_test 64e "check grant consumption (no grant allocation)"
9824
9825 test_64f() {
9826         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9827
9828         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9829         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9830         $LCTL set_param debug=+cache
9831
9832         # Remount client to reset grant
9833         remount_client $MOUNT || error "failed to remount client"
9834         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9835
9836         local init_grants=$(import_param $osc_tgt initial_grant)
9837         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9838         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9839         local gbs=$(import_param $osc_tgt grant_block_size)
9840         local chunk=$(grant_chunk $osc_tgt)
9841
9842         # write random number of bytes from max_brw_size / 4 to max_brw_size
9843         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9844         # align for direct io
9845         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9846         # round to grant consumption unit
9847         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9848
9849         local grants=$((wb_round_up + extent_tax))
9850
9851         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9852         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9853                 error "error writing to $DIR/$tfile"
9854
9855         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9856                 "direct io with grant allocation"
9857
9858         rm -f $DIR/$tfile || error "rm failed"
9859
9860         # Remount client to reset grant
9861         remount_client $MOUNT || error "failed to remount client"
9862         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9863
9864         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9865
9866         # Testing that buffered IO consumes grant on the client
9867
9868         # Delay the RPC on the server so it's guaranteed to not complete even
9869         # if the RPC is sent from the client
9870         #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
9871         $LCTL set_param fail_loc=0x50a fail_val=3
9872         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 conv=notrunc ||
9873                 error "error writing to $DIR/$tfile with buffered IO"
9874
9875         check_grants $osc_tgt $((init_grants - grants)) \
9876                 "buffered io, not write rpc"
9877
9878         # Clear the fail loc and do a sync on the client
9879         $LCTL set_param fail_loc=0 fail_val=0
9880         sync
9881
9882         # RPC is now known to have sent
9883         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9884                 "buffered io, one RPC"
9885 }
9886 run_test 64f "check grant consumption (with grant allocation)"
9887
9888 test_64g() {
9889         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9890                 skip "Need MDS version at least 2.14.56"
9891
9892         local mdts=$(comma_list $(mdts_nodes))
9893
9894         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9895                         tr '\n' ' ')
9896         stack_trap "$LCTL set_param $old"
9897
9898         # generate dirty pages and increase dirty granted on MDT
9899         stack_trap "rm -f $DIR/$tfile-*"
9900         for (( i = 0; i < 10; i++)); do
9901                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9902                         error "can't set stripe"
9903                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9904                         error "can't dd"
9905                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9906                         $LFS getstripe $DIR/$tfile-$i
9907                         error "not DoM file"
9908                 }
9909         done
9910
9911         # flush dirty pages
9912         sync
9913
9914         # wait until grant shrink reset grant dirty on MDTs
9915         for ((i = 0; i < 120; i++)); do
9916                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9917                         awk '{sum=sum+$1} END {print sum}')
9918                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9919                 echo "$grant_dirty grants, $vm_dirty pages"
9920                 (( grant_dirty + vm_dirty == 0 )) && break
9921                 (( i == 3 )) && sync &&
9922                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9923                 sleep 1
9924         done
9925
9926         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9927                 awk '{sum=sum+$1} END {print sum}')
9928         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9929 }
9930 run_test 64g "grant shrink on MDT"
9931
9932 test_64h() {
9933         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9934                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9935
9936         local instance=$($LFS getname -i $DIR)
9937         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9938         local num_exps=$(do_facet ost1 \
9939             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9940         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9941         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9942         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9943
9944         # 10MiB is for file to be written, max_brw_size * 16 *
9945         # num_exps is space reserve so that tgt_grant_shrink() decided
9946         # to not shrink
9947         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9948         (( avail * 1024 < expect )) &&
9949                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9950
9951         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9952         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9953         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9954         $LCTL set_param osc.*OST0000*.grant_shrink=1
9955         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9956
9957         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9958         stack_trap "rm -f $DIR/$tfile"
9959         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9960
9961         # drop cache so that coming read would do rpc
9962         cancel_lru_locks osc
9963
9964         # shrink interval is set to 10, pause for 7 seconds so that
9965         # grant thread did not wake up yet but coming read entered
9966         # shrink mode for rpc (osc_should_shrink_grant())
9967         sleep 7
9968
9969         declare -a cur_grant_bytes
9970         declare -a tot_granted
9971         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9972         tot_granted[0]=$(do_facet ost1 \
9973             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9974
9975         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9976
9977         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9978         tot_granted[1]=$(do_facet ost1 \
9979             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9980
9981         # grant change should be equal on both sides
9982         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9983                 tot_granted[0] - tot_granted[1])) ||
9984                 error "grant change mismatch, "                                \
9985                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9986                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9987 }
9988 run_test 64h "grant shrink on read"
9989
9990 test_64i() {
9991         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9992                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9993
9994         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9995         remote_ost_nodsh && skip "remote OSTs with nodsh"
9996
9997         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9998         stack_trap "rm -f $DIR/$tfile"
9999
10000         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
10001
10002         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
10003         local instance=$($LFS getname -i $DIR)
10004
10005         local osc_tgt="$FSNAME-OST0000-osc-$instance"
10006         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
10007
10008         # shrink grants and simulate rpc loss
10009         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
10010         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
10011         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
10012
10013         fail ost1
10014
10015         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
10016
10017         local testid=$(echo $TESTNAME | tr '_' ' ')
10018
10019         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
10020                 grep "GRANT, real grant" &&
10021                 error "client has more grants then it owns" || true
10022 }
10023 run_test 64i "shrink on reconnect"
10024
10025 # bug 1414 - set/get directories' stripe info
10026 test_65a() {
10027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10028
10029         test_mkdir $DIR/$tdir
10030         touch $DIR/$tdir/f1
10031         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
10032 }
10033 run_test 65a "directory with no stripe info"
10034
10035 test_65b() {
10036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10037
10038         test_mkdir $DIR/$tdir
10039         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10040
10041         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
10042                                                 error "setstripe"
10043         touch $DIR/$tdir/f2
10044         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
10045 }
10046 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
10047
10048 test_65c() {
10049         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10050         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
10051
10052         test_mkdir $DIR/$tdir
10053         local stripesize=$($LFS getstripe -S $DIR/$tdir)
10054
10055         $LFS setstripe -S $((stripesize * 4)) -i 1 \
10056                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
10057         touch $DIR/$tdir/f3
10058         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
10059 }
10060 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
10061
10062 test_65d() {
10063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10064
10065         test_mkdir $DIR/$tdir
10066         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
10067         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10068
10069         if [[ $STRIPECOUNT -le 0 ]]; then
10070                 sc=1
10071         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
10072                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
10073                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
10074         else
10075                 sc=$(($STRIPECOUNT - 1))
10076         fi
10077         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
10078         touch $DIR/$tdir/f4 $DIR/$tdir/f5
10079         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
10080                 error "lverify failed"
10081 }
10082 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
10083
10084 test_65e() {
10085         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10086
10087         # LU-16904 delete layout when root is set as PFL layout
10088         save_layout_restore_at_exit $MOUNT
10089         $LFS setstripe -d $MOUNT || error "setstripe failed"
10090
10091         test_mkdir $DIR/$tdir
10092
10093         $LFS setstripe $DIR/$tdir || error "setstripe"
10094         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
10095                                         error "no stripe info failed"
10096         touch $DIR/$tdir/f6
10097         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
10098 }
10099 run_test 65e "directory setstripe defaults"
10100
10101 test_65f() {
10102         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10103
10104         test_mkdir $DIR/${tdir}f
10105         $RUNAS $LFS setstripe $DIR/${tdir}f &&
10106                 error "setstripe succeeded" || true
10107 }
10108 run_test 65f "dir setstripe permission (should return error) ==="
10109
10110 test_65g() {
10111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10112
10113         # LU-16904 delete layout when root is set as PFL layout
10114         save_layout_restore_at_exit $MOUNT
10115         $LFS setstripe -d $MOUNT || error "setstripe failed"
10116
10117         test_mkdir $DIR/$tdir
10118         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10119
10120         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
10121                 error "setstripe -S failed"
10122         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
10123         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
10124                 error "delete default stripe failed"
10125 }
10126 run_test 65g "directory setstripe -d"
10127
10128 test_65h() {
10129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10130
10131         test_mkdir $DIR/$tdir
10132         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10133
10134         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
10135                 error "setstripe -S failed"
10136         test_mkdir $DIR/$tdir/dd1
10137         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
10138                 error "stripe info inherit failed"
10139 }
10140 run_test 65h "directory stripe info inherit ===================="
10141
10142 test_65i() {
10143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10144
10145         save_layout_restore_at_exit $MOUNT
10146
10147         # bug6367: set non-default striping on root directory
10148         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
10149
10150         # bug12836: getstripe on -1 default directory striping
10151         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
10152
10153         # bug12836: getstripe -v on -1 default directory striping
10154         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
10155
10156         # bug12836: new find on -1 default directory striping
10157         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
10158 }
10159 run_test 65i "various tests to set root directory striping"
10160
10161 test_65j() { # bug6367
10162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10163
10164         sync; sleep 1
10165
10166         # if we aren't already remounting for each test, do so for this test
10167         if [ "$I_MOUNTED" = "yes" ]; then
10168                 cleanup || error "failed to unmount"
10169                 setup
10170         fi
10171
10172         save_layout_restore_at_exit $MOUNT
10173
10174         $LFS setstripe -d $MOUNT || error "setstripe failed"
10175 }
10176 run_test 65j "set default striping on root directory (bug 6367)="
10177
10178 cleanup_65k() {
10179         rm -rf $DIR/$tdir
10180         wait_delete_completed
10181         do_facet $SINGLEMDS "lctl set_param -n \
10182                 osp.$ost*MDT0000.max_create_count=$max_count"
10183         do_facet $SINGLEMDS "lctl set_param -n \
10184                 osp.$ost*MDT0000.create_count=$count"
10185         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10186         echo $INACTIVE_OSC "is Activate"
10187
10188         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10189 }
10190
10191 test_65k() { # bug11679
10192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10193         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10194         remote_mds_nodsh && skip "remote MDS with nodsh"
10195
10196         local disable_precreate=true
10197         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
10198                 disable_precreate=false
10199
10200         echo "Check OST status: "
10201         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
10202                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
10203
10204         for OSC in $MDS_OSCS; do
10205                 echo $OSC "is active"
10206                 do_facet $SINGLEMDS lctl --device %$OSC activate
10207         done
10208
10209         for INACTIVE_OSC in $MDS_OSCS; do
10210                 local ost=$(osc_to_ost $INACTIVE_OSC)
10211                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
10212                                lov.*md*.target_obd |
10213                                awk -F: /$ost/'{ print $1 }' | head -n 1)
10214
10215                 mkdir -p $DIR/$tdir
10216                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
10217                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
10218
10219                 echo "Deactivate: " $INACTIVE_OSC
10220                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
10221
10222                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
10223                               osp.$ost*MDT0000.create_count")
10224                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
10225                                   osp.$ost*MDT0000.max_create_count")
10226                 $disable_precreate &&
10227                         do_facet $SINGLEMDS "lctl set_param -n \
10228                                 osp.$ost*MDT0000.max_create_count=0"
10229
10230                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
10231                         [ -f $DIR/$tdir/$idx ] && continue
10232                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
10233                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
10234                                 { cleanup_65k;
10235                                   error "setstripe $idx should succeed"; }
10236                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
10237                 done
10238                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
10239                 rmdir $DIR/$tdir
10240
10241                 do_facet $SINGLEMDS "lctl set_param -n \
10242                         osp.$ost*MDT0000.max_create_count=$max_count"
10243                 do_facet $SINGLEMDS "lctl set_param -n \
10244                         osp.$ost*MDT0000.create_count=$count"
10245                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10246                 echo $INACTIVE_OSC "is Activate"
10247
10248                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10249         done
10250 }
10251 run_test 65k "validate manual striping works properly with deactivated OSCs"
10252
10253 test_65l() { # bug 12836
10254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10255
10256         test_mkdir -p $DIR/$tdir/test_dir
10257         $LFS setstripe -c -1 $DIR/$tdir/test_dir
10258         $LFS find -mtime -1 $DIR/$tdir >/dev/null
10259 }
10260 run_test 65l "lfs find on -1 stripe dir ========================"
10261
10262 test_65m() {
10263         local layout=$(save_layout $MOUNT)
10264         $RUNAS $LFS setstripe -c 2 $MOUNT && {
10265                 restore_layout $MOUNT $layout
10266                 error "setstripe should fail by non-root users"
10267         }
10268         true
10269 }
10270 run_test 65m "normal user can't set filesystem default stripe"
10271
10272 test_65n() {
10273         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
10274         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
10275                 skip "Need MDS version at least 2.12.50"
10276         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
10277
10278         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
10279         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
10280         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
10281
10282         save_layout_restore_at_exit $MOUNT
10283
10284         # new subdirectory under root directory should not inherit
10285         # the default layout from root
10286         # LU-16904 check if the root is set as PFL layout
10287         local numcomp=$($LFS getstripe --component-count $MOUNT)
10288
10289         if [[ $numcomp -eq 0 ]]; then
10290                 local dir1=$MOUNT/$tdir-1
10291                 mkdir $dir1 || error "mkdir $dir1 failed"
10292                 ! getfattr -n trusted.lov $dir1 &> /dev/null ||
10293                         error "$dir1 shouldn't have LOV EA"
10294         fi
10295
10296         # delete the default layout on root directory
10297         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
10298
10299         local dir2=$MOUNT/$tdir-2
10300         mkdir $dir2 || error "mkdir $dir2 failed"
10301         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
10302                 error "$dir2 shouldn't have LOV EA"
10303
10304         # set a new striping pattern on root directory
10305         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10306         local new_def_stripe_size=$((def_stripe_size * 2))
10307         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
10308                 error "set stripe size on $MOUNT failed"
10309
10310         # new file created in $dir2 should inherit the new stripe size from
10311         # the filesystem default
10312         local file2=$dir2/$tfile-2
10313         touch $file2 || error "touch $file2 failed"
10314
10315         local file2_stripe_size=$($LFS getstripe -S $file2)
10316         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
10317         {
10318                 echo "file2_stripe_size: '$file2_stripe_size'"
10319                 echo "new_def_stripe_size: '$new_def_stripe_size'"
10320                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
10321         }
10322
10323         local dir3=$MOUNT/$tdir-3
10324         mkdir $dir3 || error "mkdir $dir3 failed"
10325         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
10326         # the root layout, which is the actual default layout that will be used
10327         # when new files are created in $dir3.
10328         local dir3_layout=$(get_layout_param $dir3)
10329         local root_dir_layout=$(get_layout_param $MOUNT)
10330         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
10331         {
10332                 echo "dir3_layout: '$dir3_layout'"
10333                 echo "root_dir_layout: '$root_dir_layout'"
10334                 error "$dir3 should show the default layout from $MOUNT"
10335         }
10336
10337         # set OST pool on root directory
10338         local pool=$TESTNAME
10339         pool_add $pool || error "add $pool failed"
10340         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10341                 error "add targets to $pool failed"
10342
10343         $LFS setstripe -p $pool $MOUNT ||
10344                 error "set OST pool on $MOUNT failed"
10345
10346         # new file created in $dir3 should inherit the pool from
10347         # the filesystem default
10348         local file3=$dir3/$tfile-3
10349         touch $file3 || error "touch $file3 failed"
10350
10351         local file3_pool=$($LFS getstripe -p $file3)
10352         [[ "$file3_pool" = "$pool" ]] ||
10353                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
10354
10355         local dir4=$MOUNT/$tdir-4
10356         mkdir $dir4 || error "mkdir $dir4 failed"
10357         local dir4_layout=$(get_layout_param $dir4)
10358         root_dir_layout=$(get_layout_param $MOUNT)
10359         echo "$LFS getstripe -d $dir4"
10360         $LFS getstripe -d $dir4
10361         echo "$LFS getstripe -d $MOUNT"
10362         $LFS getstripe -d $MOUNT
10363         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
10364         {
10365                 echo "dir4_layout: '$dir4_layout'"
10366                 echo "root_dir_layout: '$root_dir_layout'"
10367                 error "$dir4 should show the default layout from $MOUNT"
10368         }
10369
10370         # new file created in $dir4 should inherit the pool from
10371         # the filesystem default
10372         local file4=$dir4/$tfile-4
10373         touch $file4 || error "touch $file4 failed"
10374
10375         local file4_pool=$($LFS getstripe -p $file4)
10376         [[ "$file4_pool" = "$pool" ]] ||
10377                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
10378
10379         # new subdirectory under non-root directory should inherit
10380         # the default layout from its parent directory
10381         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
10382                 error "set directory layout on $dir4 failed"
10383
10384         local dir5=$dir4/$tdir-5
10385         mkdir $dir5 || error "mkdir $dir5 failed"
10386
10387         dir4_layout=$(get_layout_param $dir4)
10388         local dir5_layout=$(get_layout_param $dir5)
10389         [[ "$dir4_layout" = "$dir5_layout" ]] ||
10390         {
10391                 echo "dir4_layout: '$dir4_layout'"
10392                 echo "dir5_layout: '$dir5_layout'"
10393                 error "$dir5 should inherit the default layout from $dir4"
10394         }
10395
10396         # though subdir under ROOT doesn't inherit default layout, but
10397         # its sub dir/file should be created with default layout.
10398         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
10399         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
10400                 skip "Need MDS version at least 2.12.59"
10401
10402         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
10403         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
10404         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
10405
10406         if [ $default_lmv_hash == "none" ]; then
10407                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
10408         else
10409                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
10410                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
10411         fi
10412
10413         $LFS setdirstripe -D -c 2 $MOUNT ||
10414                 error "setdirstripe -D -c 2 failed"
10415         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
10416         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
10417         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
10418
10419         # $dir4 layout includes pool
10420         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
10421         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10422                 error "pool lost on setstripe"
10423         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
10424         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10425                 error "pool lost on compound layout setstripe"
10426 }
10427 run_test 65n "don't inherit default layout from root for new subdirectories"
10428
10429 test_65o() {
10430         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
10431                 skip "need MDS version at least 2.14.57"
10432
10433         # set OST pool on root directory
10434         local pool=$TESTNAME
10435
10436         pool_add $pool || error "add $pool failed"
10437         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10438                 error "add targets to $pool failed"
10439
10440         local dir1=$MOUNT/$tdir
10441
10442         mkdir $dir1 || error "mkdir $dir1 failed"
10443
10444         # set a new striping pattern on root directory
10445         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10446
10447         $LFS setstripe -p $pool $dir1 ||
10448                 error "set directory layout on $dir1 failed"
10449
10450         # $dir1 layout includes pool
10451         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
10452         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10453                 error "pool lost on setstripe"
10454         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
10455         $LFS getstripe $dir1
10456         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10457                 error "pool lost on compound layout setstripe"
10458
10459         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
10460                 error "setdirstripe failed on sub-dir with inherited pool"
10461         $LFS getstripe $dir1/dir2
10462         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
10463                 error "pool lost on compound layout setdirstripe"
10464
10465         $LFS setstripe -E -1 -c 1 $dir1
10466         $LFS getstripe -d $dir1
10467         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10468                 error "pool lost on setstripe"
10469 }
10470 run_test 65o "pool inheritance for mdt component"
10471
10472 test_65p () { # LU-16152
10473         local src_dir=$DIR/$tdir/src_dir
10474         local dst_dir=$DIR/$tdir/dst_dir
10475         local yaml_file=$DIR/$tdir/layout.yaml
10476         local border
10477
10478         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10479                 skip "Need at least version 2.15.51"
10480
10481         test_mkdir -p $src_dir
10482         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
10483                 error "failed to setstripe"
10484         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
10485                 error "failed to getstripe"
10486
10487         test_mkdir -p $dst_dir
10488         $LFS setstripe --yaml $yaml_file $dst_dir ||
10489                 error "failed to setstripe with yaml file"
10490         border=$($LFS getstripe -d $dst_dir |
10491                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
10492                 error "failed to getstripe"
10493
10494         # 2048M is 0x80000000, or 2147483648
10495         (( $border == 2147483648 )) ||
10496                 error "failed to handle huge number in yaml layout"
10497 }
10498 run_test 65p "setstripe with yaml file and huge number"
10499
10500 test_65q () { # LU-16194
10501         local src_dir=$DIR/$tdir/src_dir
10502
10503         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) &&
10504         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
10505                 skip "Need at least version 2.15.51"
10506
10507         test_mkdir -p $src_dir
10508         # 8E is 0x8000 0000 0000 0000, which is negative as s64
10509         $LFS setstripe -E 8E -c 4 -E EOF -c 8 $src_dir &&
10510                 error "should fail if extent start/end >=8E"
10511
10512         # EOF should work as before
10513         $LFS setstripe -E 8M -c 4 -E EOF -c 8 $src_dir ||
10514                 error "failed to setstripe normally"
10515 }
10516 run_test 65q "setstripe with >=8E offset should fail"
10517
10518 # bug 2543 - update blocks count on client
10519 test_66() {
10520         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10521
10522         local COUNT=${COUNT:-8}
10523         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
10524         sync; sync_all_data; sync; sync_all_data
10525         cancel_lru_locks osc
10526         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
10527         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
10528 }
10529 run_test 66 "update inode blocks count on client ==============="
10530
10531 meminfo() {
10532         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
10533 }
10534
10535 swap_used() {
10536         swapon -s | awk '($1 == "'$1'") { print $4 }'
10537 }
10538
10539 # bug5265, obdfilter oa2dentry return -ENOENT
10540 # #define OBD_FAIL_SRV_ENOENT 0x217
10541 test_69() {
10542         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10543         remote_ost_nodsh && skip "remote OST with nodsh"
10544
10545         f="$DIR/$tfile"
10546         $LFS setstripe -c 1 -i 0 $f
10547         stack_trap "rm -f $f ${f}.2"
10548
10549         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
10550
10551         do_facet ost1 lctl set_param fail_loc=0x217
10552         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
10553         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
10554
10555         do_facet ost1 lctl set_param fail_loc=0
10556         $DIRECTIO write $f 0 2 || error "write error"
10557
10558         cancel_lru_locks osc
10559         $DIRECTIO read $f 0 1 || error "read error"
10560
10561         do_facet ost1 lctl set_param fail_loc=0x217
10562         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
10563
10564         do_facet ost1 lctl set_param fail_loc=0
10565 }
10566 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
10567
10568 test_70a() {
10569         # Perform a really simple test of health write and health check
10570         (( $OST1_VERSION >= $(version_code 2.15.59) )) ||
10571                 skip "OSTs < 2.15.59 doesn't have enable_health_write"
10572
10573         local orig_value="$(do_facet ost1 $LCTL get_param -n enable_health_write)"
10574
10575         stack_trap "do_facet ost1 $LCTL set_param enable_health_write $orig_value"
10576
10577         # Test with health write off
10578         do_facet ost1 $LCTL set_param enable_health_write off ||
10579                 error "can't set enable_health_write off"
10580         do_facet ost1 $LCTL get_param enable_health_write ||
10581                 error "can't get enable_health_write"
10582
10583         [[ "$(do_facet ost1 $LCTL get_param health_check)" =~ "healthy" ]] ||
10584                 error "not healthy (1)"
10585
10586         # Test with health write on
10587         do_facet ost1 $LCTL set_param enable_health_write on ||
10588                 error "can't set enable_health_write on"
10589         do_facet ost1 $LCTL get_param enable_health_write ||
10590                 error "can't get enable_health_write"
10591
10592         [[ "$(do_facet ost1 $LCTL get_param health_check)" =~ "healthy" ]] ||
10593                 error "not healthy (2)"
10594 }
10595 run_test 70a "verify health_check, health_write don't explode (on OST)"
10596
10597 test_71() {
10598         test_mkdir $DIR/$tdir
10599         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
10600         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
10601 }
10602 run_test 71 "Running dbench on lustre (don't segment fault) ===="
10603
10604 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
10605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10606         [ "$RUNAS_ID" = "$UID" ] &&
10607                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10608         # Check that testing environment is properly set up. Skip if not
10609         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
10610                 skip_env "User $RUNAS_ID does not exist - skipping"
10611
10612         touch $DIR/$tfile
10613         chmod 777 $DIR/$tfile
10614         chmod ug+s $DIR/$tfile
10615         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
10616                 error "$RUNAS dd $DIR/$tfile failed"
10617         # See if we are still setuid/sgid
10618         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10619                 error "S/gid is not dropped on write"
10620         # Now test that MDS is updated too
10621         cancel_lru_locks mdc
10622         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10623                 error "S/gid is not dropped on MDS"
10624         rm -f $DIR/$tfile
10625 }
10626 run_test 72a "Test that remove suid works properly (bug5695) ===="
10627
10628 test_72b() { # bug 24226 -- keep mode setting when size is not changing
10629         local perm
10630
10631         [ "$RUNAS_ID" = "$UID" ] &&
10632                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10633         [ "$RUNAS_ID" -eq 0 ] &&
10634                 skip_env "RUNAS_ID = 0 -- skipping"
10635         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10636         # Check that testing environment is properly set up. Skip if not
10637         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
10638                 skip_env "User $RUNAS_ID does not exist - skipping"
10639
10640         touch $DIR/${tfile}-f{g,u}
10641         test_mkdir $DIR/${tfile}-dg
10642         test_mkdir $DIR/${tfile}-du
10643         chmod 770 $DIR/${tfile}-{f,d}{g,u}
10644         chmod g+s $DIR/${tfile}-{f,d}g
10645         chmod u+s $DIR/${tfile}-{f,d}u
10646         for perm in 777 2777 4777; do
10647                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
10648                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
10649                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
10650                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
10651         done
10652         true
10653 }
10654 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
10655
10656 # bug 3462 - multiple simultaneous MDC requests
10657 test_73() {
10658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10659
10660         test_mkdir $DIR/d73-1
10661         test_mkdir $DIR/d73-2
10662         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
10663         pid1=$!
10664
10665         lctl set_param fail_loc=0x80000129
10666         $MULTIOP $DIR/d73-1/f73-2 Oc &
10667         sleep 1
10668         lctl set_param fail_loc=0
10669
10670         $MULTIOP $DIR/d73-2/f73-3 Oc &
10671         pid3=$!
10672
10673         kill -USR1 $pid1
10674         wait $pid1 || return 1
10675
10676         sleep 25
10677
10678         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
10679         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
10680         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
10681
10682         rm -rf $DIR/d73-*
10683 }
10684 run_test 73 "multiple MDC requests (should not deadlock)"
10685
10686 test_74a() { # bug 6149, 6184
10687         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10688
10689         touch $DIR/f74a
10690         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10691         #
10692         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10693         # will spin in a tight reconnection loop
10694         $LCTL set_param fail_loc=0x8000030e
10695         # get any lock that won't be difficult - lookup works.
10696         ls $DIR/f74a
10697         $LCTL set_param fail_loc=0
10698         rm -f $DIR/f74a
10699         true
10700 }
10701 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
10702
10703 test_74b() { # bug 13310
10704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10705
10706         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10707         #
10708         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10709         # will spin in a tight reconnection loop
10710         $LCTL set_param fail_loc=0x8000030e
10711         # get a "difficult" lock
10712         touch $DIR/f74b
10713         $LCTL set_param fail_loc=0
10714         rm -f $DIR/f74b
10715         true
10716 }
10717 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
10718
10719 test_74c() {
10720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10721
10722         #define OBD_FAIL_LDLM_NEW_LOCK
10723         $LCTL set_param fail_loc=0x319
10724         touch $DIR/$tfile && error "touch successful"
10725         $LCTL set_param fail_loc=0
10726         true
10727 }
10728 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
10729
10730 slab_lic=/sys/kernel/slab/lustre_inode_cache
10731 num_objects() {
10732         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
10733         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
10734                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
10735 }
10736
10737 test_76a() { # Now for b=20433, added originally in b=1443
10738         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10739
10740         cancel_lru_locks osc
10741         # there may be some slab objects cached per core
10742         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10743         local before=$(num_objects)
10744         local count=$((512 * cpus))
10745         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10746         local margin=$((count / 10))
10747         if [[ -f $slab_lic/aliases ]]; then
10748                 local aliases=$(cat $slab_lic/aliases)
10749                 (( aliases > 0 )) && margin=$((margin * aliases))
10750         fi
10751
10752         echo "before slab objects: $before"
10753         for i in $(seq $count); do
10754                 touch $DIR/$tfile
10755                 rm -f $DIR/$tfile
10756         done
10757         cancel_lru_locks osc
10758         local after=$(num_objects)
10759         echo "created: $count, after slab objects: $after"
10760         # shared slab counts are not very accurate, allow significant margin
10761         # the main goal is that the cache growth is not permanently > $count
10762         while (( after > before + margin )); do
10763                 sleep 1
10764                 after=$(num_objects)
10765                 wait=$((wait + 1))
10766                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10767                 if (( wait > 60 )); then
10768                         error "inode slab grew from $before+$margin to $after"
10769                 fi
10770         done
10771 }
10772 run_test 76a "confirm clients recycle inodes properly ===="
10773
10774 test_76b() {
10775         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10776         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10777
10778         local count=512
10779         local before=$(num_objects)
10780
10781         for i in $(seq $count); do
10782                 mkdir $DIR/$tdir
10783                 rmdir $DIR/$tdir
10784         done
10785
10786         local after=$(num_objects)
10787         local wait=0
10788
10789         while (( after > before )); do
10790                 sleep 1
10791                 after=$(num_objects)
10792                 wait=$((wait + 1))
10793                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10794                 if (( wait > 60 )); then
10795                         error "inode slab grew from $before to $after"
10796                 fi
10797         done
10798
10799         echo "slab objects before: $before, after: $after"
10800 }
10801 run_test 76b "confirm clients recycle directory inodes properly ===="
10802
10803 export ORIG_CSUM=""
10804 set_checksums()
10805 {
10806         # Note: in sptlrpc modes which enable its own bulk checksum, the
10807         # original crc32_le bulk checksum will be automatically disabled,
10808         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10809         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10810         # In this case set_checksums() will not be no-op, because sptlrpc
10811         # bulk checksum will be enabled all through the test.
10812
10813         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10814         lctl set_param -n osc.*.checksums $1
10815         return 0
10816 }
10817
10818 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10819                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10820 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10821                              tr -d [] | head -n1)}
10822 set_checksum_type()
10823 {
10824         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10825         rc=$?
10826         log "set checksum type to $1, rc = $rc"
10827         return $rc
10828 }
10829
10830 get_osc_checksum_type()
10831 {
10832         # arugment 1: OST name, like OST0000
10833         ost=$1
10834         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10835                         sed 's/.*\[\(.*\)\].*/\1/g')
10836         rc=$?
10837         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10838         echo $checksum_type
10839 }
10840
10841 F77_TMP=$TMP/f77-temp
10842 F77SZ=8
10843 setup_f77() {
10844         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10845                 error "error writing to $F77_TMP"
10846 }
10847
10848 test_77a() { # bug 10889
10849         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10850         $GSS && skip_env "could not run with gss"
10851
10852         [ ! -f $F77_TMP ] && setup_f77
10853         set_checksums 1
10854         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10855         set_checksums 0
10856         rm -f $DIR/$tfile
10857 }
10858 run_test 77a "normal checksum read/write operation"
10859
10860 test_77b() { # bug 10889
10861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10862         $GSS && skip_env "could not run with gss"
10863
10864         [ ! -f $F77_TMP ] && setup_f77
10865         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10866         $LCTL set_param fail_loc=0x80000409
10867         set_checksums 1
10868
10869         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10870                 error "dd error: $?"
10871         $LCTL set_param fail_loc=0
10872
10873         for algo in $CKSUM_TYPES; do
10874                 cancel_lru_locks osc
10875                 set_checksum_type $algo
10876                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10877                 $LCTL set_param fail_loc=0x80000408
10878                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10879                 $LCTL set_param fail_loc=0
10880         done
10881         set_checksums 0
10882         set_checksum_type $ORIG_CSUM_TYPE
10883         rm -f $DIR/$tfile
10884 }
10885 run_test 77b "checksum error on client write, read"
10886
10887 cleanup_77c() {
10888         trap 0
10889         set_checksums 0
10890         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10891         $check_ost &&
10892                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10893         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10894         $check_ost && [ -n "$ost_file_prefix" ] &&
10895                 do_facet ost1 rm -f ${ost_file_prefix}\*
10896 }
10897
10898 test_77c() {
10899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10900         $GSS && skip_env "could not run with gss"
10901         remote_ost_nodsh && skip "remote OST with nodsh"
10902
10903         local bad1
10904         local osc_file_prefix
10905         local osc_file
10906         local check_ost=false
10907         local ost_file_prefix
10908         local ost_file
10909         local orig_cksum
10910         local dump_cksum
10911         local fid
10912
10913         # ensure corruption will occur on first OSS/OST
10914         $LFS setstripe -i 0 $DIR/$tfile
10915
10916         [ ! -f $F77_TMP ] && setup_f77
10917         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10918                 error "dd write error: $?"
10919         fid=$($LFS path2fid $DIR/$tfile)
10920
10921         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10922         then
10923                 check_ost=true
10924                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10925                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10926         else
10927                 echo "OSS do not support bulk pages dump upon error"
10928         fi
10929
10930         osc_file_prefix=$($LCTL get_param -n debug_path)
10931         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10932
10933         trap cleanup_77c EXIT
10934
10935         set_checksums 1
10936         # enable bulk pages dump upon error on Client
10937         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10938         # enable bulk pages dump upon error on OSS
10939         $check_ost &&
10940                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10941
10942         # flush Client cache to allow next read to reach OSS
10943         cancel_lru_locks osc
10944
10945         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10946         $LCTL set_param fail_loc=0x80000408
10947         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10948         $LCTL set_param fail_loc=0
10949
10950         rm -f $DIR/$tfile
10951
10952         # check cksum dump on Client
10953         osc_file=$(ls ${osc_file_prefix}*)
10954         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10955         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10956         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10957         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10958         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10959                      cksum)
10960         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10961         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10962                 error "dump content does not match on Client"
10963
10964         $check_ost || skip "No need to check cksum dump on OSS"
10965
10966         # check cksum dump on OSS
10967         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10968         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10969         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10970         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10971         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10972                 error "dump content does not match on OSS"
10973
10974         cleanup_77c
10975 }
10976 run_test 77c "checksum error on client read with debug"
10977
10978 test_77d() { # bug 10889
10979         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10980         $GSS && skip_env "could not run with gss"
10981
10982         stack_trap "rm -f $DIR/$tfile"
10983         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10984         $LCTL set_param fail_loc=0x80000409
10985         set_checksums 1
10986         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10987                 error "direct write: rc=$?"
10988         $LCTL set_param fail_loc=0
10989         set_checksums 0
10990
10991         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10992         $LCTL set_param fail_loc=0x80000408
10993         set_checksums 1
10994         cancel_lru_locks osc
10995         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10996                 error "direct read: rc=$?"
10997         $LCTL set_param fail_loc=0
10998         set_checksums 0
10999 }
11000 run_test 77d "checksum error on OST direct write, read"
11001
11002 test_77f() { # bug 10889
11003         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11004         $GSS && skip_env "could not run with gss"
11005
11006         set_checksums 1
11007         stack_trap "rm -f $DIR/$tfile"
11008         for algo in $CKSUM_TYPES; do
11009                 cancel_lru_locks osc
11010                 set_checksum_type $algo
11011                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
11012                 $LCTL set_param fail_loc=0x409
11013                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
11014                         error "direct write succeeded"
11015                 $LCTL set_param fail_loc=0
11016         done
11017         set_checksum_type $ORIG_CSUM_TYPE
11018         set_checksums 0
11019 }
11020 run_test 77f "repeat checksum error on write (expect error)"
11021
11022 test_77g() { # bug 10889
11023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11024         $GSS && skip_env "could not run with gss"
11025         remote_ost_nodsh && skip "remote OST with nodsh"
11026
11027         [ ! -f $F77_TMP ] && setup_f77
11028
11029         local file=$DIR/$tfile
11030         stack_trap "rm -f $file" EXIT
11031
11032         $LFS setstripe -c 1 -i 0 $file
11033         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
11034         do_facet ost1 lctl set_param fail_loc=0x8000021a
11035         set_checksums 1
11036         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
11037                 error "write error: rc=$?"
11038         do_facet ost1 lctl set_param fail_loc=0
11039         set_checksums 0
11040
11041         cancel_lru_locks osc
11042         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
11043         do_facet ost1 lctl set_param fail_loc=0x8000021b
11044         set_checksums 1
11045         cmp $F77_TMP $file || error "file compare failed"
11046         do_facet ost1 lctl set_param fail_loc=0
11047         set_checksums 0
11048 }
11049 run_test 77g "checksum error on OST write, read"
11050
11051 test_77k() { # LU-10906
11052         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11053         $GSS && skip_env "could not run with gss"
11054
11055         local cksum_param="osc.$FSNAME*.checksums"
11056         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
11057         local checksum
11058         local i
11059
11060         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
11061         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
11062         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
11063
11064         for i in 0 1; do
11065                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
11066                         error "failed to set checksum=$i on MGS"
11067                 wait_update $HOSTNAME "$get_checksum" $i
11068                 #remount
11069                 echo "remount client, checksum should be $i"
11070                 remount_client $MOUNT || error "failed to remount client"
11071                 checksum=$(eval $get_checksum)
11072                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
11073         done
11074         # remove persistent param to avoid races with checksum mountopt below
11075         do_facet mgs $LCTL set_param -P -d $cksum_param ||
11076                 error "failed to delete checksum on MGS"
11077
11078         for opt in "checksum" "nochecksum"; do
11079                 #remount with mount option
11080                 echo "remount client with option $opt, checksum should be $i"
11081                 umount_client $MOUNT || error "failed to umount client"
11082                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
11083                         error "failed to mount client with option '$opt'"
11084                 checksum=$(eval $get_checksum)
11085                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
11086                 i=$((i - 1))
11087         done
11088
11089         remount_client $MOUNT || error "failed to remount client"
11090 }
11091 run_test 77k "enable/disable checksum correctly"
11092
11093 test_77l() {
11094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11095         $GSS && skip_env "could not run with gss"
11096
11097         set_checksums 1
11098         stack_trap "set_checksums $ORIG_CSUM" EXIT
11099         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
11100         local old
11101
11102         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
11103         $LCTL set_param osc.*.idle_timeout=10
11104         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
11105
11106         set_checksum_type invalid && error "unexpected success of invalid checksum type"
11107
11108         $LFS setstripe -c 1 -i 0 $DIR/$tfile
11109         for algo in $CKSUM_TYPES; do
11110                 set_checksum_type $algo || error "fail to set checksum type $algo"
11111                 osc_algo=$(get_osc_checksum_type OST0000)
11112                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
11113
11114                 # no locks, no reqs to let the connection idle
11115                 cancel_lru_locks osc
11116                 lru_resize_disable osc
11117                 wait_osc_import_state client ost1 IDLE
11118
11119                 # ensure ost1 is connected
11120                 stat $DIR/$tfile >/dev/null || error "can't stat"
11121                 wait_osc_import_state client ost1 FULL
11122
11123                 osc_algo=$(get_osc_checksum_type OST0000)
11124                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
11125         done
11126         return 0
11127 }
11128 run_test 77l "preferred checksum type is remembered after reconnected"
11129
11130 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
11131 rm -f $F77_TMP
11132 unset F77_TMP
11133
11134 test_77m() {
11135         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
11136                 skip "Need at least version 2.14.52"
11137         local param=checksum_speed
11138
11139         $LCTL get_param $param || error "reading $param failed"
11140
11141         csum_speeds=$($LCTL get_param -n $param)
11142
11143         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
11144                 error "known checksum types are missing"
11145 }
11146 run_test 77m "Verify checksum_speed is correctly read"
11147
11148 check_filefrag_77n() {
11149         local nr_ext=0
11150         local starts=()
11151         local ends=()
11152
11153         while read extidx a b start end rest; do
11154                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
11155                         nr_ext=$(( $nr_ext + 1 ))
11156                         starts+=( ${start%..} )
11157                         ends+=( ${end%:} )
11158                 fi
11159         done < <( filefrag -sv $1 )
11160
11161         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
11162         return 1
11163 }
11164
11165 test_77n() {
11166         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
11167
11168         touch $DIR/$tfile
11169         $TRUNCATE $DIR/$tfile 0
11170         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
11171         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
11172         check_filefrag_77n $DIR/$tfile ||
11173                 skip "$tfile blocks not contiguous around hole"
11174
11175         set_checksums 1
11176         stack_trap "set_checksums $ORIG_CSUM" EXIT
11177         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
11178         stack_trap "rm -f $DIR/$tfile"
11179
11180         for algo in $CKSUM_TYPES; do
11181                 if [[ "$algo" =~ ^t10 ]]; then
11182                         set_checksum_type $algo ||
11183                                 error "fail to set checksum type $algo"
11184                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
11185                                 error "fail to read $tfile with $algo"
11186                 fi
11187         done
11188         rm -f $DIR/$tfile
11189         return 0
11190 }
11191 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
11192
11193 test_77o() {
11194         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
11195                 skip "Need MDS version at least 2.14.55"
11196         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
11197                 skip "Need OST version at least 2.14.55"
11198         local ofd=obdfilter
11199         local mdt=mdt
11200
11201         # print OST checksum_type
11202         echo "$ofd.$FSNAME-*.checksum_type:"
11203         do_nodes $(comma_list $(osts_nodes)) \
11204                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
11205
11206         # print MDT checksum_type
11207         echo "$mdt.$FSNAME-*.checksum_type:"
11208         do_nodes $(comma_list $(mdts_nodes)) \
11209                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
11210
11211         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
11212                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
11213
11214         (( $o_count == $OSTCOUNT )) ||
11215                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
11216
11217         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
11218                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
11219
11220         (( $m_count == $MDSCOUNT )) ||
11221                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
11222 }
11223 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
11224
11225 cleanup_test_78() {
11226         trap 0
11227         rm -f $DIR/$tfile
11228 }
11229
11230 test_78() { # bug 10901
11231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11232         remote_ost || skip_env "local OST"
11233
11234         NSEQ=5
11235         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
11236         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
11237         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
11238         echo "MemTotal: $MEMTOTAL"
11239
11240         # reserve 256MB of memory for the kernel and other running processes,
11241         # and then take 1/2 of the remaining memory for the read/write buffers.
11242         if [ $MEMTOTAL -gt 512 ] ;then
11243                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
11244         else
11245                 # for those poor memory-starved high-end clusters...
11246                 MEMTOTAL=$((MEMTOTAL / 2))
11247         fi
11248         echo "Mem to use for directio: $MEMTOTAL"
11249
11250         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
11251         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
11252         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
11253         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
11254                 head -n1)
11255         echo "Smallest OST: $SMALLESTOST"
11256         [[ $SMALLESTOST -lt 10240 ]] &&
11257                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
11258
11259         trap cleanup_test_78 EXIT
11260
11261         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
11262                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
11263
11264         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
11265         echo "File size: $F78SIZE"
11266         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
11267         for i in $(seq 1 $NSEQ); do
11268                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
11269                 echo directIO rdwr round $i of $NSEQ
11270                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
11271         done
11272
11273         cleanup_test_78
11274 }
11275 run_test 78 "handle large O_DIRECT writes correctly ============"
11276
11277 test_79() { # bug 12743
11278         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11279
11280         wait_delete_completed
11281
11282         BKTOTAL=$(calc_osc_kbytes kbytestotal)
11283         BKFREE=$(calc_osc_kbytes kbytesfree)
11284         BKAVAIL=$(calc_osc_kbytes kbytesavail)
11285
11286         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
11287         DFTOTAL=`echo $STRING | cut -d, -f1`
11288         DFUSED=`echo $STRING  | cut -d, -f2`
11289         DFAVAIL=`echo $STRING | cut -d, -f3`
11290         DFFREE=$(($DFTOTAL - $DFUSED))
11291
11292         ALLOWANCE=$((64 * $OSTCOUNT))
11293
11294         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
11295            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
11296                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
11297         fi
11298         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
11299            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
11300                 error "df free($DFFREE) mismatch OST free($BKFREE)"
11301         fi
11302         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
11303            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
11304                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
11305         fi
11306 }
11307 run_test 79 "df report consistency check ======================="
11308
11309 test_80() { # bug 10718
11310         remote_ost_nodsh && skip "remote OST with nodsh"
11311         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11312
11313         # relax strong synchronous semantics for slow backends like ZFS
11314         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
11315                 local soc="obdfilter.*.sync_lock_cancel"
11316                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11317
11318                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
11319                 if [ -z "$save" ]; then
11320                         soc="obdfilter.*.sync_on_lock_cancel"
11321                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11322                 fi
11323
11324                 if [ "$save" != "never" ]; then
11325                         local hosts=$(comma_list $(osts_nodes))
11326
11327                         do_nodes $hosts $LCTL set_param $soc=never
11328                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
11329                 fi
11330         fi
11331
11332         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
11333         sync; sleep 1; sync
11334         local before=$(date +%s)
11335         cancel_lru_locks osc
11336         local after=$(date +%s)
11337         local diff=$((after - before))
11338         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
11339
11340         rm -f $DIR/$tfile
11341 }
11342 run_test 80 "Page eviction is equally fast at high offsets too"
11343
11344 test_81a() { # LU-456
11345         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11346         remote_ost_nodsh && skip "remote OST with nodsh"
11347
11348         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11349         # MUST OR with the CFS_FAIL_ONCE (0x80000000)
11350         do_facet ost1 lctl set_param fail_loc=0x80000228
11351
11352         # write should trigger a retry and success
11353         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11354         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11355         RC=$?
11356         if [ $RC -ne 0 ] ; then
11357                 error "write should success, but failed for $RC"
11358         fi
11359 }
11360 run_test 81a "OST should retry write when get -ENOSPC ==============="
11361
11362 test_81b() { # LU-456
11363         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11364         remote_ost_nodsh && skip "remote OST with nodsh"
11365
11366         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11367         # Don't OR with the CFS_FAIL_ONCE (0x80000000)
11368         do_facet ost1 lctl set_param fail_loc=0x228
11369
11370         # write should retry several times and return -ENOSPC finally
11371         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11372         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11373         RC=$?
11374         ENOSPC=28
11375         if [ $RC -ne $ENOSPC ] ; then
11376                 error "dd should fail for -ENOSPC, but succeed."
11377         fi
11378 }
11379 run_test 81b "OST should return -ENOSPC when retry still fails ======="
11380
11381 test_99() {
11382         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
11383
11384         test_mkdir $DIR/$tdir.cvsroot
11385         chown $RUNAS_ID $DIR/$tdir.cvsroot
11386
11387         cd $TMP
11388         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
11389
11390         cd /etc/init.d
11391         # some versions of cvs import exit(1) when asked to import links or
11392         # files they can't read.  ignore those files.
11393         local toignore=$(find . -type l -printf '-I %f\n' -o \
11394                          ! -perm /4 -printf '-I %f\n')
11395         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
11396                 $tdir.reposname vtag rtag
11397
11398         cd $DIR
11399         test_mkdir $DIR/$tdir.reposname
11400         chown $RUNAS_ID $DIR/$tdir.reposname
11401         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
11402
11403         cd $DIR/$tdir.reposname
11404         $RUNAS touch foo99
11405         $RUNAS cvs add -m 'addmsg' foo99
11406         $RUNAS cvs update
11407         $RUNAS cvs commit -m 'nomsg' foo99
11408         rm -fr $DIR/$tdir.cvsroot
11409 }
11410 run_test 99 "cvs strange file/directory operations"
11411
11412 test_100() {
11413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11414         [[ "$NETTYPE" =~ tcp ]] ||
11415                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
11416         [[ -n "$(type -p ss)" ]] || skip_env "ss not available"
11417         remote_ost_nodsh && skip "remote OST with nodsh"
11418         remote_mds_nodsh && skip "remote MDS with nodsh"
11419         remote_servers || skip "useless for local single node setup"
11420
11421         ss -tna | ( rc=1; while read STATE SND RCV LOCAL REMOTE STAT; do
11422                 [[ "${REMOTE/*:/}" == "$ACCEPTOR_PORT" ]] || continue
11423
11424                 rc=0
11425                 if (( ${LOCAL/*:/} >= 1024 )); then
11426                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
11427                         ss -tna
11428                         error "local: ${LOCAL/*:/} > 1024 remote: ${REMOTE/*:/}"
11429                 fi
11430         done
11431         (( $rc == 0 )) || error "privileged port not found" )
11432 }
11433 run_test 100 "check local port using privileged port"
11434
11435 function get_named_value()
11436 {
11437     local tag=$1
11438
11439     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
11440 }
11441
11442 test_101a() {
11443         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11444
11445         local s
11446         local discard
11447         local nreads=10000
11448         local cache_limit=32
11449
11450         $LCTL set_param -n osc.*-osc*.rpc_stats=0
11451         $LCTL set_param -n llite.*.read_ahead_stats=0
11452         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
11453                               awk '/^max_cached_mb/ { print $2 }')
11454         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
11455         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
11456
11457         #
11458         # randomly read 10000 of 64K chunks from file 3x 32MB in size
11459         #
11460         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
11461         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
11462
11463         discard=0
11464         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
11465                    get_named_value 'read.but.discarded'); do
11466                         discard=$(($discard + $s))
11467         done
11468
11469         $LCTL get_param osc.*-osc*.rpc_stats
11470         $LCTL get_param llite.*.read_ahead_stats
11471
11472         # Discard is generally zero, but sometimes a few random reads line up
11473         # and trigger larger readahead, which is wasted & leads to discards.
11474         if [[ $(($discard)) -gt $nreads ]]; then
11475                 error "too many ($discard) discarded pages"
11476         fi
11477         rm -f $DIR/$tfile || true
11478 }
11479 run_test 101a "check read-ahead for random reads"
11480
11481 setup_test101bc() {
11482         test_mkdir $DIR/$tdir
11483         local ssize=$1
11484         local FILE_LENGTH=$2
11485         STRIPE_OFFSET=0
11486
11487         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
11488
11489         local list=$(comma_list $(osts_nodes))
11490         set_osd_param $list '' read_cache_enable 0
11491         set_osd_param $list '' writethrough_cache_enable 0
11492
11493         trap cleanup_test101bc EXIT
11494         # prepare the read-ahead file
11495         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
11496
11497         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
11498                                 count=$FILE_SIZE_MB 2> /dev/null
11499
11500 }
11501
11502 cleanup_test101bc() {
11503         trap 0
11504         rm -rf $DIR/$tdir
11505         rm -f $DIR/$tfile
11506
11507         local list=$(comma_list $(osts_nodes))
11508         set_osd_param $list '' read_cache_enable 1
11509         set_osd_param $list '' writethrough_cache_enable 1
11510 }
11511
11512 ra_check_101() {
11513         local read_size=$1
11514         local stripe_size=$2
11515         local stride_length=$((stripe_size / read_size))
11516         local stride_width=$((stride_length * OSTCOUNT))
11517         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
11518                                 (stride_width - stride_length) ))
11519         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
11520                   get_named_value 'read.but.discarded' | calc_sum)
11521
11522         if [[ $discard -gt $discard_limit ]]; then
11523                 $LCTL get_param llite.*.read_ahead_stats
11524                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
11525         else
11526                 echo "Read-ahead success for size ${read_size}"
11527         fi
11528 }
11529
11530 test_101b() {
11531         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11532         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11533
11534         local STRIPE_SIZE=1048576
11535         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
11536
11537         if [ $SLOW == "yes" ]; then
11538                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
11539         else
11540                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
11541         fi
11542
11543         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
11544
11545         # prepare the read-ahead file
11546         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11547         cancel_lru_locks osc
11548         for BIDX in 2 4 8 16 32 64 128 256
11549         do
11550                 local BSIZE=$((BIDX*4096))
11551                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
11552                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
11553                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
11554                 $LCTL set_param -n llite.*.read_ahead_stats=0
11555                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
11556                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
11557                 cancel_lru_locks osc
11558                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
11559         done
11560         cleanup_test101bc
11561         true
11562 }
11563 run_test 101b "check stride-io mode read-ahead ================="
11564
11565 test_101c() {
11566         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11567
11568         local STRIPE_SIZE=1048576
11569         local FILE_LENGTH=$((STRIPE_SIZE*100))
11570         local nreads=10000
11571         local rsize=65536
11572         local osc_rpc_stats
11573
11574         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11575
11576         cancel_lru_locks osc
11577         $LCTL set_param osc.*.rpc_stats=0
11578         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
11579         $LCTL get_param osc.*.rpc_stats
11580         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
11581                 local stats=$($LCTL get_param -n $osc_rpc_stats)
11582                 local lines=$(echo "$stats" | awk 'END {print NR;}')
11583                 local size
11584
11585                 if [ $lines -le 20 ]; then
11586                         echo "continue debug"
11587                         continue
11588                 fi
11589                 for size in 1 2 4 8; do
11590                         local rpc=$(echo "$stats" |
11591                                     awk '($1 == "'$size':") {print $2; exit; }')
11592                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
11593                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
11594                 done
11595                 echo "$osc_rpc_stats check passed!"
11596         done
11597         cleanup_test101bc
11598         true
11599 }
11600 run_test 101c "check stripe_size aligned read-ahead"
11601
11602 test_101d() {
11603         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11604
11605         local file=$DIR/$tfile
11606         local sz_MB=${FILESIZE_101d:-80}
11607         local ra_MB=${READAHEAD_MB:-40}
11608
11609         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
11610         [ $free_MB -lt $sz_MB ] &&
11611                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
11612
11613         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
11614         $LFS setstripe -c -1 $file || error "setstripe failed"
11615
11616         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
11617         echo Cancel LRU locks on lustre client to flush the client cache
11618         cancel_lru_locks osc
11619
11620         echo Disable read-ahead
11621         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11622         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11623         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
11624         $LCTL get_param -n llite.*.max_read_ahead_mb
11625
11626         echo "Reading the test file $file with read-ahead disabled"
11627         local sz_KB=$((sz_MB * 1024 / 4))
11628         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
11629         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
11630         # 83886080 bytes (84 MB, 80 MiB) copied, 16 s, 5.2 MB/s
11631         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11632                       sed -e '/records/d' -e 's/.* \([0-9][0-9\.]*\) *s.*/\1/')
11633
11634         echo "Cancel LRU locks on lustre client to flush the client cache"
11635         cancel_lru_locks osc
11636         echo Enable read-ahead with ${ra_MB}MB
11637         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
11638
11639         echo "Reading the test file $file with read-ahead enabled"
11640         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11641                       sed -e '/records/d' -e 's/.* \([0-9][0-9\.]*\) *s.*/\1/')
11642
11643         echo "read-ahead disabled time read '$raOFF'"
11644         echo "read-ahead enabled time read '$raON'"
11645
11646         rm -f $file
11647         wait_delete_completed
11648
11649         # use awk for this check instead of bash because it handles decimals
11650         awk "{ exit !($raOFF < 0.5 || $raOFF > $raON) }" <<<"ignore_me" ||
11651                 error "readahead ${raON}s > no-readahead ${raOFF}s (${sz_MB}M)"
11652 }
11653 run_test 101d "file read with and without read-ahead enabled"
11654
11655 test_101e() {
11656         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11657
11658         local file=$DIR/$tfile
11659         local size_KB=500  #KB
11660         local count=100
11661         local bsize=1024
11662
11663         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
11664         local need_KB=$((count * size_KB))
11665         [[ $free_KB -le $need_KB ]] &&
11666                 skip_env "Need free space $need_KB, have $free_KB"
11667
11668         echo "Creating $count ${size_KB}K test files"
11669         for ((i = 0; i < $count; i++)); do
11670                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
11671         done
11672
11673         echo "Cancel LRU locks on lustre client to flush the client cache"
11674         cancel_lru_locks $OSC
11675
11676         echo "Reset readahead stats"
11677         $LCTL set_param -n llite.*.read_ahead_stats=0
11678
11679         for ((i = 0; i < $count; i++)); do
11680                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
11681         done
11682
11683         $LCTL get_param llite.*.max_cached_mb
11684         $LCTL get_param llite.*.read_ahead_stats
11685         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11686                      get_named_value 'misses' | calc_sum)
11687
11688         for ((i = 0; i < $count; i++)); do
11689                 rm -rf $file.$i 2>/dev/null
11690         done
11691
11692         #10000 means 20% reads are missing in readahead
11693         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
11694 }
11695 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
11696
11697 test_101f() {
11698         which iozone || skip_env "no iozone installed"
11699
11700         local old_debug=$($LCTL get_param debug)
11701         old_debug=${old_debug#*=}
11702         $LCTL set_param debug="reada mmap"
11703
11704         # create a test file
11705         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
11706
11707         echo Cancel LRU locks on lustre client to flush the client cache
11708         cancel_lru_locks osc
11709
11710         echo Reset readahead stats
11711         $LCTL set_param -n llite.*.read_ahead_stats=0
11712
11713         echo mmap read the file with small block size
11714         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
11715                 > /dev/null 2>&1
11716
11717         echo checking missing pages
11718         $LCTL get_param llite.*.read_ahead_stats
11719         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11720                         get_named_value 'misses' | calc_sum)
11721
11722         $LCTL set_param debug="$old_debug"
11723         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
11724         rm -f $DIR/$tfile
11725 }
11726 run_test 101f "check mmap read performance"
11727
11728 test_101g_brw_size_test() {
11729         local mb=$1
11730         local pages=$((mb * 1048576 / PAGE_SIZE))
11731         local file=$DIR/$tfile
11732
11733         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11734                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11735         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11736                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11737                         return 2
11738         done
11739
11740         stack_trap "rm -f $file" EXIT
11741         $LCTL set_param -n osc.*.rpc_stats=0
11742
11743         # 10 RPCs should be enough for the test
11744         local count=10
11745         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11746                 { error "dd write ${mb} MB blocks failed"; return 3; }
11747         cancel_lru_locks osc
11748         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11749                 { error "dd write ${mb} MB blocks failed"; return 4; }
11750
11751         # calculate number of full-sized read and write RPCs
11752         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11753                 sed -n '/pages per rpc/,/^$/p' |
11754                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11755                 END { print reads,writes }'))
11756         # allow one extra full-sized read RPC for async readahead
11757         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11758                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11759         [[ ${rpcs[1]} == $count ]] ||
11760                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11761 }
11762
11763 test_101g() {
11764         remote_ost_nodsh && skip "remote OST with nodsh"
11765
11766         local rpcs
11767         local osts=$(get_facets OST)
11768         local list=$(comma_list $(osts_nodes))
11769         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11770         local brw_size="obdfilter.*.brw_size"
11771
11772         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11773
11774         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11775
11776         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11777                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11778                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11779            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11780                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11781                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11782
11783                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11784                         suffix="M"
11785
11786                 if [[ $orig_mb -lt 16 ]]; then
11787                         save_lustre_params $osts "$brw_size" > $p
11788                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11789                                 error "set 16MB RPC size failed"
11790
11791                         echo "remount client to enable new RPC size"
11792                         remount_client $MOUNT || error "remount_client failed"
11793                 fi
11794
11795                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11796                 # should be able to set brw_size=12, but no rpc_stats for that
11797                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11798         fi
11799
11800         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11801
11802         if [[ $orig_mb -lt 16 ]]; then
11803                 restore_lustre_params < $p
11804                 remount_client $MOUNT || error "remount_client restore failed"
11805         fi
11806
11807         rm -f $p $DIR/$tfile
11808 }
11809 run_test 101g "Big bulk(4/16 MiB) readahead"
11810
11811 test_101h() {
11812         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11813
11814         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11815                 error "dd 70M file failed"
11816         echo Cancel LRU locks on lustre client to flush the client cache
11817         cancel_lru_locks osc
11818
11819         echo "Reset readahead stats"
11820         $LCTL set_param -n llite.*.read_ahead_stats 0
11821
11822         echo "Read 10M of data but cross 64M bundary"
11823         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11824         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11825                      get_named_value 'misses' | calc_sum)
11826         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11827         rm -f $p $DIR/$tfile
11828 }
11829 run_test 101h "Readahead should cover current read window"
11830
11831 test_101i() {
11832         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11833                 error "dd 10M file failed"
11834
11835         local max_per_file_mb=$($LCTL get_param -n \
11836                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11837         cancel_lru_locks osc
11838         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11839         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11840                 error "set max_read_ahead_per_file_mb to 1 failed"
11841
11842         echo "Reset readahead stats"
11843         $LCTL set_param llite.*.read_ahead_stats=0
11844
11845         dd if=$DIR/$tfile of=/dev/null bs=2M
11846
11847         $LCTL get_param llite.*.read_ahead_stats
11848         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11849                      awk '/misses/ { print $2 }')
11850         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11851         rm -f $DIR/$tfile
11852 }
11853 run_test 101i "allow current readahead to exceed reservation"
11854
11855 test_101j() {
11856         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11857                 error "setstripe $DIR/$tfile failed"
11858         local file_size=$((1048576 * 16))
11859         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11860         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11861
11862         echo Disable read-ahead
11863         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11864
11865         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11866         for blk in $PAGE_SIZE 1048576 $file_size; do
11867                 cancel_lru_locks osc
11868                 echo "Reset readahead stats"
11869                 $LCTL set_param -n llite.*.read_ahead_stats=0
11870                 local count=$(($file_size / $blk))
11871                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11872                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11873                              get_named_value 'failed.to.fast.read' | calc_sum)
11874                 $LCTL get_param -n llite.*.read_ahead_stats
11875                 [ $miss -eq $count ] || error "expected $count got $miss"
11876         done
11877
11878         rm -f $p $DIR/$tfile
11879 }
11880 run_test 101j "A complete read block should be submitted when no RA"
11881
11882 test_readahead_base() {
11883         local file=$DIR/$tfile
11884         local size=$1
11885         local iosz
11886         local ramax
11887         local ranum
11888
11889         $LCTL set_param -n llite.*.read_ahead_stats=0
11890         # The first page is not accounted into readahead
11891         ramax=$(((size + PAGE_SIZE - 1) / PAGE_SIZE - 1))
11892         iosz=$(((size + 1048575) / 1048576 * 1048576))
11893         echo "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11894
11895         $LCTL mark  "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11896         fallocate -l $size $file || error "failed to fallocate $file"
11897         cancel_lru_locks osc
11898         $MULTIOP $file or${iosz}c || error "failed to read $file"
11899         $LCTL get_param -n llite.*.read_ahead_stats
11900         ranum=$($LCTL get_param -n llite.*.read_ahead_stats |
11901                 awk '/readahead.pages/ { print $7 }' | calc_sum)
11902         (( $ranum <= $ramax )) ||
11903                 error "read-ahead pages is $ranum more than $ramax"
11904         rm -rf $file || error "failed to remove $file"
11905 }
11906
11907 test_101m()
11908 {
11909         local file=$DIR/$tfile
11910         local ramax
11911         local ranum
11912         local size
11913         local iosz
11914
11915         check_set_fallocate_or_skip
11916         stack_trap "rm -f $file" EXIT
11917
11918         test_readahead_base 4096
11919
11920         # file size: 16K = 16384
11921         test_readahead_base 16384
11922         test_readahead_base 16385
11923         test_readahead_base 16383
11924
11925         # file size: 1M + 1 = 1048576 + 1
11926         test_readahead_base 1048577
11927         # file size: 1M + 16K
11928         test_readahead_base $((1048576 + 16384))
11929
11930         # file size: stripe_size * (stripe_count - 1) + 16K
11931         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11932         test_readahead_base $((1048576 * (OSTCOUNT - 1) + 16384))
11933         # file size: stripe_size * stripe_count + 16K
11934         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11935         test_readahead_base $((1048576 * OSTCOUNT + 16384))
11936         # file size: 2 * stripe_size * stripe_count + 16K
11937         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11938         test_readahead_base $((2 * 1048576 * OSTCOUNT + 16384))
11939 }
11940 run_test 101m "read ahead for small file and last stripe of the file"
11941
11942 setup_test102() {
11943         test_mkdir $DIR/$tdir
11944         chown $RUNAS_ID $DIR/$tdir
11945         STRIPE_SIZE=65536
11946         STRIPE_OFFSET=1
11947         STRIPE_COUNT=$OSTCOUNT
11948         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11949
11950         trap cleanup_test102 EXIT
11951         cd $DIR
11952         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11953         cd $DIR/$tdir
11954         for num in 1 2 3 4; do
11955                 for count in $(seq 1 $STRIPE_COUNT); do
11956                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11957                                 local size=`expr $STRIPE_SIZE \* $num`
11958                                 local file=file"$num-$idx-$count"
11959                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11960                         done
11961                 done
11962         done
11963
11964         cd $DIR
11965         $1 tar cf $TMP/f102.tar $tdir --xattrs
11966 }
11967
11968 cleanup_test102() {
11969         trap 0
11970         rm -f $TMP/f102.tar
11971         rm -rf $DIR/d0.sanity/d102
11972 }
11973
11974 test_102a() {
11975         [ "$UID" != 0 ] && skip "must run as root"
11976         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11977                 skip_env "must have user_xattr"
11978
11979         [ -z "$(which setfattr 2>/dev/null)" ] &&
11980                 skip_env "could not find setfattr"
11981
11982         local testfile=$DIR/$tfile
11983
11984         touch $testfile
11985         echo "set/get xattr..."
11986         setfattr -n trusted.name1 -v value1 $testfile ||
11987                 error "setfattr -n trusted.name1=value1 $testfile failed"
11988         getfattr -n trusted.name1 $testfile 2> /dev/null |
11989           grep "trusted.name1=.value1" ||
11990                 error "$testfile missing trusted.name1=value1"
11991
11992         setfattr -n user.author1 -v author1 $testfile ||
11993                 error "setfattr -n user.author1=author1 $testfile failed"
11994         getfattr -n user.author1 $testfile 2> /dev/null |
11995           grep "user.author1=.author1" ||
11996                 error "$testfile missing trusted.author1=author1"
11997
11998         echo "listxattr..."
11999         setfattr -n trusted.name2 -v value2 $testfile ||
12000                 error "$testfile unable to set trusted.name2"
12001         setfattr -n trusted.name3 -v value3 $testfile ||
12002                 error "$testfile unable to set trusted.name3"
12003         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
12004             grep "trusted.name" | wc -l) -eq 3 ] ||
12005                 error "$testfile missing 3 trusted.name xattrs"
12006
12007         setfattr -n user.author2 -v author2 $testfile ||
12008                 error "$testfile unable to set user.author2"
12009         setfattr -n user.author3 -v author3 $testfile ||
12010                 error "$testfile unable to set user.author3"
12011         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
12012             grep "user.author" | wc -l) -eq 3 ] ||
12013                 error "$testfile missing 3 user.author xattrs"
12014
12015         echo "remove xattr..."
12016         setfattr -x trusted.name1 $testfile ||
12017                 error "$testfile error deleting trusted.name1"
12018         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
12019                 error "$testfile did not delete trusted.name1 xattr"
12020
12021         setfattr -x user.author1 $testfile ||
12022                 error "$testfile error deleting user.author1"
12023         echo "set lustre special xattr ..."
12024         $LFS setstripe -c1 $testfile
12025         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
12026                 awk -F "=" '/trusted.lov/ { print $2 }' )
12027         setfattr -n "trusted.lov" -v $lovea $testfile ||
12028                 error "$testfile doesn't ignore setting trusted.lov again"
12029         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
12030                 error "$testfile allow setting invalid trusted.lov"
12031         rm -f $testfile
12032 }
12033 run_test 102a "user xattr test =================================="
12034
12035 check_102b_layout() {
12036         local layout="$*"
12037         local testfile=$DIR/$tfile
12038
12039         echo "test layout '$layout'"
12040         $LFS setstripe $layout $testfile || error "setstripe failed"
12041         $LFS getstripe -y $testfile
12042
12043         echo "get/set/list trusted.lov xattr ..." # b=10930
12044         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
12045         [[ "$value" =~ "trusted.lov" ]] ||
12046                 error "can't get trusted.lov from $testfile"
12047         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
12048                 error "getstripe failed"
12049
12050         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
12051
12052         value=$(cut -d= -f2 <<<$value)
12053         # LU-13168: truncated xattr should fail if short lov_user_md header
12054         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
12055                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
12056         for len in $lens; do
12057                 echo "setfattr $len $testfile.2"
12058                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
12059                         [ $len -lt 66 ] && error "short xattr len=$len worked"
12060         done
12061         local stripe_size=$($LFS getstripe -S $testfile.2)
12062         local stripe_count=$($LFS getstripe -c $testfile.2)
12063         [[ $stripe_size -eq 65536 ]] ||
12064                 error "stripe size $stripe_size != 65536"
12065         [[ $stripe_count -eq $stripe_count_orig ]] ||
12066                 error "stripe count $stripe_count != $stripe_count_orig"
12067         rm $testfile $testfile.2
12068 }
12069
12070 test_102b() {
12071         [ -z "$(which setfattr 2>/dev/null)" ] &&
12072                 skip_env "could not find setfattr"
12073         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12074
12075         # check plain layout
12076         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
12077
12078         # and also check composite layout
12079         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
12080
12081 }
12082 run_test 102b "getfattr/setfattr for trusted.lov EAs"
12083
12084 test_102c() {
12085         [ -z "$(which setfattr 2>/dev/null)" ] &&
12086                 skip_env "could not find setfattr"
12087         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12088
12089         # b10930: get/set/list lustre.lov xattr
12090         echo "get/set/list lustre.lov xattr ..."
12091         test_mkdir $DIR/$tdir
12092         chown $RUNAS_ID $DIR/$tdir
12093         local testfile=$DIR/$tdir/$tfile
12094         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
12095                 error "setstripe failed"
12096         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
12097                 error "getstripe failed"
12098         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
12099         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
12100
12101         local testfile2=${testfile}2
12102         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
12103                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
12104
12105         $RUNAS $MCREATE $testfile2
12106         $RUNAS setfattr -n lustre.lov -v $value $testfile2
12107         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
12108         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
12109         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
12110         [ $stripe_count -eq $STRIPECOUNT ] ||
12111                 error "stripe count $stripe_count != $STRIPECOUNT"
12112 }
12113 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
12114
12115 compare_stripe_info1() {
12116         local stripe_index_all_zero=true
12117
12118         for num in 1 2 3 4; do
12119                 for count in $(seq 1 $STRIPE_COUNT); do
12120                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
12121                                 local size=$((STRIPE_SIZE * num))
12122                                 local file=file"$num-$offset-$count"
12123                                 stripe_size=$($LFS getstripe -S $PWD/$file)
12124                                 [[ $stripe_size -ne $size ]] &&
12125                                     error "$file: size $stripe_size != $size"
12126                                 stripe_count=$($LFS getstripe -c $PWD/$file)
12127                                 # allow fewer stripes to be created, ORI-601
12128                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
12129                                     error "$file: count $stripe_count != $count"
12130                                 stripe_index=$($LFS getstripe -i $PWD/$file)
12131                                 [[ $stripe_index -ne 0 ]] &&
12132                                         stripe_index_all_zero=false
12133                         done
12134                 done
12135         done
12136         $stripe_index_all_zero &&
12137                 error "all files are being extracted starting from OST index 0"
12138         return 0
12139 }
12140
12141 have_xattrs_include() {
12142         tar --help | grep -q xattrs-include &&
12143                 echo --xattrs-include="lustre.*"
12144 }
12145
12146 test_102d() {
12147         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12148         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12149
12150         XINC=$(have_xattrs_include)
12151         setup_test102
12152         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
12153         cd $DIR/$tdir/$tdir
12154         compare_stripe_info1
12155 }
12156 run_test 102d "tar restore stripe info from tarfile,not keep osts"
12157
12158 test_102f() {
12159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12160         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12161
12162         XINC=$(have_xattrs_include)
12163         setup_test102
12164         test_mkdir $DIR/$tdir.restore
12165         cd $DIR
12166         tar cf - --xattrs $tdir | tar xf - \
12167                 -C $DIR/$tdir.restore --xattrs $XINC
12168         cd $DIR/$tdir.restore/$tdir
12169         compare_stripe_info1
12170 }
12171 run_test 102f "tar copy files, not keep osts"
12172
12173 grow_xattr() {
12174         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
12175                 skip "must have user_xattr"
12176         [ -z "$(which setfattr 2>/dev/null)" ] &&
12177                 skip_env "could not find setfattr"
12178         [ -z "$(which getfattr 2>/dev/null)" ] &&
12179                 skip_env "could not find getfattr"
12180
12181         local xsize=${1:-1024}  # in bytes
12182         local file=$DIR/$tfile
12183         local value="$(generate_string $xsize)"
12184         local xbig=trusted.big
12185         local toobig=$2
12186
12187         touch $file
12188         log "save $xbig on $file"
12189         if [ -z "$toobig" ]
12190         then
12191                 setfattr -n $xbig -v $value $file ||
12192                         error "saving $xbig on $file failed"
12193         else
12194                 setfattr -n $xbig -v $value $file &&
12195                         error "saving $xbig on $file succeeded"
12196                 return 0
12197         fi
12198
12199         local orig=$(get_xattr_value $xbig $file)
12200         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
12201
12202         local xsml=trusted.sml
12203         log "save $xsml on $file"
12204         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
12205
12206         local new=$(get_xattr_value $xbig $file)
12207         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
12208
12209         log "grow $xsml on $file"
12210         setfattr -n $xsml -v "$value" $file ||
12211                 error "growing $xsml on $file failed"
12212
12213         new=$(get_xattr_value $xbig $file)
12214         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
12215         log "$xbig still valid after growing $xsml"
12216
12217         rm -f $file
12218 }
12219
12220 test_102h() { # bug 15777
12221         grow_xattr 1024
12222 }
12223 run_test 102h "grow xattr from inside inode to external block"
12224
12225 test_102ha() {
12226         large_xattr_enabled || skip_env "ea_inode feature disabled"
12227
12228         echo "setting xattr of max xattr size: $(max_xattr_size)"
12229         grow_xattr $(max_xattr_size)
12230
12231         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
12232         echo "This should fail:"
12233         grow_xattr $(($(max_xattr_size) + 10)) 1
12234 }
12235 run_test 102ha "grow xattr from inside inode to external inode"
12236
12237 test_102i() { # bug 17038
12238         [ -z "$(which getfattr 2>/dev/null)" ] &&
12239                 skip "could not find getfattr"
12240
12241         touch $DIR/$tfile
12242         ln -s $DIR/$tfile $DIR/${tfile}link
12243         getfattr -n trusted.lov $DIR/$tfile ||
12244                 error "lgetxattr on $DIR/$tfile failed"
12245         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
12246                 grep -i "no such attr" ||
12247                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
12248         rm -f $DIR/$tfile $DIR/${tfile}link
12249 }
12250 run_test 102i "lgetxattr test on symbolic link ============"
12251
12252 test_102j() {
12253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12254         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12255
12256         XINC=$(have_xattrs_include)
12257         setup_test102 "$RUNAS"
12258         chown $RUNAS_ID $DIR/$tdir
12259         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
12260         cd $DIR/$tdir/$tdir
12261         compare_stripe_info1 "$RUNAS"
12262 }
12263 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
12264
12265 test_102k() {
12266         [ -z "$(which setfattr 2>/dev/null)" ] &&
12267                 skip "could not find setfattr"
12268
12269         touch $DIR/$tfile
12270         # b22187 just check that does not crash for regular file.
12271         setfattr -n trusted.lov $DIR/$tfile
12272         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
12273         local test_kdir=$DIR/$tdir
12274         test_mkdir $test_kdir
12275         local default_size=$($LFS getstripe -S $test_kdir)
12276         local default_count=$($LFS getstripe -c $test_kdir)
12277         local default_offset=$($LFS getstripe -i $test_kdir)
12278         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
12279                 error 'dir setstripe failed'
12280         setfattr -n trusted.lov $test_kdir
12281         local stripe_size=$($LFS getstripe -S $test_kdir)
12282         local stripe_count=$($LFS getstripe -c $test_kdir)
12283         local stripe_offset=$($LFS getstripe -i $test_kdir)
12284         [ $stripe_size -eq $default_size ] ||
12285                 error "stripe size $stripe_size != $default_size"
12286         [ $stripe_count -eq $default_count ] ||
12287                 error "stripe count $stripe_count != $default_count"
12288         [ $stripe_offset -eq $default_offset ] ||
12289                 error "stripe offset $stripe_offset != $default_offset"
12290         rm -rf $DIR/$tfile $test_kdir
12291 }
12292 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
12293
12294 test_102l() {
12295         [ -z "$(which getfattr 2>/dev/null)" ] &&
12296                 skip "could not find getfattr"
12297
12298         # LU-532 trusted. xattr is invisible to non-root
12299         local testfile=$DIR/$tfile
12300
12301         touch $testfile
12302
12303         echo "listxattr as user..."
12304         chown $RUNAS_ID $testfile
12305         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
12306             grep -q "trusted" &&
12307                 error "$testfile trusted xattrs are user visible"
12308
12309         return 0;
12310 }
12311 run_test 102l "listxattr size test =================================="
12312
12313 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
12314         local path=$DIR/$tfile
12315         touch $path
12316
12317         listxattr_size_check $path || error "listattr_size_check $path failed"
12318 }
12319 run_test 102m "Ensure listxattr fails on small bufffer ========"
12320
12321 cleanup_test102
12322
12323 getxattr() { # getxattr path name
12324         # Return the base64 encoding of the value of xattr name on path.
12325         local path=$1
12326         local name=$2
12327
12328         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
12329         # file: $path
12330         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12331         #
12332         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12333
12334         getfattr --absolute-names --encoding=base64 --name=$name $path |
12335                 awk -F= -v name=$name '$1 == name {
12336                         print substr($0, index($0, "=") + 1);
12337         }'
12338 }
12339
12340 test_102n() { # LU-4101 mdt: protect internal xattrs
12341         [ -z "$(which setfattr 2>/dev/null)" ] &&
12342                 skip "could not find setfattr"
12343         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
12344         then
12345                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
12346         fi
12347
12348         local file0=$DIR/$tfile.0
12349         local file1=$DIR/$tfile.1
12350         local xattr0=$TMP/$tfile.0
12351         local xattr1=$TMP/$tfile.1
12352         local namelist="lov lma lmv link fid version som hsm"
12353         local name
12354         local value
12355
12356         rm -rf $file0 $file1 $xattr0 $xattr1
12357         touch $file0 $file1
12358
12359         # Get 'before' xattrs of $file1.
12360         getfattr --absolute-names --dump --match=- $file1 > $xattr0
12361
12362         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
12363                 namelist+=" lfsck_namespace"
12364         for name in $namelist; do
12365                 # Try to copy xattr from $file0 to $file1.
12366                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12367
12368                 setfattr --name=trusted.$name --value="$value" $file1 ||
12369                         error "setxattr 'trusted.$name' failed"
12370
12371                 # Try to set a garbage xattr.
12372                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12373
12374                 if [[ x$name == "xlov" ]]; then
12375                         setfattr --name=trusted.lov --value="$value" $file1 &&
12376                         error "setxattr invalid 'trusted.lov' success"
12377                 else
12378                         setfattr --name=trusted.$name --value="$value" $file1 ||
12379                                 error "setxattr invalid 'trusted.$name' failed"
12380                 fi
12381
12382                 # Try to remove the xattr from $file1. We don't care if this
12383                 # appears to succeed or fail, we just don't want there to be
12384                 # any changes or crashes.
12385                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12386         done
12387
12388         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
12389         then
12390                 name="lfsck_ns"
12391                 # Try to copy xattr from $file0 to $file1.
12392                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12393
12394                 setfattr --name=trusted.$name --value="$value" $file1 ||
12395                         error "setxattr 'trusted.$name' failed"
12396
12397                 # Try to set a garbage xattr.
12398                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12399
12400                 setfattr --name=trusted.$name --value="$value" $file1 ||
12401                         error "setxattr 'trusted.$name' failed"
12402
12403                 # Try to remove the xattr from $file1. We don't care if this
12404                 # appears to succeed or fail, we just don't want there to be
12405                 # any changes or crashes.
12406                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12407         fi
12408
12409         # Get 'after' xattrs of file1.
12410         getfattr --absolute-names --dump --match=- $file1 > $xattr1
12411
12412         if ! diff $xattr0 $xattr1; then
12413                 error "before and after xattrs of '$file1' differ"
12414         fi
12415
12416         rm -rf $file0 $file1 $xattr0 $xattr1
12417
12418         return 0
12419 }
12420 run_test 102n "silently ignore setxattr on internal trusted xattrs"
12421
12422 test_102p() { # LU-4703 setxattr did not check ownership
12423         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
12424                 skip "MDS needs to be at least 2.5.56"
12425
12426         local testfile=$DIR/$tfile
12427
12428         touch $testfile
12429
12430         echo "setfacl as user..."
12431         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
12432         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
12433
12434         echo "setfattr as user..."
12435         setfacl -m "u:$RUNAS_ID:---" $testfile
12436         $RUNAS setfattr -x system.posix_acl_access $testfile
12437         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
12438 }
12439 run_test 102p "check setxattr(2) correctly fails without permission"
12440
12441 test_102q() {
12442         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
12443                 skip "MDS needs to be at least 2.6.92"
12444
12445         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
12446 }
12447 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
12448
12449 test_102r() {
12450         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
12451                 skip "MDS needs to be at least 2.6.93"
12452
12453         touch $DIR/$tfile || error "touch"
12454         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
12455         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
12456         rm $DIR/$tfile || error "rm"
12457
12458         #normal directory
12459         mkdir -p $DIR/$tdir || error "mkdir"
12460         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12461         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12462         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12463                 error "$testfile error deleting user.author1"
12464         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12465                 grep "user.$(basename $tdir)" &&
12466                 error "$tdir did not delete user.$(basename $tdir)"
12467         rmdir $DIR/$tdir || error "rmdir"
12468
12469         #striped directory
12470         test_mkdir $DIR/$tdir
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 "rm striped dir"
12479 }
12480 run_test 102r "set EAs with empty values"
12481
12482 test_102s() {
12483         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12484                 skip "MDS needs to be at least 2.11.52"
12485
12486         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12487
12488         save_lustre_params client "llite.*.xattr_cache" > $save
12489
12490         for cache in 0 1; do
12491                 lctl set_param llite.*.xattr_cache=$cache
12492
12493                 rm -f $DIR/$tfile
12494                 touch $DIR/$tfile || error "touch"
12495                 for prefix in lustre security system trusted user; do
12496                         # Note getxattr() may fail with 'Operation not
12497                         # supported' or 'No such attribute' depending
12498                         # on prefix and cache.
12499                         getfattr -n $prefix.n102s $DIR/$tfile &&
12500                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
12501                 done
12502         done
12503
12504         restore_lustre_params < $save
12505 }
12506 run_test 102s "getting nonexistent xattrs should fail"
12507
12508 test_102t() {
12509         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12510                 skip "MDS needs to be at least 2.11.52"
12511
12512         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12513
12514         save_lustre_params client "llite.*.xattr_cache" > $save
12515
12516         for cache in 0 1; do
12517                 lctl set_param llite.*.xattr_cache=$cache
12518
12519                 for buf_size in 0 256; do
12520                         rm -f $DIR/$tfile
12521                         touch $DIR/$tfile || error "touch"
12522                         setfattr -n user.multiop $DIR/$tfile
12523                         $MULTIOP $DIR/$tfile oa$buf_size ||
12524                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
12525                 done
12526         done
12527
12528         restore_lustre_params < $save
12529 }
12530 run_test 102t "zero length xattr values handled correctly"
12531
12532 run_acl_subtest()
12533 {
12534         local test=$LUSTRE/tests/acl/$1.test
12535         local tmp=$(mktemp -t $1-XXXXXX).test
12536         local bin=$2
12537         local dmn=$3
12538         local grp=$4
12539         local nbd=$5
12540         export LANG=C
12541
12542
12543         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
12544         local sedgroups="-e s/:users/:$grp/g"
12545         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
12546
12547         sed $sedusers $sedgroups < $test > $tmp
12548         stack_trap "rm -f $tmp"
12549         [[ -s $tmp ]] || error "sed failed to create test script"
12550
12551         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
12552         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
12553 }
12554
12555 test_103a() {
12556         [ "$UID" != 0 ] && skip "must run as root"
12557         $GSS && skip_env "could not run under gss"
12558         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
12559                 skip_env "must have acl enabled"
12560         which setfacl || skip_env "could not find setfacl"
12561         remote_mds_nodsh && skip "remote MDS with nodsh"
12562
12563         local mdts=$(comma_list $(mdts_nodes))
12564         local saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
12565
12566         [[ -z "$saved" ]] || do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE
12567         stack_trap "[[ -z \"$saved\" ]] || \
12568                     do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$saved" EXIT
12569
12570         ACLBIN=${ACLBIN:-"bin"}
12571         ACLDMN=${ACLDMN:-"daemon"}
12572         ACLGRP=${ACLGRP:-"users"}
12573         ACLNBD=${ACLNBD:-"nobody"}
12574
12575         if ! id $ACLBIN ||
12576            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
12577                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
12578                 ACLBIN=$USER0
12579                 if ! id $ACLBIN ; then
12580                         cat /etc/passwd
12581                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
12582                 fi
12583         fi
12584         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
12585            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
12586                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
12587                 ACLDMN=$USER1
12588                 if ! id $ACLDMN ; then
12589                         cat /etc/passwd
12590                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
12591                 fi
12592         fi
12593         if ! getent group $ACLGRP; then
12594                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
12595                 ACLGRP="$TSTUSR"
12596                 if ! getent group $ACLGRP; then
12597                         echo "cannot find group '$ACLGRP', adding it"
12598                         cat /etc/group
12599                         add_group 60000 $ACLGRP
12600                 fi
12601         fi
12602
12603         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
12604         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
12605         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12606
12607         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12608                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
12609                 ACLGRP="$TSTUSR"
12610                 if ! getent group $ACLGRP; then
12611                         echo "cannot find group '$ACLGRP', adding it"
12612                         cat /etc/group
12613                         add_group 60000 $ACLGRP
12614                 fi
12615                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12616                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12617                         cat /etc/group
12618                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
12619                 fi
12620         fi
12621
12622         gpasswd -a $ACLDMN $ACLBIN ||
12623                 error "setting client group failed"             # LU-5641
12624         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
12625                 error "setting MDS group failed"                # LU-5641
12626
12627         declare -a identity_old
12628
12629         for ((num = 1; num <= $MDSCOUNT; num++)); do
12630                 switch_identity $num true || identity_old[$num]=$?
12631         done
12632
12633         SAVE_UMASK=$(umask)
12634         umask 0022
12635         mkdir -p $DIR/$tdir
12636         cd $DIR/$tdir
12637
12638         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
12639         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
12640         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
12641         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
12642         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
12643         # CentOS7- uses nobody=99, while newer distros use nobody=65534
12644         if ! id -u $ACLNBD ||
12645            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
12646                 ACLNBD="nfsnobody"
12647                 if ! id -u $ACLNBD; then
12648                         ACLNBD=""
12649                 fi
12650         fi
12651         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
12652                 add_group $(id -u $ACLNBD) $ACLNBD
12653                 if ! getent group $ACLNBD; then
12654                         ACLNBD=""
12655                 fi
12656         fi
12657         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
12658            [[ -n "$ACLNBD" ]] && which setfattr; then
12659                 run_acl_subtest permissions_xattr \
12660                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
12661         elif [[ -z "$ACLNBD" ]]; then
12662                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
12663         else
12664                 echo "skip 'permission_xattr' test - missing setfattr command"
12665         fi
12666         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
12667
12668         # inheritance test got from HP
12669         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
12670         chmod +x make-tree || error "chmod +x failed"
12671         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
12672         rm -f make-tree
12673
12674         echo "LU-974 ignore umask when acl is enabled..."
12675         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
12676         if [ $MDSCOUNT -ge 2 ]; then
12677                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
12678         fi
12679
12680         echo "LU-2561 newly created file is same size as directory..."
12681         if [ "$mds1_FSTYPE" != "zfs" ]; then
12682                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
12683         else
12684                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
12685         fi
12686
12687         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
12688
12689         cd $SAVE_PWD
12690         umask $SAVE_UMASK
12691
12692         for ((num = 1; num <= $MDSCOUNT; num++)); do
12693                 if [[ "${identity_old[$num]}" == 1 ]]; then
12694                         switch_identity $num false || identity_old[$num]=$?
12695                 fi
12696         done
12697 }
12698 run_test 103a "acl test"
12699
12700 test_103b() {
12701         declare -a pids
12702         local U
12703
12704         stack_trap "rm -f $DIR/$tfile.*"
12705         for U in {0..511}; do
12706                 {
12707                 local O=$(printf "%04o" $U)
12708
12709                 umask $(printf "%04o" $((511 ^ $O)))
12710                 $LFS setstripe -c 1 $DIR/$tfile.s$O
12711                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
12712
12713                 (( $S == ($O & 0666) )) ||
12714                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
12715
12716                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
12717                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
12718                 (( $S == ($O & 0666) )) ||
12719                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
12720
12721                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
12722                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
12723                 (( $S == ($O & 0666) )) ||
12724                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
12725                 rm -f $DIR/$tfile.[smp]$0
12726                 } &
12727                 local pid=$!
12728
12729                 # limit the concurrently running threads to 64. LU-11878
12730                 local idx=$((U % 64))
12731                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
12732                 pids[idx]=$pid
12733         done
12734         wait
12735 }
12736 run_test 103b "umask lfs setstripe"
12737
12738 test_103c() {
12739         mkdir -p $DIR/$tdir
12740         cp -rp $DIR/$tdir $DIR/$tdir.bak
12741
12742         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
12743                 error "$DIR/$tdir shouldn't contain default ACL"
12744         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
12745                 error "$DIR/$tdir.bak shouldn't contain default ACL"
12746         true
12747 }
12748 run_test 103c "'cp -rp' won't set empty acl"
12749
12750 test_103e() {
12751         local numacl
12752         local fileacl
12753         local saved_debug=$($LCTL get_param -n debug)
12754
12755         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
12756                 skip "MDS needs to be at least 2.14.52"
12757
12758         large_xattr_enabled || skip_env "ea_inode feature disabled"
12759
12760         mkdir -p $DIR/$tdir
12761         # add big LOV EA to cause reply buffer overflow earlier
12762         $LFS setstripe -C 1000 $DIR/$tdir
12763         lctl set_param mdc.*-mdc*.stats=clear
12764
12765         $LCTL set_param debug=0
12766         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
12767         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
12768
12769         # add a large number of default ACLs (expect 8000+ for 2.13+)
12770         for U in {2..7000}; do
12771                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
12772                         error "Able to add just $U default ACLs"
12773         done
12774         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
12775         echo "$numacl default ACLs created"
12776
12777         stat $DIR/$tdir || error "Cannot stat directory"
12778         # check file creation
12779         touch $DIR/$tdir/$tfile ||
12780                 error "failed to create $tfile with $numacl default ACLs"
12781         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
12782         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12783         echo "$fileacl ACLs were inherited"
12784         (( $fileacl == $numacl )) ||
12785                 error "Not all default ACLs were inherited: $numacl != $fileacl"
12786         # check that new ACLs creation adds new ACLs to inherited ACLs
12787         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
12788                 error "Cannot set new ACL"
12789         numacl=$((numacl + 1))
12790         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12791         (( $fileacl == $numacl )) ||
12792                 error "failed to add new ACL: $fileacl != $numacl as expected"
12793         # adds more ACLs to a file to reach their maximum at 8000+
12794         numacl=0
12795         for U in {20000..25000}; do
12796                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12797                 numacl=$((numacl + 1))
12798         done
12799         echo "Added $numacl more ACLs to the file"
12800         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12801         echo "Total $fileacl ACLs in file"
12802         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12803         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12804         rmdir $DIR/$tdir || error "Cannot remove directory"
12805 }
12806 run_test 103e "inheritance of big amount of default ACLs"
12807
12808 test_103f() {
12809         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12810                 skip "MDS needs to be at least 2.14.51"
12811
12812         large_xattr_enabled || skip_env "ea_inode feature disabled"
12813
12814         # enable changelog to consume more internal MDD buffers
12815         changelog_register
12816
12817         mkdir -p $DIR/$tdir
12818         # add big LOV EA
12819         $LFS setstripe -C 1000 $DIR/$tdir
12820         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12821         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12822         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12823         rmdir $DIR/$tdir || error "Cannot remove directory"
12824 }
12825 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12826
12827 test_104a() {
12828         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12829
12830         touch $DIR/$tfile
12831         lfs df || error "lfs df failed"
12832         lfs df -ih || error "lfs df -ih failed"
12833         lfs df -h $DIR || error "lfs df -h $DIR failed"
12834         lfs df -i $DIR || error "lfs df -i $DIR failed"
12835         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12836         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12837
12838         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12839         lctl --device %$OSC deactivate
12840         lfs df || error "lfs df with deactivated OSC failed"
12841         lctl --device %$OSC activate
12842         # wait the osc back to normal
12843         wait_osc_import_ready client ost
12844
12845         lfs df || error "lfs df with reactivated OSC failed"
12846         rm -f $DIR/$tfile
12847 }
12848 run_test 104a "lfs df [-ih] [path] test ========================="
12849
12850 test_104b() {
12851         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12852         [ $RUNAS_ID -eq $UID ] &&
12853                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12854
12855         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12856                         grep "Permission denied" | wc -l)))
12857         if [ $denied_cnt -ne 0 ]; then
12858                 error "lfs check servers test failed"
12859         fi
12860 }
12861 run_test 104b "$RUNAS lfs check servers test ===================="
12862
12863 #
12864 # Verify $1 is within range of $2.
12865 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12866 # $1 is <= 2% of $2. Else Fail.
12867 #
12868 value_in_range() {
12869         # Strip all units (M, G, T)
12870         actual=$(echo $1 | tr -d A-Z)
12871         expect=$(echo $2 | tr -d A-Z)
12872
12873         expect_lo=$(($expect * 98 / 100)) # 2% below
12874         expect_hi=$(($expect * 102 / 100)) # 2% above
12875
12876         # permit 2% drift above and below
12877         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12878 }
12879
12880 test_104c() {
12881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12882         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12883
12884         local ost_param="osd-zfs.$FSNAME-OST0000."
12885         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12886         local ofacets=$(get_facets OST)
12887         local mfacets=$(get_facets MDS)
12888         local saved_ost_blocks=
12889         local saved_mdt_blocks=
12890
12891         echo "Before recordsize change"
12892         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12893         df=($(df -h | grep "$MOUNT"$))
12894
12895         # For checking.
12896         echo "lfs output : ${lfs_df[*]}"
12897         echo "df  output : ${df[*]}"
12898
12899         for facet in ${ofacets//,/ }; do
12900                 if [ -z $saved_ost_blocks ]; then
12901                         saved_ost_blocks=$(do_facet $facet \
12902                                 lctl get_param -n $ost_param.blocksize)
12903                         echo "OST Blocksize: $saved_ost_blocks"
12904                 fi
12905                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12906                 do_facet $facet zfs set recordsize=32768 $ost
12907         done
12908
12909         # BS too small. Sufficient for functional testing.
12910         for facet in ${mfacets//,/ }; do
12911                 if [ -z $saved_mdt_blocks ]; then
12912                         saved_mdt_blocks=$(do_facet $facet \
12913                                 lctl get_param -n $mdt_param.blocksize)
12914                         echo "MDT Blocksize: $saved_mdt_blocks"
12915                 fi
12916                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12917                 do_facet $facet zfs set recordsize=32768 $mdt
12918         done
12919
12920         # Give new values chance to reflect change
12921         sleep 2
12922
12923         echo "After recordsize change"
12924         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12925         df_after=($(df -h | grep "$MOUNT"$))
12926
12927         # For checking.
12928         echo "lfs output : ${lfs_df_after[*]}"
12929         echo "df  output : ${df_after[*]}"
12930
12931         # Verify lfs df
12932         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12933                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12934         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12935                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12936         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12937                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12938
12939         # Verify df
12940         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12941                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12942         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12943                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12944         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12945                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12946
12947         # Restore MDT recordize back to original
12948         for facet in ${mfacets//,/ }; do
12949                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12950                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12951         done
12952
12953         # Restore OST recordize back to original
12954         for facet in ${ofacets//,/ }; do
12955                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12956                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12957         done
12958
12959         return 0
12960 }
12961 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12962
12963 test_104d() {
12964         (( $RUNAS_ID != $UID )) ||
12965                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12966
12967         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12968                 skip "lustre version doesn't support lctl dl with non-root"
12969
12970         # debugfs only allows root users to access files, so the
12971         # previous move of the "devices" file to debugfs broke
12972         # "lctl dl" for non-root users. The LU-9680 Netlink
12973         # interface again allows non-root users to list devices.
12974         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12975                 error "lctl dl doesn't work for non root"
12976
12977         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12978         [ "$ost_count" -eq $OSTCOUNT ]  ||
12979                 error "lctl dl reports wrong number of OST devices"
12980
12981         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12982         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12983                 error "lctl dl reports wrong number of MDT devices"
12984 }
12985 run_test 104d "$RUNAS lctl dl test"
12986
12987 test_105a() {
12988         # doesn't work on 2.4 kernels
12989         touch $DIR/$tfile
12990         if $(flock_is_enabled); then
12991                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12992         else
12993                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12994         fi
12995         rm -f $DIR/$tfile
12996 }
12997 run_test 105a "flock when mounted without -o flock test ========"
12998
12999 test_105b() {
13000         touch $DIR/$tfile
13001         if $(flock_is_enabled); then
13002                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
13003         else
13004                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
13005         fi
13006         rm -f $DIR/$tfile
13007 }
13008 run_test 105b "fcntl when mounted without -o flock test ========"
13009
13010 test_105c() {
13011         touch $DIR/$tfile
13012         if $(flock_is_enabled); then
13013                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
13014         else
13015                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
13016         fi
13017         rm -f $DIR/$tfile
13018 }
13019 run_test 105c "lockf when mounted without -o flock test"
13020
13021 test_105d() { # bug 15924
13022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13023
13024         test_mkdir $DIR/$tdir
13025         flock_is_enabled || skip_env "mount w/o flock enabled"
13026         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
13027         $LCTL set_param fail_loc=0x80000315
13028         flocks_test 2 $DIR/$tdir
13029 }
13030 run_test 105d "flock race (should not freeze) ========"
13031
13032 test_105e() { # bug 22660 && 22040
13033         flock_is_enabled || skip_env "mount w/o flock enabled"
13034
13035         touch $DIR/$tfile
13036         flocks_test 3 $DIR/$tfile
13037 }
13038 run_test 105e "Two conflicting flocks from same process"
13039
13040 wait_end() {
13041         echo $*
13042         while :; do
13043                 [ -f $TMP/${tfile}_sTOP ] && return
13044                 sleep 1
13045         done
13046 }
13047
13048 test_105f() {
13049         flock_is_enabled || skip_env "mount w/o flock enabled"
13050
13051         local pmax=$(ulimit -u)
13052         local i=0
13053         touch $DIR/$tfile
13054         [ $pmax -gt 20 ] && pmax=20
13055         for((i=0; i <= $pmax; i++)) {
13056                 wait_end "R4000, 5000" | flocks_test 6 $DIR/$tfile &
13057         }
13058         for((i=0; i <= 10; i++)) {
13059                 local locks=$(do_facet $SINGLEMDS $LCTL get_param -n \
13060                         ldlm.namespaces.mdt-${FSNAME}-MDT0000*.lock_count)
13061                 [ $locks -ge $pmax ] && break
13062                 [ $i -eq 10 ] && error "The locks cannot be added after 10 secs"
13063                 sleep 1
13064         }
13065         touch $TMP/${tfile}_sTOP
13066         wait
13067         rm -r $DIR/$tfile $TMP/${tfile}_sTOP
13068 }
13069 run_test 105f "Enqueue same range flocks"
13070
13071 test_106() { #bug 10921
13072         test_mkdir $DIR/$tdir
13073         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
13074         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
13075 }
13076 run_test 106 "attempt exec of dir followed by chown of that dir"
13077
13078 test_107() {
13079         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13080
13081         CDIR=`pwd`
13082         local file=core
13083
13084         cd $DIR
13085         rm -f $file
13086
13087         local save_pattern=$(sysctl -n kernel.core_pattern)
13088         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
13089         sysctl -w kernel.core_pattern=$file
13090         sysctl -w kernel.core_uses_pid=0
13091
13092         ulimit -c unlimited
13093         sleep 60 &
13094         SLEEPPID=$!
13095
13096         sleep 1
13097
13098         kill -s 11 $SLEEPPID
13099         wait $SLEEPPID
13100         if [ -e $file ]; then
13101                 size=`stat -c%s $file`
13102                 [ $size -eq 0 ] && error "Fail to create core file $file"
13103         else
13104                 error "Fail to create core file $file"
13105         fi
13106         rm -f $file
13107         sysctl -w kernel.core_pattern=$save_pattern
13108         sysctl -w kernel.core_uses_pid=$save_uses_pid
13109         cd $CDIR
13110 }
13111 run_test 107 "Coredump on SIG"
13112
13113 test_110() {
13114         test_mkdir $DIR/$tdir
13115         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
13116         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
13117                 error "mkdir with 256 char should fail, but did not"
13118         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
13119                 error "create with 255 char failed"
13120         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
13121                 error "create with 256 char should fail, but did not"
13122
13123         ls -l $DIR/$tdir
13124         rm -rf $DIR/$tdir
13125 }
13126 run_test 110 "filename length checking"
13127
13128 test_116a() { # was previously test_116()
13129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13130         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13131         remote_mds_nodsh && skip "remote MDS with nodsh"
13132
13133         echo -n "Free space priority "
13134         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
13135                 head -n1
13136         declare -a AVAIL
13137         free_min_max
13138
13139         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
13140         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
13141         stack_trap simple_cleanup_common
13142
13143         # Check if we need to generate uneven OSTs
13144         test_mkdir -p $DIR/$tdir/OST${MINI}
13145         local FILL=$((MINV / 4))
13146         local DIFF=$((MAXV - MINV))
13147         local DIFF2=$((DIFF * 100 / MINV))
13148
13149         local threshold=$(do_facet $SINGLEMDS \
13150                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
13151         threshold=${threshold%%%}
13152         echo -n "Check for uneven OSTs: "
13153         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
13154
13155         if [[ $DIFF2 -gt $threshold ]]; then
13156                 echo "ok"
13157                 echo "Don't need to fill OST$MINI"
13158         else
13159                 # generate uneven OSTs. Write 2% over the QOS threshold value
13160                 echo "no"
13161                 DIFF=$((threshold - DIFF2 + 2))
13162                 DIFF2=$((MINV * DIFF / 100))
13163                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
13164                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
13165                         error "setstripe failed"
13166                 DIFF=$((DIFF2 / 2048))
13167                 i=0
13168                 while [ $i -lt $DIFF ]; do
13169                         i=$((i + 1))
13170                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
13171                                 bs=2M count=1 2>/dev/null
13172                         echo -n .
13173                 done
13174                 echo .
13175                 sync
13176                 sleep_maxage
13177                 free_min_max
13178         fi
13179
13180         DIFF=$((MAXV - MINV))
13181         DIFF2=$((DIFF * 100 / MINV))
13182         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
13183         if [ $DIFF2 -gt $threshold ]; then
13184                 echo "ok"
13185         else
13186                 skip "QOS imbalance criteria not met"
13187         fi
13188
13189         MINI1=$MINI
13190         MINV1=$MINV
13191         MAXI1=$MAXI
13192         MAXV1=$MAXV
13193
13194         # now fill using QOS
13195         $LFS setstripe -c 1 $DIR/$tdir
13196         FILL=$((FILL / 200))
13197         if [ $FILL -gt 600 ]; then
13198                 FILL=600
13199         fi
13200         echo "writing $FILL files to QOS-assigned OSTs"
13201         i=0
13202         while [ $i -lt $FILL ]; do
13203                 i=$((i + 1))
13204                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
13205                         count=1 2>/dev/null
13206                 echo -n .
13207         done
13208         echo "wrote $i 200k files"
13209         sync
13210         sleep_maxage
13211
13212         echo "Note: free space may not be updated, so measurements might be off"
13213         free_min_max
13214         DIFF2=$((MAXV - MINV))
13215         echo "free space delta: orig $DIFF final $DIFF2"
13216         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
13217         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
13218         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
13219         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
13220         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
13221         if [[ $DIFF -gt 0 ]]; then
13222                 FILL=$((DIFF2 * 100 / DIFF - 100))
13223                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
13224         fi
13225
13226         # Figure out which files were written where
13227         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
13228                awk '/'$MINI1': / {print $2; exit}')
13229         echo $UUID
13230         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
13231         echo "$MINC files created on smaller OST $MINI1"
13232         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
13233                awk '/'$MAXI1': / {print $2; exit}')
13234         echo $UUID
13235         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
13236         echo "$MAXC files created on larger OST $MAXI1"
13237         if [[ $MINC -gt 0 ]]; then
13238                 FILL=$((MAXC * 100 / MINC - 100))
13239                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
13240         fi
13241         [[ $MAXC -gt $MINC ]] ||
13242                 error_ignore LU-9 "stripe QOS didn't balance free space"
13243 }
13244 run_test 116a "stripe QOS: free space balance ==================="
13245
13246 test_116b() { # LU-2093
13247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13248         remote_mds_nodsh && skip "remote MDS with nodsh"
13249
13250 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
13251         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
13252                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
13253         [ -z "$old_rr" ] && skip "no QOS"
13254         do_facet $SINGLEMDS lctl set_param \
13255                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
13256         mkdir -p $DIR/$tdir
13257         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
13258         createmany -o $DIR/$tdir/f- 20 || error "can't create"
13259         do_facet $SINGLEMDS lctl set_param fail_loc=0
13260         rm -rf $DIR/$tdir
13261         do_facet $SINGLEMDS lctl set_param \
13262                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
13263 }
13264 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
13265
13266 test_117() # bug 10891
13267 {
13268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13269
13270         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
13271         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
13272         lctl set_param fail_loc=0x21e
13273         > $DIR/$tfile || error "truncate failed"
13274         lctl set_param fail_loc=0
13275         echo "Truncate succeeded."
13276         rm -f $DIR/$tfile
13277 }
13278 run_test 117 "verify osd extend =========="
13279
13280 NO_SLOW_RESENDCOUNT=4
13281 export OLD_RESENDCOUNT=""
13282 set_resend_count () {
13283         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
13284         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
13285         lctl set_param -n $PROC_RESENDCOUNT $1
13286         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
13287 }
13288
13289 # for reduce test_118* time (b=14842)
13290 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13291
13292 # Reset async IO behavior after error case
13293 reset_async() {
13294         FILE=$DIR/reset_async
13295
13296         # Ensure all OSCs are cleared
13297         $LFS setstripe -c -1 $FILE
13298         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
13299         sync
13300         rm $FILE
13301 }
13302
13303 test_118a() #bug 11710
13304 {
13305         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13306
13307         reset_async
13308
13309         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13310         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13311         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13312
13313         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13314                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13315                 return 1;
13316         fi
13317         rm -f $DIR/$tfile
13318 }
13319 run_test 118a "verify O_SYNC works =========="
13320
13321 test_118b()
13322 {
13323         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13324         remote_ost_nodsh && skip "remote OST with nodsh"
13325
13326         reset_async
13327
13328         #define OBD_FAIL_SRV_ENOENT 0x217
13329         set_nodes_failloc "$(osts_nodes)" 0x217
13330         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13331         RC=$?
13332         set_nodes_failloc "$(osts_nodes)" 0
13333         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13334         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13335                     grep -c writeback)
13336
13337         if [[ $RC -eq 0 ]]; then
13338                 error "Must return error due to dropped pages, rc=$RC"
13339                 return 1;
13340         fi
13341
13342         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13343                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13344                 return 1;
13345         fi
13346
13347         echo "Dirty pages not leaked on ENOENT"
13348
13349         # Due to the above error the OSC will issue all RPCs syncronously
13350         # until a subsequent RPC completes successfully without error.
13351         $MULTIOP $DIR/$tfile Ow4096yc
13352         rm -f $DIR/$tfile
13353
13354         return 0
13355 }
13356 run_test 118b "Reclaim dirty pages on fatal error =========="
13357
13358 test_118c()
13359 {
13360         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13361
13362         # for 118c, restore the original resend count, LU-1940
13363         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
13364                                 set_resend_count $OLD_RESENDCOUNT
13365         remote_ost_nodsh && skip "remote OST with nodsh"
13366
13367         reset_async
13368
13369         #define OBD_FAIL_OST_EROFS               0x216
13370         set_nodes_failloc "$(osts_nodes)" 0x216
13371
13372         # multiop should block due to fsync until pages are written
13373         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13374         MULTIPID=$!
13375         sleep 1
13376
13377         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13378                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13379         fi
13380
13381         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13382                     grep -c writeback)
13383         if [[ $WRITEBACK -eq 0 ]]; then
13384                 error "No page in writeback, writeback=$WRITEBACK"
13385         fi
13386
13387         set_nodes_failloc "$(osts_nodes)" 0
13388         wait $MULTIPID
13389         RC=$?
13390         if [[ $RC -ne 0 ]]; then
13391                 error "Multiop fsync failed, rc=$RC"
13392         fi
13393
13394         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13395         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13396                     grep -c writeback)
13397         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13398                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13399         fi
13400
13401         rm -f $DIR/$tfile
13402         echo "Dirty pages flushed via fsync on EROFS"
13403         return 0
13404 }
13405 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
13406
13407 # continue to use small resend count to reduce test_118* time (b=14842)
13408 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13409
13410 test_118d()
13411 {
13412         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13413         remote_ost_nodsh && skip "remote OST with nodsh"
13414
13415         reset_async
13416
13417         #define OBD_FAIL_OST_BRW_PAUSE_BULK
13418         set_nodes_failloc "$(osts_nodes)" 0x214
13419         # multiop should block due to fsync until pages are written
13420         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13421         MULTIPID=$!
13422         sleep 1
13423
13424         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13425                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13426         fi
13427
13428         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13429                     grep -c writeback)
13430         if [[ $WRITEBACK -eq 0 ]]; then
13431                 error "No page in writeback, writeback=$WRITEBACK"
13432         fi
13433
13434         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
13435         set_nodes_failloc "$(osts_nodes)" 0
13436
13437         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13438         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13439                     grep -c writeback)
13440         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13441                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13442         fi
13443
13444         rm -f $DIR/$tfile
13445         echo "Dirty pages gaurenteed flushed via fsync"
13446         return 0
13447 }
13448 run_test 118d "Fsync validation inject a delay of the bulk =========="
13449
13450 test_118f() {
13451         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13452
13453         reset_async
13454
13455         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
13456         lctl set_param fail_loc=0x8000040a
13457
13458         # Should simulate EINVAL error which is fatal
13459         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13460         RC=$?
13461         if [[ $RC -eq 0 ]]; then
13462                 error "Must return error due to dropped pages, rc=$RC"
13463         fi
13464
13465         lctl set_param fail_loc=0x0
13466
13467         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13468         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13469         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13470                     grep -c writeback)
13471         if [[ $LOCKED -ne 0 ]]; then
13472                 error "Locked pages remain in cache, locked=$LOCKED"
13473         fi
13474
13475         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13476                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13477         fi
13478
13479         rm -f $DIR/$tfile
13480         echo "No pages locked after fsync"
13481
13482         reset_async
13483         return 0
13484 }
13485 run_test 118f "Simulate unrecoverable OSC side error =========="
13486
13487 test_118g() {
13488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13489
13490         reset_async
13491
13492         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
13493         lctl set_param fail_loc=0x406
13494
13495         # simulate local -ENOMEM
13496         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13497         RC=$?
13498
13499         lctl set_param fail_loc=0
13500         if [[ $RC -eq 0 ]]; then
13501                 error "Must return error due to dropped pages, rc=$RC"
13502         fi
13503
13504         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13505         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13506         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13507                         grep -c writeback)
13508         if [[ $LOCKED -ne 0 ]]; then
13509                 error "Locked pages remain in cache, locked=$LOCKED"
13510         fi
13511
13512         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13513                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13514         fi
13515
13516         rm -f $DIR/$tfile
13517         echo "No pages locked after fsync"
13518
13519         reset_async
13520         return 0
13521 }
13522 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
13523
13524 test_118h() {
13525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13526         remote_ost_nodsh && skip "remote OST with nodsh"
13527
13528         reset_async
13529
13530         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13531         set_nodes_failloc "$(osts_nodes)" 0x20e
13532         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13533         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13534         RC=$?
13535
13536         set_nodes_failloc "$(osts_nodes)" 0
13537         if [[ $RC -eq 0 ]]; then
13538                 error "Must return error due to dropped pages, rc=$RC"
13539         fi
13540
13541         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13542         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13543         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13544                     grep -c writeback)
13545         if [[ $LOCKED -ne 0 ]]; then
13546                 error "Locked pages remain in cache, locked=$LOCKED"
13547         fi
13548
13549         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13550                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13551         fi
13552
13553         rm -f $DIR/$tfile
13554         echo "No pages locked after fsync"
13555
13556         return 0
13557 }
13558 run_test 118h "Verify timeout in handling recoverables errors  =========="
13559
13560 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13561
13562 test_118i() {
13563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13564         remote_ost_nodsh && skip "remote OST with nodsh"
13565
13566         reset_async
13567
13568         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13569         set_nodes_failloc "$(osts_nodes)" 0x20e
13570
13571         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13572         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13573         PID=$!
13574         sleep 5
13575         set_nodes_failloc "$(osts_nodes)" 0
13576
13577         wait $PID
13578         RC=$?
13579         if [[ $RC -ne 0 ]]; then
13580                 error "got error, but should be not, rc=$RC"
13581         fi
13582
13583         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13584         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13585         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13586         if [[ $LOCKED -ne 0 ]]; then
13587                 error "Locked pages remain in cache, locked=$LOCKED"
13588         fi
13589
13590         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13591                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13592         fi
13593
13594         rm -f $DIR/$tfile
13595         echo "No pages locked after fsync"
13596
13597         return 0
13598 }
13599 run_test 118i "Fix error before timeout in recoverable error  =========="
13600
13601 [ "$SLOW" = "no" ] && set_resend_count 4
13602
13603 test_118j() {
13604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13605         remote_ost_nodsh && skip "remote OST with nodsh"
13606
13607         reset_async
13608
13609         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
13610         set_nodes_failloc "$(osts_nodes)" 0x220
13611
13612         # return -EIO from OST
13613         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13614         RC=$?
13615         set_nodes_failloc "$(osts_nodes)" 0x0
13616         if [[ $RC -eq 0 ]]; then
13617                 error "Must return error due to dropped pages, rc=$RC"
13618         fi
13619
13620         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13621         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13622         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13623         if [[ $LOCKED -ne 0 ]]; then
13624                 error "Locked pages remain in cache, locked=$LOCKED"
13625         fi
13626
13627         # in recoverable error on OST we want resend and stay until it finished
13628         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13629                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13630         fi
13631
13632         rm -f $DIR/$tfile
13633         echo "No pages locked after fsync"
13634
13635         return 0
13636 }
13637 run_test 118j "Simulate unrecoverable OST side error =========="
13638
13639 test_118k()
13640 {
13641         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13642         remote_ost_nodsh && skip "remote OSTs with nodsh"
13643
13644         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13645         set_nodes_failloc "$(osts_nodes)" 0x20e
13646         test_mkdir $DIR/$tdir
13647
13648         for ((i=0;i<10;i++)); do
13649                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
13650                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
13651                 SLEEPPID=$!
13652                 sleep 0.500s
13653                 kill $SLEEPPID
13654                 wait $SLEEPPID
13655         done
13656
13657         set_nodes_failloc "$(osts_nodes)" 0
13658         rm -rf $DIR/$tdir
13659 }
13660 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
13661
13662 test_118l() # LU-646
13663 {
13664         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13665
13666         test_mkdir $DIR/$tdir
13667         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
13668         rm -rf $DIR/$tdir
13669 }
13670 run_test 118l "fsync dir"
13671
13672 test_118m() # LU-3066
13673 {
13674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13675
13676         test_mkdir $DIR/$tdir
13677         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
13678         rm -rf $DIR/$tdir
13679 }
13680 run_test 118m "fdatasync dir ========="
13681
13682 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13683
13684 test_118n()
13685 {
13686         local begin
13687         local end
13688
13689         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13690         remote_ost_nodsh && skip "remote OSTs with nodsh"
13691
13692         # Sleep to avoid a cached response.
13693         #define OBD_STATFS_CACHE_SECONDS 1
13694         sleep 2
13695
13696         # Inject a 10 second delay in the OST_STATFS handler.
13697         #define OBD_FAIL_OST_STATFS_DELAY 0x242
13698         set_nodes_failloc "$(osts_nodes)" 0x242
13699
13700         begin=$SECONDS
13701         stat --file-system $MOUNT > /dev/null
13702         end=$SECONDS
13703
13704         set_nodes_failloc "$(osts_nodes)" 0
13705
13706         if ((end - begin > 20)); then
13707             error "statfs took $((end - begin)) seconds, expected 10"
13708         fi
13709 }
13710 run_test 118n "statfs() sends OST_STATFS requests in parallel"
13711
13712 test_119a() # bug 11737
13713 {
13714         BSIZE=$((512 * 1024))
13715         directio write $DIR/$tfile 0 1 $BSIZE
13716         # We ask to read two blocks, which is more than a file size.
13717         # directio will indicate an error when requested and actual
13718         # sizes aren't equeal (a normal situation in this case) and
13719         # print actual read amount.
13720         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
13721         if [ "$NOB" != "$BSIZE" ]; then
13722                 error "read $NOB bytes instead of $BSIZE"
13723         fi
13724         rm -f $DIR/$tfile
13725 }
13726 run_test 119a "Short directIO read must return actual read amount"
13727
13728 test_119b() # bug 11737
13729 {
13730         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13731
13732         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
13733         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
13734         sync
13735         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
13736                 error "direct read failed"
13737         rm -f $DIR/$tfile
13738 }
13739 run_test 119b "Sparse directIO read must return actual read amount"
13740
13741 test_119c() # bug 13099
13742 {
13743         BSIZE=1048576
13744         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
13745         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
13746         rm -f $DIR/$tfile
13747 }
13748 run_test 119c "Testing for direct read hitting hole"
13749
13750 # Note: test 119d was removed, skipping 119d for new tests to avoid polluting
13751 # Maloo test history
13752
13753 test_119e()
13754 {
13755         (( $MDS1_VERSION >= $(version_code 2.15.58) )) ||
13756                 skip "Need server version at least 2.15.58"
13757         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13758
13759         local stripe_size=$((1024 * 1024)) #1 MiB
13760         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13761         local file_size=$((25 * stripe_size))
13762         local bsizes
13763
13764         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13765         stack_trap "rm -f $DIR/$tfile*"
13766
13767         # Just a bit bigger than the largest size in the test set below
13768         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13769                 error "buffered i/o to create file failed"
13770
13771         # trivial test of unaligned DIO
13772         dd if=$DIR/$tfile.1 bs=4095 of=$DIR/$tfile.2 count=4 \
13773                 iflag=direct oflag=direct ||
13774                 error "trivial unaligned dio failed"
13775
13776         # Test of disabling unaligned DIO support
13777         $LCTL set_param llite.*.unaligned_dio=0
13778         stack_trap "$LCTL set_param llite.*.unaligned_dio=1"
13779         echo "testing disabling unaligned DIO - 'invalid argument' expected:"
13780         dd if=$DIR/$tfile.1 bs=1024 of=$DIR/$tfile.2 count=4 \
13781                 iflag=direct oflag=direct &&
13782                 error "unaligned dio succeeded when disabled"
13783         $LCTL set_param llite.*.unaligned_dio=1
13784
13785         # Clean up before next part of test
13786         rm -f $DIR/$tfile.2
13787
13788         if zfs_or_rotational; then
13789                 # DIO on ZFS can take up to 2 seconds per IO
13790                 # rotational is better, but still slow.
13791                 # Limit testing on those media to larger sizes
13792                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13793                         $((stripe_size + 1024))"
13794         else
13795                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13796                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13797                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13798                         $((stripe_size - 1)) $stripe_size \
13799                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13800                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13801         fi
13802
13803         for bs in $bsizes; do
13804                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13805                 echo "Read/write with DIO at size $bs"
13806                 # Read and write with DIO from source to dest
13807                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 \
13808                         iflag=direct oflag=direct ||
13809                         error "dio failed"
13810
13811                 ls -la $DIR/$tfile.1 $DIR/$tfile.2
13812                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13813                         error "size incorrect, file copy read/write bsize: $bs"
13814                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13815                         error "files differ, bsize $bs"
13816                 rm -f $DIR/$tfile.2
13817         done
13818 }
13819 run_test 119e "Basic tests of dio read and write at various sizes"
13820
13821 test_119f()
13822 {
13823         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13824
13825         local stripe_size=$((1024 * 1024)) #1 MiB
13826         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13827         local file_size=$((25 * stripe_size))
13828         local bsizes
13829
13830         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13831         stack_trap "rm -f $DIR/$tfile*"
13832
13833         # Just a bit bigger than the largest size in the test set below
13834         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13835                 error "buffered i/o to create file failed"
13836
13837         if zfs_or_rotational; then
13838                 # DIO on ZFS can take up to 2 seconds per IO
13839                 # rotational is better, but still slow.
13840                 # Limit testing on those media to larger sizes
13841                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13842                         $((stripe_size + 1024))"
13843         else
13844                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13845                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13846                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13847                         $((stripe_size - 1)) $stripe_size \
13848                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13849                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13850         fi
13851
13852         for bs in $bsizes; do
13853                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13854                 # Read and write with DIO from source to dest in two
13855                 # threads - should give correct copy of file
13856
13857                 echo "bs: $bs"
13858                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13859                         oflag=direct conv=notrunc &
13860                 pid_dio1=$!
13861                 # Note block size is different here for a more interesting race
13862                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
13863                         iflag=direct oflag=direct conv=notrunc &
13864                 pid_dio2=$!
13865                 wait $pid_dio1
13866                 rc1=$?
13867                 wait $pid_dio2
13868                 rc2=$?
13869                 if (( rc1 != 0 )); then
13870                         error "dio copy 1 w/bsize $bs failed: $rc1"
13871                 fi
13872                 if (( rc2 != 0 )); then
13873                         error "dio copy 2 w/bsize $bs failed: $rc2"
13874                 fi
13875
13876
13877                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13878                         error "size incorrect, file copy read/write bsize: $bs"
13879                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13880                         error "files differ, bsize $bs"
13881                 rm -f $DIR/$tfile.2
13882         done
13883 }
13884 run_test 119f "dio vs dio race"
13885
13886 test_119g()
13887 {
13888         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13889
13890         local stripe_size=$((1024 * 1024)) #1 MiB
13891         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13892         local file_size=$((25 * stripe_size))
13893         local bsizes
13894
13895         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13896         stack_trap "rm -f $DIR/$tfile*"
13897
13898         # Just a bit bigger than the largest size in the test set below
13899         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13900                 error "buffered i/o to create file failed"
13901
13902         if zfs_or_rotational; then
13903                 # DIO on ZFS can take up to 2 seconds per IO
13904                 # rotational is better, but still slow.
13905                 # Limit testing on those media to larger sizes
13906                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13907                         $((stripe_size + 1024))"
13908         else
13909                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13910                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13911                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13912                         $((stripe_size - 1)) $stripe_size \
13913                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13914                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13915         fi
13916
13917         for bs in $bsizes; do
13918                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13919                 echo "bs: $bs"
13920                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13921                         oflag=direct conv=notrunc &
13922                 pid_dio1=$!
13923                 # Buffered I/O with similar but not the same block size
13924                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 &
13925                 pid_bio2=$!
13926                 wait $pid_dio1
13927                 rc1=$?
13928                 wait $pid_bio2
13929                 rc2=$?
13930                 if (( rc1 != 0 )); then
13931                         error "dio copy 1 w/bsize $bs failed: $rc1"
13932                 fi
13933                 if (( rc2 != 0 )); then
13934                         error "buffered copy 2 w/bsize $bs failed: $rc2"
13935                 fi
13936
13937                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13938                         error "size incorrect"
13939                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13940                         error "files differ, bsize $bs"
13941                 rm -f $DIR/$tfile.2
13942         done
13943 }
13944 run_test 119g "dio vs buffered I/O race"
13945
13946 test_119h()
13947 {
13948         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13949
13950         local stripe_size=$((1024 * 1024)) #1 MiB
13951         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13952         local file_size=$((25 * stripe_size))
13953         local bsizes
13954
13955         stack_trap "rm -f $DIR/$tfile.*"
13956
13957         if zfs_or_rotational; then
13958                 # DIO on ZFS can take up to 2 seconds per IO
13959                 # rotational is better, but still slow.
13960                 # Limit testing on those media to larger sizes
13961                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13962                         $((stripe_size + 1024))"
13963         else
13964                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13965                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13966                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13967                         $((stripe_size - 1)) $stripe_size \
13968                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13969                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13970         fi
13971
13972         for bs in $bsizes; do
13973                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13974                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13975                 echo "unaligned writes of blocksize: $bs"
13976                 # Write a file with unaligned DIO and regular DIO, and compare
13977                 # them
13978                 # with 'u', multiop randomly unaligns the io from the buffer
13979                 $MULTIOP $DIR/$tfile.1 \
13980                 oO_CREAT:O_RDWR:O_DIRECT:wu${bs}wu${bs}wu${bs}wu${bs}wu${bs} ||
13981                         error "multiop memory unaligned write failed, $bs"
13982                 $MULTIOP $DIR/$tfile.2 \
13983                 oO_CREAT:O_RDWR:O_DIRECT:w${bs}w${bs}w${bs}w${bs}w${bs} ||
13984                         error "multiop memory aligned write failed, $bs"
13985
13986                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13987                         error "files differ, bsize $bs"
13988                 rm -f $DIR/$tfile.*
13989         done
13990
13991         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13992         dd if=/dev/zero bs=$((stripe_size * 5)) of=$DIR/$tfile.1 count=5 ||
13993                 error "dd to create source file for read failed"
13994
13995         # Just a few quick tests to make sure unaligned DIO reads don't crash
13996         for bs in $bsizes; do
13997
13998                 echo "unaligned reads of blocksize: $bs"
13999                 # with 'u', multiop randomly unaligns the io from the buffer
14000                 $MULTIOP $DIR/$tfile.1 \
14001                 oO_CREAT:O_RDWR:O_DIRECT:ru${bs}ru${bs}ru${bs}ru${bs}ru${bs} ||
14002                         error "multiop memory unaligned read failed, $bs"
14003
14004         done
14005         rm -f $DIR/$tfile*
14006 }
14007 run_test 119h "basic tests of memory unaligned dio"
14008
14009 # aiocp with the '-a' option makes testing memory unaligned aio trivial
14010 test_119i()
14011 {
14012         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14013         which aiocp || skip_env "no aiocp installed"
14014
14015         local stripe_size=$((1024 * 1024)) #1 MiB
14016         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
14017         local file_size=$((25 * stripe_size))
14018         local bsizes
14019
14020         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
14021         stack_trap "rm -f $DIR/$tfile.*"
14022
14023         # Just a bit bigger than the largest size in the test set below
14024         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
14025                 error "buffered i/o to create file failed"
14026
14027         if zfs_or_rotational; then
14028                 # DIO on ZFS can take up to 2 seconds per IO
14029                 # rotational is better, but still slow.
14030                 # Limit testing on those media to larger sizes
14031                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
14032                         $((stripe_size + 1024))"
14033         else
14034                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
14035                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
14036                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
14037                         $((stripe_size - 1)) $stripe_size \
14038                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
14039                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
14040         fi
14041
14042         # Do page aligned and NOT page aligned AIO
14043         for align in 8 512 $((PAGE_SIZE)); do
14044         # Deliberately includes a few aligned sizes
14045         for bs in $bsizes; do
14046                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
14047
14048                 echo "bs: $bs, align: $align, file_size $file_size"
14049                 aiocp -a $align -b $bs -s $file_size -f O_DIRECT \
14050                         $DIR/$tfile.1 $DIR/$tfile.2 ||
14051                         error "unaligned aio failed, bs: $bs, align: $align"
14052
14053                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
14054                         error "size incorrect"
14055                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
14056                         error "files differ"
14057                 rm -f $DIR/$tfile.2
14058         done
14059         done
14060 }
14061 run_test 119i "test unaligned aio at varying sizes"
14062
14063 test_120a() {
14064         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14065         remote_mds_nodsh && skip "remote MDS with nodsh"
14066         test_mkdir -i0 -c1 $DIR/$tdir
14067         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14068                 skip_env "no early lock cancel on server"
14069
14070         lru_resize_disable mdc
14071         lru_resize_disable osc
14072         cancel_lru_locks mdc
14073         # asynchronous object destroy at MDT could cause bl ast to client
14074         cancel_lru_locks osc
14075
14076         stat $DIR/$tdir > /dev/null
14077         can1=$(do_facet mds1 \
14078                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14079                awk '/ldlm_cancel/ {print $2}')
14080         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14081                awk '/ldlm_bl_callback/ {print $2}')
14082         test_mkdir -i0 -c1 $DIR/$tdir/d1
14083         can2=$(do_facet mds1 \
14084                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14085                awk '/ldlm_cancel/ {print $2}')
14086         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14087                awk '/ldlm_bl_callback/ {print $2}')
14088         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14089         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14090         lru_resize_enable mdc
14091         lru_resize_enable osc
14092 }
14093 run_test 120a "Early Lock Cancel: mkdir test"
14094
14095 test_120b() {
14096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14097         remote_mds_nodsh && skip "remote MDS with nodsh"
14098         test_mkdir $DIR/$tdir
14099         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14100                 skip_env "no early lock cancel on server"
14101
14102         lru_resize_disable mdc
14103         lru_resize_disable osc
14104         cancel_lru_locks mdc
14105         stat $DIR/$tdir > /dev/null
14106         can1=$(do_facet $SINGLEMDS \
14107                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14108                awk '/ldlm_cancel/ {print $2}')
14109         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14110                awk '/ldlm_bl_callback/ {print $2}')
14111         touch $DIR/$tdir/f1
14112         can2=$(do_facet $SINGLEMDS \
14113                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14114                awk '/ldlm_cancel/ {print $2}')
14115         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14116                awk '/ldlm_bl_callback/ {print $2}')
14117         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14118         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14119         lru_resize_enable mdc
14120         lru_resize_enable osc
14121 }
14122 run_test 120b "Early Lock Cancel: create test"
14123
14124 test_120c() {
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 "no early lock cancel on server"
14130
14131         lru_resize_disable mdc
14132         lru_resize_disable osc
14133         test_mkdir -i0 -c1 $DIR/$tdir/d1
14134         test_mkdir -i0 -c1 $DIR/$tdir/d2
14135         touch $DIR/$tdir/d1/f1
14136         cancel_lru_locks mdc
14137         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /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         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
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 120c "Early Lock Cancel: link test"
14155
14156 test_120d() {
14157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14158         remote_mds_nodsh && skip "remote MDS with nodsh"
14159         test_mkdir -i0 -c1 $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         touch $DIR/$tdir
14166         cancel_lru_locks mdc
14167         stat $DIR/$tdir > /dev/null
14168         can1=$(do_facet mds1 \
14169                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14170                awk '/ldlm_cancel/ {print $2}')
14171         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14172                awk '/ldlm_bl_callback/ {print $2}')
14173         chmod a+x $DIR/$tdir
14174         can2=$(do_facet mds1 \
14175                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14176                awk '/ldlm_cancel/ {print $2}')
14177         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14178                awk '/ldlm_bl_callback/ {print $2}')
14179         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14180         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14181         lru_resize_enable mdc
14182         lru_resize_enable osc
14183 }
14184 run_test 120d "Early Lock Cancel: setattr test"
14185
14186 test_120e() {
14187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14188         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14189                 skip_env "no early lock cancel on server"
14190         remote_mds_nodsh && skip "remote MDS with nodsh"
14191
14192         local dlmtrace_set=false
14193
14194         test_mkdir -i0 -c1 $DIR/$tdir
14195         lru_resize_disable mdc
14196         lru_resize_disable osc
14197         ! $LCTL get_param debug | grep -q dlmtrace &&
14198                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
14199         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
14200         cancel_lru_locks mdc
14201         cancel_lru_locks osc
14202         dd if=$DIR/$tdir/f1 of=/dev/null
14203         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
14204         # XXX client can not do early lock cancel of OST lock
14205         # during unlink (LU-4206), so cancel osc lock now.
14206         sleep 2
14207         cancel_lru_locks osc
14208         can1=$(do_facet mds1 \
14209                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14210                awk '/ldlm_cancel/ {print $2}')
14211         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14212                awk '/ldlm_bl_callback/ {print $2}')
14213         unlink $DIR/$tdir/f1
14214         sleep 5
14215         can2=$(do_facet mds1 \
14216                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14217                awk '/ldlm_cancel/ {print $2}')
14218         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14219                awk '/ldlm_bl_callback/ {print $2}')
14220         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
14221                 $LCTL dk $TMP/cancel.debug.txt
14222         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
14223                 $LCTL dk $TMP/blocking.debug.txt
14224         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
14225         lru_resize_enable mdc
14226         lru_resize_enable osc
14227 }
14228 run_test 120e "Early Lock Cancel: unlink test"
14229
14230 test_120f() {
14231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14232         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14233                 skip_env "no early lock cancel on server"
14234         remote_mds_nodsh && skip "remote MDS with nodsh"
14235
14236         test_mkdir -i0 -c1 $DIR/$tdir
14237         lru_resize_disable mdc
14238         lru_resize_disable osc
14239         test_mkdir -i0 -c1 $DIR/$tdir/d1
14240         test_mkdir -i0 -c1 $DIR/$tdir/d2
14241         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
14242         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
14243         cancel_lru_locks mdc
14244         cancel_lru_locks osc
14245         dd if=$DIR/$tdir/d1/f1 of=/dev/null
14246         dd if=$DIR/$tdir/d2/f2 of=/dev/null
14247         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
14248         # XXX client can not do early lock cancel of OST lock
14249         # during rename (LU-4206), so cancel osc lock now.
14250         sleep 2
14251         cancel_lru_locks osc
14252         can1=$(do_facet mds1 \
14253                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14254                awk '/ldlm_cancel/ {print $2}')
14255         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14256                awk '/ldlm_bl_callback/ {print $2}')
14257         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
14258         sleep 5
14259         can2=$(do_facet mds1 \
14260                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14261                awk '/ldlm_cancel/ {print $2}')
14262         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14263                awk '/ldlm_bl_callback/ {print $2}')
14264         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14265         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14266         lru_resize_enable mdc
14267         lru_resize_enable osc
14268 }
14269 run_test 120f "Early Lock Cancel: rename test"
14270
14271 test_120g() {
14272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14273         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14274                 skip_env "no early lock cancel on server"
14275         remote_mds_nodsh && skip "remote MDS with nodsh"
14276
14277         lru_resize_disable mdc
14278         lru_resize_disable osc
14279         count=10000
14280         echo create $count files
14281         test_mkdir $DIR/$tdir
14282         cancel_lru_locks mdc
14283         cancel_lru_locks osc
14284         t0=$(date +%s)
14285
14286         can0=$(do_facet $SINGLEMDS \
14287                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14288                awk '/ldlm_cancel/ {print $2}')
14289         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14290                awk '/ldlm_bl_callback/ {print $2}')
14291         createmany -o $DIR/$tdir/f $count
14292         sync
14293         can1=$(do_facet $SINGLEMDS \
14294                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14295                awk '/ldlm_cancel/ {print $2}')
14296         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14297                awk '/ldlm_bl_callback/ {print $2}')
14298         t1=$(date +%s)
14299         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
14300         echo rm $count files
14301         rm -r $DIR/$tdir
14302         sync
14303         can2=$(do_facet $SINGLEMDS \
14304                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14305                awk '/ldlm_cancel/ {print $2}')
14306         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14307                awk '/ldlm_bl_callback/ {print $2}')
14308         t2=$(date +%s)
14309         echo total: $count removes in $((t2-t1))
14310         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
14311         sleep 2
14312         # wait for commitment of removal
14313         lru_resize_enable mdc
14314         lru_resize_enable osc
14315 }
14316 run_test 120g "Early Lock Cancel: performance test"
14317
14318 test_121() { #bug #10589
14319         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14320
14321         rm -rf $DIR/$tfile
14322         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
14323 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
14324         lctl set_param fail_loc=0x310
14325         cancel_lru_locks osc > /dev/null
14326         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
14327         lctl set_param fail_loc=0
14328         [[ $reads -eq $writes ]] ||
14329                 error "read $reads blocks, must be $writes blocks"
14330 }
14331 run_test 121 "read cancel race ========="
14332
14333 test_123a_base() { # was test 123, statahead(bug 11401)
14334         local lsx="$1"
14335
14336         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
14337
14338         SLOWOK=0
14339         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
14340                 log "testing UP system. Performance may be lower than expected."
14341                 SLOWOK=1
14342         fi
14343         running_in_vm && SLOWOK=1
14344
14345         $LCTL set_param mdc.*.batch_stats=0
14346
14347         rm -rf $DIR/$tdir
14348         test_mkdir $DIR/$tdir
14349         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
14350         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
14351         MULT=10
14352         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
14353                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
14354
14355                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
14356                 lctl set_param -n llite.*.statahead_max 0
14357                 lctl get_param llite.*.statahead_max
14358                 cancel_lru_locks mdc
14359                 cancel_lru_locks osc
14360                 stime=$(date +%s)
14361                 time $lsx $DIR/$tdir | wc -l
14362                 etime=$(date +%s)
14363                 delta=$((etime - stime))
14364                 log "$lsx $i files without statahead: $delta sec"
14365                 lctl set_param llite.*.statahead_max=$max
14366
14367                 swrong=$(lctl get_param -n llite.*.statahead_stats |
14368                          awk '/statahead.wrong:/ { print $NF }')
14369                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
14370                 cancel_lru_locks mdc
14371                 cancel_lru_locks osc
14372                 stime=$(date +%s)
14373                 time $lsx $DIR/$tdir | wc -l
14374                 etime=$(date +%s)
14375                 delta_sa=$((etime - stime))
14376                 log "$lsx $i files with statahead: $delta_sa sec"
14377                 lctl get_param -n llite.*.statahead_stats
14378                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
14379                          awk '/statahead.wrong:/ { print $NF }')
14380
14381                 [[ $swrong -lt $ewrong ]] &&
14382                         log "statahead was stopped, maybe too many locks held!"
14383                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
14384
14385                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
14386                         max=$(lctl get_param -n llite.*.statahead_max |
14387                                 head -n 1)
14388                         lctl set_param -n llite.*.statahead_max 0
14389                         lctl get_param llite.*.statahead_max
14390                         cancel_lru_locks mdc
14391                         cancel_lru_locks osc
14392                         stime=$(date +%s)
14393                         time $lsx $DIR/$tdir | wc -l
14394                         etime=$(date +%s)
14395                         delta=$((etime - stime))
14396                         log "$lsx $i files again without statahead: $delta sec"
14397                         lctl set_param llite.*.statahead_max=$max
14398                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
14399                                 if [ $SLOWOK -eq 0 ]; then
14400                                         error "$lsx $i files is slower with statahead!"
14401                                 else
14402                                         log "$lsx $i files is slower with statahead!"
14403                                 fi
14404                                 break
14405                         fi
14406                 fi
14407
14408                 [ $delta -gt 20 ] && break
14409                 [ $delta -gt 8 ] && MULT=$((50 / delta))
14410                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
14411         done
14412         log "$lsx done"
14413
14414         stime=$(date +%s)
14415         rm -r $DIR/$tdir
14416         sync
14417         etime=$(date +%s)
14418         delta=$((etime - stime))
14419         log "rm -r $DIR/$tdir/: $delta seconds"
14420         log "rm done"
14421         lctl get_param -n llite.*.statahead_stats
14422         $LCTL get_param mdc.*.batch_stats
14423 }
14424
14425 test_123aa() {
14426         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14427
14428         test_123a_base "ls -l"
14429 }
14430 run_test 123aa "verify statahead work"
14431
14432 test_123ab() {
14433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14434
14435         statx_supported || skip_env "Test must be statx() syscall supported"
14436
14437         test_123a_base "$STATX -l"
14438 }
14439 run_test 123ab "verify statahead work by using statx"
14440
14441 test_123ac() {
14442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14443
14444         statx_supported || skip_env "Test must be statx() syscall supported"
14445
14446         local rpcs_before
14447         local rpcs_after
14448         local agl_before
14449         local agl_after
14450
14451         cancel_lru_locks $OSC
14452         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14453         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
14454                      awk '/agl.total:/ { print $NF }')
14455         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
14456         test_123a_base "$STATX --cached=always -D"
14457         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
14458                     awk '/agl.total:/ { print $NF }')
14459         [ $agl_before -eq $agl_after ] ||
14460                 error "Should not trigger AGL thread - $agl_before:$agl_after"
14461         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14462         [ $rpcs_after -eq $rpcs_before ] ||
14463                 error "$STATX should not send glimpse RPCs to $OSC"
14464 }
14465 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
14466
14467 test_batch_statahead() {
14468         local max=$1
14469         local batch_max=$2
14470         local num=10000
14471         local batch_rpcs
14472         local unbatch_rpcs
14473         local hit_total
14474
14475         echo -e "\nbatching: statahead_max=$max statahead_batch_max=$batch_max"
14476         $LCTL set_param mdc.*.batch_stats=0
14477         $LCTL set_param llite.*.statahead_max=$max
14478         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14479         # Verify that batched statahead is faster than one without statahead
14480         test_123a_base "ls -l"
14481
14482         stack_trap "rm -rf $DIR/$tdir" EXIT
14483         mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
14484         createmany -o $DIR/$tdir/$tfile $num || error "failed to create files"
14485
14486         # unbatched statahead
14487         $LCTL set_param llite.*.statahead_batch_max=0
14488         $LCTL set_param llite.*.statahead_stats=clear
14489         $LCTL set_param mdc.*.stats=clear
14490         cancel_lru_locks mdc
14491         cancel_lru_locks osc
14492         time ls -l $DIR/$tdir | wc -l
14493         unbatch_rpcs=$(calc_stats mdc.*.stats ldlm_ibits_enqueue)
14494         wait_update_facet client "pgrep ll_sa" "" 35 ||
14495                 error "ll_sa thread is still running"
14496         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14497                     awk '/hit.total:/ { print $NF }')
14498         # hit ratio should be larger than 75% (7500).
14499         (( $hit_total > 7500 )) ||
14500                 error "unbatched statahead hit count ($hit_total) is too low"
14501
14502         # batched statahead
14503         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14504         $LCTL set_param llite.*.statahead_stats=clear
14505         $LCTL set_param mdc.*.batch_stats=clear
14506         $LCTL set_param mdc.*.stats=clear
14507         cancel_lru_locks mdc
14508         cancel_lru_locks osc
14509         time ls -l $DIR/$tdir | wc -l
14510         batch_rpcs=$(calc_stats mdc.*.stats mds_batch)
14511         # wait for statahead thread to quit and update statahead stats
14512         wait_update_facet client "pgrep ll_sa" "" 35 ||
14513                 error "ll_sa thread is still running"
14514         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14515                     awk '/hit.total:/ { print $NF }')
14516         # hit ratio should be larger than 75% (7500).
14517         (( $hit_total > 7500 )) ||
14518                 error "batched statahead hit count ($hit_total) is too low"
14519
14520         echo "unbatched RPCs: $unbatch_rpcs, batched RPCs: $batch_rpcs"
14521         (( $unbatch_rpcs > $batch_rpcs )) ||
14522                 error "batched statahead does not reduce RPC count"
14523         $LCTL get_param mdc.*.batch_stats
14524 }
14525
14526 test_123ad() {
14527         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14528
14529         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
14530                 skip "Need server version at least 2.15.53"
14531
14532         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14533                 skip "Server does not support batch RPC"
14534
14535         local max
14536         local batch_max
14537
14538         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14539         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14540
14541         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14542         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14543
14544         test_batch_statahead 32 32
14545         test_batch_statahead 2048 256
14546 }
14547 run_test 123ad "Verify batching statahead works correctly"
14548
14549 test_123b () { # statahead(bug 15027)
14550         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14551
14552         test_mkdir $DIR/$tdir
14553         createmany -o $DIR/$tdir/$tfile-%d 1000
14554
14555         cancel_lru_locks mdc
14556         cancel_lru_locks osc
14557
14558 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
14559         lctl set_param fail_loc=0x80000803
14560         ls -lR $DIR/$tdir > /dev/null
14561         log "ls done"
14562         lctl set_param fail_loc=0x0
14563         lctl get_param -n llite.*.statahead_stats
14564         rm -r $DIR/$tdir
14565         sync
14566
14567 }
14568 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
14569
14570 test_123c() {
14571         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
14572
14573         test_mkdir -i 0 -c 1 $DIR/$tdir.0
14574         test_mkdir -i 1 -c 1 $DIR/$tdir.1
14575         touch $DIR/$tdir.1/{1..3}
14576         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
14577
14578         remount_client $MOUNT
14579
14580         $MULTIOP $DIR/$tdir.0 Q
14581
14582         # let statahead to complete
14583         ls -l $DIR/$tdir.0 > /dev/null
14584
14585         testid=$(echo $TESTNAME | tr '_' ' ')
14586         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
14587                 error "statahead warning" || true
14588 }
14589 run_test 123c "Can not initialize inode warning on DNE statahead"
14590
14591 test_123d() {
14592         local num=100
14593         local swrong
14594         local ewrong
14595
14596         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
14597         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
14598                 error "setdirstripe $DIR/$tdir failed"
14599         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
14600         remount_client $MOUNT
14601         $LCTL get_param llite.*.statahead_max
14602         $LCTL set_param llite.*.statahead_stats=0 ||
14603                 error "clear statahead_stats failed"
14604         swrong=$(lctl get_param -n llite.*.statahead_stats |
14605                  awk '/statahead.wrong:/ { print $NF }')
14606         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
14607         # wait for statahead thread finished to update hit/miss stats.
14608         sleep 1
14609         $LCTL get_param -n llite.*.statahead_stats
14610         ewrong=$(lctl get_param -n llite.*.statahead_stats |
14611                  awk '/statahead.wrong:/ { print $NF }')
14612         (( $swrong == $ewrong )) ||
14613                 log "statahead was stopped, maybe too many locks held!"
14614 }
14615 run_test 123d "Statahead on striped directories works correctly"
14616
14617 test_123e() {
14618         local max
14619         local batch_max
14620         local dir=$DIR/$tdir
14621
14622         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14623                 skip "Server does not support batch RPC"
14624
14625         mkdir $dir || error "mkdir $dir failed"
14626         $LFS setstripe -C 32 $dir || error "setstripe $dir failed"
14627         stack_trap "rm -rf $dir"
14628
14629         touch $dir/$tfile.{0..1000} || error "touch 1000 files failed"
14630
14631         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14632         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14633         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14634         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14635
14636         $LCTL set_param llite.*.statahead_max=2048
14637         $LCTL set_param llite.*.statahead_batch_max=1024
14638
14639         ls -l $dir
14640         $LCTL get_param mdc.*.batch_stats
14641         $LCTL get_param llite.*.statahead_*
14642 }
14643 run_test 123e "statahead with large wide striping"
14644
14645 test_123f() {
14646         local max
14647         local batch_max
14648         local dir=$DIR/$tdir
14649
14650         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14651                 skip "Server does not support batch RPC"
14652
14653         mkdir $dir || error "mkdir $dir failed"
14654         $LFS setstripe -C 1000 $dir || error "setstripe $dir failed"
14655         stack_trap "rm -rf $dir"
14656
14657         touch $dir/$tfile.{0..200} || error "touch 200 files failed"
14658
14659         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14660         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14661
14662         $LCTL set_param llite.*.statahead_max=64
14663         $LCTL set_param llite.*.statahead_batch_max=64
14664
14665         ls -l $dir
14666         lctl get_param mdc.*.batch_stats
14667         lctl get_param llite.*.statahead_*
14668
14669         $LCTL set_param llite.*.statahead_max=$max
14670         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14671 }
14672 run_test 123f "Retry mechanism with large wide striping files"
14673
14674 test_123g() {
14675         local dir=$DIR/$tdir
14676         local num=1000
14677
14678         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14679                 skip "Server does not support batch RPC"
14680
14681         mkdir $dir || error "failed to mkdir $dir"
14682         createmany -o $dir/$tfile $num || error "failed creatmany files"
14683         cancel_lru_locks mdc
14684         cancel_lru_locks osc
14685
14686         $LCTL set_param llite.*.statahead_stats=clear
14687         $LCTL set_param mdc.*.batch_stats=clear
14688         aheadmany -c stat -s 0 -e $num -b $tfile -d $dir ||
14689                 error "aheadmany $dir with $tfile failed"
14690         wait_update_facet client "pgrep ll_sa" "" 35 ||
14691                 error "ll_sa thread is still running"
14692         $LCTL get_param -n llite.*.statahead_stats
14693         $LCTL get_param -n mdc.*.batch_stats
14694
14695         local count
14696
14697         count=$($LCTL get_param -n llite.*.statahead_stats |
14698                 awk '/hit.total:/ {print $2}')
14699         echo "Hit total: $count"
14700         # Hit ratio should be >= 75%
14701         (( $count > num * 75 / 100 )) ||
14702                 error "hit total $count is be > 75% of $num"
14703 }
14704 run_test 123g "Test for stat-ahead advise"
14705
14706 test_123h_base() {
14707         local dir=$DIR/$tdir
14708         local cmd="touch $dir/$tfile.{$1}"
14709         local fcnt=$2
14710
14711         stack_trap "rm -rf $dir"
14712         mkdir -p $dir || error "failed to mkdir $dir"
14713         eval $cmd
14714
14715         cancel_lru_locks mdc
14716         $LCTL set_param llite.*.statahead_stats=clear
14717         $LCTL set_param mdc.*.batch_stats=0
14718         $LCTL set_param llite.*.statahead_max=1024
14719         $LCTL set_param llite.*.statahead_batch_max=1024
14720         lctl get_param -n llite.*.statahead_stats
14721         du -a $dir > /dev/null
14722         echo "Wait statahead thread (ll_sa_xxx) to exit..."
14723         wait_update_facet client "pgrep ll_sa" "" 35 ||
14724                 error "ll_sa statahead thread does not quit in 35s"
14725         $LCTL get_param -n llite.*.statahead_stats
14726         $LCTL get_param -n mdc.*.batch_stats
14727
14728         local count=$($LCTL get_param -n llite.*.statahead_stats |
14729                         awk '/fname.total:/ {print $2}')
14730
14731         [ $count == 1 ] || error "File name pattern statahead not trigger"
14732         count=$($LCTL get_param -n llite.*.statahead_stats |
14733                 awk '/hit.total:/ {print $2}')
14734         # Hit ratio should be >= 75%
14735         (( $count > fcnt * 75 / 100 )) ||
14736                 error "hit total is too low: $count"
14737         rm -rf $dir || error "rm -rf $dir failed"
14738 }
14739
14740 test_123h() {
14741         local max
14742         local batch_max
14743         local enabled
14744
14745         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14746                 skip "Server does not support batch RPC"
14747
14748         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14749         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14750         enabled=$($LCTL get_param -n llite.*.enable_statahead_fname | head -n 1)
14751         stack_trap "$LCTL set_param llite.*.statahead_max=$max"
14752         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max"
14753         stack_trap "$LCTL set_param llite.*.enable_statahead_fname=$enabled"
14754
14755         $LCTL set_param llite.*.enable_statahead_fname=1
14756
14757         echo "Scan a directory with number regularized fname"
14758         test_123h_base "0..10000" 10000
14759
14760         echo "Scan a directory with zeroed padding number regularized fname"
14761         test_123h_base "000000..010000" 10000
14762 }
14763 run_test 123h "Verify statahead work with the fname pattern via du"
14764
14765 test_123i_base() {
14766         local fmt=$1
14767         local iocmd=$2
14768         local dir=$DIR/$tdir
14769         local cmd="createmany -m $fmt"
14770
14771         echo "Command:"
14772         echo "- $cmd"
14773         echo "- $iocmd"
14774         stack_trap "unlinkmany $fmt"
14775         mkdir -p $dir || error "failed to mkdir $dir"
14776         eval $cmd
14777
14778         cancel_lru_locks mdc
14779         $LCTL set_param llite.*.statahead_stats=clear
14780         $LCTL set_param mdc.*.batch_stats=0
14781
14782         echo "statahead_stats (Pre):"
14783         lctl get_param -n llite.*.statahead_stats
14784         eval $iocmd || error "$iocmd failed"
14785         echo "statahead_stats (Post):"
14786         $LCTL get_param -n llite.*.statahead_stats
14787         $LCTL get_param -n mdc.*.batch_stats
14788
14789         echo "Wait the statahead thread (ll_sa_xxx) to exit ..."
14790         wait_update_facet client "pgrep ll_sa" "" 35 ||
14791                 error "ll_sa statahead thread does not quit in 35s"
14792         $LCTL get_param -n llite.*.statahead_stats
14793         $LCTL get_param -n mdc.*.batch_stats
14794
14795         local count=$($LCTL get_param -n llite.*.statahead_stats |
14796                         awk '/fname.total:/ {print $2}')
14797
14798         [ $count == 1 ] || error "File name pattern statahead not trigger"
14799         count=$($LCTL get_param -n llite.*.statahead_stats |
14800                 awk '/hit.total:/ {print $2}')
14801         # Hit ratio should be >= 75%
14802         (( $count > 750 )) || error "hit total is too low: $count"
14803 }
14804
14805 test_123i() {
14806         local dir=$DIR/$tdir
14807         local cnt=1000
14808         local max
14809         local batch_max
14810         local enabled
14811         local min
14812
14813         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14814                 skip "Server does not support batch RPC"
14815
14816         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14817         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14818         min=$($LCTL get_param -n llite.*.statahead_min | head -n 1)
14819         enabled=$($LCTL get_param -n llite.*.enable_statahead_fname | head -n 1)
14820         stack_trap "$LCTL set_param llite.*.statahead_max=$max"
14821         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max"
14822         stack_trap "$LCTL set_param llite.*.statahead_min=$min"
14823         stack_trap "$LCTL set_param llite.*.enable_statahead_fname=$enabled"
14824         $LCTL set_param llite.*.statahead_max=1024
14825         $LCTL set_param llite.*.statahead_batch_max=32
14826         $LCTL set_param llite.*.statahead_min=64
14827         $LCTL set_param llite.*.enable_statahead_fname=1
14828
14829         test_123i_base "$dir/$tfile.%06d $cnt" "ls $dir/* > /dev/null"
14830         test_123i_base "$dir/$tfile $cnt" \
14831                 "aheadmany -c stat -N -s 0 -e $cnt -b $tfile -d $dir"
14832 }
14833 run_test 123i "Verify statahead work with the fname indexing pattern"
14834
14835 test_124a() {
14836         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14837         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14838                 skip_env "no lru resize on server"
14839
14840         local NR=2000
14841
14842         test_mkdir $DIR/$tdir
14843
14844         log "create $NR files at $DIR/$tdir"
14845         createmany -o $DIR/$tdir/f $NR ||
14846                 error "failed to create $NR files in $DIR/$tdir"
14847
14848         cancel_lru_locks mdc
14849         ls -l $DIR/$tdir > /dev/null
14850
14851         local NSDIR=""
14852         local LRU_SIZE=0
14853         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
14854                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
14855                 LRU_SIZE=$($LCTL get_param -n $PARAM)
14856                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
14857                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
14858                         log "NSDIR=$NSDIR"
14859                         log "NS=$(basename $NSDIR)"
14860                         break
14861                 fi
14862         done
14863
14864         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
14865                 skip "Not enough cached locks created!"
14866         fi
14867         log "LRU=$LRU_SIZE"
14868
14869         local SLEEP=30
14870
14871         # We know that lru resize allows one client to hold $LIMIT locks
14872         # for 10h. After that locks begin to be killed by client.
14873         local MAX_HRS=10
14874         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
14875         log "LIMIT=$LIMIT"
14876         if [ $LIMIT -lt $LRU_SIZE ]; then
14877                 skip "Limit is too small $LIMIT"
14878         fi
14879
14880         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
14881         # killing locks. Some time was spent for creating locks. This means
14882         # that up to the moment of sleep finish we must have killed some of
14883         # them (10-100 locks). This depends on how fast ther were created.
14884         # Many of them were touched in almost the same moment and thus will
14885         # be killed in groups.
14886         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
14887
14888         # Use $LRU_SIZE_B here to take into account real number of locks
14889         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
14890         local LRU_SIZE_B=$LRU_SIZE
14891         log "LVF=$LVF"
14892         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
14893         log "OLD_LVF=$OLD_LVF"
14894         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
14895
14896         # Let's make sure that we really have some margin. Client checks
14897         # cached locks every 10 sec.
14898         SLEEP=$((SLEEP+20))
14899         log "Sleep ${SLEEP} sec"
14900         local SEC=0
14901         while ((SEC<$SLEEP)); do
14902                 echo -n "..."
14903                 sleep 5
14904                 SEC=$((SEC+5))
14905                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
14906                 echo -n "$LRU_SIZE"
14907         done
14908         echo ""
14909         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
14910         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
14911
14912         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
14913                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
14914                 unlinkmany $DIR/$tdir/f $NR
14915                 return
14916         }
14917
14918         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
14919         log "unlink $NR files at $DIR/$tdir"
14920         unlinkmany $DIR/$tdir/f $NR
14921 }
14922 run_test 124a "lru resize ======================================="
14923
14924 get_max_pool_limit()
14925 {
14926         local limit=$($LCTL get_param \
14927                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
14928         local max=0
14929         for l in $limit; do
14930                 if [[ $l -gt $max ]]; then
14931                         max=$l
14932                 fi
14933         done
14934         echo $max
14935 }
14936
14937 test_124b() {
14938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14939         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14940                 skip_env "no lru resize on server"
14941
14942         LIMIT=$(get_max_pool_limit)
14943
14944         NR=$(($(default_lru_size)*20))
14945         if [[ $NR -gt $LIMIT ]]; then
14946                 log "Limit lock number by $LIMIT locks"
14947                 NR=$LIMIT
14948         fi
14949
14950         IFree=$(mdsrate_inodes_available)
14951         if [ $IFree -lt $NR ]; then
14952                 log "Limit lock number by $IFree inodes"
14953                 NR=$IFree
14954         fi
14955
14956         lru_resize_disable mdc
14957         test_mkdir -p $DIR/$tdir/disable_lru_resize
14958
14959         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
14960         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
14961         cancel_lru_locks mdc
14962         stime=`date +%s`
14963         PID=""
14964         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14965         PID="$PID $!"
14966         sleep 2
14967         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14968         PID="$PID $!"
14969         sleep 2
14970         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14971         PID="$PID $!"
14972         wait $PID
14973         etime=`date +%s`
14974         nolruresize_delta=$((etime-stime))
14975         log "ls -la time: $nolruresize_delta seconds"
14976         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14977         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
14978
14979         lru_resize_enable mdc
14980         test_mkdir -p $DIR/$tdir/enable_lru_resize
14981
14982         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
14983         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
14984         cancel_lru_locks mdc
14985         stime=`date +%s`
14986         PID=""
14987         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14988         PID="$PID $!"
14989         sleep 2
14990         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14991         PID="$PID $!"
14992         sleep 2
14993         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14994         PID="$PID $!"
14995         wait $PID
14996         etime=`date +%s`
14997         lruresize_delta=$((etime-stime))
14998         log "ls -la time: $lruresize_delta seconds"
14999         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
15000
15001         if [ $lruresize_delta -gt $nolruresize_delta ]; then
15002                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
15003         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
15004                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
15005         else
15006                 log "lru resize performs the same with no lru resize"
15007         fi
15008         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
15009 }
15010 run_test 124b "lru resize (performance test) ======================="
15011
15012 test_124c() {
15013         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15014         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
15015                 skip_env "no lru resize on server"
15016
15017         # cache ununsed locks on client
15018         local nr=100
15019         cancel_lru_locks mdc
15020         test_mkdir $DIR/$tdir
15021         createmany -o $DIR/$tdir/f $nr ||
15022                 error "failed to create $nr files in $DIR/$tdir"
15023         ls -l $DIR/$tdir > /dev/null
15024
15025         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15026         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15027         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
15028         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
15029         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
15030
15031         # set lru_max_age to 1 sec
15032         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
15033         echo "sleep $((recalc_p * 2)) seconds..."
15034         sleep $((recalc_p * 2))
15035
15036         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
15037         # restore lru_max_age
15038         $LCTL set_param -n $nsdir.lru_max_age $max_age
15039         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
15040         unlinkmany $DIR/$tdir/f $nr
15041 }
15042 run_test 124c "LRUR cancel very aged locks"
15043
15044 test_124d() {
15045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15046         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
15047                 skip_env "no lru resize on server"
15048
15049         # cache ununsed locks on client
15050         local nr=100
15051
15052         lru_resize_disable mdc
15053         stack_trap "lru_resize_enable mdc" EXIT
15054
15055         cancel_lru_locks mdc
15056
15057         # asynchronous object destroy at MDT could cause bl ast to client
15058         test_mkdir $DIR/$tdir
15059         createmany -o $DIR/$tdir/f $nr ||
15060                 error "failed to create $nr files in $DIR/$tdir"
15061         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
15062
15063         ls -l $DIR/$tdir > /dev/null
15064
15065         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15066         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15067         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
15068         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
15069
15070         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
15071
15072         # set lru_max_age to 1 sec
15073         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
15074         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
15075
15076         echo "sleep $((recalc_p * 2)) seconds..."
15077         sleep $((recalc_p * 2))
15078
15079         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
15080
15081         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
15082 }
15083 run_test 124d "cancel very aged locks if lru-resize disabled"
15084
15085 test_125() { # 13358
15086         $LCTL get_param -n llite.*.client_type | grep -q local ||
15087                 skip "must run as local client"
15088         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
15089                 skip_env "must have acl enabled"
15090         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15091         id $USER0 || skip_env "missing user $USER0"
15092
15093         test_mkdir $DIR/$tdir
15094         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
15095         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
15096                 error "setfacl $DIR/$tdir failed"
15097         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
15098 }
15099 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
15100
15101 test_126() { # bug 12829/13455
15102         $GSS && skip_env "must run as gss disabled"
15103         $LCTL get_param -n llite.*.client_type | grep -q local ||
15104                 skip "must run as local client"
15105         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
15106
15107         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
15108         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
15109         rm -f $DIR/$tfile
15110         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
15111 }
15112 run_test 126 "check that the fsgid provided by the client is taken into account"
15113
15114 test_127a() { # bug 15521
15115         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15116         local name count samp unit min max sum sumsq
15117         local tmpfile=$TMP/$tfile.tmp
15118
15119         # enable stats header if it is disabled
15120         $LCTL set_param enable_stats_header=1
15121
15122         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
15123         echo "stats before reset"
15124         stack_trap "rm -f $tmpfile"
15125         local now=$(date +%s)
15126
15127         $LCTL get_param osc.*.stats | tee $tmpfile
15128
15129         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
15130         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
15131         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
15132         local uptime=$(awk '{ print $1 }' /proc/uptime)
15133
15134         # snapshot_time should match POSIX epoch time, allow some delta for VMs
15135         (( ${snapshot_time%\.*} >= $now - 5 &&
15136            ${snapshot_time%\.*} <= $now + 5 )) ||
15137                 error "snapshot_time=$snapshot_time != now=$now"
15138         # elapsed _should_ be from mount, but at least less than uptime
15139         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
15140                 error "elapsed=$elapsed > uptime=$uptime"
15141         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
15142            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
15143                 error "elapsed=$elapsed != $snapshot_time - $start_time"
15144
15145         $LCTL set_param osc.*.stats=0
15146         local reset=$(date +%s)
15147         local fsize=$((2048 * 1024))
15148
15149         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
15150         cancel_lru_locks osc
15151         dd if=$DIR/$tfile of=/dev/null bs=$fsize
15152
15153         now=$(date +%s)
15154         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
15155         while read name count samp unit min max sum sumsq; do
15156                 [[ "$samp" == "samples" ]] || continue
15157
15158                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
15159                 [ ! $min ] && error "Missing min value for $name proc entry"
15160                 eval $name=$count || error "Wrong proc format"
15161
15162                 case $name in
15163                 read_bytes|write_bytes)
15164                         [[ "$unit" =~ "bytes" ]] ||
15165                                 error "unit is not 'bytes': $unit"
15166                         (( $min >= 4096 )) || error "min is too small: $min"
15167                         (( $min <= $fsize )) || error "min is too big: $min"
15168                         (( $max >= 4096 )) || error "max is too small: $max"
15169                         (( $max <= $fsize )) || error "max is too big: $max"
15170                         (( $sum == $fsize )) || error "sum is wrong: $sum"
15171                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
15172                                 error "sumsquare is too small: $sumsq"
15173                         (( $sumsq <= $fsize * $fsize )) ||
15174                                 error "sumsquare is too big: $sumsq"
15175                         ;;
15176                 ost_read|ost_write)
15177                         [[ "$unit" =~ "usec" ]] ||
15178                                 error "unit is not 'usec': $unit"
15179                         ;;
15180                 *)      ;;
15181                 esac
15182         done < $tmpfile
15183
15184         #check that we actually got some stats
15185         [ "$read_bytes" ] || error "Missing read_bytes stats"
15186         [ "$write_bytes" ] || error "Missing write_bytes stats"
15187         [ "$read_bytes" != 0 ] || error "no read done"
15188         [ "$write_bytes" != 0 ] || error "no write done"
15189
15190         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
15191         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
15192         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
15193
15194         # snapshot_time should match POSIX epoch time, allow some delta for VMs
15195         (( ${snapshot_time%\.*} >= $now - 5 &&
15196            ${snapshot_time%\.*} <= $now + 5 )) ||
15197                 error "reset snapshot_time=$snapshot_time != now=$now"
15198         # elapsed should be from time of stats reset
15199         (( ${elapsed%\.*} >= $now - $reset - 2 &&
15200            ${elapsed%\.*} <= $now - $reset + 2 )) ||
15201                 error "reset elapsed=$elapsed > $now - $reset"
15202         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
15203            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
15204                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
15205 }
15206 run_test 127a "verify the client stats are sane"
15207
15208 test_127b() { # bug LU-333
15209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15210         local name count samp unit min max sum sumsq
15211
15212         echo "stats before reset"
15213         $LCTL get_param llite.*.stats
15214         $LCTL set_param llite.*.stats=0
15215
15216         # perform 2 reads and writes so MAX is different from SUM.
15217         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
15218         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
15219         cancel_lru_locks osc
15220         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
15221         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
15222
15223         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
15224         stack_trap "rm -f $TMP/$tfile.tmp"
15225         while read name count samp unit min max sum sumsq; do
15226                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
15227                 eval $name=$count || error "Wrong proc format"
15228
15229                 case $name in
15230                 read_bytes|write_bytes)
15231                         [[ "$unit" =~ "bytes" ]] ||
15232                                 error "unit is not 'bytes': $unit"
15233                         (( $count == 2 )) || error "count is not 2: $count"
15234                         (( $min == $PAGE_SIZE )) ||
15235                                 error "min is not $PAGE_SIZE: $min"
15236                         (( $max == $PAGE_SIZE )) ||
15237                                 error "max is not $PAGE_SIZE: $max"
15238                         (( $sum == $PAGE_SIZE * 2 )) ||
15239                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
15240                         ;;
15241                 read|write)
15242                         [[ "$unit" =~ "usec" ]] ||
15243                                 error "unit is not 'usec': $unit"
15244                         ;;
15245                 *)      ;;
15246                 esac
15247         done < $TMP/$tfile.tmp
15248
15249         #check that we actually got some stats
15250         [ "$read_bytes" ] || error "Missing read_bytes stats"
15251         [ "$write_bytes" ] || error "Missing write_bytes stats"
15252         [ "$read_bytes" != 0 ] || error "no read done"
15253         [ "$write_bytes" != 0 ] || error "no write done"
15254 }
15255 run_test 127b "verify the llite client stats are sane"
15256
15257 test_127c() { # LU-12394
15258         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
15259         local size
15260         local bsize
15261         local reads
15262         local writes
15263         local count
15264
15265         $LCTL set_param llite.*.extents_stats=1
15266         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
15267
15268         # Use two stripes so there is enough space in default config
15269         $LFS setstripe -c 2 $DIR/$tfile
15270
15271         # Extent stats start at 0-4K and go in power of two buckets
15272         # LL_HIST_START = 12 --> 2^12 = 4K
15273         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
15274         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
15275         # small configs
15276         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
15277                 do
15278                 # Write and read, 2x each, second time at a non-zero offset
15279                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
15280                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
15281                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
15282                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
15283                 rm -f $DIR/$tfile
15284         done
15285
15286         $LCTL get_param llite.*.extents_stats
15287
15288         count=2
15289         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
15290                 do
15291                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
15292                                 grep -m 1 $bsize)
15293                 reads=$(echo $bucket | awk '{print $5}')
15294                 writes=$(echo $bucket | awk '{print $9}')
15295                 [ "$reads" -eq $count ] ||
15296                         error "$reads reads in < $bsize bucket, expect $count"
15297                 [ "$writes" -eq $count ] ||
15298                         error "$writes writes in < $bsize bucket, expect $count"
15299         done
15300
15301         # Test mmap write and read
15302         $LCTL set_param llite.*.extents_stats=c
15303         size=512
15304         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
15305         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
15306         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
15307
15308         $LCTL get_param llite.*.extents_stats
15309
15310         count=$(((size*1024) / PAGE_SIZE))
15311
15312         bsize=$((2 * PAGE_SIZE / 1024))K
15313
15314         bucket=$($LCTL get_param -n llite.*.extents_stats |
15315                         grep -m 1 $bsize)
15316         reads=$(echo $bucket | awk '{print $5}')
15317         writes=$(echo $bucket | awk '{print $9}')
15318         # mmap writes fault in the page first, creating an additonal read
15319         [ "$reads" -eq $((2 * count)) ] ||
15320                 error "$reads reads in < $bsize bucket, expect $count"
15321         [ "$writes" -eq $count ] ||
15322                 error "$writes writes in < $bsize bucket, expect $count"
15323 }
15324 run_test 127c "test llite extent stats with regular & mmap i/o"
15325
15326 test_128() { # bug 15212
15327         touch $DIR/$tfile
15328         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
15329                 find $DIR/$tfile
15330                 find $DIR/$tfile
15331         EOF
15332
15333         result=$(grep error $TMP/$tfile.log)
15334         rm -f $DIR/$tfile $TMP/$tfile.log
15335         [ -z "$result" ] ||
15336                 error "consecutive find's under interactive lfs failed"
15337 }
15338 run_test 128 "interactive lfs for 2 consecutive find's"
15339
15340 set_dir_limits () {
15341         local mntdev
15342         local canondev
15343         local node
15344
15345         local ldproc=/proc/fs/ldiskfs
15346         local facets=$(get_facets MDS)
15347
15348         for facet in ${facets//,/ }; do
15349                 canondev=$(ldiskfs_canon \
15350                            *.$(convert_facet2label $facet).mntdev $facet)
15351                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
15352                         ldproc=/sys/fs/ldiskfs
15353                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
15354                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
15355         done
15356 }
15357
15358 check_mds_dmesg() {
15359         local facets=$(get_facets MDS)
15360         for facet in ${facets//,/ }; do
15361                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
15362         done
15363         return 1
15364 }
15365
15366 test_129() {
15367         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15368         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
15369                 skip "Need MDS version with at least 2.5.56"
15370         if [ "$mds1_FSTYPE" != ldiskfs ]; then
15371                 skip_env "ldiskfs only test"
15372         fi
15373         remote_mds_nodsh && skip "remote MDS with nodsh"
15374
15375         local ENOSPC=28
15376         local has_warning=false
15377
15378         rm -rf $DIR/$tdir
15379         mkdir -p $DIR/$tdir
15380
15381         # block size of mds1
15382         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
15383         set_dir_limits $maxsize $((maxsize * 6 / 8))
15384         stack_trap "set_dir_limits 0 0"
15385         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
15386         local dirsize=$(stat -c%s "$DIR/$tdir")
15387         local nfiles=0
15388         while (( $dirsize <= $maxsize )); do
15389                 $MCREATE $DIR/$tdir/file_base_$nfiles
15390                 rc=$?
15391                 # check two errors:
15392                 # ENOSPC for ext4 max_dir_size, which has been used since
15393                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
15394                 if (( rc == ENOSPC )); then
15395                         set_dir_limits 0 0
15396                         echo "rc=$rc returned as expected after $nfiles files"
15397
15398                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
15399                                 error "create failed w/o dir size limit"
15400
15401                         # messages may be rate limited if test is run repeatedly
15402                         check_mds_dmesg '"is approaching max"' ||
15403                                 echo "warning message should be output"
15404                         check_mds_dmesg '"has reached max"' ||
15405                                 echo "reached message should be output"
15406
15407                         dirsize=$(stat -c%s "$DIR/$tdir")
15408
15409                         [[ $dirsize -ge $maxsize ]] && return 0
15410                         error "dirsize $dirsize < $maxsize after $nfiles files"
15411                 elif (( rc != 0 )); then
15412                         break
15413                 fi
15414                 nfiles=$((nfiles + 1))
15415                 dirsize=$(stat -c%s "$DIR/$tdir")
15416         done
15417
15418         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
15419 }
15420 run_test 129 "test directory size limit ========================"
15421
15422 OLDIFS="$IFS"
15423 cleanup_130() {
15424         trap 0
15425         IFS="$OLDIFS"
15426         rm -f $DIR/$tfile
15427 }
15428
15429 test_130a() {
15430         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
15431         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
15432
15433         trap cleanup_130 EXIT RETURN
15434
15435         local fm_file=$DIR/$tfile
15436         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
15437         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
15438                 error "dd failed for $fm_file"
15439
15440         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
15441         filefrag -ves $fm_file
15442         local rc=$?
15443         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15444                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15445         (( $rc == 0 )) || error "filefrag $fm_file failed"
15446
15447         filefrag_op=$(filefrag -ve -k $fm_file |
15448                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15449         local lun=$($LFS getstripe -i $fm_file)
15450
15451         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
15452         IFS=$'\n'
15453         local tot_len=0
15454         for line in $filefrag_op; do
15455                 local frag_lun=$(echo $line | cut -d: -f5)
15456                 local ext_len=$(echo $line | cut -d: -f4)
15457
15458                 if (( $frag_lun != $lun )); then
15459                         error "FIEMAP on 1-stripe file($fm_file) failed"
15460                         return
15461                 fi
15462                 (( tot_len += ext_len ))
15463         done
15464
15465         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
15466                 error "FIEMAP on 1-stripe file($fm_file) failed"
15467                 return
15468         fi
15469
15470         echo "FIEMAP on single striped file succeeded"
15471 }
15472 run_test 130a "FIEMAP (1-stripe file)"
15473
15474 test_130b() {
15475         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15476
15477         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15478         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15479         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15480                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15481
15482         trap cleanup_130 EXIT RETURN
15483
15484         local fm_file=$DIR/$tfile
15485         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15486                 error "setstripe on $fm_file"
15487
15488         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
15489                 error "dd failed on $fm_file"
15490
15491         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15492         filefrag_op=$(filefrag -ve -k $fm_file |
15493                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15494
15495         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15496                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15497
15498         IFS=$'\n'
15499         local tot_len=0
15500         local num_luns=1
15501
15502         for line in $filefrag_op; do
15503                 local frag_lun=$(echo $line | cut -d: -f5 |
15504                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15505                 local ext_len=$(echo $line | cut -d: -f4)
15506                 if (( $frag_lun != $last_lun )); then
15507                         if (( tot_len != 1024 )); then
15508                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15509                                 return
15510                         else
15511                                 (( num_luns += 1 ))
15512                                 tot_len=0
15513                         fi
15514                 fi
15515                 (( tot_len += ext_len ))
15516                 last_lun=$frag_lun
15517         done
15518         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
15519                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15520                 return
15521         fi
15522
15523         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
15524 }
15525 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
15526
15527 test_130c() {
15528         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15529
15530         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15531         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15532         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15533                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15534
15535         trap cleanup_130 EXIT RETURN
15536
15537         local fm_file=$DIR/$tfile
15538         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
15539
15540         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
15541                 error "dd failed on $fm_file"
15542
15543         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15544         filefrag_op=$(filefrag -ve -k $fm_file |
15545                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15546
15547         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15548                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15549
15550         IFS=$'\n'
15551         local tot_len=0
15552         local num_luns=1
15553         for line in $filefrag_op; do
15554                 local frag_lun=$(echo $line | cut -d: -f5 |
15555                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15556                 local ext_len=$(echo $line | cut -d: -f4)
15557                 if (( $frag_lun != $last_lun )); then
15558                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
15559                         if (( logical != 512 )); then
15560                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
15561                                 return
15562                         fi
15563                         if (( tot_len != 512 )); then
15564                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15565                                 return
15566                         else
15567                                 (( num_luns += 1 ))
15568                                 tot_len=0
15569                         fi
15570                 fi
15571                 (( tot_len += ext_len ))
15572                 last_lun=$frag_lun
15573         done
15574         if (( num_luns != 2 || tot_len != 512 )); then
15575                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15576                 return
15577         fi
15578
15579         echo "FIEMAP on 2-stripe file with hole succeeded"
15580 }
15581 run_test 130c "FIEMAP (2-stripe file with hole)"
15582
15583 test_130d() {
15584         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
15585
15586         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15587         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15588         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15589                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15590
15591         trap cleanup_130 EXIT RETURN
15592
15593         local fm_file=$DIR/$tfile
15594         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15595                         error "setstripe on $fm_file"
15596
15597         local actual_stripe_count=$($LFS getstripe -c $fm_file)
15598         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
15599                 error "dd failed on $fm_file"
15600
15601         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15602         filefrag_op=$(filefrag -ve -k $fm_file |
15603                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15604
15605         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15606                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15607
15608         IFS=$'\n'
15609         local tot_len=0
15610         local num_luns=1
15611         for line in $filefrag_op; do
15612                 local frag_lun=$(echo $line | cut -d: -f5 |
15613                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15614                 local ext_len=$(echo $line | cut -d: -f4)
15615                 if (( $frag_lun != $last_lun )); then
15616                         if (( tot_len != 1024 )); then
15617                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15618                                 return
15619                         else
15620                                 (( num_luns += 1 ))
15621                                 local tot_len=0
15622                         fi
15623                 fi
15624                 (( tot_len += ext_len ))
15625                 last_lun=$frag_lun
15626         done
15627         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
15628                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15629                 return
15630         fi
15631
15632         echo "FIEMAP on N-stripe file succeeded"
15633 }
15634 run_test 130d "FIEMAP (N-stripe file)"
15635
15636 test_130e() {
15637         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15638
15639         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15640         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15641         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15642                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15643
15644         trap cleanup_130 EXIT RETURN
15645
15646         local fm_file=$DIR/$tfile
15647         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
15648         stack_trap "rm -f $fm_file"
15649
15650         local num_blks=512
15651         local expected_len=$(( (num_blks / 2) * 64 ))
15652         for ((i = 0; i < $num_blks; i++)); do
15653                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
15654                         conv=notrunc > /dev/null 2>&1
15655         done
15656
15657         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15658         filefrag_op=$(filefrag -ve -k $fm_file |
15659                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15660
15661         local last_lun=$(echo $filefrag_op | cut -d: -f5)
15662
15663         IFS=$'\n'
15664         local tot_len=0
15665         local num_luns=1
15666         for line in $filefrag_op; do
15667                 local frag_lun=$(echo $line | cut -d: -f5)
15668                 local ext_len=$(echo $line | cut -d: -f4)
15669                 if (( $frag_lun != $last_lun )); then
15670                         if (( tot_len != $expected_len )); then
15671                                 error "OST$last_lun $tot_len != $expected_len"
15672                         else
15673                                 (( num_luns += 1 ))
15674                                 tot_len=0
15675                         fi
15676                 fi
15677                 (( tot_len += ext_len ))
15678                 last_lun=$frag_lun
15679         done
15680         if (( num_luns != 2 || tot_len != $expected_len )); then
15681                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
15682         fi
15683
15684         echo "FIEMAP with continuation calls succeeded"
15685 }
15686 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
15687
15688 test_130f() {
15689         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15690         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15691         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15692                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15693
15694         local fm_file=$DIR/$tfile
15695         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
15696                 error "multiop create with lov_delay_create on $fm_file"
15697
15698         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15699         filefrag_extents=$(filefrag -vek $fm_file |
15700                            awk '/extents? found/ { print $2 }')
15701         if (( $filefrag_extents != 0 )); then
15702                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
15703         fi
15704
15705         rm -f $fm_file
15706 }
15707 run_test 130f "FIEMAP (unstriped file)"
15708
15709 test_130g() {
15710         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
15711                 skip "Need MDS version with at least 2.12.53 for overstriping"
15712         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15713         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15714         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15715                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15716
15717         local file=$DIR/$tfile
15718         local nr=$((OSTCOUNT * 100))
15719
15720         $LFS setstripe -C $nr -S1M $file ||
15721                 error "failed to setstripe -C $nr $file"
15722
15723         stack_trap "rm -f $file"
15724         dd if=/dev/zero of=$file count=$nr bs=1M
15725         sync
15726         nr=$($LFS getstripe -c $file)
15727
15728         local extents=$(filefrag -v $file |
15729                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
15730
15731         echo "filefrag list $extents extents in file with stripecount $nr"
15732         if (( extents < nr )); then
15733                 $LFS getstripe $file
15734                 filefrag -v $file
15735                 error "filefrag printed $extents < $nr extents"
15736         fi
15737 }
15738 run_test 130g "FIEMAP (overstripe file)"
15739
15740 # Test for writev/readv
15741 test_131a() {
15742         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
15743                 error "writev test failed"
15744         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
15745                 error "readv failed"
15746         rm -f $DIR/$tfile
15747 }
15748 run_test 131a "test iov's crossing stripe boundary for writev/readv"
15749
15750 test_131b() {
15751         local fsize=$((524288 + 1048576 + 1572864))
15752         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
15753                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15754                         error "append writev test failed"
15755
15756         ((fsize += 1572864 + 1048576))
15757         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
15758                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15759                         error "append writev test failed"
15760         rm -f $DIR/$tfile
15761 }
15762 run_test 131b "test append writev"
15763
15764 test_131c() {
15765         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
15766         error "NOT PASS"
15767 }
15768 run_test 131c "test read/write on file w/o objects"
15769
15770 test_131d() {
15771         rwv -f $DIR/$tfile -w -n 1 1572864
15772         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
15773         if [ "$NOB" != 1572864 ]; then
15774                 error "Short read filed: read $NOB bytes instead of 1572864"
15775         fi
15776         rm -f $DIR/$tfile
15777 }
15778 run_test 131d "test short read"
15779
15780 test_131e() {
15781         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
15782         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
15783         error "read hitting hole failed"
15784         rm -f $DIR/$tfile
15785 }
15786 run_test 131e "test read hitting hole"
15787
15788 check_stats() {
15789         local facet=$1
15790         local op=$2
15791         local want=${3:-0}
15792         local res
15793
15794         # open             11 samples [usecs] 468 4793 13658 35791898
15795         case $facet in
15796         mds*) res=($(do_facet $facet \
15797                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
15798                  ;;
15799         ost*) res=($(do_facet $facet \
15800                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
15801                  ;;
15802         *) error "Wrong facet '$facet'" ;;
15803         esac
15804         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
15805         # if $want is zero, it means any stat increment is ok.
15806         if (( $want > 0 )); then
15807                 local count=${res[1]}
15808
15809                 if (( $count != $want )); then
15810                         if [[ $facet =~ "mds" ]]; then
15811                                 do_nodes $(comma_list $(mdts_nodes)) \
15812                                         $LCTL get_param mdt.*.md_stats
15813                         else
15814                                 do_nodes $(comma_list $(osts-nodes)) \
15815                                         $LCTL get_param obdfilter.*.stats
15816                         fi
15817                         error "The $op counter on $facet is $count, not $want"
15818                 fi
15819         fi
15820 }
15821
15822 test_133a() {
15823         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15824         remote_ost_nodsh && skip "remote OST with nodsh"
15825         remote_mds_nodsh && skip "remote MDS with nodsh"
15826         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15827                 skip_env "MDS doesn't support rename stats"
15828
15829         local testdir=$DIR/${tdir}/stats_testdir
15830
15831         mkdir_on_mdt0 $DIR/${tdir}
15832
15833         # clear stats.
15834         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15835         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15836
15837         # verify mdt stats first.
15838         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15839         check_stats $SINGLEMDS "mkdir" 1
15840
15841         # clear "open" from "lfs mkdir" above
15842         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15843         touch ${testdir}/${tfile} || error "touch failed"
15844         check_stats $SINGLEMDS "open" 1
15845         check_stats $SINGLEMDS "close" 1
15846         # open should match close
15847         ls -lR ${testdir}
15848         check_stats $SINGLEMDS "open" 2
15849         check_stats $SINGLEMDS "close" 2
15850         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
15851                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
15852                 check_stats $SINGLEMDS "mknod" 2
15853         }
15854         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
15855         check_stats $SINGLEMDS "unlink" 1
15856         rm -f ${testdir}/${tfile} || error "file remove failed"
15857         check_stats $SINGLEMDS "unlink" 2
15858
15859         # remove working dir and check mdt stats again.
15860         rmdir ${testdir} || error "rmdir failed"
15861         check_stats $SINGLEMDS "rmdir" 1
15862
15863         local testdir1=$DIR/${tdir}/stats_testdir1
15864         mkdir_on_mdt0 ${testdir}
15865         mkdir_on_mdt0 ${testdir1}
15866         touch ${testdir1}/test1
15867         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
15868         check_stats $SINGLEMDS "crossdir_rename" 1
15869
15870         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
15871         check_stats $SINGLEMDS "samedir_rename" 1
15872
15873         rm -rf $DIR/${tdir}
15874 }
15875 run_test 133a "Verifying MDT stats ========================================"
15876
15877 test_133b() {
15878         local res
15879
15880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15881         remote_ost_nodsh && skip "remote OST with nodsh"
15882         remote_mds_nodsh && skip "remote MDS with nodsh"
15883
15884         local testdir=$DIR/${tdir}/stats_testdir
15885
15886         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15887         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15888         touch ${testdir}/${tfile} || error "touch failed"
15889         cancel_lru_locks mdc
15890
15891         # clear stats.
15892         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15893         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15894
15895         # extra mdt stats verification.
15896         chmod 444 ${testdir}/${tfile} || error "chmod failed"
15897         check_stats $SINGLEMDS "setattr" 1
15898         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15899         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
15900         then            # LU-1740
15901                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
15902                 check_stats $SINGLEMDS "getattr" 1
15903         fi
15904         rm -rf $DIR/${tdir}
15905
15906         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
15907         # so the check below is not reliable
15908         [ $MDSCOUNT -eq 1 ] || return 0
15909
15910         # Sleep to avoid a cached response.
15911         #define OBD_STATFS_CACHE_SECONDS 1
15912         sleep 2
15913         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15914         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15915         $LFS df || error "lfs failed"
15916         check_stats $SINGLEMDS "statfs" 1
15917
15918         # check aggregated statfs (LU-10018)
15919         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
15920                 return 0
15921         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
15922                 return 0
15923         sleep 2
15924         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15925         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15926         df $DIR
15927         check_stats $SINGLEMDS "statfs" 1
15928
15929         # We want to check that the client didn't send OST_STATFS to
15930         # ost1 but the MDT also uses OST_STATFS for precreate. So some
15931         # extra care is needed here.
15932         if remote_mds; then
15933                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
15934                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
15935
15936                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
15937                 [ "$res" ] && error "OST got STATFS"
15938         fi
15939
15940         return 0
15941 }
15942 run_test 133b "Verifying extra MDT stats =================================="
15943
15944 test_133c() {
15945         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15946         remote_ost_nodsh && skip "remote OST with nodsh"
15947         remote_mds_nodsh && skip "remote MDS with nodsh"
15948
15949         local testdir=$DIR/$tdir/stats_testdir
15950
15951         test_mkdir -p $testdir
15952
15953         # verify obdfilter stats.
15954         $LFS setstripe -c 1 -i 0 $testdir/$tfile
15955         sync
15956         cancel_lru_locks osc
15957         wait_delete_completed
15958
15959         # clear stats.
15960         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15961         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15962
15963         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
15964                 error "dd failed"
15965         sync
15966         cancel_lru_locks osc
15967         check_stats ost1 "write" 1
15968
15969         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
15970         check_stats ost1 "read" 1
15971
15972         > $testdir/$tfile || error "truncate failed"
15973         check_stats ost1 "punch" 1
15974
15975         rm -f $testdir/$tfile || error "file remove failed"
15976         wait_delete_completed
15977         check_stats ost1 "destroy" 1
15978
15979         rm -rf $DIR/$tdir
15980 }
15981 run_test 133c "Verifying OST stats ========================================"
15982
15983 order_2() {
15984         local value=$1
15985         local orig=$value
15986         local order=1
15987
15988         while [ $value -ge 2 ]; do
15989                 order=$((order*2))
15990                 value=$((value/2))
15991         done
15992
15993         if [ $orig -gt $order ]; then
15994                 order=$((order*2))
15995         fi
15996         echo $order
15997 }
15998
15999 size_in_KMGT() {
16000     local value=$1
16001     local size=('K' 'M' 'G' 'T');
16002     local i=0
16003     local size_string=$value
16004
16005     while [ $value -ge 1024 ]; do
16006         if [ $i -gt 3 ]; then
16007             #T is the biggest unit we get here, if that is bigger,
16008             #just return XXXT
16009             size_string=${value}T
16010             break
16011         fi
16012         value=$((value >> 10))
16013         if [ $value -lt 1024 ]; then
16014             size_string=${value}${size[$i]}
16015             break
16016         fi
16017         i=$((i + 1))
16018     done
16019
16020     echo $size_string
16021 }
16022
16023 get_rename_size() {
16024         local size=$1
16025         local context=${2:-.}
16026         local sample=$(do_facet $SINGLEMDS $LCTL \
16027                 get_param mdt.$FSNAME-MDT0000.rename_stats |
16028                 grep -A1 $context |
16029                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
16030         echo $sample
16031 }
16032
16033 test_133d() {
16034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16035         remote_ost_nodsh && skip "remote OST with nodsh"
16036         remote_mds_nodsh && skip "remote MDS with nodsh"
16037         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
16038                 skip_env "MDS doesn't support rename stats"
16039
16040         local testdir1=$DIR/${tdir}/stats_testdir1
16041         local testdir2=$DIR/${tdir}/stats_testdir2
16042         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
16043
16044         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
16045
16046         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
16047         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
16048
16049         createmany -o $testdir1/test 512 || error "createmany failed"
16050
16051         # check samedir rename size
16052         mv ${testdir1}/test0 ${testdir1}/test_0
16053
16054         local testdir1_size=$(ls -l $DIR/${tdir} |
16055                 awk '/stats_testdir1/ {print $5}')
16056         local testdir2_size=$(ls -l $DIR/${tdir} |
16057                 awk '/stats_testdir2/ {print $5}')
16058
16059         testdir1_size=$(order_2 $testdir1_size)
16060         testdir2_size=$(order_2 $testdir2_size)
16061
16062         testdir1_size=$(size_in_KMGT $testdir1_size)
16063         testdir2_size=$(size_in_KMGT $testdir2_size)
16064
16065         echo "source rename dir size: ${testdir1_size}"
16066         echo "target rename dir size: ${testdir2_size}"
16067
16068         local cmd="do_facet $SINGLEMDS $LCTL "
16069         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
16070
16071         eval $cmd || error "$cmd failed"
16072         local samedir=$($cmd | grep 'same_dir')
16073         local same_sample=$(get_rename_size $testdir1_size)
16074         [ -z "$samedir" ] && error "samedir_rename_size count error"
16075         [[ $same_sample -eq 1 ]] ||
16076                 error "samedir_rename_size error $same_sample"
16077         echo "Check same dir rename stats success"
16078
16079         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
16080
16081         # check crossdir rename size
16082         mv ${testdir1}/test_0 ${testdir2}/test_0
16083
16084         testdir1_size=$(ls -l $DIR/${tdir} |
16085                 awk '/stats_testdir1/ {print $5}')
16086         testdir2_size=$(ls -l $DIR/${tdir} |
16087                 awk '/stats_testdir2/ {print $5}')
16088
16089         testdir1_size=$(order_2 $testdir1_size)
16090         testdir2_size=$(order_2 $testdir2_size)
16091
16092         testdir1_size=$(size_in_KMGT $testdir1_size)
16093         testdir2_size=$(size_in_KMGT $testdir2_size)
16094
16095         echo "source rename dir size: ${testdir1_size}"
16096         echo "target rename dir size: ${testdir2_size}"
16097
16098         eval $cmd || error "$cmd failed"
16099         local crossdir=$($cmd | grep 'crossdir')
16100         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
16101         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
16102         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
16103         [[ $src_sample -eq 1 ]] ||
16104                 error "crossdir_rename_size error $src_sample"
16105         [[ $tgt_sample -eq 1 ]] ||
16106                 error "crossdir_rename_size error $tgt_sample"
16107         echo "Check cross dir rename stats success"
16108         rm -rf $DIR/${tdir}
16109 }
16110 run_test 133d "Verifying rename_stats ========================================"
16111
16112 test_133e() {
16113         remote_mds_nodsh && skip "remote MDS with nodsh"
16114         remote_ost_nodsh && skip "remote OST with nodsh"
16115         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16116
16117         local testdir=$DIR/${tdir}/stats_testdir
16118         local ctr f0 f1 bs=32768 count=42 sum
16119
16120         mkdir -p ${testdir} || error "mkdir failed"
16121
16122         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
16123
16124         for ctr in {write,read}_bytes; do
16125                 sync
16126                 cancel_lru_locks osc
16127
16128                 do_facet ost1 $LCTL set_param -n \
16129                         "obdfilter.*.exports.clear=clear"
16130
16131                 if [ $ctr = write_bytes ]; then
16132                         f0=/dev/zero
16133                         f1=${testdir}/${tfile}
16134                 else
16135                         f0=${testdir}/${tfile}
16136                         f1=/dev/null
16137                 fi
16138
16139                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
16140                         error "dd failed"
16141                 sync
16142                 cancel_lru_locks osc
16143
16144                 sum=$(do_facet ost1 $LCTL get_param \
16145                         "obdfilter.*.exports.*.stats" |
16146                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
16147                                 $1 == ctr { sum += $7 }
16148                                 END { printf("%0.0f", sum) }')
16149
16150                 if ((sum != bs * count)); then
16151                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
16152                 fi
16153         done
16154
16155         rm -rf $DIR/${tdir}
16156 }
16157 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
16158
16159 test_133f() {
16160         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
16161                 skip "too old lustre for get_param -R ($facet_ver)"
16162
16163         # verifying readability.
16164         $LCTL get_param -R '*' &> /dev/null
16165
16166         # Verifing writability with badarea_io.
16167         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
16168         local skipped_params='force_lbug|changelog_mask|daemon_file'
16169         $LCTL list_param -FR '*' | grep '=' | tr -d = |
16170                 egrep -v "$skipped_params" |
16171                 xargs -n 1 find $proc_dirs -name |
16172                 xargs -n 1 badarea_io ||
16173                 error "client badarea_io failed"
16174
16175         # remount the FS in case writes/reads /proc break the FS
16176         cleanup || error "failed to unmount"
16177         setup || error "failed to setup"
16178 }
16179 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
16180
16181 test_133g() {
16182         remote_mds_nodsh && skip "remote MDS with nodsh"
16183         remote_ost_nodsh && skip "remote OST with nodsh"
16184
16185         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
16186         local proc_dirs_str=$(eval echo $proc_dirs)
16187         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
16188         local facet
16189         for facet in mds1 ost1; do
16190                 local facet_ver=$(lustre_version_code $facet)
16191                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
16192                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
16193                 else
16194                         log "$facet: too old lustre for get_param -R"
16195                 fi
16196                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
16197                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
16198                                 tr -d = | egrep -v $skipped_params |
16199                                 xargs -n 1 find $proc_dirs_str -name |
16200                                 xargs -n 1 badarea_io" ||
16201                                         error "$facet badarea_io failed"
16202                 else
16203                         skip_noexit "$facet: too old lustre for get_param -R"
16204                 fi
16205         done
16206
16207         # remount the FS in case writes/reads /proc break the FS
16208         cleanup || error "failed to unmount"
16209         setup || error "failed to setup"
16210 }
16211 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
16212
16213 test_133h() {
16214         remote_mds_nodsh && skip "remote MDS with nodsh"
16215         remote_ost_nodsh && skip "remote OST with nodsh"
16216         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
16217                 skip "Need MDS version at least 2.9.54"
16218
16219         local facet
16220         for facet in client mds1 ost1; do
16221                 # Get the list of files that are missing the terminating newline
16222                 local plist=$(do_facet $facet
16223                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
16224                 local ent
16225                 for ent in $plist; do
16226                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
16227                                 awk -v FS='\v' -v RS='\v\v' \
16228                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
16229                                         print FILENAME}'" 2>/dev/null)
16230                         [ -z $missing ] || {
16231                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
16232                                 error "file does not end with newline: $facet-$ent"
16233                         }
16234                 done
16235         done
16236 }
16237 run_test 133h "Proc files should end with newlines"
16238
16239 test_134a() {
16240         remote_mds_nodsh && skip "remote MDS with nodsh"
16241         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
16242                 skip "Need MDS version at least 2.7.54"
16243
16244         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
16245         cancel_lru_locks mdc
16246
16247         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
16248         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
16249         [ $unused -eq 0 ] || error "$unused locks are not cleared"
16250
16251         local nr=1000
16252         createmany -o $DIR/$tdir/f $nr ||
16253                 error "failed to create $nr files in $DIR/$tdir"
16254         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
16255
16256         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
16257         do_facet mds1 $LCTL set_param fail_loc=0x327
16258         do_facet mds1 $LCTL set_param fail_val=500
16259         touch $DIR/$tdir/m
16260
16261         echo "sleep 10 seconds ..."
16262         sleep 10
16263         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
16264
16265         do_facet mds1 $LCTL set_param fail_loc=0
16266         do_facet mds1 $LCTL set_param fail_val=0
16267         [ $lck_cnt -lt $unused ] ||
16268                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
16269
16270         rm $DIR/$tdir/m
16271         unlinkmany $DIR/$tdir/f $nr
16272 }
16273 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
16274
16275 test_134b() {
16276         remote_mds_nodsh && skip "remote MDS with nodsh"
16277         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
16278                 skip "Need MDS version at least 2.7.54"
16279
16280         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
16281         cancel_lru_locks mdc
16282
16283         local low_wm=$(do_facet mds1 $LCTL get_param -n \
16284                         ldlm.lock_reclaim_threshold_mb)
16285         # disable reclaim temporarily
16286         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
16287
16288         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
16289         do_facet mds1 $LCTL set_param fail_loc=0x328
16290         do_facet mds1 $LCTL set_param fail_val=500
16291
16292         $LCTL set_param debug=+trace
16293
16294         local nr=600
16295         createmany -o $DIR/$tdir/f $nr &
16296         local create_pid=$!
16297
16298         echo "Sleep $TIMEOUT seconds ..."
16299         sleep $TIMEOUT
16300         if ! ps -p $create_pid  > /dev/null 2>&1; then
16301                 do_facet mds1 $LCTL set_param fail_loc=0
16302                 do_facet mds1 $LCTL set_param fail_val=0
16303                 do_facet mds1 $LCTL set_param \
16304                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
16305                 error "createmany finished incorrectly!"
16306         fi
16307         do_facet mds1 $LCTL set_param fail_loc=0
16308         do_facet mds1 $LCTL set_param fail_val=0
16309         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
16310         wait $create_pid || return 1
16311
16312         unlinkmany $DIR/$tdir/f $nr
16313 }
16314 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
16315
16316 test_135() {
16317         remote_mds_nodsh && skip "remote MDS with nodsh"
16318         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
16319                 skip "Need MDS version at least 2.13.50"
16320         local fname
16321
16322         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
16323
16324 #define OBD_FAIL_PLAIN_RECORDS 0x1319
16325         #set only one record at plain llog
16326         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
16327
16328         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
16329
16330         #fill already existed plain llog each 64767
16331         #wrapping whole catalog
16332         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
16333
16334         createmany -o $DIR/$tdir/$tfile_ 64700
16335         for (( i = 0; i < 64700; i = i + 2 ))
16336         do
16337                 rm $DIR/$tdir/$tfile_$i &
16338                 rm $DIR/$tdir/$tfile_$((i + 1)) &
16339                 local pid=$!
16340                 wait $pid
16341         done
16342
16343         #waiting osp synchronization
16344         wait_delete_completed
16345 }
16346 run_test 135 "Race catalog processing"
16347
16348 test_136() {
16349         remote_mds_nodsh && skip "remote MDS with nodsh"
16350         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
16351                 skip "Need MDS version at least 2.13.50"
16352         local fname
16353
16354         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
16355         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
16356         #set only one record at plain llog
16357 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
16358         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
16359
16360         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
16361
16362         #fill already existed 2 plain llogs each 64767
16363         #wrapping whole catalog
16364         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
16365         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
16366         wait_delete_completed
16367
16368         createmany -o $DIR/$tdir/$tfile_ 10
16369         sleep 25
16370
16371         do_facet $SINGLEMDS $LCTL set_param fail_val=3
16372         for (( i = 0; i < 10; i = i + 3 ))
16373         do
16374                 rm $DIR/$tdir/$tfile_$i &
16375                 rm $DIR/$tdir/$tfile_$((i + 1)) &
16376                 local pid=$!
16377                 wait $pid
16378                 sleep 7
16379                 rm $DIR/$tdir/$tfile_$((i + 2)) &
16380         done
16381
16382         #waiting osp synchronization
16383         wait_delete_completed
16384 }
16385 run_test 136 "Race catalog processing 2"
16386
16387 test_140() { #bug-17379
16388         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16389
16390         test_mkdir $DIR/$tdir
16391         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
16392         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
16393
16394         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
16395         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
16396         local i=0
16397         while i=$((i + 1)); do
16398                 test_mkdir $i
16399                 cd $i || error "Changing to $i"
16400                 ln -s ../stat stat || error "Creating stat symlink"
16401                 # Read the symlink until ELOOP present,
16402                 # not LBUGing the system is considered success,
16403                 # we didn't overrun the stack.
16404                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
16405                 if [ $ret -ne 0 ]; then
16406                         if [ $ret -eq 40 ]; then
16407                                 break  # -ELOOP
16408                         else
16409                                 error "Open stat symlink"
16410                                         return
16411                         fi
16412                 fi
16413         done
16414         i=$((i - 1))
16415         echo "The symlink depth = $i"
16416         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
16417                 error "Invalid symlink depth"
16418
16419         # Test recursive symlink
16420         ln -s symlink_self symlink_self
16421         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
16422         echo "open symlink_self returns $ret"
16423         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
16424 }
16425 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
16426
16427 test_150a() {
16428         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16429
16430         local TF="$TMP/$tfile"
16431
16432         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16433         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16434         cp $TF $DIR/$tfile
16435         cancel_lru_locks $OSC
16436         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
16437         remount_client $MOUNT
16438         df -P $MOUNT
16439         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
16440
16441         $TRUNCATE $TF 6000
16442         $TRUNCATE $DIR/$tfile 6000
16443         cancel_lru_locks $OSC
16444         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
16445
16446         echo "12345" >>$TF
16447         echo "12345" >>$DIR/$tfile
16448         cancel_lru_locks $OSC
16449         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
16450
16451         echo "12345" >>$TF
16452         echo "12345" >>$DIR/$tfile
16453         cancel_lru_locks $OSC
16454         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
16455 }
16456 run_test 150a "truncate/append tests"
16457
16458 test_150b() {
16459         check_set_fallocate_or_skip
16460         local out
16461
16462         touch $DIR/$tfile
16463         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16464         out=$(check_fallocate $DIR/$tfile 2>&1) ||
16465                 skip_eopnotsupp "$out|check_fallocate failed"
16466 }
16467 run_test 150b "Verify fallocate (prealloc) functionality"
16468
16469 test_150bb() {
16470         check_set_fallocate_or_skip
16471
16472         touch $DIR/$tfile
16473         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16474         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
16475         > $DIR/$tfile
16476         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
16477         # precomputed md5sum for 20MB of zeroes
16478         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
16479         local sum=($(md5sum $DIR/$tfile))
16480
16481         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
16482
16483         check_set_fallocate 1
16484
16485         > $DIR/$tfile
16486         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
16487         sum=($(md5sum $DIR/$tfile))
16488
16489         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
16490 }
16491 run_test 150bb "Verify fallocate modes both zero space"
16492
16493 test_150c() {
16494         check_set_fallocate_or_skip
16495         local striping="-c2"
16496
16497         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16498         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
16499         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
16500         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
16501         local want=$((OSTCOUNT * 1048576))
16502
16503         # Must allocate all requested space, not more than 5% extra
16504         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16505                 error "bytes $bytes is not $want"
16506
16507         rm -f $DIR/$tfile
16508
16509         echo "verify fallocate on PFL file"
16510
16511         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
16512
16513         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
16514                 error "Create $DIR/$tfile failed"
16515         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
16516         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
16517         want=$((512 * 1048576))
16518
16519         # Must allocate all requested space, not more than 5% extra
16520         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16521                 error "bytes $bytes is not $want"
16522 }
16523 run_test 150c "Verify fallocate Size and Blocks"
16524
16525 test_150d() {
16526         check_set_fallocate_or_skip
16527         local striping="-c2"
16528
16529         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
16530
16531         stack_trap "rm -f $DIR/$tdir; wait_delete_completed"
16532         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
16533                 error "setstripe failed"
16534         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
16535         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
16536         local want=$((OSTCOUNT * 1048576))
16537
16538         # Must allocate all requested space, not more than 5% extra
16539         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16540                 error "bytes $bytes is not $want"
16541 }
16542 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
16543
16544 test_150e() {
16545         check_set_fallocate_or_skip
16546
16547         echo "df before:"
16548         $LFS df
16549         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16550         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16551                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16552
16553         # Find OST with Minimum Size
16554         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16555                        sort -un | head -1)
16556
16557         # Get 100MB per OST of the available space to reduce run time
16558         # else 60% of the available space if we are running SLOW tests
16559         if [ $SLOW == "no" ]; then
16560                 local space=$((1024 * 100 * OSTCOUNT))
16561         else
16562                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
16563         fi
16564
16565         fallocate -l${space}k $DIR/$tfile ||
16566                 error "fallocate ${space}k $DIR/$tfile failed"
16567         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
16568
16569         # get size immediately after fallocate. This should be correctly
16570         # updated
16571         local size=$(stat -c '%s' $DIR/$tfile)
16572         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
16573
16574         # Sleep for a while for statfs to get updated. And not pull from cache.
16575         sleep 2
16576
16577         echo "df after fallocate:"
16578         $LFS df
16579
16580         (( size / 1024 == space )) || error "size $size != requested $space"
16581         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
16582                 error "used $used < space $space"
16583
16584         rm $DIR/$tfile || error "rm failed"
16585         sync
16586         wait_delete_completed
16587
16588         echo "df after unlink:"
16589         $LFS df
16590 }
16591 run_test 150e "Verify 60% of available OST space consumed by fallocate"
16592
16593 test_150f() {
16594         local size
16595         local blocks
16596         local want_size_before=20480 # in bytes
16597         local want_blocks_before=40 # 512 sized blocks
16598         local want_blocks_after=24  # 512 sized blocks
16599         local length=$(((want_blocks_before - want_blocks_after) * 512))
16600
16601         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16602                 skip "need at least 2.14.0 for fallocate punch"
16603
16604         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16605                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16606         fi
16607
16608         check_set_fallocate_or_skip
16609         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16610
16611         [[ "x$DOM" == "xyes" ]] &&
16612                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
16613
16614         echo "Verify fallocate punch: Range within the file range"
16615         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16616                 error "dd failed for bs 4096 and count 5"
16617
16618         # Call fallocate with punch range which is within the file range
16619         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
16620                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
16621         # client must see changes immediately after fallocate
16622         size=$(stat -c '%s' $DIR/$tfile)
16623         blocks=$(stat -c '%b' $DIR/$tfile)
16624
16625         # Verify punch worked.
16626         (( blocks == want_blocks_after )) ||
16627                 error "punch failed: blocks $blocks != $want_blocks_after"
16628
16629         (( size == want_size_before )) ||
16630                 error "punch failed: size $size != $want_size_before"
16631
16632         # Verify there is hole in file
16633         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
16634         # precomputed md5sum
16635         local expect="4a9a834a2db02452929c0a348273b4aa"
16636
16637         cksum=($(md5sum $DIR/$tfile))
16638         [[ "${cksum[0]}" == "$expect" ]] ||
16639                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16640
16641         # Start second sub-case for fallocate punch.
16642         echo "Verify fallocate punch: Range overlapping and less than blocksize"
16643         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16644                 error "dd failed for bs 4096 and count 5"
16645
16646         # Punch range less than block size will have no change in block count
16647         want_blocks_after=40  # 512 sized blocks
16648
16649         # Punch overlaps two blocks and less than blocksize
16650         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
16651                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
16652         size=$(stat -c '%s' $DIR/$tfile)
16653         blocks=$(stat -c '%b' $DIR/$tfile)
16654
16655         # Verify punch worked.
16656         (( blocks == want_blocks_after )) ||
16657                 error "punch failed: blocks $blocks != $want_blocks_after"
16658
16659         (( size == want_size_before )) ||
16660                 error "punch failed: size $size != $want_size_before"
16661
16662         # Verify if range is really zero'ed out. We expect Zeros.
16663         # precomputed md5sum
16664         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
16665         cksum=($(md5sum $DIR/$tfile))
16666         [[ "${cksum[0]}" == "$expect" ]] ||
16667                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16668 }
16669 run_test 150f "Verify fallocate punch functionality"
16670
16671 test_150g() {
16672         local space
16673         local size
16674         local blocks
16675         local blocks_after
16676         local size_after
16677         local BS=4096 # Block size in bytes
16678
16679         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16680                 skip "need at least 2.14.0 for fallocate punch"
16681
16682         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16683                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16684         fi
16685
16686         check_set_fallocate_or_skip
16687         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16688
16689         if [[ "x$DOM" == "xyes" ]]; then
16690                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
16691                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
16692         else
16693                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16694                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16695         fi
16696
16697         # Get 100MB per OST of the available space to reduce run time
16698         # else 60% of the available space if we are running SLOW tests
16699         if [ $SLOW == "no" ]; then
16700                 space=$((1024 * 100 * OSTCOUNT))
16701         else
16702                 # Find OST with Minimum Size
16703                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16704                         sort -un | head -1)
16705                 echo "min size OST: $space"
16706                 space=$(((space * 60)/100 * OSTCOUNT))
16707         fi
16708         # space in 1k units, round to 4k blocks
16709         local blkcount=$((space * 1024 / $BS))
16710
16711         echo "Verify fallocate punch: Very large Range"
16712         fallocate -l${space}k $DIR/$tfile ||
16713                 error "fallocate ${space}k $DIR/$tfile failed"
16714         # write 1M at the end, start and in the middle
16715         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
16716                 error "dd failed: bs $BS count 256"
16717         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
16718                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
16719         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
16720                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
16721
16722         # Gather stats.
16723         size=$(stat -c '%s' $DIR/$tfile)
16724
16725         # gather punch length.
16726         local punch_size=$((size - (BS * 2)))
16727
16728         echo "punch_size = $punch_size"
16729         echo "size - punch_size: $((size - punch_size))"
16730         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
16731
16732         # Call fallocate to punch all except 2 blocks. We leave the
16733         # first and the last block
16734         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
16735         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
16736                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
16737
16738         size_after=$(stat -c '%s' $DIR/$tfile)
16739         blocks_after=$(stat -c '%b' $DIR/$tfile)
16740
16741         # Verify punch worked.
16742         # Size should be kept
16743         (( size == size_after )) ||
16744                 error "punch failed: size $size != $size_after"
16745
16746         # two 4k data blocks to remain plus possible 1 extra extent block
16747         (( blocks_after <= ((BS / 512) * 3) )) ||
16748                 error "too many blocks remains: $blocks_after"
16749
16750         # Verify that file has hole between the first and the last blocks
16751         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
16752         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
16753
16754         echo "Hole at [$hole_start, $hole_end)"
16755         (( hole_start == BS )) ||
16756                 error "no hole at offset $BS after punch"
16757
16758         (( hole_end == BS + punch_size )) ||
16759                 error "data at offset $hole_end < $((BS + punch_size))"
16760 }
16761 run_test 150g "Verify fallocate punch on large range"
16762
16763 test_150h() {
16764         local file=$DIR/$tfile
16765         local size
16766
16767         check_set_fallocate_or_skip
16768         statx_supported || skip_env "Test must be statx() syscall supported"
16769
16770         # fallocate() does not update the size information on the MDT
16771         fallocate -l 16K $file || error "failed to fallocate $file"
16772         cancel_lru_locks $OSC
16773         # STATX with cached-always mode will not send glimpse RPCs to OST,
16774         # it uses the caching attrs on the client side as much as possible.
16775         size=$($STATX --cached=always -c %s $file)
16776         [ $size == 16384 ] ||
16777                 error "size after fallocate() is $size, expected 16384"
16778 }
16779 run_test 150h "Verify extend fallocate updates the file size"
16780
16781 #LU-2902 roc_hit was not able to read all values from lproc
16782 function roc_hit_init() {
16783         local list=$(comma_list $(osts_nodes))
16784         local dir=$DIR/$tdir-check
16785         local file=$dir/$tfile
16786         local BEFORE
16787         local AFTER
16788         local idx
16789
16790         test_mkdir $dir
16791         #use setstripe to do a write to every ost
16792         for i in $(seq 0 $((OSTCOUNT-1))); do
16793                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
16794                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
16795                 idx=$(printf %04x $i)
16796                 BEFORE=$(get_osd_param $list *OST*$idx stats |
16797                         awk '$1 == "cache_access" {sum += $7}
16798                                 END { printf("%0.0f", sum) }')
16799
16800                 cancel_lru_locks osc
16801                 cat $file >/dev/null
16802
16803                 AFTER=$(get_osd_param $list *OST*$idx stats |
16804                         awk '$1 == "cache_access" {sum += $7}
16805                                 END { printf("%0.0f", sum) }')
16806
16807                 echo BEFORE:$BEFORE AFTER:$AFTER
16808                 if ! let "AFTER - BEFORE == 4"; then
16809                         rm -rf $dir
16810                         error "roc_hit is not safe to use"
16811                 fi
16812                 rm $file
16813         done
16814
16815         rm -rf $dir
16816 }
16817
16818 function roc_hit() {
16819         local list=$(comma_list $(osts_nodes))
16820         echo $(get_osd_param $list '' stats |
16821                 awk '$1 == "cache_hit" {sum += $7}
16822                         END { printf("%0.0f", sum) }')
16823 }
16824
16825 function set_cache() {
16826         local on=1
16827
16828         if [ "$2" == "off" ]; then
16829                 on=0;
16830         fi
16831         local list=$(comma_list $(osts_nodes))
16832         set_osd_param $list '' $1_cache_enable $on
16833
16834         cancel_lru_locks osc
16835 }
16836
16837 test_151() {
16838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16839         remote_ost_nodsh && skip "remote OST with nodsh"
16840         (( CLIENT_VERSION == OST1_VERSION )) ||
16841                 skip "LU-13081: no interop testing for OSS cache"
16842
16843         local CPAGES=3
16844         local list=$(comma_list $(osts_nodes))
16845
16846         # check whether obdfilter is cache capable at all
16847         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
16848                 skip "not cache-capable obdfilter"
16849         fi
16850
16851         # check cache is enabled on all obdfilters
16852         if get_osd_param $list '' read_cache_enable | grep 0; then
16853                 skip "oss cache is disabled"
16854         fi
16855
16856         set_osd_param $list '' writethrough_cache_enable 1
16857
16858         # check write cache is enabled on all obdfilters
16859         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
16860                 skip "oss write cache is NOT enabled"
16861         fi
16862
16863         roc_hit_init
16864
16865         #define OBD_FAIL_OBD_NO_LRU  0x609
16866         do_nodes $list $LCTL set_param fail_loc=0x609
16867
16868         # pages should be in the case right after write
16869         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
16870                 error "dd failed"
16871
16872         local BEFORE=$(roc_hit)
16873         cancel_lru_locks osc
16874         cat $DIR/$tfile >/dev/null
16875         local AFTER=$(roc_hit)
16876
16877         do_nodes $list $LCTL set_param fail_loc=0
16878
16879         if ! let "AFTER - BEFORE == CPAGES"; then
16880                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
16881         fi
16882
16883         cancel_lru_locks osc
16884         # invalidates OST cache
16885         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
16886         set_osd_param $list '' read_cache_enable 0
16887         cat $DIR/$tfile >/dev/null
16888
16889         # now data shouldn't be found in the cache
16890         BEFORE=$(roc_hit)
16891         cancel_lru_locks osc
16892         cat $DIR/$tfile >/dev/null
16893         AFTER=$(roc_hit)
16894         if let "AFTER - BEFORE != 0"; then
16895                 error "IN CACHE: before: $BEFORE, after: $AFTER"
16896         fi
16897
16898         set_osd_param $list '' read_cache_enable 1
16899         rm -f $DIR/$tfile
16900 }
16901 run_test 151 "test cache on oss and controls ==============================="
16902
16903 test_152() {
16904         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16905
16906         local TF="$TMP/$tfile"
16907
16908         # simulate ENOMEM during write
16909 #define OBD_FAIL_OST_NOMEM      0x226
16910         lctl set_param fail_loc=0x80000226
16911         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16912         cp $TF $DIR/$tfile
16913         sync || error "sync failed"
16914         lctl set_param fail_loc=0
16915
16916         # discard client's cache
16917         cancel_lru_locks osc
16918
16919         # simulate ENOMEM during read
16920         lctl set_param fail_loc=0x80000226
16921         cmp $TF $DIR/$tfile || error "cmp failed"
16922         lctl set_param fail_loc=0
16923
16924         rm -f $TF
16925 }
16926 run_test 152 "test read/write with enomem ============================"
16927
16928 test_153() {
16929         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
16930 }
16931 run_test 153 "test if fdatasync does not crash ======================="
16932
16933 dot_lustre_fid_permission_check() {
16934         local fid=$1
16935         local ffid=$MOUNT/.lustre/fid/$fid
16936         local test_dir=$2
16937
16938         echo "stat fid $fid"
16939         stat $ffid || error "stat $ffid failed."
16940         echo "touch fid $fid"
16941         touch $ffid || error "touch $ffid failed."
16942         echo "write to fid $fid"
16943         cat /etc/hosts > $ffid || error "write $ffid failed."
16944         echo "read fid $fid"
16945         diff /etc/hosts $ffid || error "read $ffid failed."
16946         echo "append write to fid $fid"
16947         cat /etc/hosts >> $ffid || error "append write $ffid failed."
16948         echo "rename fid $fid"
16949         mv $ffid $test_dir/$tfile.1 &&
16950                 error "rename $ffid to $tfile.1 should fail."
16951         touch $test_dir/$tfile.1
16952         mv $test_dir/$tfile.1 $ffid &&
16953                 error "rename $tfile.1 to $ffid should fail."
16954         rm -f $test_dir/$tfile.1
16955         echo "truncate fid $fid"
16956         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
16957         echo "link fid $fid"
16958         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
16959         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
16960                 id $USER0 || skip_env "missing user $USER0"
16961                 echo "setfacl fid $fid"
16962                 setfacl -R -m u:$USER0:rwx $ffid ||
16963                         error "setfacl $ffid failed"
16964                 echo "getfacl fid $fid"
16965                 getfacl $ffid || error "getfacl $ffid failed."
16966         fi
16967         echo "unlink fid $fid"
16968         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
16969         echo "mknod fid $fid"
16970         mknod $ffid c 1 3 && error "mknod $ffid should fail."
16971
16972         fid=[0xf00000400:0x1:0x0]
16973         ffid=$MOUNT/.lustre/fid/$fid
16974
16975         echo "stat non-exist fid $fid"
16976         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
16977         echo "write to non-exist fid $fid"
16978         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
16979         echo "link new fid $fid"
16980         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
16981
16982         mkdir -p $test_dir/$tdir
16983         touch $test_dir/$tdir/$tfile
16984         fid=$($LFS path2fid $test_dir/$tdir)
16985         rc=$?
16986         [ $rc -ne 0 ] &&
16987                 error "error: could not get fid for $test_dir/$dir/$tfile."
16988
16989         ffid=$MOUNT/.lustre/fid/$fid
16990
16991         echo "ls $fid"
16992         ls $ffid || error "ls $ffid failed."
16993         echo "touch $fid/$tfile.1"
16994         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
16995
16996         echo "touch $MOUNT/.lustre/fid/$tfile"
16997         touch $MOUNT/.lustre/fid/$tfile && \
16998                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
16999
17000         echo "setxattr to $MOUNT/.lustre/fid"
17001         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
17002
17003         echo "listxattr for $MOUNT/.lustre/fid"
17004         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
17005
17006         echo "delxattr from $MOUNT/.lustre/fid"
17007         setfattr -x trusted.name1 $MOUNT/.lustre/fid
17008
17009         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
17010         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
17011                 error "touch invalid fid should fail."
17012
17013         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
17014         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
17015                 error "touch non-normal fid should fail."
17016
17017         echo "rename $tdir to $MOUNT/.lustre/fid"
17018         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
17019                 error "rename to $MOUNT/.lustre/fid should fail."
17020
17021         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
17022         then            # LU-3547
17023                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
17024                 local new_obf_mode=777
17025
17026                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
17027                 chmod $new_obf_mode $DIR/.lustre/fid ||
17028                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
17029
17030                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
17031                 [ $obf_mode -eq $new_obf_mode ] ||
17032                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
17033
17034                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
17035                 chmod $old_obf_mode $DIR/.lustre/fid ||
17036                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
17037         fi
17038
17039         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
17040         fid=$($LFS path2fid $test_dir/$tfile-2)
17041
17042         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
17043         then # LU-5424
17044                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
17045                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
17046                         error "create lov data thru .lustre failed"
17047         fi
17048         echo "cp /etc/passwd $test_dir/$tfile-2"
17049         cp /etc/passwd $test_dir/$tfile-2 ||
17050                 error "copy to $test_dir/$tfile-2 failed."
17051         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
17052         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
17053                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
17054
17055         rm -rf $test_dir/tfile.lnk
17056         rm -rf $test_dir/$tfile-2
17057 }
17058
17059 test_154A() {
17060         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
17061                 skip "Need MDS version at least 2.4.1"
17062
17063         local tf=$DIR/$tfile
17064         touch $tf
17065
17066         local fid=$($LFS path2fid $tf)
17067         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
17068
17069         # check that we get the same pathname back
17070         local rootpath
17071         local found
17072         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
17073                 echo "$rootpath $fid"
17074                 found=$($LFS fid2path $rootpath "$fid")
17075                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
17076                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
17077         done
17078
17079         # check wrong root path format
17080         rootpath=$MOUNT"_wrong"
17081         found=$($LFS fid2path $rootpath "$fid")
17082         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
17083 }
17084 run_test 154A "lfs path2fid and fid2path basic checks"
17085
17086 test_154B() {
17087         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
17088                 skip "Need MDS version at least 2.4.1"
17089
17090         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
17091         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
17092         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
17093         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
17094
17095         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
17096         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
17097
17098         # check that we get the same pathname
17099         echo "PFID: $PFID, name: $name"
17100         local FOUND=$($LFS fid2path $MOUNT "$PFID")
17101         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
17102         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
17103                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
17104
17105         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
17106 }
17107 run_test 154B "verify the ll_decode_linkea tool"
17108
17109 test_154a() {
17110         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17111         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17112         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
17113                 skip "Need MDS version at least 2.2.51"
17114         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
17115
17116         cp /etc/hosts $DIR/$tfile
17117
17118         fid=$($LFS path2fid $DIR/$tfile)
17119         rc=$?
17120         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
17121
17122         dot_lustre_fid_permission_check "$fid" $DIR ||
17123                 error "dot lustre permission check $fid failed"
17124
17125         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
17126
17127         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
17128
17129         touch $MOUNT/.lustre/file &&
17130                 error "creation is not allowed under .lustre"
17131
17132         mkdir $MOUNT/.lustre/dir &&
17133                 error "mkdir is not allowed under .lustre"
17134
17135         rm -rf $DIR/$tfile
17136 }
17137 run_test 154a "Open-by-FID"
17138
17139 test_154b() {
17140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17141         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17142         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17143         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
17144                 skip "Need MDS version at least 2.2.51"
17145
17146         local remote_dir=$DIR/$tdir/remote_dir
17147         local MDTIDX=1
17148         local rc=0
17149
17150         mkdir -p $DIR/$tdir
17151         $LFS mkdir -i $MDTIDX $remote_dir ||
17152                 error "create remote directory failed"
17153
17154         cp /etc/hosts $remote_dir/$tfile
17155
17156         fid=$($LFS path2fid $remote_dir/$tfile)
17157         rc=$?
17158         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
17159
17160         dot_lustre_fid_permission_check "$fid" $remote_dir ||
17161                 error "dot lustre permission check $fid failed"
17162         rm -rf $DIR/$tdir
17163 }
17164 run_test 154b "Open-by-FID for remote directory"
17165
17166 test_154c() {
17167         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
17168                 skip "Need MDS version at least 2.4.1"
17169
17170         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
17171         local FID1=$($LFS path2fid $DIR/$tfile.1)
17172         local FID2=$($LFS path2fid $DIR/$tfile.2)
17173         local FID3=$($LFS path2fid $DIR/$tfile.3)
17174
17175         local N=1
17176         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
17177                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
17178                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
17179                 local want=FID$N
17180                 [ "$FID" = "${!want}" ] ||
17181                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
17182                 N=$((N + 1))
17183         done
17184
17185         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
17186         do
17187                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
17188                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
17189                 N=$((N + 1))
17190         done
17191 }
17192 run_test 154c "lfs path2fid and fid2path multiple arguments"
17193
17194 test_154d() {
17195         remote_mds_nodsh && skip "remote MDS with nodsh"
17196         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
17197                 skip "Need MDS version at least 2.5.53"
17198
17199         if remote_mds; then
17200                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
17201         else
17202                 nid="0@lo"
17203         fi
17204         local proc_ofile="mdt.*.exports.'$nid'.open_files"
17205         local fd
17206         local cmd
17207
17208         rm -f $DIR/$tfile
17209         touch $DIR/$tfile
17210
17211         local fid=$($LFS path2fid $DIR/$tfile)
17212         # Open the file
17213         fd=$(free_fd)
17214         cmd="exec $fd<$DIR/$tfile"
17215         eval $cmd
17216         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
17217         echo "$fid_list" | grep "$fid"
17218         rc=$?
17219
17220         cmd="exec $fd>/dev/null"
17221         eval $cmd
17222         if [ $rc -ne 0 ]; then
17223                 error "FID $fid not found in open files list $fid_list"
17224         fi
17225 }
17226 run_test 154d "Verify open file fid"
17227
17228 test_154e()
17229 {
17230         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
17231                 skip "Need MDS version at least 2.6.50"
17232
17233         if ls -a $MOUNT | grep -q '^\.lustre$'; then
17234                 error ".lustre returned by readdir"
17235         fi
17236 }
17237 run_test 154e ".lustre is not returned by readdir"
17238
17239 test_154f() {
17240         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17241
17242         # create parent directory on a single MDT to avoid cross-MDT hardlinks
17243         mkdir_on_mdt0 $DIR/$tdir
17244         # test dirs inherit from its stripe
17245         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
17246         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
17247         cp /etc/hosts $DIR/$tdir/foo1/$tfile
17248         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
17249         touch $DIR/f
17250
17251         # get fid of parents
17252         local FID0=$($LFS path2fid $DIR/$tdir)
17253         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
17254         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
17255         local FID3=$($LFS path2fid $DIR)
17256
17257         # check that path2fid --parents returns expected <parent_fid>/name
17258         # 1) test for a directory (single parent)
17259         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
17260         [ "$parent" == "$FID0/foo1" ] ||
17261                 error "expected parent: $FID0/foo1, got: $parent"
17262
17263         # 2) test for a file with nlink > 1 (multiple parents)
17264         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
17265         echo "$parent" | grep -F "$FID1/$tfile" ||
17266                 error "$FID1/$tfile not returned in parent list"
17267         echo "$parent" | grep -F "$FID2/link" ||
17268                 error "$FID2/link not returned in parent list"
17269
17270         # 3) get parent by fid
17271         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
17272         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17273         echo "$parent" | grep -F "$FID1/$tfile" ||
17274                 error "$FID1/$tfile not returned in parent list (by fid)"
17275         echo "$parent" | grep -F "$FID2/link" ||
17276                 error "$FID2/link not returned in parent list (by fid)"
17277
17278         # 4) test for entry in root directory
17279         parent=$($LFS path2fid --parents $DIR/f)
17280         echo "$parent" | grep -F "$FID3/f" ||
17281                 error "$FID3/f not returned in parent list"
17282
17283         # 5) test it on root directory
17284         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
17285                 error "$MOUNT should not have parents"
17286
17287         # enable xattr caching and check that linkea is correctly updated
17288         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
17289         save_lustre_params client "llite.*.xattr_cache" > $save
17290         lctl set_param llite.*.xattr_cache 1
17291
17292         # 6.1) linkea update on rename
17293         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
17294
17295         # get parents by fid
17296         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17297         # foo1 should no longer be returned in parent list
17298         echo "$parent" | grep -F "$FID1" &&
17299                 error "$FID1 should no longer be in parent list"
17300         # the new path should appear
17301         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
17302                 error "$FID2/$tfile.moved is not in parent list"
17303
17304         # 6.2) linkea update on unlink
17305         rm -f $DIR/$tdir/foo2/link
17306         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17307         # foo2/link should no longer be returned in parent list
17308         echo "$parent" | grep -F "$FID2/link" &&
17309                 error "$FID2/link should no longer be in parent list"
17310         true
17311
17312         rm -f $DIR/f
17313         restore_lustre_params < $save
17314         rm -f $save
17315 }
17316 run_test 154f "get parent fids by reading link ea"
17317
17318 test_154g()
17319 {
17320         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
17321            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
17322                 skip "Need MDS version at least 2.6.92"
17323
17324         mkdir_on_mdt0 $DIR/$tdir
17325         llapi_fid_test -d $DIR/$tdir
17326 }
17327 run_test 154g "various llapi FID tests"
17328
17329 test_154h()
17330 {
17331         (( $CLIENT_VERSION >= $(version_code 2.15.55.1) )) ||
17332                 skip "Need client at least version 2.15.55.1"
17333
17334         # Create an empty file
17335         touch $DIR/$tfile
17336
17337         # Get FID (interactive mode) and save under $TMP/$tfile.log
17338         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
17339                 path2fid $DIR/$tfile
17340         EOF
17341
17342         fid=$(cat $TMP/$tfile.log)
17343         # $fid should not be empty
17344         [[ ! -z $fid ]] || error "FID is empty"
17345         $LFS rmfid $DIR "$fid" || error "rmfid failed for $fid"
17346 }
17347 run_test 154h "Verify interactive path2fid"
17348
17349 test_155_small_load() {
17350     local temp=$TMP/$tfile
17351     local file=$DIR/$tfile
17352
17353     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
17354         error "dd of=$temp bs=6096 count=1 failed"
17355     cp $temp $file
17356     cancel_lru_locks $OSC
17357     cmp $temp $file || error "$temp $file differ"
17358
17359     $TRUNCATE $temp 6000
17360     $TRUNCATE $file 6000
17361     cmp $temp $file || error "$temp $file differ (truncate1)"
17362
17363     echo "12345" >>$temp
17364     echo "12345" >>$file
17365     cmp $temp $file || error "$temp $file differ (append1)"
17366
17367     echo "12345" >>$temp
17368     echo "12345" >>$file
17369     cmp $temp $file || error "$temp $file differ (append2)"
17370
17371     rm -f $temp $file
17372     true
17373 }
17374
17375 test_155_big_load() {
17376         remote_ost_nodsh && skip "remote OST with nodsh"
17377
17378         local temp=$TMP/$tfile
17379         local file=$DIR/$tfile
17380
17381         free_min_max
17382         local cache_size=$(do_facet ost$((MAXI+1)) \
17383                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
17384
17385         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
17386         # pre-set value
17387         if [ -z "$cache_size" ]; then
17388                 cache_size=256
17389         fi
17390         local large_file_size=$((cache_size * 2))
17391
17392         echo "OSS cache size: $cache_size KB"
17393         echo "Large file size: $large_file_size KB"
17394
17395         [ $MAXV -le $large_file_size ] &&
17396                 skip_env "max available OST size needs > $large_file_size KB"
17397
17398         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
17399
17400         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
17401                 error "dd of=$temp bs=$large_file_size count=1k failed"
17402         cp $temp $file
17403         ls -lh $temp $file
17404         cancel_lru_locks osc
17405         cmp $temp $file || error "$temp $file differ"
17406
17407         rm -f $temp $file
17408         true
17409 }
17410
17411 save_writethrough() {
17412         local facets=$(get_facets OST)
17413
17414         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
17415 }
17416
17417 test_155a() {
17418         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17419
17420         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17421
17422         save_writethrough $p
17423
17424         set_cache read on
17425         set_cache writethrough on
17426         test_155_small_load
17427         restore_lustre_params < $p
17428         rm -f $p
17429 }
17430 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
17431
17432 test_155b() {
17433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17434
17435         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17436
17437         save_writethrough $p
17438
17439         set_cache read on
17440         set_cache writethrough off
17441         test_155_small_load
17442         restore_lustre_params < $p
17443         rm -f $p
17444 }
17445 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
17446
17447 test_155c() {
17448         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17449
17450         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17451
17452         save_writethrough $p
17453
17454         set_cache read off
17455         set_cache writethrough on
17456         test_155_small_load
17457         restore_lustre_params < $p
17458         rm -f $p
17459 }
17460 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
17461
17462 test_155d() {
17463         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17464
17465         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17466
17467         save_writethrough $p
17468
17469         set_cache read off
17470         set_cache writethrough off
17471         test_155_small_load
17472         restore_lustre_params < $p
17473         rm -f $p
17474 }
17475 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
17476
17477 test_155e() {
17478         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17479
17480         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17481
17482         save_writethrough $p
17483
17484         set_cache read on
17485         set_cache writethrough on
17486         test_155_big_load
17487         restore_lustre_params < $p
17488         rm -f $p
17489 }
17490 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
17491
17492 test_155f() {
17493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17494
17495         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17496
17497         save_writethrough $p
17498
17499         set_cache read on
17500         set_cache writethrough off
17501         test_155_big_load
17502         restore_lustre_params < $p
17503         rm -f $p
17504 }
17505 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
17506
17507 test_155g() {
17508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17509
17510         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17511
17512         save_writethrough $p
17513
17514         set_cache read off
17515         set_cache writethrough on
17516         test_155_big_load
17517         restore_lustre_params < $p
17518         rm -f $p
17519 }
17520 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
17521
17522 test_155h() {
17523         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17524
17525         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17526
17527         save_writethrough $p
17528
17529         set_cache read off
17530         set_cache writethrough off
17531         test_155_big_load
17532         restore_lustre_params < $p
17533         rm -f $p
17534 }
17535 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
17536
17537 test_156() {
17538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17539         remote_ost_nodsh && skip "remote OST with nodsh"
17540         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
17541                 skip "stats not implemented on old servers"
17542         [ "$ost1_FSTYPE" = "zfs" ] &&
17543                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
17544         (( CLIENT_VERSION == OST1_VERSION )) ||
17545                 skip "LU-13081: no interop testing for OSS cache"
17546
17547         local CPAGES=3
17548         local BEFORE
17549         local AFTER
17550         local file="$DIR/$tfile"
17551         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17552
17553         save_writethrough $p
17554         roc_hit_init
17555
17556         log "Turn on read and write cache"
17557         set_cache read on
17558         set_cache writethrough on
17559
17560         log "Write data and read it back."
17561         log "Read should be satisfied from the cache."
17562         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17563         BEFORE=$(roc_hit)
17564         cancel_lru_locks osc
17565         cat $file >/dev/null
17566         AFTER=$(roc_hit)
17567         if ! let "AFTER - BEFORE == CPAGES"; then
17568                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
17569         else
17570                 log "cache hits: before: $BEFORE, after: $AFTER"
17571         fi
17572
17573         log "Read again; it should be satisfied from the cache."
17574         BEFORE=$AFTER
17575         cancel_lru_locks osc
17576         cat $file >/dev/null
17577         AFTER=$(roc_hit)
17578         if ! let "AFTER - BEFORE == CPAGES"; then
17579                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
17580         else
17581                 log "cache hits:: before: $BEFORE, after: $AFTER"
17582         fi
17583
17584         log "Turn off the read cache and turn on the write cache"
17585         set_cache read off
17586         set_cache writethrough on
17587
17588         log "Read again; it should be satisfied from the cache."
17589         BEFORE=$(roc_hit)
17590         cancel_lru_locks osc
17591         cat $file >/dev/null
17592         AFTER=$(roc_hit)
17593         if ! let "AFTER - BEFORE == CPAGES"; then
17594                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
17595         else
17596                 log "cache hits:: before: $BEFORE, after: $AFTER"
17597         fi
17598
17599         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17600                 # > 2.12.56 uses pagecache if cached
17601                 log "Read again; it should not be satisfied from the cache."
17602                 BEFORE=$AFTER
17603                 cancel_lru_locks osc
17604                 cat $file >/dev/null
17605                 AFTER=$(roc_hit)
17606                 if ! let "AFTER - BEFORE == 0"; then
17607                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
17608                 else
17609                         log "cache hits:: before: $BEFORE, after: $AFTER"
17610                 fi
17611         fi
17612
17613         log "Write data and read it back."
17614         log "Read should be satisfied from the cache."
17615         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17616         BEFORE=$(roc_hit)
17617         cancel_lru_locks osc
17618         cat $file >/dev/null
17619         AFTER=$(roc_hit)
17620         if ! let "AFTER - BEFORE == CPAGES"; then
17621                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
17622         else
17623                 log "cache hits:: before: $BEFORE, after: $AFTER"
17624         fi
17625
17626         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17627                 # > 2.12.56 uses pagecache if cached
17628                 log "Read again; it should not be satisfied from the cache."
17629                 BEFORE=$AFTER
17630                 cancel_lru_locks osc
17631                 cat $file >/dev/null
17632                 AFTER=$(roc_hit)
17633                 if ! let "AFTER - BEFORE == 0"; then
17634                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
17635                 else
17636                         log "cache hits:: before: $BEFORE, after: $AFTER"
17637                 fi
17638         fi
17639
17640         log "Turn off read and write cache"
17641         set_cache read off
17642         set_cache writethrough off
17643
17644         log "Write data and read it back"
17645         log "It should not be satisfied from the cache."
17646         rm -f $file
17647         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17648         cancel_lru_locks osc
17649         BEFORE=$(roc_hit)
17650         cat $file >/dev/null
17651         AFTER=$(roc_hit)
17652         if ! let "AFTER - BEFORE == 0"; then
17653                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
17654         else
17655                 log "cache hits:: before: $BEFORE, after: $AFTER"
17656         fi
17657
17658         log "Turn on the read cache and turn off the write cache"
17659         set_cache read on
17660         set_cache writethrough off
17661
17662         log "Write data and read it back"
17663         log "It should not be satisfied from the cache."
17664         rm -f $file
17665         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17666         BEFORE=$(roc_hit)
17667         cancel_lru_locks osc
17668         cat $file >/dev/null
17669         AFTER=$(roc_hit)
17670         if ! let "AFTER - BEFORE == 0"; then
17671                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
17672         else
17673                 log "cache hits:: before: $BEFORE, after: $AFTER"
17674         fi
17675
17676         log "Read again; it should be satisfied from the cache."
17677         BEFORE=$(roc_hit)
17678         cancel_lru_locks osc
17679         cat $file >/dev/null
17680         AFTER=$(roc_hit)
17681         if ! let "AFTER - BEFORE == CPAGES"; then
17682                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
17683         else
17684                 log "cache hits:: before: $BEFORE, after: $AFTER"
17685         fi
17686
17687         restore_lustre_params < $p
17688         rm -f $p $file
17689 }
17690 run_test 156 "Verification of tunables"
17691
17692 test_160a() {
17693         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17694         remote_mds_nodsh && skip "remote MDS with nodsh"
17695         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17696                 skip "Need MDS version at least 2.2.0"
17697
17698         changelog_register || error "changelog_register failed"
17699         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17700         changelog_users $SINGLEMDS | grep -q $cl_user ||
17701                 error "User $cl_user not found in changelog_users"
17702
17703         mkdir_on_mdt0 $DIR/$tdir
17704
17705         # change something
17706         test_mkdir -p $DIR/$tdir/pics/2008/zachy
17707         changelog_clear 0 || error "changelog_clear failed"
17708         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
17709         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
17710         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17711         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17712         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17713         rm $DIR/$tdir/pics/desktop.jpg
17714
17715         echo "verifying changelog mask"
17716         changelog_chmask "-MKDIR"
17717         changelog_chmask "-CLOSE"
17718
17719         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
17720         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
17721
17722         changelog_chmask "+MKDIR"
17723         changelog_chmask "+CLOSE"
17724
17725         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
17726         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
17727
17728         MKDIRS=$(changelog_dump | grep -c "MKDIR")
17729         CLOSES=$(changelog_dump | grep -c "CLOSE")
17730         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
17731         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
17732
17733         # verify contents
17734         echo "verifying target fid"
17735         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
17736         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
17737         [ "$fidc" == "$fidf" ] ||
17738                 error "changelog '$tfile' fid $fidc != file fid $fidf"
17739         echo "verifying parent fid"
17740         # The FID returned from the Changelog may be the directory shard on
17741         # a different MDT, and not the FID returned by path2fid on the parent.
17742         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
17743         # since this is what will matter when recreating this file in the tree.
17744         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
17745         local pathp=$($LFS fid2path $MOUNT "$fidp")
17746         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
17747                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
17748
17749         echo "getting records for $cl_user"
17750         changelog_users $SINGLEMDS
17751         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
17752         local nclr=3
17753         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
17754                 error "changelog_clear failed"
17755         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
17756         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
17757         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
17758                 error "user index expect $user_rec1 + $nclr != $user_rec2"
17759
17760         local min0_rec=$(changelog_users $SINGLEMDS |
17761                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
17762         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
17763                           awk '{ print $1; exit; }')
17764
17765         changelog_dump | tail -n 5
17766         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
17767         [ $first_rec == $((min0_rec + 1)) ] ||
17768                 error "first index should be $min0_rec + 1 not $first_rec"
17769
17770         # LU-3446 changelog index reset on MDT restart
17771         local cur_rec1=$(changelog_users $SINGLEMDS |
17772                          awk '/^current.index:/ { print $NF }')
17773         changelog_clear 0 ||
17774                 error "clear all changelog records for $cl_user failed"
17775         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
17776         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
17777                 error "Fail to start $SINGLEMDS"
17778         local cur_rec2=$(changelog_users $SINGLEMDS |
17779                          awk '/^current.index:/ { print $NF }')
17780         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
17781         [ $cur_rec1 == $cur_rec2 ] ||
17782                 error "current index should be $cur_rec1 not $cur_rec2"
17783
17784         echo "verifying users from this test are deregistered"
17785         changelog_deregister || error "changelog_deregister failed"
17786         changelog_users $SINGLEMDS | grep -q $cl_user &&
17787                 error "User '$cl_user' still in changelog_users"
17788
17789         # lctl get_param -n mdd.*.changelog_users
17790         # current_index: 144
17791         # ID    index (idle seconds)
17792         # cl3   144   (2) mask=<list>
17793         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
17794                 # this is the normal case where all users were deregistered
17795                 # make sure no new records are added when no users are present
17796                 local last_rec1=$(changelog_users $SINGLEMDS |
17797                                   awk '/^current.index:/ { print $NF }')
17798                 touch $DIR/$tdir/chloe
17799                 local last_rec2=$(changelog_users $SINGLEMDS |
17800                                   awk '/^current.index:/ { print $NF }')
17801                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
17802                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
17803         else
17804                 # any changelog users must be leftovers from a previous test
17805                 changelog_users $SINGLEMDS
17806                 echo "other changelog users; can't verify off"
17807         fi
17808 }
17809 run_test 160a "changelog sanity"
17810
17811 test_160b() { # LU-3587
17812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17813         remote_mds_nodsh && skip "remote MDS with nodsh"
17814         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17815                 skip "Need MDS version at least 2.2.0"
17816
17817         changelog_register || error "changelog_register failed"
17818         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17819         changelog_users $SINGLEMDS | grep -q $cl_user ||
17820                 error "User '$cl_user' not found in changelog_users"
17821
17822         local longname1=$(str_repeat a 255)
17823         local longname2=$(str_repeat b 255)
17824
17825         cd $DIR
17826         echo "creating very long named file"
17827         touch $longname1 || error "create of '$longname1' failed"
17828         echo "renaming very long named file"
17829         mv $longname1 $longname2
17830
17831         changelog_dump | grep RENME | tail -n 5
17832         rm -f $longname2
17833 }
17834 run_test 160b "Verify that very long rename doesn't crash in changelog"
17835
17836 test_160c() {
17837         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17838         remote_mds_nodsh && skip "remote MDS with nodsh"
17839
17840         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
17841                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
17842                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
17843                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
17844
17845         local rc=0
17846
17847         # Registration step
17848         changelog_register || error "changelog_register failed"
17849
17850         rm -rf $DIR/$tdir
17851         mkdir -p $DIR/$tdir
17852         $MCREATE $DIR/$tdir/foo_160c
17853         changelog_chmask "-TRUNC"
17854         $TRUNCATE $DIR/$tdir/foo_160c 200
17855         changelog_chmask "+TRUNC"
17856         $TRUNCATE $DIR/$tdir/foo_160c 199
17857         changelog_dump | tail -n 5
17858         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
17859         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
17860 }
17861 run_test 160c "verify that changelog log catch the truncate event"
17862
17863 test_160d() {
17864         remote_mds_nodsh && skip "remote MDS with nodsh"
17865         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17866         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17867         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
17868                 skip "Need MDS version at least 2.7.60"
17869
17870         # Registration step
17871         changelog_register || error "changelog_register failed"
17872
17873         mkdir -p $DIR/$tdir/migrate_dir
17874         changelog_clear 0 || error "changelog_clear failed"
17875
17876         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
17877         changelog_dump | tail -n 5
17878         local migrates=$(changelog_dump | grep -c "MIGRT")
17879         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
17880 }
17881 run_test 160d "verify that changelog log catch the migrate event"
17882
17883 test_160e() {
17884         remote_mds_nodsh && skip "remote MDS with nodsh"
17885
17886         # Create a user
17887         changelog_register || error "changelog_register failed"
17888
17889         local MDT0=$(facet_svc $SINGLEMDS)
17890         local rc
17891
17892         # No user (expect fail)
17893         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
17894         rc=$?
17895         if [ $rc -eq 0 ]; then
17896                 error "Should fail without user"
17897         elif [ $rc -ne 4 ]; then
17898                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
17899         fi
17900
17901         # Delete a future user (expect fail)
17902         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
17903         rc=$?
17904         if [ $rc -eq 0 ]; then
17905                 error "Deleted non-existant user cl77"
17906         elif [ $rc -ne 2 ]; then
17907                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
17908         fi
17909
17910         # Clear to a bad index (1 billion should be safe)
17911         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
17912         rc=$?
17913
17914         if [ $rc -eq 0 ]; then
17915                 error "Successfully cleared to invalid CL index"
17916         elif [ $rc -ne 22 ]; then
17917                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
17918         fi
17919 }
17920 run_test 160e "changelog negative testing (should return errors)"
17921
17922 test_160f() {
17923         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17924         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17925                 skip "Need MDS version at least 2.10.56"
17926
17927         local mdts=$(comma_list $(mdts_nodes))
17928
17929         # Create a user
17930         changelog_register || error "first changelog_register failed"
17931         changelog_register || error "second changelog_register failed"
17932         local cl_users
17933         declare -A cl_user1
17934         declare -A cl_user2
17935         local user_rec1
17936         local user_rec2
17937         local i
17938
17939         # generate some changelog records to accumulate on each MDT
17940         # use all_char because created files should be evenly distributed
17941         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17942                 error "test_mkdir $tdir failed"
17943         log "$(date +%s): creating first files"
17944         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17945                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
17946                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
17947         done
17948
17949         # check changelogs have been generated
17950         local start=$SECONDS
17951         local idle_time=$((MDSCOUNT * 5 + 5))
17952         local nbcl=$(changelog_dump | wc -l)
17953         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17954
17955         for param in "changelog_max_idle_time=$idle_time" \
17956                      "changelog_gc=1" \
17957                      "changelog_min_gc_interval=2" \
17958                      "changelog_min_free_cat_entries=3"; do
17959                 local MDT0=$(facet_svc $SINGLEMDS)
17960                 local var="${param%=*}"
17961                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17962
17963                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17964                 do_nodes $mdts $LCTL set_param mdd.*.$param
17965         done
17966
17967         # force cl_user2 to be idle (1st part), but also cancel the
17968         # cl_user1 records so that it is not evicted later in the test.
17969         local sleep1=$((idle_time / 2))
17970         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
17971         sleep $sleep1
17972
17973         # simulate changelog catalog almost full
17974         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
17975         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
17976
17977         for i in $(seq $MDSCOUNT); do
17978                 cl_users=(${CL_USERS[mds$i]})
17979                 cl_user1[mds$i]="${cl_users[0]}"
17980                 cl_user2[mds$i]="${cl_users[1]}"
17981
17982                 [ -n "${cl_user1[mds$i]}" ] ||
17983                         error "mds$i: no user registered"
17984                 [ -n "${cl_user2[mds$i]}" ] ||
17985                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17986
17987                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17988                 [ -n "$user_rec1" ] ||
17989                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17990                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17991                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17992                 [ -n "$user_rec2" ] ||
17993                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17994                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17995                      "$user_rec1 + 2 == $user_rec2"
17996                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17997                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17998                               "$user_rec1 + 2, but is $user_rec2"
17999                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
18000                 [ -n "$user_rec2" ] ||
18001                         error "mds$i: User ${cl_user2[mds$i]} not registered"
18002                 [ $user_rec1 == $user_rec2 ] ||
18003                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
18004                               "$user_rec1, but is $user_rec2"
18005         done
18006
18007         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
18008         local sleep2=$((idle_time - (SECONDS - start) + 1))
18009         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
18010         sleep $sleep2
18011
18012         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
18013         # cl_user1 should be OK because it recently processed records.
18014         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
18015         for ((i = 0; i < MDSCOUNT * 2; i++)); do
18016                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
18017                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
18018         done
18019
18020         # ensure gc thread is done
18021         for i in $(mdts_nodes); do
18022                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
18023                         error "$i: GC-thread not done"
18024         done
18025
18026         local first_rec
18027         for (( i = 1; i <= MDSCOUNT; i++ )); do
18028                 # check cl_user1 still registered
18029                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
18030                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18031                 # check cl_user2 unregistered
18032                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
18033                         error "mds$i: User ${cl_user2[mds$i]} still registered"
18034
18035                 # check changelogs are present and starting at $user_rec1 + 1
18036                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18037                 [ -n "$user_rec1" ] ||
18038                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18039                 first_rec=$($LFS changelog $(facet_svc mds$i) |
18040                             awk '{ print $1; exit; }')
18041
18042                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
18043                 [ $((user_rec1 + 1)) == $first_rec ] ||
18044                         error "mds$i: rec $first_rec != $user_rec1 + 1"
18045         done
18046 }
18047 run_test 160f "changelog garbage collect (timestamped users)"
18048
18049 test_160g() {
18050         remote_mds_nodsh && skip "remote MDS with nodsh"
18051         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
18052                 skip "Need MDS version at least 2.14.55"
18053
18054         local mdts=$(comma_list $(mdts_nodes))
18055
18056         # Create a user
18057         changelog_register || error "first changelog_register failed"
18058         changelog_register || error "second changelog_register failed"
18059         local cl_users
18060         declare -A cl_user1
18061         declare -A cl_user2
18062         local user_rec1
18063         local user_rec2
18064         local i
18065
18066         # generate some changelog records to accumulate on each MDT
18067         # use all_char because created files should be evenly distributed
18068         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18069                 error "test_mkdir $tdir failed"
18070         for ((i = 0; i < MDSCOUNT; i++)); do
18071                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18072                         error "create $DIR/$tdir/d$i.1 failed"
18073         done
18074
18075         # check changelogs have been generated
18076         local nbcl=$(changelog_dump | wc -l)
18077         (( $nbcl > 0 )) || error "no changelogs found"
18078
18079         # reduce the max_idle_indexes value to make sure we exceed it
18080         for param in "changelog_max_idle_indexes=2" \
18081                      "changelog_gc=1" \
18082                      "changelog_min_gc_interval=2"; do
18083                 local MDT0=$(facet_svc $SINGLEMDS)
18084                 local var="${param%=*}"
18085                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18086
18087                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18088                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
18089                         error "unable to set mdd.*.$param"
18090         done
18091
18092         local start=$SECONDS
18093         for i in $(seq $MDSCOUNT); do
18094                 cl_users=(${CL_USERS[mds$i]})
18095                 cl_user1[mds$i]="${cl_users[0]}"
18096                 cl_user2[mds$i]="${cl_users[1]}"
18097
18098                 [ -n "${cl_user1[mds$i]}" ] ||
18099                         error "mds$i: user1 is not registered"
18100                 [ -n "${cl_user2[mds$i]}" ] ||
18101                         error "mds$i: only ${cl_user1[mds$i]} is registered"
18102
18103                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18104                 [ -n "$user_rec1" ] ||
18105                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
18106                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
18107                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18108                 [ -n "$user_rec2" ] ||
18109                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
18110                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
18111                      "$user_rec1 + 2 == $user_rec2"
18112                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
18113                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
18114                               "expected $user_rec1 + 2, but is $user_rec2"
18115                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
18116                 [ -n "$user_rec2" ] ||
18117                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
18118                 [ $user_rec1 == $user_rec2 ] ||
18119                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
18120                               "expected $user_rec1, but is $user_rec2"
18121         done
18122
18123         # ensure we are past the previous changelog_min_gc_interval set above
18124         local sleep2=$((start + 2 - SECONDS))
18125         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18126         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
18127         # cl_user1 should be OK because it recently processed records.
18128         for ((i = 0; i < MDSCOUNT; i++)); do
18129                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
18130                         error "create $DIR/$tdir/d$i.3 failed"
18131         done
18132
18133         # ensure gc thread is done
18134         for i in $(mdts_nodes); do
18135                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
18136                         error "$i: GC-thread not done"
18137         done
18138
18139         local first_rec
18140         for (( i = 1; i <= MDSCOUNT; i++ )); do
18141                 # check cl_user1 still registered
18142                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
18143                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
18144                 # check cl_user2 unregistered
18145                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
18146                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
18147
18148                 # check changelogs are present and starting at $user_rec1 + 1
18149                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18150                 [ -n "$user_rec1" ] ||
18151                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
18152                 first_rec=$($LFS changelog $(facet_svc mds$i) |
18153                             awk '{ print $1; exit; }')
18154
18155                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
18156                 [ $((user_rec1 + 1)) == $first_rec ] ||
18157                         error "mds$i: rec $first_rec != $user_rec1 + 1"
18158         done
18159 }
18160 run_test 160g "changelog garbage collect on idle records"
18161
18162 test_160h() {
18163         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18164         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
18165                 skip "Need MDS version at least 2.10.56"
18166
18167         local mdts=$(comma_list $(mdts_nodes))
18168
18169         # Create a user
18170         changelog_register || error "first changelog_register failed"
18171         changelog_register || error "second changelog_register failed"
18172         local cl_users
18173         declare -A cl_user1
18174         declare -A cl_user2
18175         local user_rec1
18176         local user_rec2
18177         local i
18178
18179         # generate some changelog records to accumulate on each MDT
18180         # use all_char because created files should be evenly distributed
18181         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18182                 error "test_mkdir $tdir failed"
18183         for ((i = 0; i < MDSCOUNT; i++)); do
18184                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18185                         error "create $DIR/$tdir/d$i.1 failed"
18186         done
18187
18188         # check changelogs have been generated
18189         local nbcl=$(changelog_dump | wc -l)
18190         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18191
18192         for param in "changelog_max_idle_time=10" \
18193                      "changelog_gc=1" \
18194                      "changelog_min_gc_interval=2"; do
18195                 local MDT0=$(facet_svc $SINGLEMDS)
18196                 local var="${param%=*}"
18197                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18198
18199                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18200                 do_nodes $mdts $LCTL set_param mdd.*.$param
18201         done
18202
18203         # force cl_user2 to be idle (1st part)
18204         sleep 9
18205
18206         for i in $(seq $MDSCOUNT); do
18207                 cl_users=(${CL_USERS[mds$i]})
18208                 cl_user1[mds$i]="${cl_users[0]}"
18209                 cl_user2[mds$i]="${cl_users[1]}"
18210
18211                 [ -n "${cl_user1[mds$i]}" ] ||
18212                         error "mds$i: no user registered"
18213                 [ -n "${cl_user2[mds$i]}" ] ||
18214                         error "mds$i: only ${cl_user2[mds$i]} is registered"
18215
18216                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18217                 [ -n "$user_rec1" ] ||
18218                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18219                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
18220                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18221                 [ -n "$user_rec2" ] ||
18222                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18223                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
18224                      "$user_rec1 + 2 == $user_rec2"
18225                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
18226                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
18227                               "$user_rec1 + 2, but is $user_rec2"
18228                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
18229                 [ -n "$user_rec2" ] ||
18230                         error "mds$i: User ${cl_user2[mds$i]} not registered"
18231                 [ $user_rec1 == $user_rec2 ] ||
18232                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
18233                               "$user_rec1, but is $user_rec2"
18234         done
18235
18236         # force cl_user2 to be idle (2nd part) and to reach
18237         # changelog_max_idle_time
18238         sleep 2
18239
18240         # force each GC-thread start and block then
18241         # one per MDT/MDD, set fail_val accordingly
18242         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
18243         do_nodes $mdts $LCTL set_param fail_loc=0x1316
18244
18245         # generate more changelogs to trigger fail_loc
18246         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
18247                 error "create $DIR/$tdir/${tfile}bis failed"
18248
18249         # stop MDT to stop GC-thread, should be done in back-ground as it will
18250         # block waiting for the thread to be released and exit
18251         declare -A stop_pids
18252         for i in $(seq $MDSCOUNT); do
18253                 stop mds$i &
18254                 stop_pids[mds$i]=$!
18255         done
18256
18257         for i in $(mdts_nodes); do
18258                 local facet
18259                 local nb=0
18260                 local facets=$(facets_up_on_host $i)
18261
18262                 for facet in ${facets//,/ }; do
18263                         if [[ $facet == mds* ]]; then
18264                                 nb=$((nb + 1))
18265                         fi
18266                 done
18267                 # ensure each MDS's gc threads are still present and all in "R"
18268                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
18269                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
18270                         error "$i: expected $nb GC-thread"
18271                 wait_update $i \
18272                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
18273                         "R" 20 ||
18274                         error "$i: GC-thread not found in R-state"
18275                 # check umounts of each MDT on MDS have reached kthread_stop()
18276                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
18277                         error "$i: expected $nb umount"
18278                 wait_update $i \
18279                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
18280                         error "$i: umount not found in D-state"
18281         done
18282
18283         # release all GC-threads
18284         do_nodes $mdts $LCTL set_param fail_loc=0
18285
18286         # wait for MDT stop to complete
18287         for i in $(seq $MDSCOUNT); do
18288                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
18289         done
18290
18291         # XXX
18292         # may try to check if any orphan changelog records are present
18293         # via ldiskfs/zfs and llog_reader...
18294
18295         # re-start/mount MDTs
18296         for i in $(seq $MDSCOUNT); do
18297                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
18298                         error "Fail to start mds$i"
18299         done
18300
18301         local first_rec
18302         for i in $(seq $MDSCOUNT); do
18303                 # check cl_user1 still registered
18304                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
18305                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18306                 # check cl_user2 unregistered
18307                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
18308                         error "mds$i: User ${cl_user2[mds$i]} still registered"
18309
18310                 # check changelogs are present and starting at $user_rec1 + 1
18311                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18312                 [ -n "$user_rec1" ] ||
18313                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18314                 first_rec=$($LFS changelog $(facet_svc mds$i) |
18315                             awk '{ print $1; exit; }')
18316
18317                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
18318                 [ $((user_rec1 + 1)) == $first_rec ] ||
18319                         error "mds$i: first index should be $user_rec1 + 1, " \
18320                               "but is $first_rec"
18321         done
18322 }
18323 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
18324               "during mount"
18325
18326 test_160i() {
18327
18328         local mdts=$(comma_list $(mdts_nodes))
18329
18330         changelog_register || error "first changelog_register failed"
18331
18332         # generate some changelog records to accumulate on each MDT
18333         # use all_char because created files should be evenly distributed
18334         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18335                 error "test_mkdir $tdir failed"
18336         for ((i = 0; i < MDSCOUNT; i++)); do
18337                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18338                         error "create $DIR/$tdir/d$i.1 failed"
18339         done
18340
18341         # check changelogs have been generated
18342         local nbcl=$(changelog_dump | wc -l)
18343         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18344
18345         # simulate race between register and unregister
18346         # XXX as fail_loc is set per-MDS, with DNE configs the race
18347         # simulation will only occur for one MDT per MDS and for the
18348         # others the normal race scenario will take place
18349         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
18350         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
18351         do_nodes $mdts $LCTL set_param fail_val=1
18352
18353         # unregister 1st user
18354         changelog_deregister &
18355         local pid1=$!
18356         # wait some time for deregister work to reach race rdv
18357         sleep 2
18358         # register 2nd user
18359         changelog_register || error "2nd user register failed"
18360
18361         wait $pid1 || error "1st user deregister failed"
18362
18363         local i
18364         local last_rec
18365         declare -A LAST_REC
18366         for i in $(seq $MDSCOUNT); do
18367                 if changelog_users mds$i | grep "^cl"; then
18368                         # make sure new records are added with one user present
18369                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
18370                                           awk '/^current.index:/ { print $NF }')
18371                 else
18372                         error "mds$i has no user registered"
18373                 fi
18374         done
18375
18376         # generate more changelog records to accumulate on each MDT
18377         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
18378                 error "create $DIR/$tdir/${tfile}bis failed"
18379
18380         for i in $(seq $MDSCOUNT); do
18381                 last_rec=$(changelog_users $SINGLEMDS |
18382                            awk '/^current.index:/ { print $NF }')
18383                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
18384                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
18385                         error "changelogs are off on mds$i"
18386         done
18387 }
18388 run_test 160i "changelog user register/unregister race"
18389
18390 test_160j() {
18391         remote_mds_nodsh && skip "remote MDS with nodsh"
18392         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
18393                 skip "Need MDS version at least 2.12.56"
18394
18395         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
18396         stack_trap "umount $MOUNT2" EXIT
18397
18398         changelog_register || error "first changelog_register failed"
18399         stack_trap "changelog_deregister" EXIT
18400
18401         # generate some changelog
18402         # use all_char because created files should be evenly distributed
18403         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18404                 error "mkdir $tdir failed"
18405         for ((i = 0; i < MDSCOUNT; i++)); do
18406                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18407                         error "create $DIR/$tdir/d$i.1 failed"
18408         done
18409
18410         # open the changelog device
18411         exec 3>/dev/changelog-$FSNAME-MDT0000
18412         stack_trap "exec 3>&-" EXIT
18413         exec 4</dev/changelog-$FSNAME-MDT0000
18414         stack_trap "exec 4<&-" EXIT
18415
18416         # umount the first lustre mount
18417         umount $MOUNT
18418         stack_trap "mount_client $MOUNT" EXIT
18419
18420         # read changelog, which may or may not fail, but should not crash
18421         cat <&4 >/dev/null
18422
18423         # clear changelog
18424         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18425         changelog_users $SINGLEMDS | grep -q $cl_user ||
18426                 error "User $cl_user not found in changelog_users"
18427
18428         printf 'clear:'$cl_user':0' >&3
18429 }
18430 run_test 160j "client can be umounted while its chanangelog is being used"
18431
18432 test_160k() {
18433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18434         remote_mds_nodsh && skip "remote MDS with nodsh"
18435
18436         mkdir -p $DIR/$tdir/1/1
18437
18438         changelog_register || error "changelog_register failed"
18439         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18440
18441         changelog_users $SINGLEMDS | grep -q $cl_user ||
18442                 error "User '$cl_user' not found in changelog_users"
18443 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
18444         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
18445         rmdir $DIR/$tdir/1/1 & sleep 1
18446         mkdir $DIR/$tdir/2
18447         touch $DIR/$tdir/2/2
18448         rm -rf $DIR/$tdir/2
18449
18450         wait
18451         sleep 4
18452
18453         changelog_dump | grep rmdir || error "rmdir not recorded"
18454 }
18455 run_test 160k "Verify that changelog records are not lost"
18456
18457 # Verifies that a file passed as a parameter has recently had an operation
18458 # performed on it that has generated an MTIME changelog which contains the
18459 # correct parent FID. As files might reside on a different MDT from the
18460 # parent directory in DNE configurations, the FIDs are translated to paths
18461 # before being compared, which should be identical
18462 compare_mtime_changelog() {
18463         local file="${1}"
18464         local mdtidx
18465         local mtime
18466         local cl_fid
18467         local pdir
18468         local dir
18469
18470         mdtidx=$($LFS getstripe --mdt-index $file)
18471         mdtidx=$(printf "%04x" $mdtidx)
18472
18473         # Obtain the parent FID from the MTIME changelog
18474         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
18475         [ -z "$mtime" ] && error "MTIME changelog not recorded"
18476
18477         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
18478         [ -z "$cl_fid" ] && error "parent FID not present"
18479
18480         # Verify that the path for the parent FID is the same as the path for
18481         # the test directory
18482         pdir=$($LFS fid2path $MOUNT "$cl_fid")
18483
18484         dir=$(dirname $1)
18485
18486         [[ "${pdir%/}" == "$dir" ]] ||
18487                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
18488 }
18489
18490 test_160l() {
18491         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18492
18493         remote_mds_nodsh && skip "remote MDS with nodsh"
18494         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
18495                 skip "Need MDS version at least 2.13.55"
18496
18497         local cl_user
18498
18499         changelog_register || error "changelog_register failed"
18500         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18501
18502         changelog_users $SINGLEMDS | grep -q $cl_user ||
18503                 error "User '$cl_user' not found in changelog_users"
18504
18505         # Clear some types so that MTIME changelogs are generated
18506         changelog_chmask "-CREAT"
18507         changelog_chmask "-CLOSE"
18508
18509         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
18510
18511         # Test CL_MTIME during setattr
18512         touch $DIR/$tdir/$tfile
18513         compare_mtime_changelog $DIR/$tdir/$tfile
18514
18515         # Test CL_MTIME during close
18516         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
18517         compare_mtime_changelog $DIR/$tdir/${tfile}_2
18518 }
18519 run_test 160l "Verify that MTIME changelog records contain the parent FID"
18520
18521 test_160m() {
18522         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18523         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18524                 skip "Need MDS version at least 2.14.51"
18525         local cl_users
18526         local cl_user1
18527         local cl_user2
18528         local pid1
18529
18530         # Create a user
18531         changelog_register || error "first changelog_register failed"
18532         changelog_register || error "second changelog_register failed"
18533
18534         cl_users=(${CL_USERS[mds1]})
18535         cl_user1="${cl_users[0]}"
18536         cl_user2="${cl_users[1]}"
18537         # generate some changelog records to accumulate on MDT0
18538         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18539         createmany -m $DIR/$tdir/$tfile 50 ||
18540                 error "create $DIR/$tdir/$tfile failed"
18541         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18542         rm -f $DIR/$tdir
18543
18544         # check changelogs have been generated
18545         local nbcl=$(changelog_dump | wc -l)
18546         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18547
18548 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
18549         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
18550
18551         __changelog_clear mds1 $cl_user1 +10
18552         __changelog_clear mds1 $cl_user2 0 &
18553         pid1=$!
18554         sleep 2
18555         __changelog_clear mds1 $cl_user1 0 ||
18556                 error "fail to cancel record for $cl_user1"
18557         wait $pid1
18558         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
18559 }
18560 run_test 160m "Changelog clear race"
18561
18562 test_160n() {
18563         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18564         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18565                 skip "Need MDS version at least 2.14.51"
18566         local cl_users
18567         local cl_user1
18568         local cl_user2
18569         local pid1
18570         local first_rec
18571         local last_rec=0
18572
18573         # Create a user
18574         changelog_register || error "first changelog_register failed"
18575
18576         cl_users=(${CL_USERS[mds1]})
18577         cl_user1="${cl_users[0]}"
18578
18579         # generate some changelog records to accumulate on MDT0
18580         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18581         first_rec=$(changelog_users $SINGLEMDS |
18582                         awk '/^current.index:/ { print $NF }')
18583         while (( last_rec < (( first_rec + 65000)) )); do
18584                 createmany -m $DIR/$tdir/$tfile 10000 ||
18585                         error "create $DIR/$tdir/$tfile failed"
18586
18587                 for i in $(seq 0 10000); do
18588                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
18589                                 > /dev/null
18590                 done
18591
18592                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
18593                         error "unlinkmany failed unlink"
18594                 last_rec=$(changelog_users $SINGLEMDS |
18595                         awk '/^current.index:/ { print $NF }')
18596                 echo last record $last_rec
18597                 (( last_rec == 0 )) && error "no changelog found"
18598         done
18599
18600 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
18601         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
18602
18603         __changelog_clear mds1 $cl_user1 0 &
18604         pid1=$!
18605         sleep 2
18606         __changelog_clear mds1 $cl_user1 0 ||
18607                 error "fail to cancel record for $cl_user1"
18608         wait $pid1
18609         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
18610 }
18611 run_test 160n "Changelog destroy race"
18612
18613 test_160o() {
18614         local mdt="$(facet_svc $SINGLEMDS)"
18615
18616         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18617         remote_mds_nodsh && skip "remote MDS with nodsh"
18618         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
18619                 skip "Need MDS version at least 2.14.52"
18620
18621         changelog_register --user test_160o -m unlnk+close+open ||
18622                 error "changelog_register failed"
18623
18624         do_facet $SINGLEMDS $LCTL --device $mdt \
18625                                 changelog_register -u "Tt3_-#" &&
18626                 error "bad symbols in name should fail"
18627
18628         do_facet $SINGLEMDS $LCTL --device $mdt \
18629                                 changelog_register -u test_160o &&
18630                 error "the same name registration should fail"
18631
18632         do_facet $SINGLEMDS $LCTL --device $mdt \
18633                         changelog_register -u test_160toolongname &&
18634                 error "too long name registration should fail"
18635
18636         changelog_chmask "MARK+HSM"
18637         lctl get_param mdd.*.changelog*mask
18638         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18639         changelog_users $SINGLEMDS | grep -q $cl_user ||
18640                 error "User $cl_user not found in changelog_users"
18641         #verify username
18642         echo $cl_user | grep -q test_160o ||
18643                 error "User $cl_user has no specific name 'test160o'"
18644
18645         # change something
18646         changelog_clear 0 || error "changelog_clear failed"
18647         # generate some changelog records to accumulate on MDT0
18648         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18649         touch $DIR/$tdir/$tfile                 # open 1
18650
18651         OPENS=$(changelog_dump | grep -c "OPEN")
18652         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
18653
18654         # must be no MKDIR it wasn't set as user mask
18655         MKDIR=$(changelog_dump | grep -c "MKDIR")
18656         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
18657
18658         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
18659                                 mdd.$mdt.changelog_current_mask -n)
18660         # register maskless user
18661         changelog_register || error "changelog_register failed"
18662         # effective mask should be not changed because it is not minimal
18663         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18664                                 mdd.$mdt.changelog_current_mask -n)
18665         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
18666         # set server mask to minimal value
18667         changelog_chmask "MARK"
18668         # check effective mask again, should be treated as DEFMASK now
18669         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18670                                 mdd.$mdt.changelog_current_mask -n)
18671         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18672
18673         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
18674                 # set server mask back to some value
18675                 changelog_chmask "CLOSE,UNLNK"
18676                 # check effective mask again, should not remain as DEFMASK
18677                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
18678                                 mdd.$mdt.changelog_current_mask -n)
18679                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
18680         fi
18681
18682         do_facet $SINGLEMDS $LCTL --device $mdt \
18683                                 changelog_deregister -u test_160o ||
18684                 error "cannot deregister by name"
18685 }
18686 run_test 160o "changelog user name and mask"
18687
18688 test_160p() {
18689         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18690         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18691                 skip "Need MDS version at least 2.14.51"
18692         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
18693         local cl_users
18694         local cl_user1
18695         local entry_count
18696
18697         # Create a user
18698         changelog_register || error "first changelog_register failed"
18699
18700         cl_users=(${CL_USERS[mds1]})
18701         cl_user1="${cl_users[0]}"
18702
18703         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18704         createmany -m $DIR/$tdir/$tfile 50 ||
18705                 error "create $DIR/$tdir/$tfile failed"
18706         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18707         rm -rf $DIR/$tdir
18708
18709         # check changelogs have been generated
18710         entry_count=$(changelog_dump | wc -l)
18711         ((entry_count != 0)) || error "no changelog entries found"
18712
18713         # remove changelog_users and check that orphan entries are removed
18714         stop mds1
18715         local dev=$(mdsdevname 1)
18716         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
18717         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
18718         entry_count=$(changelog_dump | wc -l)
18719         ((entry_count == 0)) ||
18720                 error "found $entry_count changelog entries, expected none"
18721 }
18722 run_test 160p "Changelog orphan cleanup with no users"
18723
18724 test_160q() {
18725         local mdt="$(facet_svc $SINGLEMDS)"
18726         local clu
18727
18728         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18729         remote_mds_nodsh && skip "remote MDS with nodsh"
18730         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
18731                 skip "Need MDS version at least 2.14.54"
18732
18733         # set server mask to minimal value like server init does
18734         changelog_chmask "MARK"
18735         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
18736                 error "changelog_register failed"
18737         # check effective mask again, should be treated as DEFMASK now
18738         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18739                                 mdd.$mdt.changelog_current_mask -n)
18740         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
18741                 error "changelog_deregister failed"
18742         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18743 }
18744 run_test 160q "changelog effective mask is DEFMASK if not set"
18745
18746 test_160s() {
18747         remote_mds_nodsh && skip "remote MDS with nodsh"
18748         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
18749                 skip "Need MDS version at least 2.14.55"
18750
18751         local mdts=$(comma_list $(mdts_nodes))
18752
18753         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
18754         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
18755                                        fail_val=$((24 * 3600 * 10))
18756
18757         # Create a user which is 10 days old
18758         changelog_register || error "first changelog_register failed"
18759         local cl_users
18760         declare -A cl_user1
18761         local i
18762
18763         # generate some changelog records to accumulate on each MDT
18764         # use all_char because created files should be evenly distributed
18765         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18766                 error "test_mkdir $tdir failed"
18767         for ((i = 0; i < MDSCOUNT; i++)); do
18768                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18769                         error "create $DIR/$tdir/d$i.1 failed"
18770         done
18771
18772         # check changelogs have been generated
18773         local nbcl=$(changelog_dump | wc -l)
18774         (( nbcl > 0 )) || error "no changelogs found"
18775
18776         # reduce the max_idle_indexes value to make sure we exceed it
18777         for param in "changelog_max_idle_indexes=2097446912" \
18778                      "changelog_max_idle_time=2592000" \
18779                      "changelog_gc=1" \
18780                      "changelog_min_gc_interval=2"; do
18781                 local MDT0=$(facet_svc $SINGLEMDS)
18782                 local var="${param%=*}"
18783                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18784
18785                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18786                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
18787                         error "unable to set mdd.*.$param"
18788         done
18789
18790         local start=$SECONDS
18791         for i in $(seq $MDSCOUNT); do
18792                 cl_users=(${CL_USERS[mds$i]})
18793                 cl_user1[mds$i]="${cl_users[0]}"
18794
18795                 [[ -n "${cl_user1[mds$i]}" ]] ||
18796                         error "mds$i: no user registered"
18797         done
18798
18799         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
18800         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
18801
18802         # ensure we are past the previous changelog_min_gc_interval set above
18803         local sleep2=$((start + 2 - SECONDS))
18804         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18805
18806         # Generate one more changelog to trigger GC
18807         for ((i = 0; i < MDSCOUNT; i++)); do
18808                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
18809                         error "create $DIR/$tdir/d$i.3 failed"
18810         done
18811
18812         # ensure gc thread is done
18813         for node in $(mdts_nodes); do
18814                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
18815                         error "$node: GC-thread not done"
18816         done
18817
18818         do_nodes $mdts $LCTL set_param fail_loc=0
18819
18820         for (( i = 1; i <= MDSCOUNT; i++ )); do
18821                 # check cl_user1 is purged
18822                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
18823                         error "mds$i: User ${cl_user1[mds$i]} is registered"
18824         done
18825         return 0
18826 }
18827 run_test 160s "changelog garbage collect on idle records * time"
18828
18829 test_160t() {
18830         remote_mds_nodsh && skip "remote MDS with nodsh"
18831         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
18832                 skip "Need MDS version at least 2.15.50"
18833
18834         local MDT0=$(facet_svc $SINGLEMDS)
18835         local cl_users
18836         local cl_user1
18837         local cl_user2
18838         local start
18839
18840         changelog_register --user user1 -m all ||
18841                 error "user1 failed to register"
18842
18843         mkdir_on_mdt0 $DIR/$tdir
18844         # create default overstripe to maximize changelog size
18845         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
18846         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
18847         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18848
18849         # user2 consumes less records so less space
18850         changelog_register --user user2 || error "user2 failed to register"
18851         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
18852         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18853
18854         # check changelogs have been generated
18855         local nbcl=$(changelog_dump | wc -l)
18856         (( nbcl > 0 )) || error "no changelogs found"
18857
18858         # reduce the changelog_min_gc_interval to force check
18859         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
18860                 local var="${param%=*}"
18861                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18862
18863                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
18864                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
18865                         error "unable to set mdd.*.$param"
18866         done
18867
18868         start=$SECONDS
18869         cl_users=(${CL_USERS[mds1]})
18870         cl_user1="${cl_users[0]}"
18871         cl_user2="${cl_users[1]}"
18872
18873         [[ -n $cl_user1 ]] ||
18874                 error "mds1: user #1 isn't registered"
18875         [[ -n $cl_user2 ]] ||
18876                 error "mds1: user #2 isn't registered"
18877
18878         # ensure we are past the previous changelog_min_gc_interval set above
18879         local sleep2=$((start + 2 - SECONDS))
18880         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18881
18882         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
18883         do_facet mds1 $LCTL set_param fail_loc=0x018c \
18884                         fail_val=$(((llog_size1 + llog_size2) / 2))
18885
18886         # Generate more changelog to trigger GC
18887         createmany -o $DIR/$tdir/u3_ 4 ||
18888                 error "create failed for more files"
18889
18890         # ensure gc thread is done
18891         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
18892                 error "mds1: GC-thread not done"
18893
18894         do_facet mds1 $LCTL set_param fail_loc=0
18895
18896         # check cl_user1 is purged
18897         changelog_users mds1 | grep -q "$cl_user1" &&
18898                 error "User $cl_user1 is registered"
18899         # check cl_user2 is not purged
18900         changelog_users mds1 | grep -q "$cl_user2" ||
18901                 error "User $cl_user2 is not registered"
18902 }
18903 run_test 160t "changelog garbage collect on lack of space"
18904
18905 test_160u() { # LU-17400
18906         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18907         remote_mds_nodsh && skip "remote MDS with nodsh"
18908         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
18909                 skip "Need MDS version at least 2.2.0"
18910
18911         cd $DIR || error "cd $DIR failed"
18912
18913         # ensure changelog has a clean view if tests are run multiple times
18914         [ -d rename ] && rm -rf rename
18915
18916         changelog_register || error "changelog_register failed"
18917         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18918
18919         changelog_users $SINGLEMDS | grep -q $cl_user ||
18920                 error "User '$cl_user' not found in changelog_users"
18921
18922         local longname1=$(str_repeat a 255)
18923
18924         echo "creating simple directory tree"
18925         mkdir -p rename/a || error "create of simple directory tree failed"
18926         echo "creating rename/hw file"
18927         echo "hello world" > rename/hw || error "create of rename/hw failed"
18928         echo "creating very long named file"
18929         touch rename/$longname1 || error "create of 'rename/$longname1' failed"
18930         echo "move rename/hw to rename/a/a.hw"
18931         mv rename/hw rename/a/a.hw || error "mv failed"
18932
18933         RENME=($(changelog_dump | grep "RENME"))
18934         #declare -p RENME # for debugging captured value with indexes
18935
18936         [[ "${RENME[11]}" == "a.hw" && "${RENME[14]}" == "hw" ]] ||
18937                 error "changelog rename record type name/sname error"
18938 }
18939 run_test 160u "changelog rename record type name and sname strings are correct"
18940
18941 test_161a() {
18942         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18943
18944         test_mkdir -c1 $DIR/$tdir
18945         cp /etc/hosts $DIR/$tdir/$tfile
18946         test_mkdir -c1 $DIR/$tdir/foo1
18947         test_mkdir -c1 $DIR/$tdir/foo2
18948         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
18949         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
18950         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
18951         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
18952         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
18953         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18954                 $LFS fid2path $DIR $FID
18955                 error "bad link ea"
18956         fi
18957         # middle
18958         rm $DIR/$tdir/foo2/zachary
18959         # last
18960         rm $DIR/$tdir/foo2/thor
18961         # first
18962         rm $DIR/$tdir/$tfile
18963         # rename
18964         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
18965         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
18966                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
18967         rm $DIR/$tdir/foo2/maggie
18968
18969         # overflow the EA
18970         local longname=$tfile.avg_len_is_thirty_two_
18971         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
18972                 error_noexit 'failed to unlink many hardlinks'" EXIT
18973         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
18974                 error "failed to hardlink many files"
18975         links=$($LFS fid2path $DIR $FID | wc -l)
18976         echo -n "${links}/1000 links in link EA"
18977         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
18978 }
18979 run_test 161a "link ea sanity"
18980
18981 test_161b() {
18982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18983         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
18984
18985         local MDTIDX=1
18986         local remote_dir=$DIR/$tdir/remote_dir
18987
18988         mkdir -p $DIR/$tdir
18989         $LFS mkdir -i $MDTIDX $remote_dir ||
18990                 error "create remote directory failed"
18991
18992         cp /etc/hosts $remote_dir/$tfile
18993         mkdir -p $remote_dir/foo1
18994         mkdir -p $remote_dir/foo2
18995         ln $remote_dir/$tfile $remote_dir/foo1/sofia
18996         ln $remote_dir/$tfile $remote_dir/foo2/zachary
18997         ln $remote_dir/$tfile $remote_dir/foo1/luna
18998         ln $remote_dir/$tfile $remote_dir/foo2/thor
18999
19000         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
19001                      tr -d ']')
19002         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
19003                 $LFS fid2path $DIR $FID
19004                 error "bad link ea"
19005         fi
19006         # middle
19007         rm $remote_dir/foo2/zachary
19008         # last
19009         rm $remote_dir/foo2/thor
19010         # first
19011         rm $remote_dir/$tfile
19012         # rename
19013         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
19014         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
19015         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
19016                 $LFS fid2path $DIR $FID
19017                 error "bad link rename"
19018         fi
19019         rm $remote_dir/foo2/maggie
19020
19021         # overflow the EA
19022         local longname=filename_avg_len_is_thirty_two_
19023         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
19024                 error "failed to hardlink many files"
19025         links=$($LFS fid2path $DIR $FID | wc -l)
19026         echo -n "${links}/1000 links in link EA"
19027         [[ ${links} -gt 60 ]] ||
19028                 error "expected at least 60 links in link EA"
19029         unlinkmany $remote_dir/foo2/$longname 1000 ||
19030         error "failed to unlink many hardlinks"
19031 }
19032 run_test 161b "link ea sanity under remote directory"
19033
19034 test_161c() {
19035         remote_mds_nodsh && skip "remote MDS with nodsh"
19036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19037         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
19038                 skip "Need MDS version at least 2.1.5"
19039
19040         # define CLF_RENAME_LAST 0x0001
19041         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
19042         changelog_register || error "changelog_register failed"
19043
19044         rm -rf $DIR/$tdir
19045         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
19046         touch $DIR/$tdir/foo_161c
19047         touch $DIR/$tdir/bar_161c
19048         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
19049         changelog_dump | grep RENME | tail -n 5
19050         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
19051         changelog_clear 0 || error "changelog_clear failed"
19052         if [ x$flags != "x0x1" ]; then
19053                 error "flag $flags is not 0x1"
19054         fi
19055
19056         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
19057         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
19058         touch $DIR/$tdir/foo_161c
19059         touch $DIR/$tdir/bar_161c
19060         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
19061         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
19062         changelog_dump | grep RENME | tail -n 5
19063         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
19064         changelog_clear 0 || error "changelog_clear failed"
19065         if [ x$flags != "x0x0" ]; then
19066                 error "flag $flags is not 0x0"
19067         fi
19068         echo "rename overwrite a target having nlink > 1," \
19069                 "changelog record has flags of $flags"
19070
19071         # rename doesn't overwrite a target (changelog flag 0x0)
19072         touch $DIR/$tdir/foo_161c
19073         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
19074         changelog_dump | grep RENME | tail -n 5
19075         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
19076         changelog_clear 0 || error "changelog_clear failed"
19077         if [ x$flags != "x0x0" ]; then
19078                 error "flag $flags is not 0x0"
19079         fi
19080         echo "rename doesn't overwrite a target," \
19081                 "changelog record has flags of $flags"
19082
19083         # define CLF_UNLINK_LAST 0x0001
19084         # unlink a file having nlink = 1 (changelog flag 0x1)
19085         rm -f $DIR/$tdir/foo2_161c
19086         changelog_dump | grep UNLNK | tail -n 5
19087         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
19088         changelog_clear 0 || error "changelog_clear failed"
19089         if [ x$flags != "x0x1" ]; then
19090                 error "flag $flags is not 0x1"
19091         fi
19092         echo "unlink a file having nlink = 1," \
19093                 "changelog record has flags of $flags"
19094
19095         # unlink a file having nlink > 1 (changelog flag 0x0)
19096         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
19097         rm -f $DIR/$tdir/foobar_161c
19098         changelog_dump | grep UNLNK | tail -n 5
19099         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
19100         changelog_clear 0 || error "changelog_clear failed"
19101         if [ x$flags != "x0x0" ]; then
19102                 error "flag $flags is not 0x0"
19103         fi
19104         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
19105 }
19106 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
19107
19108 test_161d() {
19109         remote_mds_nodsh && skip "remote MDS with nodsh"
19110         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
19111
19112         local pid
19113         local fid
19114
19115         changelog_register || error "changelog_register failed"
19116
19117         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
19118         # interfer with $MOUNT/.lustre/fid/ access
19119         mkdir $DIR/$tdir
19120         [[ $? -eq 0 ]] || error "mkdir failed"
19121
19122         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | CFS_FAIL_ONCE
19123         $LCTL set_param fail_loc=0x8000140c
19124         # 5s pause
19125         $LCTL set_param fail_val=5
19126
19127         # create file
19128         echo foofoo > $DIR/$tdir/$tfile &
19129         pid=$!
19130
19131         # wait for create to be delayed
19132         sleep 2
19133
19134         ps -p $pid
19135         [[ $? -eq 0 ]] || error "create should be blocked"
19136
19137         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
19138         stack_trap "rm -f $tempfile"
19139         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
19140         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
19141         # some delay may occur during ChangeLog publishing and file read just
19142         # above, that could allow file write to happen finally
19143         [[ -s $tempfile ]] && echo "file should be empty"
19144
19145         $LCTL set_param fail_loc=0
19146
19147         wait $pid
19148         [[ $? -eq 0 ]] || error "create failed"
19149 }
19150 run_test 161d "create with concurrent .lustre/fid access"
19151
19152 check_path() {
19153         local expected="$1"
19154         shift
19155         local fid="$2"
19156
19157         local path
19158         path=$($LFS fid2path "$@")
19159         local rc=$?
19160
19161         if [ $rc -ne 0 ]; then
19162                 error "path looked up of '$expected' failed: rc=$rc"
19163         elif [ "$path" != "$expected" ]; then
19164                 error "path looked up '$path' instead of '$expected'"
19165         else
19166                 echo "FID '$fid' resolves to path '$path' as expected"
19167         fi
19168 }
19169
19170 test_162a() { # was test_162
19171         test_mkdir -p -c1 $DIR/$tdir/d2
19172         touch $DIR/$tdir/d2/$tfile
19173         touch $DIR/$tdir/d2/x1
19174         touch $DIR/$tdir/d2/x2
19175         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
19176         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
19177         # regular file
19178         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
19179         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
19180
19181         # softlink
19182         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
19183         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
19184         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
19185
19186         # softlink to wrong file
19187         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
19188         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
19189         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
19190
19191         # hardlink
19192         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
19193         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
19194         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
19195         # fid2path dir/fsname should both work
19196         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
19197         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
19198
19199         # hardlink count: check that there are 2 links
19200         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
19201         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
19202
19203         # hardlink indexing: remove the first link
19204         rm $DIR/$tdir/d2/p/q/r/hlink
19205         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
19206 }
19207 run_test 162a "path lookup sanity"
19208
19209 test_162b() {
19210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19211         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19212
19213         mkdir $DIR/$tdir
19214         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19215                                 error "create striped dir failed"
19216
19217         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
19218                                         tail -n 1 | awk '{print $2}')
19219         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
19220
19221         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
19222         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
19223
19224         # regular file
19225         for ((i=0;i<5;i++)); do
19226                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
19227                         error "get fid for f$i failed"
19228                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
19229
19230                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
19231                         error "get fid for d$i failed"
19232                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
19233         done
19234
19235         return 0
19236 }
19237 run_test 162b "striped directory path lookup sanity"
19238
19239 # LU-4239: Verify fid2path works with paths 100 or more directories deep
19240 test_162c() {
19241         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
19242                 skip "Need MDS version at least 2.7.51"
19243
19244         local lpath=$tdir.local
19245         local rpath=$tdir.remote
19246
19247         test_mkdir $DIR/$lpath
19248         test_mkdir $DIR/$rpath
19249
19250         for ((i = 0; i <= 101; i++)); do
19251                 lpath="$lpath/$i"
19252                 mkdir $DIR/$lpath
19253                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
19254                         error "get fid for local directory $DIR/$lpath failed"
19255                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
19256
19257                 rpath="$rpath/$i"
19258                 test_mkdir $DIR/$rpath
19259                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
19260                         error "get fid for remote directory $DIR/$rpath failed"
19261                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
19262         done
19263
19264         return 0
19265 }
19266 run_test 162c "fid2path works with paths 100 or more directories deep"
19267
19268 oalr_event_count() {
19269         local event="${1}"
19270         local trace="${2}"
19271
19272         awk -v name="${FSNAME}-OST0000" \
19273             -v event="${event}" \
19274             '$1 == "TRACE" && $2 == event && $3 == name' \
19275             "${trace}" |
19276         wc -l
19277 }
19278
19279 oalr_expect_event_count() {
19280         local event="${1}"
19281         local trace="${2}"
19282         local expect="${3}"
19283         local count
19284
19285         count=$(oalr_event_count "${event}" "${trace}")
19286         if ((count == expect)); then
19287                 return 0
19288         fi
19289
19290         error_noexit "${event} event count was '${count}', expected ${expect}"
19291         cat "${trace}" >&2
19292         exit 1
19293 }
19294
19295 cleanup_165() {
19296         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
19297         stop ost1
19298         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
19299 }
19300
19301 setup_165() {
19302         sync # Flush previous IOs so we can count log entries.
19303         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
19304         stack_trap cleanup_165 EXIT
19305 }
19306
19307 test_165a() {
19308         local trace="/tmp/${tfile}.trace"
19309         local rc
19310         local count
19311
19312         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19313                 skip "OFD access log unsupported"
19314
19315         setup_165
19316         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19317         sleep 5
19318
19319         do_facet ost1 ofd_access_log_reader --list
19320         stop ost1
19321
19322         do_facet ost1 killall -TERM ofd_access_log_reader
19323         wait
19324         rc=$?
19325
19326         if ((rc != 0)); then
19327                 error "ofd_access_log_reader exited with rc = '${rc}'"
19328         fi
19329
19330         # Parse trace file for discovery events:
19331         oalr_expect_event_count alr_log_add "${trace}" 1
19332         oalr_expect_event_count alr_log_eof "${trace}" 1
19333         oalr_expect_event_count alr_log_free "${trace}" 1
19334 }
19335 run_test 165a "ofd access log discovery"
19336
19337 test_165b() {
19338         local trace="/tmp/${tfile}.trace"
19339         local file="${DIR}/${tfile}"
19340         local pfid1
19341         local pfid2
19342         local -a entry
19343         local rc
19344         local count
19345         local size
19346         local flags
19347
19348         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19349                 skip "OFD access log unsupported"
19350
19351         setup_165
19352         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19353         sleep 5
19354
19355         do_facet ost1 ofd_access_log_reader --list
19356
19357         lfs setstripe -c 1 -i 0 "${file}"
19358         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19359                 error "cannot create '${file}'"
19360
19361         sleep 5
19362         do_facet ost1 killall -TERM ofd_access_log_reader
19363         wait
19364         rc=$?
19365
19366         if ((rc != 0)); then
19367                 error "ofd_access_log_reader exited with rc = '${rc}'"
19368         fi
19369
19370         oalr_expect_event_count alr_log_entry "${trace}" 1
19371
19372         pfid1=$($LFS path2fid "${file}")
19373
19374         # 1     2             3   4    5     6   7    8    9     10
19375         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
19376         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
19377
19378         echo "entry = '${entry[*]}'" >&2
19379
19380         pfid2=${entry[4]}
19381         if [[ "${pfid1}" != "${pfid2}" ]]; then
19382                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
19383         fi
19384
19385         size=${entry[8]}
19386         if ((size != 1048576)); then
19387                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
19388         fi
19389
19390         flags=${entry[10]}
19391         if [[ "${flags}" != "w" ]]; then
19392                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
19393         fi
19394
19395         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19396         sleep 5
19397
19398         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
19399                 error "cannot read '${file}'"
19400         sleep 5
19401
19402         do_facet ost1 killall -TERM ofd_access_log_reader
19403         wait
19404         rc=$?
19405
19406         if ((rc != 0)); then
19407                 error "ofd_access_log_reader exited with rc = '${rc}'"
19408         fi
19409
19410         oalr_expect_event_count alr_log_entry "${trace}" 1
19411
19412         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
19413         echo "entry = '${entry[*]}'" >&2
19414
19415         pfid2=${entry[4]}
19416         if [[ "${pfid1}" != "${pfid2}" ]]; then
19417                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
19418         fi
19419
19420         size=${entry[8]}
19421         if ((size != 524288)); then
19422                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
19423         fi
19424
19425         flags=${entry[10]}
19426         if [[ "${flags}" != "r" ]]; then
19427                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
19428         fi
19429 }
19430 run_test 165b "ofd access log entries are produced and consumed"
19431
19432 test_165c() {
19433         local trace="/tmp/${tfile}.trace"
19434         local file="${DIR}/${tdir}/${tfile}"
19435
19436         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19437                 skip "OFD access log unsupported"
19438
19439         test_mkdir "${DIR}/${tdir}"
19440
19441         setup_165
19442         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19443         sleep 5
19444
19445         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
19446
19447         # 4096 / 64 = 64. Create twice as many entries.
19448         for ((i = 0; i < 128; i++)); do
19449                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
19450                         error "cannot create file"
19451         done
19452
19453         sync
19454
19455         do_facet ost1 killall -TERM ofd_access_log_reader
19456         wait
19457         rc=$?
19458         if ((rc != 0)); then
19459                 error "ofd_access_log_reader exited with rc = '${rc}'"
19460         fi
19461
19462         unlinkmany  "${file}-%d" 128
19463 }
19464 run_test 165c "full ofd access logs do not block IOs"
19465
19466 oal_get_read_count() {
19467         local stats="$1"
19468
19469         # STATS lustre-OST0001 alr_read_count 1
19470
19471         do_facet ost1 cat "${stats}" |
19472         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
19473              END { print count; }'
19474 }
19475
19476 oal_expect_read_count() {
19477         local stats="$1"
19478         local count
19479         local expect="$2"
19480
19481         # Ask ofd_access_log_reader to write stats.
19482         do_facet ost1 killall -USR1 ofd_access_log_reader
19483
19484         # Allow some time for things to happen.
19485         sleep 1
19486
19487         count=$(oal_get_read_count "${stats}")
19488         if ((count == expect)); then
19489                 return 0
19490         fi
19491
19492         error_noexit "bad read count, got ${count}, expected ${expect}"
19493         do_facet ost1 cat "${stats}" >&2
19494         exit 1
19495 }
19496
19497 test_165d() {
19498         local stats="/tmp/${tfile}.stats"
19499         local file="${DIR}/${tdir}/${tfile}"
19500         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
19501
19502         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19503                 skip "OFD access log unsupported"
19504
19505         test_mkdir "${DIR}/${tdir}"
19506
19507         setup_165
19508         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
19509         sleep 5
19510
19511         lfs setstripe -c 1 -i 0 "${file}"
19512
19513         do_facet ost1 lctl set_param "${param}=rw"
19514         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19515                 error "cannot create '${file}'"
19516         oal_expect_read_count "${stats}" 1
19517
19518         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19519                 error "cannot read '${file}'"
19520         oal_expect_read_count "${stats}" 2
19521
19522         do_facet ost1 lctl set_param "${param}=r"
19523         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19524                 error "cannot create '${file}'"
19525         oal_expect_read_count "${stats}" 2
19526
19527         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19528                 error "cannot read '${file}'"
19529         oal_expect_read_count "${stats}" 3
19530
19531         do_facet ost1 lctl set_param "${param}=w"
19532         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19533                 error "cannot create '${file}'"
19534         oal_expect_read_count "${stats}" 4
19535
19536         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19537                 error "cannot read '${file}'"
19538         oal_expect_read_count "${stats}" 4
19539
19540         do_facet ost1 lctl set_param "${param}=0"
19541         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19542                 error "cannot create '${file}'"
19543         oal_expect_read_count "${stats}" 4
19544
19545         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19546                 error "cannot read '${file}'"
19547         oal_expect_read_count "${stats}" 4
19548
19549         do_facet ost1 killall -TERM ofd_access_log_reader
19550         wait
19551         rc=$?
19552         if ((rc != 0)); then
19553                 error "ofd_access_log_reader exited with rc = '${rc}'"
19554         fi
19555 }
19556 run_test 165d "ofd_access_log mask works"
19557
19558 test_165e() {
19559         local stats="/tmp/${tfile}.stats"
19560         local file0="${DIR}/${tdir}-0/${tfile}"
19561         local file1="${DIR}/${tdir}-1/${tfile}"
19562
19563         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19564                 skip "OFD access log unsupported"
19565
19566         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
19567
19568         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
19569         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
19570
19571         lfs setstripe -c 1 -i 0 "${file0}"
19572         lfs setstripe -c 1 -i 0 "${file1}"
19573
19574         setup_165
19575         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
19576         sleep 5
19577
19578         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
19579                 error "cannot create '${file0}'"
19580         sync
19581         oal_expect_read_count "${stats}" 0
19582
19583         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
19584                 error "cannot create '${file1}'"
19585         sync
19586         oal_expect_read_count "${stats}" 1
19587
19588         do_facet ost1 killall -TERM ofd_access_log_reader
19589         wait
19590         rc=$?
19591         if ((rc != 0)); then
19592                 error "ofd_access_log_reader exited with rc = '${rc}'"
19593         fi
19594 }
19595 run_test 165e "ofd_access_log MDT index filter works"
19596
19597 test_165f() {
19598         local trace="/tmp/${tfile}.trace"
19599         local rc
19600         local count
19601
19602         setup_165
19603         do_facet ost1 timeout 60 ofd_access_log_reader \
19604                 --exit-on-close --debug=- --trace=- > "${trace}" &
19605         sleep 5
19606         stop ost1
19607
19608         wait
19609         rc=$?
19610
19611         if ((rc != 0)); then
19612                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
19613                 cat "${trace}"
19614                 exit 1
19615         fi
19616 }
19617 run_test 165f "ofd_access_log_reader --exit-on-close works"
19618
19619 test_169() {
19620         # do directio so as not to populate the page cache
19621         log "creating a 10 Mb file"
19622         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
19623                 error "multiop failed while creating a file"
19624         log "starting reads"
19625         dd if=$DIR/$tfile of=/dev/null bs=4096 &
19626         log "truncating the file"
19627         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
19628                 error "multiop failed while truncating the file"
19629         log "killing dd"
19630         kill %+ || true # reads might have finished
19631         echo "wait until dd is finished"
19632         wait
19633         log "removing the temporary file"
19634         rm -rf $DIR/$tfile || error "tmp file removal failed"
19635 }
19636 run_test 169 "parallel read and truncate should not deadlock"
19637
19638 test_170() {
19639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19640
19641         $LCTL clear     # bug 18514
19642         $LCTL debug_daemon start $TMP/${tfile}_log_good
19643         touch $DIR/$tfile
19644         $LCTL debug_daemon stop
19645         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
19646                 error "sed failed to read log_good"
19647
19648         $LCTL debug_daemon start $TMP/${tfile}_log_good
19649         rm -rf $DIR/$tfile
19650         $LCTL debug_daemon stop
19651
19652         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
19653                error "lctl df log_bad failed"
19654
19655         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19656         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19657
19658         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
19659         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
19660
19661         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
19662                 error "bad_line good_line1 good_line2 are empty"
19663
19664         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19665         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
19666         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19667
19668         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
19669         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19670         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19671
19672         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
19673                 error "bad_line_new good_line_new are empty"
19674
19675         local expected_good=$((good_line1 + good_line2*2))
19676
19677         rm -f $TMP/${tfile}*
19678         # LU-231, short malformed line may not be counted into bad lines
19679         if [ $bad_line -ne $bad_line_new ] &&
19680                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
19681                 error "expected $bad_line bad lines, but got $bad_line_new"
19682                 return 1
19683         fi
19684
19685         if [ $expected_good -ne $good_line_new ]; then
19686                 error "expected $expected_good good lines, but got $good_line_new"
19687                 return 2
19688         fi
19689         true
19690 }
19691 run_test 170 "test lctl df to handle corrupted log ====================="
19692
19693 test_171() { # bug20592
19694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19695
19696         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
19697         $LCTL set_param fail_loc=0x50e
19698         $LCTL set_param fail_val=3000
19699         multiop_bg_pause $DIR/$tfile O_s || true
19700         local MULTIPID=$!
19701         kill -USR1 $MULTIPID
19702         # cause log dump
19703         sleep 3
19704         wait $MULTIPID
19705         if dmesg | grep "recursive fault"; then
19706                 error "caught a recursive fault"
19707         fi
19708         $LCTL set_param fail_loc=0
19709         true
19710 }
19711 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
19712
19713 test_172() {
19714
19715         #define OBD_FAIL_OBD_CLEANUP  0x60e
19716         $LCTL set_param fail_loc=0x60e
19717         umount $MOUNT || error "umount $MOUNT failed"
19718         stack_trap "mount_client $MOUNT"
19719
19720         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
19721                 error "no client OBDs are remained"
19722
19723         $LCTL dl | while read devno state type name foo; do
19724                 case $type in
19725                 lov|osc|lmv|mdc)
19726                         $LCTL --device $name cleanup
19727                         $LCTL --device $name detach
19728                         ;;
19729                 *)
19730                         # skip server devices
19731                         ;;
19732                 esac
19733         done
19734
19735         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
19736                 $LCTL dl | egrep " osc | lov | lmv | mdc "
19737                 error "some client OBDs are still remained"
19738         fi
19739
19740 }
19741 run_test 172 "manual device removal with lctl cleanup/detach ======"
19742
19743 # it would be good to share it with obdfilter-survey/iokit-libecho code
19744 setup_obdecho_osc () {
19745         local rc=0
19746         local ost_nid=$1
19747         local obdfilter_name=$2
19748         echo "Creating new osc for $obdfilter_name on $ost_nid"
19749         # make sure we can find loopback nid
19750         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
19751
19752         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
19753                            ${obdfilter_name}_osc_UUID || rc=2; }
19754         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
19755                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
19756         return $rc
19757 }
19758
19759 cleanup_obdecho_osc () {
19760         local obdfilter_name=$1
19761         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
19762         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
19763         return 0
19764 }
19765
19766 obdecho_test() {
19767         local OBD=$1
19768         local node=$2
19769         local pages=${3:-64}
19770         local rc=0
19771         local id
19772
19773         local count=10
19774         local obd_size=$(get_obd_size $node $OBD)
19775         local page_size=$(get_page_size $node)
19776         if [[ -n "$obd_size" ]]; then
19777                 local new_count=$((obd_size / (pages * page_size / 1024)))
19778                 [[ $new_count -ge $count ]] || count=$new_count
19779         fi
19780
19781         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
19782         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
19783                            rc=2; }
19784         if [ $rc -eq 0 ]; then
19785             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
19786             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
19787         fi
19788         echo "New object id is $id"
19789         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
19790                            rc=4; }
19791         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
19792                            "test_brw $count w v $pages $id" || rc=4; }
19793         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
19794                            rc=4; }
19795         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
19796                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
19797         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
19798                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
19799         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
19800         return $rc
19801 }
19802
19803 test_180a() {
19804         skip "obdecho on osc is no longer supported"
19805 }
19806 run_test 180a "test obdecho on osc"
19807
19808 test_180b() {
19809         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19810         remote_ost_nodsh && skip "remote OST with nodsh"
19811
19812         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19813                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19814                 error "failed to load module obdecho"
19815
19816         local target=$(do_facet ost1 $LCTL dl |
19817                        awk '/obdfilter/ { print $4; exit; }')
19818
19819         if [ -n "$target" ]; then
19820                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
19821         else
19822                 do_facet ost1 $LCTL dl
19823                 error "there is no obdfilter target on ost1"
19824         fi
19825 }
19826 run_test 180b "test obdecho directly on obdfilter"
19827
19828 test_180c() { # LU-2598
19829         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19830         remote_ost_nodsh && skip "remote OST with nodsh"
19831         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
19832                 skip "Need MDS version at least 2.4.0"
19833
19834         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19835                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19836                 error "failed to load module obdecho"
19837
19838         local target=$(do_facet ost1 $LCTL dl |
19839                        awk '/obdfilter/ { print $4; exit; }')
19840
19841         if [ -n "$target" ]; then
19842                 local pages=16384 # 64MB bulk I/O RPC size
19843
19844                 obdecho_test "$target" ost1 "$pages" ||
19845                         error "obdecho_test with pages=$pages failed with $?"
19846         else
19847                 do_facet ost1 $LCTL dl
19848                 error "there is no obdfilter target on ost1"
19849         fi
19850 }
19851 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
19852
19853 test_181() { # bug 22177
19854         test_mkdir $DIR/$tdir
19855         # create enough files to index the directory
19856         createmany -o $DIR/$tdir/foobar 4000
19857         # print attributes for debug purpose
19858         lsattr -d .
19859         # open dir
19860         multiop_bg_pause $DIR/$tdir D_Sc || return 1
19861         MULTIPID=$!
19862         # remove the files & current working dir
19863         unlinkmany $DIR/$tdir/foobar 4000
19864         rmdir $DIR/$tdir
19865         kill -USR1 $MULTIPID
19866         wait $MULTIPID
19867         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
19868         return 0
19869 }
19870 run_test 181 "Test open-unlinked dir ========================"
19871
19872 test_182a() {
19873         local fcount=1000
19874         local tcount=10
19875
19876         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19877
19878         $LCTL set_param mdc.*.rpc_stats=clear
19879
19880         for (( i = 0; i < $tcount; i++ )) ; do
19881                 mkdir $DIR/$tdir/$i
19882         done
19883
19884         for (( i = 0; i < $tcount; i++ )) ; do
19885                 createmany -o $DIR/$tdir/$i/f- $fcount &
19886         done
19887         wait
19888
19889         for (( i = 0; i < $tcount; i++ )) ; do
19890                 unlinkmany $DIR/$tdir/$i/f- $fcount &
19891         done
19892         wait
19893
19894         $LCTL get_param mdc.*.rpc_stats
19895
19896         rm -rf $DIR/$tdir
19897 }
19898 run_test 182a "Test parallel modify metadata operations from mdc"
19899
19900 test_182b() {
19901         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19902         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19903         local dcount=1000
19904         local tcount=10
19905         local stime
19906         local etime
19907         local delta
19908
19909         do_facet mds1 $LCTL list_param \
19910                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
19911                 skip "MDS lacks parallel RPC handling"
19912
19913         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19914
19915         rpc_count=$(do_facet mds1 $LCTL get_param -n \
19916                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
19917
19918         stime=$(date +%s)
19919         createmany -i 0 -d $DIR/$tdir/t- $tcount
19920
19921         for (( i = 0; i < $tcount; i++ )) ; do
19922                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19923         done
19924         wait
19925         etime=$(date +%s)
19926         delta=$((etime - stime))
19927         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
19928
19929         stime=$(date +%s)
19930         for (( i = 0; i < $tcount; i++ )) ; do
19931                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
19932         done
19933         wait
19934         etime=$(date +%s)
19935         delta=$((etime - stime))
19936         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
19937
19938         rm -rf $DIR/$tdir
19939
19940         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19941
19942         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
19943
19944         stime=$(date +%s)
19945         createmany -i 0 -d $DIR/$tdir/t- $tcount
19946
19947         for (( i = 0; i < $tcount; i++ )) ; do
19948                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19949         done
19950         wait
19951         etime=$(date +%s)
19952         delta=$((etime - stime))
19953         echo "Time for file creation $delta sec for 1 RPC sent at a time"
19954
19955         stime=$(date +%s)
19956         for (( i = 0; i < $tcount; i++ )) ; do
19957                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
19958         done
19959         wait
19960         etime=$(date +%s)
19961         delta=$((etime - stime))
19962         echo "Time for file removal $delta sec for 1 RPC sent at a time"
19963
19964         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
19965 }
19966 run_test 182b "Test parallel modify metadata operations from osp"
19967
19968 test_183() { # LU-2275
19969         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19970         remote_mds_nodsh && skip "remote MDS with nodsh"
19971         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
19972                 skip "Need MDS version at least 2.3.56"
19973
19974         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19975         echo aaa > $DIR/$tdir/$tfile
19976
19977 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
19978         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
19979
19980         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
19981         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
19982
19983         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19984
19985         # Flush negative dentry cache
19986         touch $DIR/$tdir/$tfile
19987
19988         # We are not checking for any leaked references here, they'll
19989         # become evident next time we do cleanup with module unload.
19990         rm -rf $DIR/$tdir
19991 }
19992 run_test 183 "No crash or request leak in case of strange dispositions ========"
19993
19994 # test suite 184 is for LU-2016, LU-2017
19995 test_184a() {
19996         check_swap_layouts_support
19997
19998         dir0=$DIR/$tdir/$testnum
19999         test_mkdir -p -c1 $dir0
20000         ref1=/etc/passwd
20001         ref2=/etc/group
20002         file1=$dir0/f1
20003         file2=$dir0/f2
20004         $LFS setstripe -c1 $file1
20005         cp $ref1 $file1
20006         $LFS setstripe -c2 $file2
20007         cp $ref2 $file2
20008         gen1=$($LFS getstripe -g $file1)
20009         gen2=$($LFS getstripe -g $file2)
20010
20011         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
20012         gen=$($LFS getstripe -g $file1)
20013         [[ $gen1 != $gen ]] ||
20014                 error "Layout generation on $file1 does not change"
20015         gen=$($LFS getstripe -g $file2)
20016         [[ $gen2 != $gen ]] ||
20017                 error "Layout generation on $file2 does not change"
20018
20019         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
20020         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20021
20022         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
20023 }
20024 run_test 184a "Basic layout swap"
20025
20026 test_184b() {
20027         check_swap_layouts_support
20028
20029         dir0=$DIR/$tdir/$testnum
20030         mkdir -p $dir0 || error "creating dir $dir0"
20031         file1=$dir0/f1
20032         file2=$dir0/f2
20033         file3=$dir0/f3
20034         dir1=$dir0/d1
20035         dir2=$dir0/d2
20036         mkdir $dir1 $dir2
20037         $LFS setstripe -c1 $file1
20038         $LFS setstripe -c2 $file2
20039         $LFS setstripe -c1 $file3
20040         chown $RUNAS_ID $file3
20041         gen1=$($LFS getstripe -g $file1)
20042         gen2=$($LFS getstripe -g $file2)
20043
20044         $LFS swap_layouts $dir1 $dir2 &&
20045                 error "swap of directories layouts should fail"
20046         $LFS swap_layouts $dir1 $file1 &&
20047                 error "swap of directory and file layouts should fail"
20048         $RUNAS $LFS swap_layouts $file1 $file2 &&
20049                 error "swap of file we cannot write should fail"
20050         $LFS swap_layouts $file1 $file3 &&
20051                 error "swap of file with different owner should fail"
20052         /bin/true # to clear error code
20053 }
20054 run_test 184b "Forbidden layout swap (will generate errors)"
20055
20056 test_184c() {
20057         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
20058         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
20059         check_swap_layouts_support
20060         check_swap_layout_no_dom $DIR
20061
20062         local dir0=$DIR/$tdir/$testnum
20063         mkdir -p $dir0 || error "creating dir $dir0"
20064
20065         local ref1=$dir0/ref1
20066         local ref2=$dir0/ref2
20067         local file1=$dir0/file1
20068         local file2=$dir0/file2
20069         # create a file large enough for the concurrent test
20070         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
20071         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
20072         echo "ref file size: ref1($(stat -c %s $ref1))," \
20073              "ref2($(stat -c %s $ref2))"
20074
20075         cp $ref2 $file2
20076         dd if=$ref1 of=$file1 bs=16k &
20077         local DD_PID=$!
20078
20079         # Make sure dd starts to copy file, but wait at most 5 seconds
20080         local loops=0
20081         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
20082
20083         $LFS swap_layouts $file1 $file2
20084         local rc=$?
20085         wait $DD_PID
20086         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
20087         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
20088
20089         # how many bytes copied before swapping layout
20090         local copied=$(stat -c %s $file2)
20091         local remaining=$(stat -c %s $ref1)
20092         remaining=$((remaining - copied))
20093         echo "Copied $copied bytes before swapping layout..."
20094
20095         cmp -n $copied $file1 $ref2 | grep differ &&
20096                 error "Content mismatch [0, $copied) of ref2 and file1"
20097         cmp -n $copied $file2 $ref1 ||
20098                 error "Content mismatch [0, $copied) of ref1 and file2"
20099         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
20100                 error "Content mismatch [$copied, EOF) of ref1 and file1"
20101
20102         # clean up
20103         rm -f $ref1 $ref2 $file1 $file2
20104 }
20105 run_test 184c "Concurrent write and layout swap"
20106
20107 test_184d() {
20108         check_swap_layouts_support
20109         check_swap_layout_no_dom $DIR
20110         [ -z "$(which getfattr 2>/dev/null)" ] &&
20111                 skip_env "no getfattr command"
20112
20113         local file1=$DIR/$tdir/$tfile-1
20114         local file2=$DIR/$tdir/$tfile-2
20115         local file3=$DIR/$tdir/$tfile-3
20116         local lovea1
20117         local lovea2
20118
20119         mkdir -p $DIR/$tdir
20120         touch $file1 || error "create $file1 failed"
20121         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
20122                 error "create $file2 failed"
20123         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
20124                 error "create $file3 failed"
20125         lovea1=$(get_layout_param $file1)
20126
20127         $LFS swap_layouts $file2 $file3 ||
20128                 error "swap $file2 $file3 layouts failed"
20129         $LFS swap_layouts $file1 $file2 ||
20130                 error "swap $file1 $file2 layouts failed"
20131
20132         lovea2=$(get_layout_param $file2)
20133         echo "$lovea1"
20134         echo "$lovea2"
20135         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
20136
20137         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
20138         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
20139 }
20140 run_test 184d "allow stripeless layouts swap"
20141
20142 test_184e() {
20143         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
20144                 skip "Need MDS version at least 2.6.94"
20145         check_swap_layouts_support
20146         check_swap_layout_no_dom $DIR
20147         [ -z "$(which getfattr 2>/dev/null)" ] &&
20148                 skip_env "no getfattr command"
20149
20150         local file1=$DIR/$tdir/$tfile-1
20151         local file2=$DIR/$tdir/$tfile-2
20152         local file3=$DIR/$tdir/$tfile-3
20153         local lovea
20154
20155         mkdir -p $DIR/$tdir
20156         touch $file1 || error "create $file1 failed"
20157         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
20158                 error "create $file2 failed"
20159         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
20160                 error "create $file3 failed"
20161
20162         $LFS swap_layouts $file1 $file2 ||
20163                 error "swap $file1 $file2 layouts failed"
20164
20165         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
20166         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
20167
20168         echo 123 > $file1 || error "Should be able to write into $file1"
20169
20170         $LFS swap_layouts $file1 $file3 ||
20171                 error "swap $file1 $file3 layouts failed"
20172
20173         echo 123 > $file1 || error "Should be able to write into $file1"
20174
20175         rm -rf $file1 $file2 $file3
20176 }
20177 run_test 184e "Recreate layout after stripeless layout swaps"
20178
20179 test_184f() {
20180         # Create a file with name longer than sizeof(struct stat) ==
20181         # 144 to see if we can get chars from the file name to appear
20182         # in the returned striping. Note that 'f' == 0x66.
20183         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
20184
20185         mkdir -p $DIR/$tdir
20186         mcreate $DIR/$tdir/$file
20187         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
20188                 error "IOC_MDC_GETFILEINFO returned garbage striping"
20189         fi
20190 }
20191 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
20192
20193 test_185() { # LU-2441
20194         # LU-3553 - no volatile file support in old servers
20195         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
20196                 skip "Need MDS version at least 2.3.60"
20197
20198         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
20199         touch $DIR/$tdir/spoo
20200         local mtime1=$(stat -c "%Y" $DIR/$tdir)
20201         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
20202                 error "cannot create/write a volatile file"
20203         [ "$FILESET" == "" ] &&
20204         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
20205                 error "FID is still valid after close"
20206
20207         multiop_bg_pause $DIR/$tdir Vw4096_c
20208         local multi_pid=$!
20209
20210         local OLD_IFS=$IFS
20211         IFS=":"
20212         local fidv=($fid)
20213         IFS=$OLD_IFS
20214         # assume that the next FID for this client is sequential, since stdout
20215         # is unfortunately eaten by multiop_bg_pause
20216         local n=$((${fidv[1]} + 1))
20217         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
20218         if [ "$FILESET" == "" ]; then
20219                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
20220                         error "FID is missing before close"
20221         fi
20222         kill -USR1 $multi_pid
20223         # 1 second delay, so if mtime change we will see it
20224         sleep 1
20225         local mtime2=$(stat -c "%Y" $DIR/$tdir)
20226         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
20227 }
20228 run_test 185 "Volatile file support"
20229
20230 function create_check_volatile() {
20231         local idx=$1
20232         local tgt
20233
20234         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
20235         local PID=$!
20236         sleep 1
20237         local FID=$(cat /tmp/${tfile}.fid)
20238         [ "$FID" == "" ] && error "can't get FID for volatile"
20239         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
20240         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
20241         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
20242         kill -USR1 $PID
20243         wait
20244         sleep 1
20245         cancel_lru_locks mdc # flush opencache
20246         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
20247         return 0
20248 }
20249
20250 test_185a(){
20251         # LU-12516 - volatile creation via .lustre
20252         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
20253                 skip "Need MDS version at least 2.3.55"
20254
20255         create_check_volatile 0
20256         [ $MDSCOUNT -lt 2 ] && return 0
20257
20258         # DNE case
20259         create_check_volatile 1
20260
20261         return 0
20262 }
20263 run_test 185a "Volatile file creation in .lustre/fid/"
20264
20265 test_187a() {
20266         remote_mds_nodsh && skip "remote MDS with nodsh"
20267         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
20268                 skip "Need MDS version at least 2.3.0"
20269
20270         local dir0=$DIR/$tdir/$testnum
20271         mkdir -p $dir0 || error "creating dir $dir0"
20272
20273         local file=$dir0/file1
20274         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
20275         stack_trap "rm -f $file"
20276         local dv1=$($LFS data_version $file)
20277         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
20278         local dv2=$($LFS data_version $file)
20279         [[ $dv1 != $dv2 ]] ||
20280                 error "data version did not change on write $dv1 == $dv2"
20281 }
20282 run_test 187a "Test data version change"
20283
20284 test_187b() {
20285         remote_mds_nodsh && skip "remote MDS with nodsh"
20286         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
20287                 skip "Need MDS version at least 2.3.0"
20288
20289         local dir0=$DIR/$tdir/$testnum
20290         mkdir -p $dir0 || error "creating dir $dir0"
20291
20292         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
20293         [[ ${DV[0]} != ${DV[1]} ]] ||
20294                 error "data version did not change on write"\
20295                       " ${DV[0]} == ${DV[1]}"
20296
20297         # clean up
20298         rm -f $file1
20299 }
20300 run_test 187b "Test data version change on volatile file"
20301
20302 test_200() {
20303         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20304         remote_mgs_nodsh && skip "remote MGS with nodsh"
20305         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
20306
20307         local POOL=${POOL:-cea1}
20308         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
20309         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
20310         # Pool OST targets
20311         local first_ost=0
20312         local last_ost=$(($OSTCOUNT - 1))
20313         local ost_step=2
20314         local ost_list=$(seq $first_ost $ost_step $last_ost)
20315         local ost_range="$first_ost $last_ost $ost_step"
20316         local test_path=$POOL_ROOT/$POOL_DIR_NAME
20317         local file_dir=$POOL_ROOT/file_tst
20318         local subdir=$test_path/subdir
20319         local rc=0
20320
20321         while : ; do
20322                 # former test_200a test_200b
20323                 pool_add $POOL                          || { rc=$? ; break; }
20324                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
20325                 # former test_200c test_200d
20326                 mkdir -p $test_path
20327                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
20328                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
20329                 mkdir -p $subdir
20330                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
20331                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
20332                                                         || { rc=$? ; break; }
20333                 # former test_200e test_200f
20334                 local files=$((OSTCOUNT*3))
20335                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
20336                                                         || { rc=$? ; break; }
20337                 pool_create_files $POOL $file_dir $files "$ost_list" \
20338                                                         || { rc=$? ; break; }
20339                 # former test_200g test_200h
20340                 pool_lfs_df $POOL                       || { rc=$? ; break; }
20341                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
20342
20343                 # former test_201a test_201b test_201c
20344                 pool_remove_first_target $POOL          || { rc=$? ; break; }
20345
20346                 local f=$test_path/$tfile
20347                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
20348                 pool_remove $POOL $f                    || { rc=$? ; break; }
20349                 break
20350         done
20351
20352         destroy_test_pools
20353
20354         return $rc
20355 }
20356 run_test 200 "OST pools"
20357
20358 # usage: default_attr <count | size | offset>
20359 default_attr() {
20360         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
20361 }
20362
20363 # usage: check_default_stripe_attr
20364 check_default_stripe_attr() {
20365         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
20366         case $1 in
20367         --stripe-count|-c)
20368                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
20369         --stripe-size|-S)
20370                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
20371         --stripe-index|-i)
20372                 EXPECTED=-1;;
20373         *)
20374                 error "unknown getstripe attr '$1'"
20375         esac
20376
20377         [ $ACTUAL == $EXPECTED ] ||
20378                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
20379 }
20380
20381 test_204a() {
20382         test_mkdir $DIR/$tdir
20383         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
20384
20385         check_default_stripe_attr --stripe-count
20386         check_default_stripe_attr --stripe-size
20387         check_default_stripe_attr --stripe-index
20388 }
20389 run_test 204a "Print default stripe attributes"
20390
20391 test_204b() {
20392         test_mkdir $DIR/$tdir
20393         $LFS setstripe --stripe-count 1 $DIR/$tdir
20394
20395         check_default_stripe_attr --stripe-size
20396         check_default_stripe_attr --stripe-index
20397 }
20398 run_test 204b "Print default stripe size and offset"
20399
20400 test_204c() {
20401         test_mkdir $DIR/$tdir
20402         $LFS setstripe --stripe-size 65536 $DIR/$tdir
20403
20404         check_default_stripe_attr --stripe-count
20405         check_default_stripe_attr --stripe-index
20406 }
20407 run_test 204c "Print default stripe count and offset"
20408
20409 test_204d() {
20410         test_mkdir $DIR/$tdir
20411         $LFS setstripe --stripe-index 0 $DIR/$tdir
20412
20413         check_default_stripe_attr --stripe-count
20414         check_default_stripe_attr --stripe-size
20415 }
20416 run_test 204d "Print default stripe count and size"
20417
20418 test_204e() {
20419         test_mkdir $DIR/$tdir
20420         $LFS setstripe -d $DIR/$tdir
20421
20422         # LU-16904 check if root is set as PFL layout
20423         local numcomp=$($LFS getstripe --component-count $MOUNT)
20424
20425         if [[ $numcomp -gt 0 ]]; then
20426                 check_default_stripe_attr --stripe-count
20427         else
20428                 check_default_stripe_attr --stripe-count --raw
20429         fi
20430         check_default_stripe_attr --stripe-size --raw
20431         check_default_stripe_attr --stripe-index --raw
20432 }
20433 run_test 204e "Print raw stripe attributes"
20434
20435 test_204f() {
20436         test_mkdir $DIR/$tdir
20437         $LFS setstripe --stripe-count 1 $DIR/$tdir
20438
20439         check_default_stripe_attr --stripe-size --raw
20440         check_default_stripe_attr --stripe-index --raw
20441 }
20442 run_test 204f "Print raw stripe size and offset"
20443
20444 test_204g() {
20445         test_mkdir $DIR/$tdir
20446         $LFS setstripe --stripe-size 65536 $DIR/$tdir
20447
20448         check_default_stripe_attr --stripe-count --raw
20449         check_default_stripe_attr --stripe-index --raw
20450 }
20451 run_test 204g "Print raw stripe count and offset"
20452
20453 test_204h() {
20454         test_mkdir $DIR/$tdir
20455         $LFS setstripe --stripe-index 0 $DIR/$tdir
20456
20457         check_default_stripe_attr --stripe-count --raw
20458         check_default_stripe_attr --stripe-size --raw
20459 }
20460 run_test 204h "Print raw stripe count and size"
20461
20462 # Figure out which job scheduler is being used, if any,
20463 # or use a fake one
20464 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
20465         JOBENV=SLURM_JOB_ID
20466 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
20467         JOBENV=LSB_JOBID
20468 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
20469         JOBENV=PBS_JOBID
20470 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
20471         JOBENV=LOADL_STEP_ID
20472 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
20473         JOBENV=JOB_ID
20474 else
20475         $LCTL list_param jobid_name > /dev/null 2>&1
20476         if [ $? -eq 0 ]; then
20477                 JOBENV=nodelocal
20478         else
20479                 JOBENV=FAKE_JOBID
20480         fi
20481 fi
20482 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
20483
20484 verify_jobstats() {
20485         local cmd=($1)
20486         shift
20487         local facets="$@"
20488
20489 # we don't really need to clear the stats for this test to work, since each
20490 # command has a unique jobid, but it makes debugging easier if needed.
20491 #       for facet in $facets; do
20492 #               local dev=$(convert_facet2label $facet)
20493 #               # clear old jobstats
20494 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
20495 #       done
20496
20497         # use a new JobID for each test, or we might see an old one
20498         [ "$JOBENV" = "FAKE_JOBID" ] &&
20499                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
20500
20501         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
20502
20503         [ "$JOBENV" = "nodelocal" ] && {
20504                 FAKE_JOBID=id.$testnum.%e.$RANDOM
20505                 $LCTL set_param jobid_name=$FAKE_JOBID
20506                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
20507         }
20508
20509         log "Test: ${cmd[*]}"
20510         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
20511
20512         if [ $JOBENV = "FAKE_JOBID" ]; then
20513                 FAKE_JOBID=$JOBVAL ${cmd[*]}
20514         else
20515                 ${cmd[*]}
20516         fi
20517
20518         # all files are created on OST0000
20519         for facet in $facets; do
20520                 local stats="*.$(convert_facet2label $facet).job_stats"
20521
20522                 # strip out libtool wrappers for in-tree executables
20523                 if (( $(do_facet $facet lctl get_param $stats |
20524                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
20525                         do_facet $facet lctl get_param $stats
20526                         error "No jobstats for $JOBVAL found on $facet::$stats"
20527                 fi
20528         done
20529 }
20530
20531 jobstats_set() {
20532         local new_jobenv=$1
20533
20534         set_persistent_param_and_check client "jobid_var" \
20535                 "$FSNAME.sys.jobid_var" $new_jobenv
20536 }
20537
20538 test_205a() { # Job stats
20539         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20540         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
20541                 skip "Need MDS version with at least 2.7.1"
20542         remote_mgs_nodsh && skip "remote MGS with nodsh"
20543         remote_mds_nodsh && skip "remote MDS with nodsh"
20544         remote_ost_nodsh && skip "remote OST with nodsh"
20545         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
20546                 skip "Server doesn't support jobstats"
20547         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
20548
20549         local old_jobenv=$($LCTL get_param -n jobid_var)
20550         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
20551         stack_trap "jobstats_set $old_jobenv" EXIT
20552
20553         changelog_register
20554
20555         local old_jobid_name=$($LCTL get_param jobid_name)
20556         stack_trap "$LCTL set_param $old_jobid_name" EXIT
20557
20558         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
20559                                 mdt.*.job_cleanup_interval | head -n 1)
20560         local new_interval=5
20561         do_facet $SINGLEMDS \
20562                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
20563         stack_trap "do_facet $SINGLEMDS \
20564                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
20565         local start=$SECONDS
20566
20567         local cmd
20568         # mkdir
20569         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
20570         verify_jobstats "$cmd" "$SINGLEMDS"
20571         # rmdir
20572         cmd="rmdir $DIR/$tdir"
20573         verify_jobstats "$cmd" "$SINGLEMDS"
20574         # mkdir on secondary MDT
20575         if [ $MDSCOUNT -gt 1 ]; then
20576                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
20577                 verify_jobstats "$cmd" "mds2"
20578         fi
20579         # mknod
20580         cmd="mknod $DIR/$tfile c 1 3"
20581         verify_jobstats "$cmd" "$SINGLEMDS"
20582         # unlink
20583         cmd="rm -f $DIR/$tfile"
20584         verify_jobstats "$cmd" "$SINGLEMDS"
20585         # create all files on OST0000 so verify_jobstats can find OST stats
20586         # open & close
20587         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
20588         verify_jobstats "$cmd" "$SINGLEMDS"
20589         # setattr
20590         cmd="touch $DIR/$tfile"
20591         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20592         # write
20593         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
20594         verify_jobstats "$cmd" "ost1"
20595         # read
20596         cancel_lru_locks osc
20597         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
20598         verify_jobstats "$cmd" "ost1"
20599         # truncate
20600         cmd="$TRUNCATE $DIR/$tfile 0"
20601         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20602         # rename
20603         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
20604         verify_jobstats "$cmd" "$SINGLEMDS"
20605         # jobstats expiry - sleep until old stats should be expired
20606         local left=$((new_interval + 5 - (SECONDS - start)))
20607         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
20608                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
20609                         "0" $left
20610         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
20611         verify_jobstats "$cmd" "$SINGLEMDS"
20612         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
20613             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
20614
20615         # Ensure that jobid are present in changelog (if supported by MDS)
20616         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
20617                 changelog_dump | tail -10
20618                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
20619                 [ $jobids -eq 9 ] ||
20620                         error "Wrong changelog jobid count $jobids != 9"
20621
20622                 # LU-5862
20623                 JOBENV="disable"
20624                 jobstats_set $JOBENV
20625                 touch $DIR/$tfile
20626                 changelog_dump | grep $tfile
20627                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
20628                 [ $jobids -eq 0 ] ||
20629                         error "Unexpected jobids when jobid_var=$JOBENV"
20630         fi
20631
20632         # test '%j' access to environment variable - if supported
20633         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
20634                 JOBENV="JOBCOMPLEX"
20635                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20636
20637                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20638         fi
20639
20640         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
20641                 JOBENV="JOBCOMPLEX"
20642                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
20643
20644                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20645         fi
20646
20647         # test '%j' access to per-session jobid - if supported
20648         if lctl list_param jobid_this_session > /dev/null 2>&1
20649         then
20650                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
20651                 lctl set_param jobid_this_session=$USER
20652
20653                 JOBENV="JOBCOMPLEX"
20654                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20655
20656                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20657         fi
20658 }
20659 run_test 205a "Verify job stats"
20660
20661 # LU-13117, LU-13597, LU-16599
20662 test_205b() {
20663         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
20664                 skip "Need MDS version at least 2.13.54.91"
20665
20666         local job_stats="mdt.*.job_stats"
20667         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
20668
20669         do_facet mds1 $LCTL set_param $job_stats=clear
20670
20671         # Setting jobid_var to USER might not be supported
20672         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
20673         $LCTL set_param jobid_var=USER || true
20674         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
20675         $LCTL set_param jobid_name="%j.%e.%u"
20676
20677         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
20678         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
20679                 { do_facet mds1 $LCTL get_param $job_stats;
20680                   error "Unexpected jobid found"; }
20681         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
20682                 { do_facet mds1 $LCTL get_param $job_stats;
20683                   error "wrong job_stats format found"; }
20684
20685         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
20686                 echo "MDS does not yet escape jobid" && return 0
20687
20688         mkdir_on_mdt0 $DIR/$tdir
20689         $LCTL set_param jobid_var=TEST205b
20690         env -i TEST205b="has sp" touch $DIR/$tdir/$tfile.2
20691         local jobid=$(do_facet mds1 $LCTL get_param $job_stats |
20692                       awk '/has\\x20sp/ {print $3}')
20693         [[ -n "$jobid" ]] || { do_facet mds1 $LCTL get_param $job_stats;
20694                   error "jobid not escaped"; }
20695
20696         if (( $MDS1_VERSION >= $(version_code 2.15.53.139) )); then
20697                 # need to run such a command on mds1:
20698                 # lctl set_param mdt.$FSNAME-MDT0000.job_stats='"has\x20sp.touch.0"'
20699                 #
20700                 # there might be multiple MDTs on single mds server, so need to
20701                 # specifiy MDT0000. Or the command will fail due to other MDTs
20702                 do_facet_vp mds1 $LCTL set_param mdt.$FSNAME-MDT0000.job_stats=$jobid ||
20703                         error "cannot clear escaped jobid in job_stats";
20704         else
20705                 echo "MDS does not support clearing escaped jobid"
20706         fi
20707 }
20708 run_test 205b "Verify job stats jobid and output format"
20709
20710 # LU-13733
20711 test_205c() {
20712         $LCTL set_param llite.*.stats=0
20713         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
20714         $LCTL get_param llite.*.stats
20715         $LCTL get_param llite.*.stats | grep \
20716                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
20717                         error "wrong client stats format found"
20718 }
20719 run_test 205c "Verify client stats format"
20720
20721 test_205d() {
20722         local file=$DIR/$tdir/$tfile
20723
20724         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20725                 skip "need lustre >= 2.15.53 for lljobstat"
20726         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20727                 skip "need lustre >= 2.15.53 for lljobstat"
20728         verify_yaml_available || skip_env "YAML verification not installed"
20729
20730         test_mkdir -i 0 $DIR/$tdir
20731         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
20732         stack_trap "rm -rf $DIR/$tdir"
20733
20734         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
20735                 error "failed to write data to $file"
20736         mv $file $file.2
20737
20738         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
20739         echo -n 'verify rename_stats...'
20740         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
20741                 verify_yaml || error "rename_stats is not valid YAML"
20742         echo " OK"
20743
20744         echo -n 'verify mdt job_stats...'
20745         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
20746                 verify_yaml || error "job_stats on mds1 is not valid YAML"
20747         echo " OK"
20748
20749         echo -n 'verify ost job_stats...'
20750         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
20751                 verify_yaml || error "job_stats on ost1 is not valid YAML"
20752         echo " OK"
20753 }
20754 run_test 205d "verify the format of some stats files"
20755
20756 test_205e() {
20757         local ops_comma
20758         local file=$DIR/$tdir/$tfile
20759         local -a cli_params
20760
20761         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20762                 skip "need lustre >= 2.15.53 for lljobstat"
20763         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20764                 skip "need lustre >= 2.15.53 for lljobstat"
20765         verify_yaml_available || skip_env "YAML verification not installed"
20766
20767         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20768         $LCTL set_param jobid_var=nodelocal jobid_name=205e.%e.%u
20769         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20770
20771         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
20772         stack_trap "rm -rf $DIR/$tdir"
20773
20774         $LFS setstripe -E EOF -i 0 -c 1 $file ||
20775                 error "failed to create $file on ost1"
20776         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
20777                 error "failed to write data to $file"
20778
20779         do_facet mds1 "$LCTL get_param *.*.job_stats"
20780         do_facet ost1 "$LCTL get_param *.*.job_stats"
20781
20782         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
20783         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
20784                 error "The output of lljobstat is not an valid YAML"
20785
20786         # verify that job dd.0 does exist and has some ops on ost1
20787         # typically this line is like:
20788         # - 205e.dd.0:            {ops: 20, ...}
20789         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
20790                     awk '$2=="205e.dd.0:" {print $4}')
20791
20792         (( ${ops_comma%,} >= 10 )) ||
20793                 error "cannot find job 205e.dd.0 with ops >= 10"
20794 }
20795 run_test 205e "verify the output of lljobstat"
20796
20797 test_205f() {
20798         verify_yaml_available || skip_env "YAML verification not installed"
20799
20800         # check both qos_ost_weights and qos_mdt_weights
20801         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
20802         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
20803                 error "qos_ost_weights is not valid YAML"
20804 }
20805 run_test 205f "verify qos_ost_weights YAML format "
20806
20807 __test_205_jobstats_dump() {
20808         local -a pids
20809         local nbr_instance=$1
20810
20811         while true; do
20812                 if (( ${#pids[@]} >= nbr_instance )); then
20813                         wait ${pids[@]}
20814                         pids=()
20815                 fi
20816
20817                 do_facet mds1 "$LCTL get_param mdt.*.job_stats > /dev/null" &
20818                 pids+=( $! )
20819         done
20820 }
20821
20822 __test_205_cleanup() {
20823         kill $@
20824         # Clear all job entries
20825         do_facet mds1 "$LCTL set_param mdt.*.job_stats=clear"
20826 }
20827
20828 test_205g() {
20829         local -a mds1_params
20830         local -a cli_params
20831         local pids
20832         local interval=5
20833
20834         mds1_params=( $(do_facet mds1 $LCTL get_param mdt.*.job_cleanup_interval) )
20835         do_facet mds1 $LCTL set_param mdt.*.job_cleanup_interval=$interval
20836         stack_trap "do_facet mds1 $LCTL set_param ${mds1_params[*]}" EXIT
20837
20838         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20839         $LCTL set_param jobid_var=TEST205G_ID jobid_name=%j.%p
20840         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20841
20842         # start jobs loop
20843         export TEST205G_ID=205g
20844         stack_trap "unset TEST205G_ID" EXIT
20845         while true; do
20846                 printf $DIR/$tfile.{0001..1000} | xargs -P10 -n1 touch
20847         done & pids="$! "
20848
20849         __test_205_jobstats_dump 4 & pids+="$! "
20850         stack_trap "__test_205_cleanup $pids" EXIT INT
20851
20852         [[ $SLOW == "no" ]] && sleep 90 || sleep 240
20853 }
20854 run_test 205g "stress test for job_stats procfile"
20855
20856 test_205h() {
20857         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
20858                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
20859         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
20860
20861         local dir=$DIR/$tdir
20862         local f=$dir/$tfile
20863         local f2=$dir/$tfile-2
20864         local f3=$dir/$tfile-3
20865         local subdir=$DIR/dir
20866         local val
20867
20868         local mdts=$(comma_list $(mdts_nodes))
20869         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20870         local client_saved=$($LCTL get_param -n jobid_var)
20871
20872         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20873         stack_trap "$LCTL set_param jobid_var=$client_saved" EXIT
20874
20875         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job ||
20876                 error "failed to set job_xattr parameter to user.job"
20877         $LCTL set_param jobid_var=procname.uid ||
20878                 error "failed to set jobid_var parameter"
20879
20880         test_mkdir $dir
20881
20882         touch $f
20883         val=$(getfattr -n user.job $f | grep user.job)
20884         [[ $val = user.job=\"touch.0\" ]] ||
20885                 error "expected user.job=\"touch.0\", got '$val'"
20886
20887         mkdir $subdir
20888         val=$(getfattr -n user.job $subdir | grep user.job)
20889         [[ $val = user.job=\"mkdir.0\" ]] ||
20890                 error "expected user.job=\"mkdir.0\", got '$val'"
20891
20892         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE ||
20893                 error "failed to set job_xattr parameter to NONE"
20894
20895         touch $f2
20896         val=$(getfattr -d $f2)
20897         [[ -z $val ]] ||
20898                 error "expected no user xattr, got '$val'"
20899
20900         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=trusted.job ||
20901                 error "failed to set job_xattr parameter to trusted.job"
20902
20903         touch $f3
20904         val=$(getfattr -n trusted.job $f3 | grep trusted.job)
20905         [[ $val = trusted.job=\"touch.0\" ]] ||
20906                 error "expected trusted.job=\"touch.0\", got '$val'"
20907 }
20908 run_test 205h "check jobid xattr is stored correctly"
20909
20910 test_205i() {
20911         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
20912                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
20913
20914         local mdts=$(comma_list $(mdts_nodes))
20915         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20916
20917         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20918
20919         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.1234567 ||
20920                 error "failed to set mdt.*.job_xattr to user.1234567"
20921
20922         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.12345678 &&
20923                 error "failed to reject too long job_xattr name"
20924
20925         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=userjob &&
20926                 error "failed to reject job_xattr name in bad format"
20927
20928         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job/ &&
20929                 error "failed to reject job_xattr name with invalid character"
20930
20931         do_nodes $mdts "printf 'mdt.*.job_xattr=user.job\x80' |
20932                         xargs $LCTL set_param" &&
20933                 error "failed to reject job_xattr name with non-ascii character"
20934
20935         return 0
20936 }
20937 run_test 205i "check job_xattr parameter accepts and rejects values correctly"
20938
20939 # LU-1480, LU-1773 and LU-1657
20940 test_206() {
20941         mkdir -p $DIR/$tdir
20942         $LFS setstripe -c -1 $DIR/$tdir
20943 #define OBD_FAIL_LOV_INIT 0x1403
20944         $LCTL set_param fail_loc=0xa0001403
20945         $LCTL set_param fail_val=1
20946         touch $DIR/$tdir/$tfile || true
20947 }
20948 run_test 206 "fail lov_init_raid0() doesn't lbug"
20949
20950 test_207a() {
20951         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20952         local fsz=`stat -c %s $DIR/$tfile`
20953         cancel_lru_locks mdc
20954
20955         # do not return layout in getattr intent
20956 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
20957         $LCTL set_param fail_loc=0x170
20958         local sz=`stat -c %s $DIR/$tfile`
20959
20960         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
20961
20962         rm -rf $DIR/$tfile
20963 }
20964 run_test 207a "can refresh layout at glimpse"
20965
20966 test_207b() {
20967         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20968         local cksum=`md5sum $DIR/$tfile`
20969         local fsz=`stat -c %s $DIR/$tfile`
20970         cancel_lru_locks mdc
20971         cancel_lru_locks osc
20972
20973         # do not return layout in getattr intent
20974 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
20975         $LCTL set_param fail_loc=0x171
20976
20977         # it will refresh layout after the file is opened but before read issues
20978         echo checksum is "$cksum"
20979         echo "$cksum" |md5sum -c --quiet || error "file differs"
20980
20981         rm -rf $DIR/$tfile
20982 }
20983 run_test 207b "can refresh layout at open"
20984
20985 test_208() {
20986         # FIXME: in this test suite, only RD lease is used. This is okay
20987         # for now as only exclusive open is supported. After generic lease
20988         # is done, this test suite should be revised. - Jinshan
20989
20990         remote_mds_nodsh && skip "remote MDS with nodsh"
20991         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
20992                 skip "Need MDS version at least 2.4.52"
20993
20994         echo "==== test 1: verify get lease work"
20995         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
20996
20997         echo "==== test 2: verify lease can be broken by upcoming open"
20998         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20999         local PID=$!
21000         sleep 2
21001
21002         $MULTIOP $DIR/$tfile oO_RDWR:c
21003         kill -USR1 $PID && wait $PID || error "break lease error"
21004
21005         echo "==== test 3: verify lease can't be granted if an open already exists"
21006         $MULTIOP $DIR/$tfile oO_RDWR:_c &
21007         local PID=$!
21008         sleep 2
21009
21010         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
21011         kill -USR1 $PID && wait $PID || error "open file error"
21012
21013         echo "==== test 4: lease can sustain over recovery"
21014         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
21015         PID=$!
21016         sleep 2
21017
21018         fail mds1
21019
21020         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
21021
21022         echo "==== test 5: lease broken can't be regained by replay"
21023         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
21024         PID=$!
21025         sleep 2
21026
21027         # open file to break lease and then recovery
21028         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
21029         fail mds1
21030
21031         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
21032
21033         rm -f $DIR/$tfile
21034 }
21035 run_test 208 "Exclusive open"
21036
21037 test_209() {
21038         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
21039                 skip_env "must have disp_stripe"
21040
21041         touch $DIR/$tfile
21042         sync; sleep 5; sync;
21043
21044         echo 3 > /proc/sys/vm/drop_caches
21045         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
21046                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
21047         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
21048
21049         # open/close 500 times
21050         for i in $(seq 500); do
21051                 cat $DIR/$tfile
21052         done
21053
21054         echo 3 > /proc/sys/vm/drop_caches
21055         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
21056                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
21057         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
21058
21059         echo "before: $req_before, after: $req_after"
21060         [ $((req_after - req_before)) -ge 300 ] &&
21061                 error "open/close requests are not freed"
21062         return 0
21063 }
21064 run_test 209 "read-only open/close requests should be freed promptly"
21065
21066 test_210() {
21067         local pid
21068
21069         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
21070         pid=$!
21071         sleep 1
21072
21073         $LFS getstripe $DIR/$tfile
21074         kill -USR1 $pid
21075         wait $pid || error "multiop failed"
21076
21077         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
21078         pid=$!
21079         sleep 1
21080
21081         $LFS getstripe $DIR/$tfile
21082         kill -USR1 $pid
21083         wait $pid || error "multiop failed"
21084 }
21085 run_test 210 "lfs getstripe does not break leases"
21086
21087 function test_211() {
21088         local PID
21089         local id
21090         local rc
21091
21092         stack_trap "rm -f $DIR/$tfile" EXIT
21093         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=10 oflag=direct ||
21094                 error "can't create file"
21095         $LFS mirror extend -N $DIR/$tfile ||
21096                 error "can't create a replica"
21097         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
21098         $LFS getstripe $DIR/$tfile
21099         stale=$($LFS getstripe $DIR/$tfile | grep stale | wc -l)
21100         (( $stale != 1 )) && error "expected 1 stale, found $stale"
21101
21102         $MULTIOP $DIR/$tfile OeW_E+eUc &
21103         PID=$!
21104         sleep 0.3
21105
21106         id=$($LFS getstripe $DIR/$tfile |
21107                 awk '/lcme_mirror_id:/{id=$2}/lcme_flags.*init$/{print id}')
21108         $LFS mirror split -d --mirror-id $id $DIR/$tfile &&
21109                 error "removed last in-sync replica?"
21110
21111         kill -USR1 $PID
21112         wait $PID
21113         (( $? == 0 )) || error "failed split broke the lease"
21114 }
21115 run_test 211 "failed mirror split doesn't break write lease"
21116
21117 test_212() {
21118         size=`date +%s`
21119         size=$((size % 8192 + 1))
21120         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
21121         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
21122         rm -f $DIR/f212 $DIR/f212.xyz
21123 }
21124 run_test 212 "Sendfile test ============================================"
21125
21126 test_213() {
21127         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
21128         cancel_lru_locks osc
21129         lctl set_param fail_loc=0x8000040f
21130         # generate a read lock
21131         cat $DIR/$tfile > /dev/null
21132         # write to the file, it will try to cancel the above read lock.
21133         cat /etc/hosts >> $DIR/$tfile
21134 }
21135 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
21136
21137 test_214() { # for bug 20133
21138         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
21139         for (( i=0; i < 340; i++ )) ; do
21140                 touch $DIR/$tdir/d214c/a$i
21141         done
21142
21143         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
21144         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
21145         ls $DIR/d214c || error "ls $DIR/d214c failed"
21146         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
21147         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
21148 }
21149 run_test 214 "hash-indexed directory test - bug 20133"
21150
21151 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
21152 create_lnet_proc_files() {
21153         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
21154 }
21155
21156 # counterpart of create_lnet_proc_files
21157 remove_lnet_proc_files() {
21158         rm -f $TMP/lnet_$1.sys
21159 }
21160
21161 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
21162 # 3rd arg as regexp for body
21163 check_lnet_proc_stats() {
21164         local l=$(cat "$TMP/lnet_$1" |wc -l)
21165         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
21166
21167         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
21168 }
21169
21170 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
21171 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
21172 # optional and can be regexp for 2nd line (lnet.routes case)
21173 check_lnet_proc_entry() {
21174         local blp=2          # blp stands for 'position of 1st line of body'
21175         [ -z "$5" ] || blp=3 # lnet.routes case
21176
21177         local l=$(cat "$TMP/lnet_$1" |wc -l)
21178         # subtracting one from $blp because the body can be empty
21179         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
21180
21181         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
21182                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
21183
21184         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
21185                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
21186
21187         # bail out if any unexpected line happened
21188         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
21189         [ "$?" != 0 ] || error "$2 misformatted"
21190 }
21191
21192 test_215() { # for bugs 18102, 21079, 21517
21193         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21194
21195         local N='(0|[1-9][0-9]*)'       # non-negative numeric
21196         local P='[1-9][0-9]*'           # positive numeric
21197         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
21198         local NET='[a-z][a-z0-9]*'      # LNet net like o2ib2
21199         local ADDR='[0-9.]+'            # LNet addr like 10.0.0.1
21200         local ADDR6='([0-9a-f]{0,4}:){2,7}[0-9a-f]{0,4}' # IPv6 LNet addr
21201         local NID="$ADDR@$NET"          # LNet nid like 10.0.0.1@o2ib2
21202         local NID6="$ADDR6@$NET"        # LNet nid like 2601:8c1:c180::cbdd@tcp
21203
21204         local L1 # regexp for 1st line
21205         local L2 # regexp for 2nd line (optional)
21206         local BR # regexp for the rest (body)
21207
21208         # lnet.stats should look as 11 space-separated non-negative numerics
21209         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
21210         create_lnet_proc_files "stats"
21211         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
21212         remove_lnet_proc_files "stats"
21213
21214         # lnet.routes should look like this:
21215         # Routing disabled/enabled
21216         # net hops priority state router
21217         # where net is a string like tcp0, hops > 0, priority >= 0,
21218         # state is up/down,
21219         # router is a string like 192.168.1.1@tcp2
21220         L1="^Routing (disabled|enabled)$"
21221         L2="^net +hops +priority +state +router$"
21222         BR="^$NET +$N +(0|1) +(up|down) +($NID|$NID6)$"
21223         create_lnet_proc_files "routes"
21224         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
21225         remove_lnet_proc_files "routes"
21226
21227         # lnet.routers should look like this:
21228         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
21229         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
21230         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
21231         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
21232         L1="^ref +rtr_ref +alive +router$"
21233         BR="^$P +$P +(up|down) +($NID|$NID6)$"
21234         create_lnet_proc_files "routers"
21235         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
21236         remove_lnet_proc_files "routers"
21237
21238         # lnet.peers should look like this:
21239         # nid refs state last max rtr min tx min queue
21240         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
21241         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
21242         # numeric (0 or >0 or <0), queue >= 0.
21243         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
21244         BR="^($NID|$NID6) +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
21245         create_lnet_proc_files "peers"
21246         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
21247         remove_lnet_proc_files "peers"
21248
21249         # lnet.buffers  should look like this:
21250         # pages count credits min
21251         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
21252         L1="^pages +count +credits +min$"
21253         BR="^ +$N +$N +$I +$I$"
21254         create_lnet_proc_files "buffers"
21255         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
21256         remove_lnet_proc_files "buffers"
21257
21258         # lnet.nis should look like this:
21259         # nid status alive refs peer rtr max tx min
21260         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
21261         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
21262         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
21263         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
21264         BR="^($NID|$NID6) +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
21265         create_lnet_proc_files "nis"
21266         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
21267         remove_lnet_proc_files "nis"
21268
21269         # can we successfully write to lnet.stats?
21270         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
21271 }
21272 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
21273
21274 test_216() { # bug 20317
21275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21276         remote_ost_nodsh && skip "remote OST with nodsh"
21277
21278         local node
21279         local facets=$(get_facets OST)
21280         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
21281
21282         save_lustre_params client "osc.*.contention_seconds" > $p
21283         save_lustre_params $facets \
21284                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
21285         save_lustre_params $facets \
21286                 "ldlm.namespaces.filter-*.contended_locks" >> $p
21287         save_lustre_params $facets \
21288                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
21289         clear_stats osc.*.osc_stats
21290
21291         # agressive lockless i/o settings
21292         do_nodes $(comma_list $(osts_nodes)) \
21293                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
21294                         ldlm.namespaces.filter-*.contended_locks=0 \
21295                         ldlm.namespaces.filter-*.contention_seconds=60"
21296         lctl set_param -n osc.*.contention_seconds=60
21297
21298         $DIRECTIO write $DIR/$tfile 0 10 4096
21299         $CHECKSTAT -s 40960 $DIR/$tfile
21300
21301         # disable lockless i/o
21302         do_nodes $(comma_list $(osts_nodes)) \
21303                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
21304                         ldlm.namespaces.filter-*.contended_locks=32 \
21305                         ldlm.namespaces.filter-*.contention_seconds=0"
21306         lctl set_param -n osc.*.contention_seconds=0
21307         clear_stats osc.*.osc_stats
21308
21309         dd if=/dev/zero of=$DIR/$tfile count=0
21310         $CHECKSTAT -s 0 $DIR/$tfile
21311
21312         restore_lustre_params <$p
21313         rm -f $p
21314         rm $DIR/$tfile
21315 }
21316 run_test 216 "check lockless direct write updates file size and kms correctly"
21317
21318 test_217() { # bug 22430
21319         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21320
21321         local node
21322
21323         for node in $(nodes_list); do
21324                 local nid=$(host_nids_address $node $NETTYPE)
21325                 local node_ip=$(do_node $node getent ahostsv4 $node |
21326                                 awk '{ print $1; exit; }')
21327
21328                 echo "node: '$node', nid: '$nid', node_ip='$node_ip'"
21329                 # if hostname matches any NID, use hostname for better testing
21330                 if [[ -z "$nid" || "$nid" =~ "$node_ip" ]]; then
21331                         echo "lctl ping node $node@$NETTYPE"
21332                         lctl ping $node@$NETTYPE ||
21333                                 error "ping $node@$NETTYPE failed rc=$?"
21334                 else # otherwise, at least test 'lctl ping' is working
21335                         echo "lctl ping nid $(h2nettype $nid)"
21336                         lctl ping $(h2nettype $nid) ||
21337                                 error "ping $(h2nettype $nid) failed rc=$?"
21338                         echo "skipping $node (no hyphen detected)"
21339                 fi
21340         done
21341
21342         return 0
21343 }
21344 run_test 217 "check lctl ping for hostnames with embedded hyphen ('-')"
21345
21346 test_218() {
21347         # do directio so as not to populate the page cache
21348         log "creating a 10 Mb file"
21349         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
21350                 error "multiop failed while creating a file"
21351         log "starting reads"
21352         dd if=$DIR/$tfile of=/dev/null bs=4096 &
21353         log "truncating the file"
21354         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
21355                 error "multiop failed while truncating the file"
21356         log "killing dd"
21357         kill %+ || true # reads might have finished
21358         echo "wait until dd is finished"
21359         wait
21360         log "removing the temporary file"
21361         rm -rf $DIR/$tfile || error "tmp file removal failed"
21362 }
21363 run_test 218 "parallel read and truncate should not deadlock"
21364
21365 test_219() {
21366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21367
21368         # write one partial page
21369         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
21370         # set no grant so vvp_io_commit_write will do sync write
21371         $LCTL set_param fail_loc=0x411
21372         # write a full page at the end of file
21373         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
21374
21375         $LCTL set_param fail_loc=0
21376         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
21377         $LCTL set_param fail_loc=0x411
21378         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
21379
21380         # LU-4201
21381         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
21382         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
21383 }
21384 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
21385
21386 test_220() { #LU-325
21387         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21388         remote_ost_nodsh && skip "remote OST with nodsh"
21389         remote_mds_nodsh && skip "remote MDS with nodsh"
21390         remote_mgs_nodsh && skip "remote MGS with nodsh"
21391
21392         local OSTIDX=0
21393
21394         # create on MDT0000 so the last_id and next_id are correct
21395         mkdir_on_mdt0 $DIR/$tdir
21396         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
21397         OST=${OST%_UUID}
21398
21399         # on the mdt's osc
21400         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
21401         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
21402                         osp.$mdtosc_proc1.prealloc_last_id)
21403         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
21404                         osp.$mdtosc_proc1.prealloc_next_id)
21405
21406         $LFS df -i
21407
21408         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
21409         #define OBD_FAIL_OST_ENOINO              0x229
21410         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
21411         create_pool $FSNAME.$TESTNAME || return 1
21412         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
21413
21414         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
21415
21416         MDSOBJS=$((last_id - next_id))
21417         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
21418
21419         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
21420         echo "OST still has $count kbytes free"
21421
21422         echo "create $MDSOBJS files @next_id..."
21423         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
21424
21425         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
21426                         osp.$mdtosc_proc1.prealloc_last_id)
21427         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
21428                         osp.$mdtosc_proc1.prealloc_next_id)
21429
21430         echo "after creation, last_id=$last_id2, next_id=$next_id2"
21431         $LFS df -i
21432
21433         echo "cleanup..."
21434
21435         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
21436         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
21437
21438         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
21439                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
21440         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
21441                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
21442         echo "unlink $MDSOBJS files @$next_id..."
21443         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
21444 }
21445 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
21446
21447 test_221() {
21448         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21449
21450         dd if=`which date` of=$MOUNT/date oflag=sync
21451         chmod +x $MOUNT/date
21452
21453         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
21454         $LCTL set_param fail_loc=0x80001401
21455
21456         $MOUNT/date > /dev/null
21457         rm -f $MOUNT/date
21458 }
21459 run_test 221 "make sure fault and truncate race to not cause OOM"
21460
21461 test_222a () {
21462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21463
21464         rm -rf $DIR/$tdir
21465         test_mkdir $DIR/$tdir
21466         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21467         createmany -o $DIR/$tdir/$tfile 10
21468         cancel_lru_locks mdc
21469         cancel_lru_locks osc
21470         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21471         $LCTL set_param fail_loc=0x31a
21472         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
21473         $LCTL set_param fail_loc=0
21474         rm -r $DIR/$tdir
21475 }
21476 run_test 222a "AGL for ls should not trigger CLIO lock failure"
21477
21478 test_222b () {
21479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21480
21481         rm -rf $DIR/$tdir
21482         test_mkdir $DIR/$tdir
21483         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21484         createmany -o $DIR/$tdir/$tfile 10
21485         cancel_lru_locks mdc
21486         cancel_lru_locks osc
21487         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21488         $LCTL set_param fail_loc=0x31a
21489         rm -r $DIR/$tdir || error "AGL for rmdir failed"
21490         $LCTL set_param fail_loc=0
21491 }
21492 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
21493
21494 test_223 () {
21495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21496
21497         rm -rf $DIR/$tdir
21498         test_mkdir $DIR/$tdir
21499         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21500         createmany -o $DIR/$tdir/$tfile 10
21501         cancel_lru_locks mdc
21502         cancel_lru_locks osc
21503         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
21504         $LCTL set_param fail_loc=0x31b
21505         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
21506         $LCTL set_param fail_loc=0
21507         rm -r $DIR/$tdir
21508 }
21509 run_test 223 "osc reenqueue if without AGL lock granted ======================="
21510
21511 test_224a() { # LU-1039, MRP-303
21512         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21513         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
21514         $LCTL set_param fail_loc=0x508
21515         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
21516         $LCTL set_param fail_loc=0
21517         df $DIR
21518 }
21519 run_test 224a "Don't panic on bulk IO failure"
21520
21521 test_224bd_sub() { # LU-1039, MRP-303
21522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21523         local timeout=$1
21524
21525         shift
21526         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
21527
21528         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21529
21530         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
21531         cancel_lru_locks osc
21532         set_checksums 0
21533         stack_trap "set_checksums $ORIG_CSUM" EXIT
21534         local at_max_saved=0
21535
21536         # adaptive timeouts may prevent seeing the issue
21537         if at_is_enabled; then
21538                 at_max_saved=$(at_max_get mds)
21539                 at_max_set 0 mds client
21540                 stack_trap "at_max_set $at_max_saved mds client" EXIT
21541         fi
21542
21543         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
21544         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
21545         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
21546
21547         do_facet ost1 $LCTL set_param fail_loc=0
21548         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
21549         df $DIR
21550 }
21551
21552 test_224b() {
21553         test_224bd_sub 3 error "dd failed"
21554 }
21555 run_test 224b "Don't panic on bulk IO failure"
21556
21557 test_224c() { # LU-6441
21558         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21559         remote_mds_nodsh && skip "remote MDS with nodsh"
21560
21561         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
21562         save_writethrough $p
21563         set_cache writethrough on
21564
21565         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
21566         local at_max=$($LCTL get_param -n at_max)
21567         local timeout=$($LCTL get_param -n timeout)
21568         local test_at="at_max"
21569         local param_at="$FSNAME.sys.at_max"
21570         local test_timeout="timeout"
21571         local param_timeout="$FSNAME.sys.timeout"
21572
21573         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
21574
21575         set_persistent_param_and_check client "$test_at" "$param_at" 0
21576         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
21577
21578         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
21579         do_facet ost1 "$LCTL set_param fail_loc=0x520"
21580         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21581         stack_trap "rm -f $DIR/$tfile"
21582         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
21583         sync
21584         do_facet ost1 "$LCTL set_param fail_loc=0"
21585
21586         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
21587         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
21588                 $timeout
21589
21590         $LCTL set_param -n $pages_per_rpc
21591         restore_lustre_params < $p
21592         rm -f $p
21593 }
21594 run_test 224c "Don't hang if one of md lost during large bulk RPC"
21595
21596 test_224d() { # LU-11169
21597         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
21598 }
21599 run_test 224d "Don't corrupt data on bulk IO timeout"
21600
21601 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
21602 test_225a () {
21603         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21604         if [ -z ${MDSSURVEY} ]; then
21605                 skip_env "mds-survey not found"
21606         fi
21607         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21608                 skip "Need MDS version at least 2.2.51"
21609
21610         local mds=$(facet_host $SINGLEMDS)
21611         local target=$(do_nodes $mds 'lctl dl' |
21612                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21613
21614         local cmd1="file_count=1000 thrhi=4"
21615         local cmd2="dir_count=2 layer=mdd stripe_count=0"
21616         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21617         local cmd="$cmd1 $cmd2 $cmd3"
21618
21619         rm -f ${TMP}/mds_survey*
21620         echo + $cmd
21621         eval $cmd || error "mds-survey with zero-stripe failed"
21622         cat ${TMP}/mds_survey*
21623         rm -f ${TMP}/mds_survey*
21624 }
21625 run_test 225a "Metadata survey sanity with zero-stripe"
21626
21627 test_225b () {
21628         if [ -z ${MDSSURVEY} ]; then
21629                 skip_env "mds-survey not found"
21630         fi
21631         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21632                 skip "Need MDS version at least 2.2.51"
21633         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21634         remote_mds_nodsh && skip "remote MDS with nodsh"
21635         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
21636                 skip_env "Need to mount OST to test"
21637         fi
21638
21639         local mds=$(facet_host $SINGLEMDS)
21640         local target=$(do_nodes $mds 'lctl dl' |
21641                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21642
21643         local cmd1="file_count=1000 thrhi=4"
21644         local cmd2="dir_count=2 layer=mdd stripe_count=1"
21645         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21646         local cmd="$cmd1 $cmd2 $cmd3"
21647
21648         rm -f ${TMP}/mds_survey*
21649         echo + $cmd
21650         eval $cmd || error "mds-survey with stripe_count failed"
21651         cat ${TMP}/mds_survey*
21652         rm -f ${TMP}/mds_survey*
21653 }
21654 run_test 225b "Metadata survey sanity with stripe_count = 1"
21655
21656 mcreate_path2fid () {
21657         local mode=$1
21658         local major=$2
21659         local minor=$3
21660         local name=$4
21661         local desc=$5
21662         local path=$DIR/$tdir/$name
21663         local fid
21664         local rc
21665         local fid_path
21666
21667         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
21668                 error "cannot create $desc"
21669
21670         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
21671         rc=$?
21672         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
21673
21674         fid_path=$($LFS fid2path $MOUNT $fid)
21675         rc=$?
21676         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
21677
21678         [ "$path" == "$fid_path" ] ||
21679                 error "fid2path returned $fid_path, expected $path"
21680
21681         echo "pass with $path and $fid"
21682 }
21683
21684 test_226a () {
21685         rm -rf $DIR/$tdir
21686         mkdir -p $DIR/$tdir
21687
21688         mcreate_path2fid 0010666 0 0 fifo "FIFO"
21689         mcreate_path2fid 0020666 1 3 null "character special file (null)"
21690         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
21691         mcreate_path2fid 0040666 0 0 dir "directory"
21692         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
21693         mcreate_path2fid 0100666 0 0 file "regular file"
21694         mcreate_path2fid 0120666 0 0 link "symbolic link"
21695         mcreate_path2fid 0140666 0 0 sock "socket"
21696 }
21697 run_test 226a "call path2fid and fid2path on files of all type"
21698
21699 test_226b () {
21700         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21701
21702         local MDTIDX=1
21703
21704         rm -rf $DIR/$tdir
21705         mkdir -p $DIR/$tdir
21706         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
21707                 error "create remote directory failed"
21708         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
21709         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
21710                                 "character special file (null)"
21711         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
21712                                 "character special file (no device)"
21713         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
21714         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
21715                                 "block special file (loop)"
21716         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
21717         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
21718         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
21719 }
21720 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
21721
21722 test_226c () {
21723         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21724         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
21725                 skip "Need MDS version at least 2.13.55"
21726
21727         local submnt=/mnt/submnt
21728         local srcfile=/etc/passwd
21729         local dstfile=$submnt/passwd
21730         local path
21731         local fid
21732
21733         rm -rf $DIR/$tdir
21734         rm -rf $submnt
21735         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
21736                 error "create remote directory failed"
21737         mkdir -p $submnt || error "create $submnt failed"
21738         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
21739                 error "mount $submnt failed"
21740         stack_trap "umount $submnt" EXIT
21741
21742         cp $srcfile $dstfile
21743         fid=$($LFS path2fid $dstfile)
21744         path=$($LFS fid2path $submnt "$fid")
21745         [ "$path" = "$dstfile" ] ||
21746                 error "fid2path $submnt $fid failed ($path != $dstfile)"
21747 }
21748 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
21749
21750 test_226d () {
21751         (( $CLIENT_VERSION >= $(version_code 2.15.57) )) ||
21752                 skip "Need client at least version 2.15.57"
21753
21754         # Define First test dataset
21755         local testdirs_01=$DIR/$tdir
21756         local testdata_01=$testdirs_01/${tdir}_01
21757         local testresult_01=${tdir}_01
21758         # Define Second test dataset
21759         local testdirs_02=$DIR/$tdir/$tdir
21760         local testdata_02=$testdirs_02/${tdir}_02
21761         local testresult_02=${tdir}_02
21762         # Define third test dataset (top level)
21763         local testdata_03=$DIR/${tdir}_03
21764         local testresult_03=${tdir}_03
21765
21766         # Create first test dataset
21767         mkdir -p $testdirs_01 || error "cannot create dir $testdirs_01"
21768         touch $testdata_01 || error "cannot create file $testdata_01"
21769
21770         # Create second test dataset
21771         mkdir -p $testdirs_02 || error "cannot create dir $testdirs_02"
21772         touch $testdata_02 || error "cannot create file $testdata_02"
21773
21774         # Create third test dataset
21775         touch $testdata_03 || error "cannot create file $testdata_03"
21776
21777         local fid01=$($LFS getstripe -F "$testdata_01") ||
21778                 error "getstripe failed on $testdata_01"
21779         local fid02=$($LFS getstripe -F "$testdata_02") ||
21780                 error "getstripe failed on $testdata_01"
21781         local fid03=$($LFS getstripe -F "$testdata_03") ||
21782                 error "getstripe failed on $testdata_03"
21783
21784         # Verify only -n option
21785         local out1=$($LFS fid2path -n $DIR $fid01) ||
21786                 error "fid2path failed on $fid01"
21787         local out2=$($LFS fid2path -n $DIR $fid02) ||
21788                 error "fid2path failed on $fid02"
21789         local out3=$($LFS fid2path -n $DIR $fid03) ||
21790                 error "fid2path failed on $fid03"
21791
21792         [[ "$out1" == "$testresult_01" ]] ||
21793                 error "fid2path failed: Expected $testresult_01 got $out1"
21794         [[ "$out2" == "$testresult_02" ]] ||
21795                 error "fid2path failed: Expected $testresult_02 got $out2"
21796         [[ "$out3" == "$testresult_03" ]] ||
21797                 error "fid2path failed: Expected $testresult_03 got $out3"
21798
21799         # Verify with option -fn together
21800         out1=$($LFS fid2path -fn $DIR $fid01) ||
21801                 error "fid2path -fn failed on $fid01"
21802         out2=$($LFS fid2path -fn $DIR $fid02) ||
21803                 error "fid2path -fn failed on $fid02"
21804         out3=$($LFS fid2path -fn $DIR $fid03) ||
21805                 error "fid2path -fn failed on $fid03"
21806
21807         local tmpout=$(echo $out1 | cut -d" " -f2)
21808         [[ "$tmpout" == "$testresult_01" ]] ||
21809                 error "fid2path -fn failed: Expected $testresult_01 got $out1"
21810
21811         tmpout=$(echo $out2 | cut -d" " -f2)
21812         [[ "$tmpout" == "$testresult_02" ]] ||
21813                 error "fid2path -fn failed: Expected $testresult_02 got $out2"
21814
21815         tmpout=$(echo $out3 | cut -d" " -f2)
21816         [[ "$tmpout" == "$testresult_03" ]] ||
21817                 error "fid2path -fn failed: Expected $testresult_03 got $out3"
21818 }
21819 run_test 226d "verify fid2path with -n and -fn option"
21820
21821 test_226e () {
21822         (( $CLIENT_VERSION >= $(version_code 2.15.56) )) ||
21823                 skip "Need client at least version 2.15.56"
21824
21825         # Define filename with 'newline' and a space
21826         local testfile="Test"$'\n'"file 01"
21827         # Define link name with multiple 'newline' and a space
21828         local linkfile="Link"$'\n'"file "$'\n'"01"
21829         # Remove prior hard link
21830         rm -f $DIR/"$linkfile"
21831
21832         # Create file
21833         touch $DIR/"$testfile"
21834         # Create link
21835         ln $DIR/"$testfile" $DIR/"$linkfile"
21836
21837         local fid=$($LFS getstripe -F "$DIR/$testfile") ||
21838                 error "getstripe failed on $DIR/$testfile"
21839
21840         # Call with -0 option
21841         local out1=$($LFS fid2path -0 $DIR $fid | xargs --null -n1 \
21842                 echo "FILE:" | grep -c "FILE:")
21843
21844         # With -0 option the output should be exactly 2 lines.
21845         (( $out1 == 2 )) || error "fid2path -0 failed on $fid, $out1"
21846 }
21847 run_test 226e "Verify path2fid -0 option with newline and space"
21848
21849 # LU-1299 Executing or running ldd on a truncated executable does not
21850 # cause an out-of-memory condition.
21851 test_227() {
21852         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21853         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
21854
21855         dd if=$(which date) of=$MOUNT/date bs=1k count=1
21856         chmod +x $MOUNT/date
21857
21858         $MOUNT/date > /dev/null
21859         ldd $MOUNT/date > /dev/null
21860         rm -f $MOUNT/date
21861 }
21862 run_test 227 "running truncated executable does not cause OOM"
21863
21864 # LU-1512 try to reuse idle OI blocks
21865 test_228a() {
21866         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21867         remote_mds_nodsh && skip "remote MDS with nodsh"
21868         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21869
21870         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21871         local myDIR=$DIR/$tdir
21872
21873         mkdir -p $myDIR
21874         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21875         $LCTL set_param fail_loc=0x80001002
21876         createmany -o $myDIR/t- 10000
21877         $LCTL set_param fail_loc=0
21878         # The guard is current the largest FID holder
21879         touch $myDIR/guard
21880         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21881                     tr -d '[')
21882         local IDX=$(($SEQ % 64))
21883
21884         do_facet $SINGLEMDS sync
21885         # Make sure journal flushed.
21886         sleep 6
21887         local blk1=$(do_facet $SINGLEMDS \
21888                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21889                      grep Blockcount | awk '{print $4}')
21890
21891         # Remove old files, some OI blocks will become idle.
21892         unlinkmany $myDIR/t- 10000
21893         # Create new files, idle OI blocks should be reused.
21894         createmany -o $myDIR/t- 2000
21895         do_facet $SINGLEMDS sync
21896         # Make sure journal flushed.
21897         sleep 6
21898         local blk2=$(do_facet $SINGLEMDS \
21899                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21900                      grep Blockcount | awk '{print $4}')
21901
21902         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21903 }
21904 run_test 228a "try to reuse idle OI blocks"
21905
21906 test_228b() {
21907         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21908         remote_mds_nodsh && skip "remote MDS with nodsh"
21909         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21910
21911         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21912         local myDIR=$DIR/$tdir
21913
21914         mkdir -p $myDIR
21915         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21916         $LCTL set_param fail_loc=0x80001002
21917         createmany -o $myDIR/t- 10000
21918         $LCTL set_param fail_loc=0
21919         # The guard is current the largest FID holder
21920         touch $myDIR/guard
21921         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21922                     tr -d '[')
21923         local IDX=$(($SEQ % 64))
21924
21925         do_facet $SINGLEMDS sync
21926         # Make sure journal flushed.
21927         sleep 6
21928         local blk1=$(do_facet $SINGLEMDS \
21929                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21930                      grep Blockcount | awk '{print $4}')
21931
21932         # Remove old files, some OI blocks will become idle.
21933         unlinkmany $myDIR/t- 10000
21934
21935         # stop the MDT
21936         stop $SINGLEMDS || error "Fail to stop MDT."
21937         # remount the MDT
21938         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
21939                 error "Fail to start MDT."
21940
21941         client_up || error "Fail to df."
21942         # Create new files, idle OI blocks should be reused.
21943         createmany -o $myDIR/t- 2000
21944         do_facet $SINGLEMDS sync
21945         # Make sure journal flushed.
21946         sleep 6
21947         local blk2=$(do_facet $SINGLEMDS \
21948                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21949                      grep Blockcount | awk '{print $4}')
21950
21951         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21952 }
21953 run_test 228b "idle OI blocks can be reused after MDT restart"
21954
21955 #LU-1881
21956 test_228c() {
21957         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21958         remote_mds_nodsh && skip "remote MDS with nodsh"
21959         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21960
21961         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21962         local myDIR=$DIR/$tdir
21963
21964         mkdir -p $myDIR
21965         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21966         $LCTL set_param fail_loc=0x80001002
21967         # 20000 files can guarantee there are index nodes in the OI file
21968         createmany -o $myDIR/t- 20000
21969         $LCTL set_param fail_loc=0
21970         # The guard is current the largest FID holder
21971         touch $myDIR/guard
21972         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21973                     tr -d '[')
21974         local IDX=$(($SEQ % 64))
21975
21976         do_facet $SINGLEMDS sync
21977         # Make sure journal flushed.
21978         sleep 6
21979         local blk1=$(do_facet $SINGLEMDS \
21980                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21981                      grep Blockcount | awk '{print $4}')
21982
21983         # Remove old files, some OI blocks will become idle.
21984         unlinkmany $myDIR/t- 20000
21985         rm -f $myDIR/guard
21986         # The OI file should become empty now
21987
21988         # Create new files, idle OI blocks should be reused.
21989         createmany -o $myDIR/t- 2000
21990         do_facet $SINGLEMDS sync
21991         # Make sure journal flushed.
21992         sleep 6
21993         local blk2=$(do_facet $SINGLEMDS \
21994                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21995                      grep Blockcount | awk '{print $4}')
21996
21997         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21998 }
21999 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
22000
22001 test_229() { # LU-2482, LU-3448
22002         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22003         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
22004         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
22005                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
22006
22007         rm -f $DIR/$tfile
22008
22009         # Create a file with a released layout and stripe count 2.
22010         $MULTIOP $DIR/$tfile H2c ||
22011                 error "failed to create file with released layout"
22012
22013         $LFS getstripe -v $DIR/$tfile
22014
22015         local pattern=$($LFS getstripe -L $DIR/$tfile)
22016         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
22017
22018         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
22019                 error "getstripe"
22020         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
22021         stat $DIR/$tfile || error "failed to stat released file"
22022
22023         chown $RUNAS_ID $DIR/$tfile ||
22024                 error "chown $RUNAS_ID $DIR/$tfile failed"
22025
22026         chgrp $RUNAS_ID $DIR/$tfile ||
22027                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
22028
22029         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
22030         rm $DIR/$tfile || error "failed to remove released file"
22031 }
22032 run_test 229 "getstripe/stat/rm/attr changes work on released files"
22033
22034 test_230a() {
22035         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22036         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22037         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22038                 skip "Need MDS version at least 2.11.52"
22039
22040         local MDTIDX=1
22041
22042         test_mkdir $DIR/$tdir
22043         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
22044         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
22045         [ $mdt_idx -ne 0 ] &&
22046                 error "create local directory on wrong MDT $mdt_idx"
22047
22048         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
22049                         error "create remote directory failed"
22050         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
22051         [ $mdt_idx -ne $MDTIDX ] &&
22052                 error "create remote directory on wrong MDT $mdt_idx"
22053
22054         createmany -o $DIR/$tdir/test_230/t- 10 ||
22055                 error "create files on remote directory failed"
22056         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
22057         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
22058         rm -r $DIR/$tdir || error "unlink remote directory failed"
22059 }
22060 run_test 230a "Create remote directory and files under the remote directory"
22061
22062 test_230b() {
22063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22064         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22065         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22066                 skip "Need MDS version at least 2.11.52"
22067
22068         local MDTIDX=1
22069         local mdt_index
22070         local i
22071         local file
22072         local pid
22073         local stripe_count
22074         local migrate_dir=$DIR/$tdir/migrate_dir
22075         local other_dir=$DIR/$tdir/other_dir
22076
22077         test_mkdir $DIR/$tdir
22078         test_mkdir -i0 -c1 $migrate_dir
22079         test_mkdir -i0 -c1 $other_dir
22080         for ((i=0; i<10; i++)); do
22081                 mkdir -p $migrate_dir/dir_${i}
22082                 createmany -o $migrate_dir/dir_${i}/f 10 ||
22083                         error "create files under remote dir failed $i"
22084         done
22085
22086         cp /etc/passwd $migrate_dir/$tfile
22087         cp /etc/passwd $other_dir/$tfile
22088         chattr +SAD $migrate_dir
22089         chattr +SAD $migrate_dir/$tfile
22090
22091         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
22092         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
22093         local old_dir_mode=$(stat -c%f $migrate_dir)
22094         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
22095
22096         mkdir -p $migrate_dir/dir_default_stripe2
22097         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
22098         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
22099
22100         mkdir -p $other_dir
22101         ln $migrate_dir/$tfile $other_dir/luna
22102         ln $migrate_dir/$tfile $migrate_dir/sofia
22103         ln $other_dir/$tfile $migrate_dir/david
22104         ln -s $migrate_dir/$tfile $other_dir/zachary
22105         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
22106         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
22107
22108         local len
22109         local lnktgt
22110
22111         # inline symlink
22112         for len in 58 59 60; do
22113                 lnktgt=$(str_repeat 'l' $len)
22114                 touch $migrate_dir/$lnktgt
22115                 ln -s $lnktgt $migrate_dir/${len}char_ln
22116         done
22117
22118         # PATH_MAX
22119         for len in 4094 4095; do
22120                 lnktgt=$(str_repeat 'l' $len)
22121                 ln -s $lnktgt $migrate_dir/${len}char_ln
22122         done
22123
22124         # NAME_MAX
22125         for len in 254 255; do
22126                 touch $migrate_dir/$(str_repeat 'l' $len)
22127         done
22128
22129         $LFS migrate -m $MDTIDX $migrate_dir ||
22130                 error "fails on migrating remote dir to MDT1"
22131
22132         echo "migratate to MDT1, then checking.."
22133         for ((i = 0; i < 10; i++)); do
22134                 for file in $(find $migrate_dir/dir_${i}); do
22135                         mdt_index=$($LFS getstripe -m $file)
22136                         # broken symlink getstripe will fail
22137                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
22138                                 error "$file is not on MDT${MDTIDX}"
22139                 done
22140         done
22141
22142         # the multiple link file should still in MDT0
22143         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
22144         [ $mdt_index == 0 ] ||
22145                 error "$file is not on MDT${MDTIDX}"
22146
22147         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
22148         [ "$old_dir_flag" = "$new_dir_flag" ] ||
22149                 error " expect $old_dir_flag get $new_dir_flag"
22150
22151         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
22152         [ "$old_file_flag" = "$new_file_flag" ] ||
22153                 error " expect $old_file_flag get $new_file_flag"
22154
22155         local new_dir_mode=$(stat -c%f $migrate_dir)
22156         [ "$old_dir_mode" = "$new_dir_mode" ] ||
22157                 error "expect mode $old_dir_mode get $new_dir_mode"
22158
22159         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
22160         [ "$old_file_mode" = "$new_file_mode" ] ||
22161                 error "expect mode $old_file_mode get $new_file_mode"
22162
22163         diff /etc/passwd $migrate_dir/$tfile ||
22164                 error "$tfile different after migration"
22165
22166         diff /etc/passwd $other_dir/luna ||
22167                 error "luna different after migration"
22168
22169         diff /etc/passwd $migrate_dir/sofia ||
22170                 error "sofia different after migration"
22171
22172         diff /etc/passwd $migrate_dir/david ||
22173                 error "david different after migration"
22174
22175         diff /etc/passwd $other_dir/zachary ||
22176                 error "zachary different after migration"
22177
22178         diff /etc/passwd $migrate_dir/${tfile}_ln ||
22179                 error "${tfile}_ln different after migration"
22180
22181         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
22182                 error "${tfile}_ln_other different after migration"
22183
22184         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
22185         [ $stripe_count = 2 ] ||
22186                 error "dir strpe_count $d != 2 after migration."
22187
22188         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
22189         [ $stripe_count = 2 ] ||
22190                 error "file strpe_count $d != 2 after migration."
22191
22192         #migrate back to MDT0
22193         MDTIDX=0
22194
22195         $LFS migrate -m $MDTIDX $migrate_dir ||
22196                 error "fails on migrating remote dir to MDT0"
22197
22198         echo "migrate back to MDT0, checking.."
22199         for file in $(find $migrate_dir); do
22200                 mdt_index=$($LFS getstripe -m $file)
22201                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
22202                         error "$file is not on MDT${MDTIDX}"
22203         done
22204
22205         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
22206         [ "$old_dir_flag" = "$new_dir_flag" ] ||
22207                 error " expect $old_dir_flag get $new_dir_flag"
22208
22209         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
22210         [ "$old_file_flag" = "$new_file_flag" ] ||
22211                 error " expect $old_file_flag get $new_file_flag"
22212
22213         local new_dir_mode=$(stat -c%f $migrate_dir)
22214         [ "$old_dir_mode" = "$new_dir_mode" ] ||
22215                 error "expect mode $old_dir_mode get $new_dir_mode"
22216
22217         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
22218         [ "$old_file_mode" = "$new_file_mode" ] ||
22219                 error "expect mode $old_file_mode get $new_file_mode"
22220
22221         diff /etc/passwd ${migrate_dir}/$tfile ||
22222                 error "$tfile different after migration"
22223
22224         diff /etc/passwd ${other_dir}/luna ||
22225                 error "luna different after migration"
22226
22227         diff /etc/passwd ${migrate_dir}/sofia ||
22228                 error "sofia different after migration"
22229
22230         diff /etc/passwd ${other_dir}/zachary ||
22231                 error "zachary different after migration"
22232
22233         diff /etc/passwd $migrate_dir/${tfile}_ln ||
22234                 error "${tfile}_ln different after migration"
22235
22236         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
22237                 error "${tfile}_ln_other different after migration"
22238
22239         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
22240         [ $stripe_count = 2 ] ||
22241                 error "dir strpe_count $d != 2 after migration."
22242
22243         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
22244         [ $stripe_count = 2 ] ||
22245                 error "file strpe_count $d != 2 after migration."
22246
22247         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22248 }
22249 run_test 230b "migrate directory"
22250
22251 test_230c() {
22252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22253         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22254         remote_mds_nodsh && skip "remote MDS with nodsh"
22255         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22256                 skip "Need MDS version at least 2.11.52"
22257
22258         local MDTIDX=1
22259         local total=3
22260         local mdt_index
22261         local file
22262         local migrate_dir=$DIR/$tdir/migrate_dir
22263
22264         #If migrating directory fails in the middle, all entries of
22265         #the directory is still accessiable.
22266         test_mkdir $DIR/$tdir
22267         test_mkdir -i0 -c1 $migrate_dir
22268         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
22269         stat $migrate_dir
22270         createmany -o $migrate_dir/f $total ||
22271                 error "create files under ${migrate_dir} failed"
22272
22273         # fail after migrating top dir, and this will fail only once, so the
22274         # first sub file migration will fail (currently f3), others succeed.
22275         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
22276         do_facet mds1 lctl set_param fail_loc=0x1801
22277         local t=$(ls $migrate_dir | wc -l)
22278         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
22279                 error "migrate should fail"
22280         local u=$(ls $migrate_dir | wc -l)
22281         [ "$u" == "$t" ] || error "$u != $t during migration"
22282
22283         # add new dir/file should succeed
22284         mkdir $migrate_dir/dir ||
22285                 error "mkdir failed under migrating directory"
22286         touch $migrate_dir/file ||
22287                 error "create file failed under migrating directory"
22288
22289         # add file with existing name should fail
22290         for file in $migrate_dir/f*; do
22291                 stat $file > /dev/null || error "stat $file failed"
22292                 $OPENFILE -f O_CREAT:O_EXCL $file &&
22293                         error "open(O_CREAT|O_EXCL) $file should fail"
22294                 $MULTIOP $file m && error "create $file should fail"
22295                 touch $DIR/$tdir/remote_dir/$tfile ||
22296                         error "touch $tfile failed"
22297                 ln $DIR/$tdir/remote_dir/$tfile $file &&
22298                         error "link $file should fail"
22299                 mdt_index=$($LFS getstripe -m $file)
22300                 if [ $mdt_index == 0 ]; then
22301                         # file failed to migrate is not allowed to rename to
22302                         mv $DIR/$tdir/remote_dir/$tfile $file &&
22303                                 error "rename to $file should fail"
22304                 else
22305                         mv $DIR/$tdir/remote_dir/$tfile $file ||
22306                                 error "rename to $file failed"
22307                 fi
22308                 echo hello >> $file || error "write $file failed"
22309         done
22310
22311         # resume migration with different options should fail
22312         $LFS migrate -m 0 $migrate_dir &&
22313                 error "migrate -m 0 $migrate_dir should fail"
22314
22315         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
22316                 error "migrate -c 2 $migrate_dir should fail"
22317
22318         # resume migration should succeed
22319         $LFS migrate -m $MDTIDX $migrate_dir ||
22320                 error "migrate $migrate_dir failed"
22321
22322         echo "Finish migration, then checking.."
22323         for file in $(find $migrate_dir); do
22324                 mdt_index=$($LFS getstripe -m $file)
22325                 [ $mdt_index == $MDTIDX ] ||
22326                         error "$file is not on MDT${MDTIDX}"
22327         done
22328
22329         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22330 }
22331 run_test 230c "check directory accessiblity if migration failed"
22332
22333 test_230d() {
22334         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22335         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22336         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22337                 skip "Need MDS version at least 2.11.52"
22338         # LU-11235
22339         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
22340
22341         local migrate_dir=$DIR/$tdir/migrate_dir
22342         local old_index
22343         local new_index
22344         local old_count
22345         local new_count
22346         local new_hash
22347         local mdt_index
22348         local i
22349         local j
22350
22351         old_index=$((RANDOM % MDSCOUNT))
22352         old_count=$((MDSCOUNT - old_index))
22353         new_index=$((RANDOM % MDSCOUNT))
22354         new_count=$((MDSCOUNT - new_index))
22355         new_hash=1 # for all_char
22356
22357         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
22358         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
22359
22360         test_mkdir $DIR/$tdir
22361         test_mkdir -i $old_index -c $old_count $migrate_dir
22362
22363         for ((i=0; i<100; i++)); do
22364                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
22365                 createmany -o $migrate_dir/dir_${i}/f 100 ||
22366                         error "create files under remote dir failed $i"
22367         done
22368
22369         echo -n "Migrate from MDT$old_index "
22370         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
22371         echo -n "to MDT$new_index"
22372         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
22373         echo
22374
22375         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
22376         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
22377                 error "migrate remote dir error"
22378
22379         echo "Finish migration, then checking.."
22380         for file in $(find $migrate_dir -maxdepth 1); do
22381                 mdt_index=$($LFS getstripe -m $file)
22382                 if [ $mdt_index -lt $new_index ] ||
22383                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
22384                         error "$file is on MDT$mdt_index"
22385                 fi
22386         done
22387
22388         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22389 }
22390 run_test 230d "check migrate big directory"
22391
22392 test_230e() {
22393         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22394         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22395         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22396                 skip "Need MDS version at least 2.11.52"
22397
22398         local i
22399         local j
22400         local a_fid
22401         local b_fid
22402
22403         mkdir_on_mdt0 $DIR/$tdir
22404         mkdir $DIR/$tdir/migrate_dir
22405         mkdir $DIR/$tdir/other_dir
22406         touch $DIR/$tdir/migrate_dir/a
22407         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
22408         ls $DIR/$tdir/other_dir
22409
22410         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22411                 error "migrate dir fails"
22412
22413         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
22414         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
22415
22416         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22417         [ $mdt_index == 0 ] || error "a is not on MDT0"
22418
22419         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
22420                 error "migrate dir fails"
22421
22422         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
22423         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
22424
22425         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22426         [ $mdt_index == 1 ] || error "a is not on MDT1"
22427
22428         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
22429         [ $mdt_index == 1 ] || error "b is not on MDT1"
22430
22431         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
22432         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
22433
22434         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
22435
22436         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22437 }
22438 run_test 230e "migrate mulitple local link files"
22439
22440 test_230f() {
22441         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22442         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22443         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22444                 skip "Need MDS version at least 2.11.52"
22445
22446         local a_fid
22447         local ln_fid
22448
22449         mkdir -p $DIR/$tdir
22450         mkdir $DIR/$tdir/migrate_dir
22451         $LFS mkdir -i1 $DIR/$tdir/other_dir
22452         touch $DIR/$tdir/migrate_dir/a
22453         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
22454         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
22455         ls $DIR/$tdir/other_dir
22456
22457         # a should be migrated to MDT1, since no other links on MDT0
22458         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22459                 error "#1 migrate dir fails"
22460         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
22461         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
22462         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22463         [ $mdt_index == 1 ] || error "a is not on MDT1"
22464
22465         # a should stay on MDT1, because it is a mulitple link file
22466         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22467                 error "#2 migrate dir fails"
22468         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22469         [ $mdt_index == 1 ] || error "a is not on MDT1"
22470
22471         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22472                 error "#3 migrate dir fails"
22473
22474         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
22475         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
22476         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
22477
22478         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
22479         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
22480
22481         # a should be migrated to MDT0, since no other links on MDT1
22482         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22483                 error "#4 migrate dir fails"
22484         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22485         [ $mdt_index == 0 ] || error "a is not on MDT0"
22486
22487         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22488 }
22489 run_test 230f "migrate mulitple remote link files"
22490
22491 test_230g() {
22492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22493         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22494         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22495                 skip "Need MDS version at least 2.11.52"
22496
22497         mkdir -p $DIR/$tdir/migrate_dir
22498
22499         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
22500                 error "migrating dir to non-exist MDT succeeds"
22501         true
22502 }
22503 run_test 230g "migrate dir to non-exist MDT"
22504
22505 test_230h() {
22506         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22507         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22508         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22509                 skip "Need MDS version at least 2.11.52"
22510
22511         local mdt_index
22512
22513         mkdir -p $DIR/$tdir/migrate_dir
22514
22515         $LFS migrate -m1 $DIR &&
22516                 error "migrating mountpoint1 should fail"
22517
22518         $LFS migrate -m1 $DIR/$tdir/.. &&
22519                 error "migrating mountpoint2 should fail"
22520
22521         # same as mv
22522         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
22523                 error "migrating $tdir/migrate_dir/.. should fail"
22524
22525         true
22526 }
22527 run_test 230h "migrate .. and root"
22528
22529 test_230i() {
22530         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22531         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22532         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22533                 skip "Need MDS version at least 2.11.52"
22534
22535         mkdir -p $DIR/$tdir/migrate_dir
22536
22537         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
22538                 error "migration fails with a tailing slash"
22539
22540         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
22541                 error "migration fails with two tailing slashes"
22542 }
22543 run_test 230i "lfs migrate -m tolerates trailing slashes"
22544
22545 test_230j() {
22546         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22547         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
22548                 skip "Need MDS version at least 2.11.52"
22549
22550         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22551         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
22552                 error "create $tfile failed"
22553         cat /etc/passwd > $DIR/$tdir/$tfile
22554
22555         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22556
22557         cmp /etc/passwd $DIR/$tdir/$tfile ||
22558                 error "DoM file mismatch after migration"
22559 }
22560 run_test 230j "DoM file data not changed after dir migration"
22561
22562 test_230k() {
22563         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
22564         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22565                 skip "Need MDS version at least 2.11.56"
22566
22567         local total=20
22568         local files_on_starting_mdt=0
22569
22570         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
22571         $LFS getdirstripe $DIR/$tdir
22572         for i in $(seq $total); do
22573                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
22574                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22575                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22576         done
22577
22578         echo "$files_on_starting_mdt files on MDT0"
22579
22580         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
22581         $LFS getdirstripe $DIR/$tdir
22582
22583         files_on_starting_mdt=0
22584         for i in $(seq $total); do
22585                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22586                         error "file $tfile.$i mismatch after migration"
22587                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
22588                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22589         done
22590
22591         echo "$files_on_starting_mdt files on MDT1 after migration"
22592         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
22593
22594         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
22595         $LFS getdirstripe $DIR/$tdir
22596
22597         files_on_starting_mdt=0
22598         for i in $(seq $total); do
22599                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22600                         error "file $tfile.$i mismatch after 2nd migration"
22601                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22602                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22603         done
22604
22605         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
22606         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
22607
22608         true
22609 }
22610 run_test 230k "file data not changed after dir migration"
22611
22612 test_230l() {
22613         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22614         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22615                 skip "Need MDS version at least 2.11.56"
22616
22617         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
22618         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
22619                 error "create files under remote dir failed $i"
22620         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22621 }
22622 run_test 230l "readdir between MDTs won't crash"
22623
22624 test_230m() {
22625         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22626         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22627                 skip "Need MDS version at least 2.11.56"
22628
22629         local MDTIDX=1
22630         local mig_dir=$DIR/$tdir/migrate_dir
22631         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
22632         local shortstr="b"
22633         local val
22634
22635         echo "Creating files and dirs with xattrs"
22636         test_mkdir $DIR/$tdir
22637         test_mkdir -i0 -c1 $mig_dir
22638         mkdir $mig_dir/dir
22639         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
22640                 error "cannot set xattr attr1 on dir"
22641         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
22642                 error "cannot set xattr attr2 on dir"
22643         touch $mig_dir/dir/f0
22644         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
22645                 error "cannot set xattr attr1 on file"
22646         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
22647                 error "cannot set xattr attr2 on file"
22648         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22649         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22650         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
22651         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22652         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
22653         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22654         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
22655         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22656         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
22657
22658         echo "Migrating to MDT1"
22659         $LFS migrate -m $MDTIDX $mig_dir ||
22660                 error "fails on migrating dir to MDT1"
22661
22662         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22663         echo "Checking xattrs"
22664         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22665         [ "$val" = $longstr ] ||
22666                 error "expecting xattr1 $longstr on dir, found $val"
22667         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22668         [ "$val" = $shortstr ] ||
22669                 error "expecting xattr2 $shortstr on dir, found $val"
22670         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22671         [ "$val" = $longstr ] ||
22672                 error "expecting xattr1 $longstr on file, found $val"
22673         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22674         [ "$val" = $shortstr ] ||
22675                 error "expecting xattr2 $shortstr on file, found $val"
22676 }
22677 run_test 230m "xattrs not changed after dir migration"
22678
22679 test_230n() {
22680         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22681         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22682                 skip "Need MDS version at least 2.13.53"
22683
22684         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
22685         cat /etc/hosts > $DIR/$tdir/$tfile
22686         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
22687         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
22688
22689         cmp /etc/hosts $DIR/$tdir/$tfile ||
22690                 error "File data mismatch after migration"
22691 }
22692 run_test 230n "Dir migration with mirrored file"
22693
22694 test_230o() {
22695         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
22696         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22697                 skip "Need MDS version at least 2.13.52"
22698
22699         local mdts=$(comma_list $(mdts_nodes))
22700         local timeout=100
22701         local restripe_status
22702         local delta
22703         local i
22704
22705         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22706
22707         # in case "crush" hash type is not set
22708         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22709
22710         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22711                            mdt.*MDT0000.enable_dir_restripe)
22712         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22713         stack_trap "do_nodes $mdts $LCTL set_param \
22714                     mdt.*.enable_dir_restripe=$restripe_status"
22715
22716         mkdir $DIR/$tdir
22717         createmany -m $DIR/$tdir/f 100 ||
22718                 error "create files under remote dir failed $i"
22719         createmany -d $DIR/$tdir/d 100 ||
22720                 error "create dirs under remote dir failed $i"
22721
22722         for i in $(seq 2 $MDSCOUNT); do
22723                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22724                 $LFS setdirstripe -c $i $DIR/$tdir ||
22725                         error "split -c $i $tdir failed"
22726                 wait_update $HOSTNAME \
22727                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
22728                         error "dir split not finished"
22729                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22730                         awk '/migrate/ {sum += $2} END { print sum }')
22731                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
22732                 # delta is around total_files/stripe_count
22733                 (( $delta < 200 / (i - 1) + 4 )) ||
22734                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
22735         done
22736 }
22737 run_test 230o "dir split"
22738
22739 test_230p() {
22740         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22741         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22742                 skip "Need MDS version at least 2.13.52"
22743
22744         local mdts=$(comma_list $(mdts_nodes))
22745         local timeout=100
22746         local restripe_status
22747         local delta
22748         local c
22749
22750         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22751
22752         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22753
22754         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22755                            mdt.*MDT0000.enable_dir_restripe)
22756         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22757         stack_trap "do_nodes $mdts $LCTL set_param \
22758                     mdt.*.enable_dir_restripe=$restripe_status"
22759
22760         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
22761         createmany -m $DIR/$tdir/f 100 ||
22762                 error "create files under remote dir failed"
22763         createmany -d $DIR/$tdir/d 100 ||
22764                 error "create dirs under remote dir failed"
22765
22766         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
22767                 local mdt_hash="crush"
22768
22769                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22770                 $LFS setdirstripe -c $c $DIR/$tdir ||
22771                         error "split -c $c $tdir failed"
22772                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
22773                         mdt_hash="$mdt_hash,fixed"
22774                 elif [ $c -eq 1 ]; then
22775                         mdt_hash="none"
22776                 fi
22777                 wait_update $HOSTNAME \
22778                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
22779                         error "dir merge not finished"
22780                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22781                         awk '/migrate/ {sum += $2} END { print sum }')
22782                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
22783                 # delta is around total_files/stripe_count
22784                 (( delta < 200 / c + 4 )) ||
22785                         error "$delta files migrated >= $((200 / c + 4))"
22786         done
22787 }
22788 run_test 230p "dir merge"
22789
22790 test_230q() {
22791         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
22792         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22793                 skip "Need MDS version at least 2.13.52"
22794
22795         local mdts=$(comma_list $(mdts_nodes))
22796         local saved_threshold=$(do_facet mds1 \
22797                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
22798         local saved_delta=$(do_facet mds1 \
22799                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
22800         local threshold=100
22801         local delta=2
22802         local total=0
22803         local stripe_count=0
22804         local stripe_index
22805         local nr_files
22806         local create
22807
22808         # test with fewer files on ZFS
22809         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
22810
22811         stack_trap "do_nodes $mdts $LCTL set_param \
22812                     mdt.*.dir_split_count=$saved_threshold"
22813         stack_trap "do_nodes $mdts $LCTL set_param \
22814                     mdt.*.dir_split_delta=$saved_delta"
22815         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
22816         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
22817         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
22818         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
22819         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
22820         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22821
22822         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22823         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22824
22825         create=$((threshold * 3 / 2))
22826         while [ $stripe_count -lt $MDSCOUNT ]; do
22827                 createmany -m $DIR/$tdir/f $total $create ||
22828                         error "create sub files failed"
22829                 stat $DIR/$tdir > /dev/null
22830                 total=$((total + create))
22831                 stripe_count=$((stripe_count + delta))
22832                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
22833
22834                 wait_update $HOSTNAME \
22835                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
22836                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
22837
22838                 wait_update $HOSTNAME \
22839                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
22840                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
22841
22842                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
22843                 echo "$nr_files/$total files on MDT$stripe_index after split"
22844                 # allow 10% margin of imbalance with crush hash
22845                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
22846                         error "$nr_files files on MDT$stripe_index after split"
22847
22848                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
22849                 [ $nr_files -eq $total ] ||
22850                         error "total sub files $nr_files != $total"
22851         done
22852
22853         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
22854
22855         echo "fixed layout directory won't auto split"
22856         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
22857         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
22858                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
22859         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
22860                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
22861 }
22862 run_test 230q "dir auto split"
22863
22864 test_230r() {
22865         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
22866         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
22867         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
22868                 skip "Need MDS version at least 2.13.54"
22869
22870         # maximum amount of local locks:
22871         # parent striped dir - 2 locks
22872         # new stripe in parent to migrate to - 1 lock
22873         # source and target - 2 locks
22874         # Total 5 locks for regular file
22875         mkdir -p $DIR/$tdir
22876         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
22877         touch $DIR/$tdir/dir1/eee
22878
22879         # create 4 hardlink for 4 more locks
22880         # Total: 9 locks > RS_MAX_LOCKS (8)
22881         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
22882         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
22883         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
22884         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
22885         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
22886         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
22887         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
22888         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
22889
22890         cancel_lru_locks mdc
22891
22892         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
22893                 error "migrate dir fails"
22894
22895         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22896 }
22897 run_test 230r "migrate with too many local locks"
22898
22899 test_230s() {
22900         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
22901                 skip "Need MDS version at least 2.14.52"
22902
22903         local mdts=$(comma_list $(mdts_nodes))
22904         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
22905                                 mdt.*MDT0000.enable_dir_restripe)
22906
22907         stack_trap "do_nodes $mdts $LCTL set_param \
22908                     mdt.*.enable_dir_restripe=$restripe_status"
22909
22910         local st
22911         for st in 0 1; do
22912                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
22913                 test_mkdir $DIR/$tdir
22914                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
22915                         error "$LFS mkdir should return EEXIST if target exists"
22916                 rmdir $DIR/$tdir
22917         done
22918 }
22919 run_test 230s "lfs mkdir should return -EEXIST if target exists"
22920
22921 test_230t()
22922 {
22923         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
22924         (( $MDS1_VERSION >= $(version_code 2.14.50) )) ||
22925                 skip "Need MDS version at least 2.14.50"
22926
22927         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
22928         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
22929         $LFS project -p 1 -s $DIR/$tdir ||
22930                 error "set $tdir project id failed"
22931         $LFS project -p 2 -s $DIR/$tdir/subdir ||
22932                 error "set subdir project id failed"
22933         local pbefore="$($LFS project -d $DIR/$tdir)"
22934         local sbefore="$($LFS project -d $DIR/$tdir/subdir)"
22935         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
22936
22937         local pafter="$($LFS project -d $DIR/$tdir)"
22938         local safter="$($LFS project -d $DIR/$tdir/subdir)"
22939         [[ "$pbefore" == "$pafter" ]] || error "projid '$pbefore' != '$pafter'"
22940         [[ "$sbefore" == "$safter" ]] || error "projid '$sbefore' != '$safter'"
22941
22942         (( $MDS1_VERSION >= $(version_code 2.15.59.107) )) ||
22943                 { echo "Need MDS >= 2.15.59.107 for projid rename"; return 0; }
22944
22945         # check rename works, even if source parent projid differs (LU-17016)
22946         test_mkdir $DIR/$tdir.2 || error "mkdir $tdir.2 failed"
22947         local fid_before=$($LFS path2fid $DIR/$tdir/subdir)
22948
22949         $LFS project -p 2 -s $DIR/$tdir.2 || error "set $tdir.2 projid failed"
22950         mrename $DIR/$tdir/subdir $DIR/$tdir.2/subdir ||
22951                 error "subdir failed rename for different source parent projid"
22952         local fid_after=$($LFS path2fid $DIR/$tdir.2/subdir)
22953
22954         [[ "$fid_before" == "$fid_after" ]] ||
22955                 error "fid before '$fid_before' != after '$fid_after'"
22956 }
22957 run_test 230t "migrate directory with project ID set"
22958
22959 test_230u()
22960 {
22961         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22962         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22963                 skip "Need MDS version at least 2.14.53"
22964
22965         local count
22966
22967         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22968         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22969         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
22970         for i in $(seq 0 $((MDSCOUNT - 1))); do
22971                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22972                 echo "$count dirs migrated to MDT$i"
22973         done
22974         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22975         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
22976 }
22977 run_test 230u "migrate directory by QOS"
22978
22979 test_230v()
22980 {
22981         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22982         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22983                 skip "Need MDS version at least 2.14.53"
22984
22985         local count
22986
22987         mkdir $DIR/$tdir || error "mkdir $tdir failed"
22988         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22989         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
22990         for i in $(seq 0 $((MDSCOUNT - 1))); do
22991                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22992                 echo "$count subdirs migrated to MDT$i"
22993                 (( i == 3 )) && (( count > 0 )) &&
22994                         error "subdir shouldn't be migrated to MDT3"
22995         done
22996         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22997         (( count == 3 )) || error "dirs migrated to $count MDTs"
22998 }
22999 run_test 230v "subdir migrated to the MDT where its parent is located"
23000
23001 test_230w() {
23002         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23003         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
23004                 skip "Need MDS version at least 2.15.0"
23005
23006         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
23007         createmany -o $DIR/$tdir/f 10 || error "create files failed"
23008         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
23009
23010         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
23011                 error "migrate failed"
23012
23013         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
23014                 error "$tdir stripe count mismatch"
23015
23016         for i in $(seq 0 9); do
23017                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
23018                         error "d$i is striped"
23019         done
23020 }
23021 run_test 230w "non-recursive mode dir migration"
23022
23023 test_230x() {
23024         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23025         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
23026                 skip "Need MDS version at least 2.15.0"
23027
23028         mkdir -p $DIR/$tdir || error "mkdir failed"
23029         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
23030
23031         local mdt_name=$(mdtname_from_index 0)
23032         local low=$(do_facet mds2 $LCTL get_param -n \
23033                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
23034         local high=$(do_facet mds2 $LCTL get_param -n \
23035                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
23036         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
23037         local maxage=$(do_facet mds2 $LCTL get_param -n \
23038                 osp.*$mdt_name-osp-MDT0001.maxage)
23039
23040         stack_trap "do_facet mds2 $LCTL set_param -n \
23041                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
23042                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
23043         stack_trap "do_facet mds2 $LCTL set_param -n \
23044                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
23045
23046         do_facet mds2 $LCTL set_param -n \
23047                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
23048         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
23049         sleep 4
23050         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
23051                 error "migrate $tdir should fail"
23052
23053         do_facet mds2 $LCTL set_param -n \
23054                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
23055         do_facet mds2 $LCTL set_param -n \
23056                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
23057         sleep 4
23058         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
23059                 error "migrate failed"
23060         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
23061                 error "$tdir stripe count mismatch"
23062 }
23063 run_test 230x "dir migration check space"
23064
23065 test_230y() {
23066         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23067         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
23068                 skip "Need MDS version at least 2.15.55.45"
23069
23070         local pid
23071
23072         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
23073         $LFS getdirstripe $DIR/$tdir
23074         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
23075         $LFS migrate -m 1 -c 2 $DIR/$tdir &
23076         pid=$!
23077         sleep 1
23078
23079         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
23080         do_facet mds2 lctl set_param fail_loc=0x1802
23081
23082         wait $pid
23083         do_facet mds2 lctl set_param fail_loc=0
23084         $LFS getdirstripe $DIR/$tdir
23085         unlinkmany -d $DIR/$tdir/d 100 || error "unlinkmany failed"
23086         rmdir $DIR/$tdir || error "rmdir $tdir failed"
23087 }
23088 run_test 230y "unlink dir with bad hash type"
23089
23090 test_230z() {
23091         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23092         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
23093                 skip "Need MDS version at least 2.15.55.45"
23094
23095         local pid
23096
23097         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
23098         $LFS getdirstripe $DIR/$tdir
23099         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
23100         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir &
23101         pid=$!
23102         sleep 1
23103
23104         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
23105         do_facet mds2 lctl set_param fail_loc=0x1802
23106
23107         wait $pid
23108         do_facet mds2 lctl set_param fail_loc=0
23109         $LFS getdirstripe $DIR/$tdir
23110
23111         # resume migration
23112         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir ||
23113                 error "resume migration failed"
23114         $LFS getdirstripe $DIR/$tdir
23115         [ $($LFS getdirstripe -H $DIR/$tdir) == "fnv_1a_64,fixed" ] ||
23116                 error "migration is not finished"
23117 }
23118 run_test 230z "resume dir migration with bad hash type"
23119
23120 test_231a()
23121 {
23122         # For simplicity this test assumes that max_pages_per_rpc
23123         # is the same across all OSCs
23124         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
23125         local bulk_size=$((max_pages * PAGE_SIZE))
23126         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
23127                                        head -n 1)
23128
23129         mkdir -p $DIR/$tdir
23130         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
23131                 error "failed to set stripe with -S ${brw_size}M option"
23132         stack_trap "rm -rf $DIR/$tdir"
23133
23134         # clear the OSC stats
23135         $LCTL set_param osc.*.stats=0 &>/dev/null
23136         stop_writeback
23137
23138         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
23139         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
23140                 oflag=direct &>/dev/null || error "dd failed"
23141
23142         sync; sleep 1; sync # just to be safe
23143         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
23144         if [ x$nrpcs != "x1" ]; then
23145                 $LCTL get_param osc.*.stats
23146                 error "found $nrpcs ost_write RPCs, not 1 as expected"
23147         fi
23148
23149         start_writeback
23150         # Drop the OSC cache, otherwise we will read from it
23151         cancel_lru_locks osc
23152
23153         # clear the OSC stats
23154         $LCTL set_param osc.*.stats=0 &>/dev/null
23155
23156         # Client reads $bulk_size.
23157         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
23158                 iflag=direct &>/dev/null || error "dd failed"
23159
23160         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
23161         if [ x$nrpcs != "x1" ]; then
23162                 $LCTL get_param osc.*.stats
23163                 error "found $nrpcs ost_read RPCs, not 1 as expected"
23164         fi
23165 }
23166 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
23167
23168 test_231b() {
23169         mkdir -p $DIR/$tdir
23170         stack_trap "rm -rf $DIR/$tdir"
23171         local i
23172         for i in {0..1023}; do
23173                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
23174                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
23175                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
23176         done
23177         sync
23178 }
23179 run_test 231b "must not assert on fully utilized OST request buffer"
23180
23181 test_232a() {
23182         mkdir -p $DIR/$tdir
23183         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
23184
23185         #define OBD_FAIL_LDLM_OST_LVB            0x31c
23186         do_facet ost1 $LCTL set_param fail_loc=0x31c
23187
23188         # ignore dd failure
23189         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
23190         stack_trap "rm -f $DIR/$tdir/$tfile"
23191
23192         do_facet ost1 $LCTL set_param fail_loc=0
23193         umount_client $MOUNT || error "umount failed"
23194         mount_client $MOUNT || error "mount failed"
23195         stop ost1 || error "cannot stop ost1"
23196         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23197 }
23198 run_test 232a "failed lock should not block umount"
23199
23200 test_232b() {
23201         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
23202                 skip "Need MDS version at least 2.10.58"
23203
23204         mkdir -p $DIR/$tdir
23205         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
23206         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
23207         stack_trap "rm -f $DIR/$tdir/$tfile"
23208         sync
23209         cancel_lru_locks osc
23210
23211         #define OBD_FAIL_LDLM_OST_LVB            0x31c
23212         do_facet ost1 $LCTL set_param fail_loc=0x31c
23213
23214         # ignore failure
23215         $LFS data_version $DIR/$tdir/$tfile || true
23216
23217         do_facet ost1 $LCTL set_param fail_loc=0
23218         umount_client $MOUNT || error "umount failed"
23219         mount_client $MOUNT || error "mount failed"
23220         stop ost1 || error "cannot stop ost1"
23221         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23222 }
23223 run_test 232b "failed data version lock should not block umount"
23224
23225 test_233a() {
23226         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
23227                 skip "Need MDS version at least 2.3.64"
23228         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
23229
23230         local fid=$($LFS path2fid $MOUNT)
23231
23232         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23233                 error "cannot access $MOUNT using its FID '$fid'"
23234 }
23235 run_test 233a "checking that OBF of the FS root succeeds"
23236
23237 test_233b() {
23238         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
23239                 skip "Need MDS version at least 2.5.90"
23240         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
23241
23242         local fid=$($LFS path2fid $MOUNT/.lustre)
23243
23244         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23245                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
23246
23247         fid=$($LFS path2fid $MOUNT/.lustre/fid)
23248         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23249                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
23250 }
23251 run_test 233b "checking that OBF of the FS .lustre succeeds"
23252
23253 test_234() {
23254         local p="$TMP/sanityN-$TESTNAME.parameters"
23255         save_lustre_params client "llite.*.xattr_cache" > $p
23256         lctl set_param llite.*.xattr_cache 1 ||
23257                 skip_env "xattr cache is not supported"
23258
23259         mkdir -p $DIR/$tdir || error "mkdir failed"
23260         touch $DIR/$tdir/$tfile || error "touch failed"
23261         # OBD_FAIL_LLITE_XATTR_ENOMEM
23262         $LCTL set_param fail_loc=0x1405
23263         getfattr -n user.attr $DIR/$tdir/$tfile &&
23264                 error "getfattr should have failed with ENOMEM"
23265         $LCTL set_param fail_loc=0x0
23266         rm -rf $DIR/$tdir
23267
23268         restore_lustre_params < $p
23269         rm -f $p
23270 }
23271 run_test 234 "xattr cache should not crash on ENOMEM"
23272
23273 test_235() {
23274         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
23275                 skip "Need MDS version at least 2.4.52"
23276
23277         flock_deadlock $DIR/$tfile
23278         local RC=$?
23279         case $RC in
23280                 0)
23281                 ;;
23282                 124) error "process hangs on a deadlock"
23283                 ;;
23284                 *) error "error executing flock_deadlock $DIR/$tfile"
23285                 ;;
23286         esac
23287 }
23288 run_test 235 "LU-1715: flock deadlock detection does not work properly"
23289
23290 #LU-2935
23291 test_236() {
23292         check_swap_layouts_support
23293
23294         local ref1=/etc/passwd
23295         local ref2=/etc/group
23296         local file1=$DIR/$tdir/f1
23297         local file2=$DIR/$tdir/f2
23298
23299         test_mkdir -c1 $DIR/$tdir
23300         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
23301         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
23302         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
23303         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
23304         local fd=$(free_fd)
23305         local cmd="exec $fd<>$file2"
23306         eval $cmd
23307         rm $file2
23308         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
23309                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
23310         cmd="exec $fd>&-"
23311         eval $cmd
23312         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
23313
23314         #cleanup
23315         rm -rf $DIR/$tdir
23316 }
23317 run_test 236 "Layout swap on open unlinked file"
23318
23319 # LU-4659 linkea consistency
23320 test_238() {
23321         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
23322                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
23323                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
23324                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
23325
23326         touch $DIR/$tfile
23327         ln $DIR/$tfile $DIR/$tfile.lnk
23328         touch $DIR/$tfile.new
23329         mv $DIR/$tfile.new $DIR/$tfile
23330         local fid1=$($LFS path2fid $DIR/$tfile)
23331         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
23332         local path1=$($LFS fid2path $FSNAME "$fid1")
23333         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
23334         local path2=$($LFS fid2path $FSNAME "$fid2")
23335         [ $tfile.lnk == $path2 ] ||
23336                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
23337         rm -f $DIR/$tfile*
23338 }
23339 run_test 238 "Verify linkea consistency"
23340
23341 test_239A() { # was test_239
23342         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
23343                 skip "Need MDS version at least 2.5.60"
23344
23345         local list=$(comma_list $(mdts_nodes))
23346
23347         mkdir -p $DIR/$tdir
23348         createmany -o $DIR/$tdir/f- 5000
23349         unlinkmany $DIR/$tdir/f- 5000
23350         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
23351                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
23352         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
23353                         osp.*MDT*.sync_in_flight" | calc_sum)
23354         [ "$changes" -eq 0 ] || error "$changes not synced"
23355 }
23356 run_test 239A "osp_sync test"
23357
23358 test_239a() { #LU-5297
23359         remote_mds_nodsh && skip "remote MDS with nodsh"
23360
23361         touch $DIR/$tfile
23362         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
23363         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
23364         chgrp $RUNAS_GID $DIR/$tfile
23365         wait_delete_completed
23366 }
23367 run_test 239a "process invalid osp sync record correctly"
23368
23369 test_239b() { #LU-5297
23370         remote_mds_nodsh && skip "remote MDS with nodsh"
23371
23372         touch $DIR/$tfile1
23373         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
23374         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
23375         chgrp $RUNAS_GID $DIR/$tfile1
23376         wait_delete_completed
23377         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
23378         touch $DIR/$tfile2
23379         chgrp $RUNAS_GID $DIR/$tfile2
23380         wait_delete_completed
23381 }
23382 run_test 239b "process osp sync record with ENOMEM error correctly"
23383
23384 test_240() {
23385         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23386         remote_mds_nodsh && skip "remote MDS with nodsh"
23387
23388         mkdir -p $DIR/$tdir
23389
23390         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
23391                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
23392         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
23393                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
23394
23395         umount_client $MOUNT || error "umount failed"
23396         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
23397         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
23398         mount_client $MOUNT || error "failed to mount client"
23399
23400         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
23401         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
23402 }
23403 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
23404
23405 test_241_bio() {
23406         local count=$1
23407         local bsize=$2
23408
23409         for LOOP in $(seq $count); do
23410                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
23411                 cancel_lru_locks $OSC || true
23412         done
23413 }
23414
23415 test_241_dio() {
23416         local count=$1
23417         local bsize=$2
23418
23419         for LOOP in $(seq $1); do
23420                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
23421                         2>/dev/null
23422         done
23423 }
23424
23425 test_241a() { # was test_241
23426         local bsize=$PAGE_SIZE
23427
23428         (( bsize < 40960 )) && bsize=40960
23429         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
23430         ls -la $DIR/$tfile
23431         cancel_lru_locks $OSC
23432         test_241_bio 1000 $bsize &
23433         PID=$!
23434         test_241_dio 1000 $bsize
23435         wait $PID
23436 }
23437 run_test 241a "bio vs dio"
23438
23439 test_241b() {
23440         local bsize=$PAGE_SIZE
23441
23442         (( bsize < 40960 )) && bsize=40960
23443         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
23444         ls -la $DIR/$tfile
23445         test_241_dio 1000 $bsize &
23446         PID=$!
23447         test_241_dio 1000 $bsize
23448         wait $PID
23449 }
23450 run_test 241b "dio vs dio"
23451
23452 test_242() {
23453         remote_mds_nodsh && skip "remote MDS with nodsh"
23454
23455         mkdir_on_mdt0 $DIR/$tdir
23456         touch $DIR/$tdir/$tfile
23457
23458         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
23459         do_facet mds1 lctl set_param fail_loc=0x105
23460         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
23461
23462         do_facet mds1 lctl set_param fail_loc=0
23463         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
23464 }
23465 run_test 242 "mdt_readpage failure should not cause directory unreadable"
23466
23467 test_243()
23468 {
23469         test_mkdir $DIR/$tdir
23470         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
23471 }
23472 run_test 243 "various group lock tests"
23473
23474 test_244a()
23475 {
23476         test_mkdir $DIR/$tdir
23477         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
23478         sendfile_grouplock $DIR/$tdir/$tfile || \
23479                 error "sendfile+grouplock failed"
23480         rm -rf $DIR/$tdir
23481 }
23482 run_test 244a "sendfile with group lock tests"
23483
23484 test_244b()
23485 {
23486         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23487
23488         local threads=50
23489         local size=$((1024*1024))
23490
23491         test_mkdir $DIR/$tdir
23492         for i in $(seq 1 $threads); do
23493                 local file=$DIR/$tdir/file_$((i / 10))
23494                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
23495                 local pids[$i]=$!
23496         done
23497         for i in $(seq 1 $threads); do
23498                 wait ${pids[$i]}
23499         done
23500 }
23501 run_test 244b "multi-threaded write with group lock"
23502
23503 test_245a() {
23504         local flagname="multi_mod_rpcs"
23505         local connect_data_name="max_mod_rpcs"
23506         local out
23507
23508         # check if multiple modify RPCs flag is set
23509         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
23510                 grep "connect_flags:")
23511         echo "$out"
23512
23513         echo "$out" | grep -qw $flagname
23514         if [ $? -ne 0 ]; then
23515                 echo "connect flag $flagname is not set"
23516                 return
23517         fi
23518
23519         # check if multiple modify RPCs data is set
23520         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
23521         echo "$out"
23522
23523         echo "$out" | grep -qw $connect_data_name ||
23524                 error "import should have connect data $connect_data_name"
23525 }
23526 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
23527
23528 test_245b() {
23529         local flagname="multi_mod_rpcs"
23530         local connect_data_name="max_mod_rpcs"
23531         local out
23532
23533         remote_mds_nodsh && skip "remote MDS with nodsh"
23534         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
23535
23536         # check if multiple modify RPCs flag is set
23537         out=$(do_facet mds1 \
23538               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
23539               grep "connect_flags:")
23540         echo "$out"
23541
23542         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
23543
23544         # check if multiple modify RPCs data is set
23545         out=$(do_facet mds1 \
23546               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
23547
23548         [[ "$out" =~ $connect_data_name ]] ||
23549                 {
23550                         echo "$out"
23551                         error "missing connect data $connect_data_name"
23552                 }
23553 }
23554 run_test 245b "check osp connection flag/data: multiple modify RPCs"
23555
23556 cleanup_247() {
23557         local submount=$1
23558
23559         trap 0
23560         umount_client $submount
23561         rmdir $submount
23562 }
23563
23564 test_247a() {
23565         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23566                 grep -q subtree ||
23567                 skip_env "Fileset feature is not supported"
23568
23569         local submount=${MOUNT}_$tdir
23570
23571         mkdir $MOUNT/$tdir
23572         mkdir -p $submount || error "mkdir $submount failed"
23573         FILESET="$FILESET/$tdir" mount_client $submount ||
23574                 error "mount $submount failed"
23575         trap "cleanup_247 $submount" EXIT
23576         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
23577         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
23578                 error "read $MOUNT/$tdir/$tfile failed"
23579         cleanup_247 $submount
23580 }
23581 run_test 247a "mount subdir as fileset"
23582
23583 test_247b() {
23584         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23585                 skip_env "Fileset feature is not supported"
23586
23587         local submount=${MOUNT}_$tdir
23588
23589         rm -rf $MOUNT/$tdir
23590         mkdir -p $submount || error "mkdir $submount failed"
23591         SKIP_FILESET=1
23592         FILESET="$FILESET/$tdir" mount_client $submount &&
23593                 error "mount $submount should fail"
23594         rmdir $submount
23595 }
23596 run_test 247b "mount subdir that dose not exist"
23597
23598 test_247c() {
23599         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23600                 skip_env "Fileset feature is not supported"
23601
23602         local submount=${MOUNT}_$tdir
23603
23604         mkdir -p $MOUNT/$tdir/dir1
23605         mkdir -p $submount || error "mkdir $submount failed"
23606         trap "cleanup_247 $submount" EXIT
23607         FILESET="$FILESET/$tdir" mount_client $submount ||
23608                 error "mount $submount failed"
23609         local fid=$($LFS path2fid $MOUNT/)
23610         $LFS fid2path $submount $fid && error "fid2path should fail"
23611         cleanup_247 $submount
23612 }
23613 run_test 247c "running fid2path outside subdirectory root"
23614
23615 test_247d() {
23616         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23617                 skip "Fileset feature is not supported"
23618
23619         local submount=${MOUNT}_$tdir
23620
23621         mkdir -p $MOUNT/$tdir/dir1
23622         mkdir -p $submount || error "mkdir $submount failed"
23623         FILESET="$FILESET/$tdir" mount_client $submount ||
23624                 error "mount $submount failed"
23625         trap "cleanup_247 $submount" EXIT
23626
23627         local td=$submount/dir1
23628         local fid=$($LFS path2fid $td)
23629         [ -z "$fid" ] && error "path2fid unable to get $td FID"
23630
23631         # check that we get the same pathname back
23632         local rootpath
23633         local found
23634         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
23635                 echo "$rootpath $fid"
23636                 found=$($LFS fid2path $rootpath "$fid")
23637                 [ -n "$found" ] || error "fid2path should succeed"
23638                 [ "$found" == "$td" ] || error "fid2path $found != $td"
23639         done
23640         # check wrong root path format
23641         rootpath=$submount"_wrong"
23642         found=$($LFS fid2path $rootpath "$fid")
23643         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
23644
23645         cleanup_247 $submount
23646 }
23647 run_test 247d "running fid2path inside subdirectory root"
23648
23649 # LU-8037
23650 test_247e() {
23651         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23652                 grep -q subtree ||
23653                 skip "Fileset feature is not supported"
23654
23655         local submount=${MOUNT}_$tdir
23656
23657         mkdir $MOUNT/$tdir
23658         mkdir -p $submount || error "mkdir $submount failed"
23659         FILESET="$FILESET/.." mount_client $submount &&
23660                 error "mount $submount should fail"
23661         rmdir $submount
23662 }
23663 run_test 247e "mount .. as fileset"
23664
23665 test_247f() {
23666         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
23667         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
23668                 skip "Need at least version 2.14.50.162"
23669         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23670                 skip "Fileset feature is not supported"
23671
23672         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
23673         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
23674                 error "mkdir remote failed"
23675         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
23676                 error "mkdir remote/subdir failed"
23677         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
23678                 error "mkdir striped failed"
23679         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
23680
23681         local submount=${MOUNT}_$tdir
23682
23683         mkdir -p $submount || error "mkdir $submount failed"
23684         stack_trap "rmdir $submount"
23685
23686         local dir
23687         local fileset=$FILESET
23688         local mdts=$(comma_list $(mdts_nodes))
23689
23690         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
23691         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
23692                 $tdir/striped/subdir $tdir/striped/.; do
23693                 FILESET="$fileset/$dir" mount_client $submount ||
23694                         error "mount $dir failed"
23695                 umount_client $submount
23696         done
23697 }
23698 run_test 247f "mount striped or remote directory as fileset"
23699
23700 test_subdir_mount_lock()
23701 {
23702         local testdir=$1
23703         local submount=${MOUNT}_$(basename $testdir)
23704
23705         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
23706
23707         mkdir -p $submount || error "mkdir $submount failed"
23708         stack_trap "rmdir $submount"
23709
23710         FILESET="$fileset/$testdir" mount_client $submount ||
23711                 error "mount $FILESET failed"
23712         stack_trap "umount $submount"
23713
23714         local mdts=$(comma_list $(mdts_nodes))
23715
23716         local nrpcs
23717
23718         stat $submount > /dev/null || error "stat $submount failed"
23719         cancel_lru_locks $MDC
23720         stat $submount > /dev/null || error "stat $submount failed"
23721         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23722         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
23723         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23724         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
23725                 awk '/getattr/ {sum += $2} END {print sum}')
23726
23727         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
23728 }
23729
23730 test_247g() {
23731         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23732
23733         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
23734                 error "mkdir $tdir failed"
23735         test_subdir_mount_lock $tdir
23736 }
23737 run_test 247g "striped directory submount revalidate ROOT from cache"
23738
23739 test_247h() {
23740         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23741         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
23742                 skip "Need MDS version at least 2.15.51"
23743
23744         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23745         test_subdir_mount_lock $tdir
23746         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
23747         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
23748                 error "mkdir $tdir.1 failed"
23749         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
23750 }
23751 run_test 247h "remote directory submount revalidate ROOT from cache"
23752
23753 test_248a() {
23754         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
23755         [ -z "$fast_read_sav" ] && skip "no fast read support"
23756
23757         # create a large file for fast read verification
23758         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
23759
23760         # make sure the file is created correctly
23761         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
23762                 { rm -f $DIR/$tfile; skip "file creation error"; }
23763
23764         echo "Test 1: verify that fast read is 4 times faster on cache read"
23765
23766         # small read with fast read enabled
23767         $LCTL set_param -n llite.*.fast_read=1
23768         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23769                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23770                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23771         # small read with fast read disabled
23772         $LCTL set_param -n llite.*.fast_read=0
23773         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23774                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23775                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23776
23777         # verify that fast read is 4 times faster for cache read
23778         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
23779                 error_not_in_vm "fast read was not 4 times faster: " \
23780                            "$t_fast vs $t_slow"
23781
23782         echo "Test 2: verify the performance between big and small read"
23783         $LCTL set_param -n llite.*.fast_read=1
23784
23785         # 1k non-cache read
23786         cancel_lru_locks osc
23787         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23788                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23789                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23790
23791         # 1M non-cache read
23792         cancel_lru_locks osc
23793         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23794                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23795                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23796
23797         # verify that big IO is not 4 times faster than small IO
23798         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
23799                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
23800
23801         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
23802         rm -f $DIR/$tfile
23803 }
23804 run_test 248a "fast read verification"
23805
23806 test_248b() {
23807         # Default short_io_bytes=16384, try both smaller and larger sizes.
23808         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
23809         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
23810         echo "bs=53248 count=113 normal buffered write"
23811         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
23812                 error "dd of initial data file failed"
23813         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
23814
23815         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
23816         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
23817                 error "dd with sync normal writes failed"
23818         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
23819
23820         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
23821         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
23822                 error "dd with sync small writes failed"
23823         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
23824
23825         cancel_lru_locks osc
23826
23827         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
23828         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
23829         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
23830         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
23831                 iflag=direct || error "dd with O_DIRECT small read failed"
23832         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
23833         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
23834                 error "compare $TMP/$tfile.1 failed"
23835
23836         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
23837         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
23838
23839         # just to see what the maximum tunable value is, and test parsing
23840         echo "test invalid parameter 2MB"
23841         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
23842                 error "too-large short_io_bytes allowed"
23843         echo "test maximum parameter 512KB"
23844         # if we can set a larger short_io_bytes, run test regardless of version
23845         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
23846                 # older clients may not allow setting it this large, that's OK
23847                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
23848                         skip "Need at least client version 2.13.50"
23849                 error "medium short_io_bytes failed"
23850         fi
23851         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23852         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
23853
23854         echo "test large parameter 64KB"
23855         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
23856         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23857
23858         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
23859         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
23860                 error "dd with sync large writes failed"
23861         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
23862
23863         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
23864         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
23865         num=$((113 * 4096 / PAGE_SIZE))
23866         echo "bs=$size count=$num oflag=direct large write $tfile.3"
23867         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
23868                 error "dd with O_DIRECT large writes failed"
23869         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
23870                 error "compare $DIR/$tfile.3 failed"
23871
23872         cancel_lru_locks osc
23873
23874         echo "bs=$size count=$num iflag=direct large read $tfile.2"
23875         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
23876                 error "dd with O_DIRECT large read failed"
23877         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
23878                 error "compare $TMP/$tfile.2 failed"
23879
23880         echo "bs=$size count=$num iflag=direct large read $tfile.3"
23881         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
23882                 error "dd with O_DIRECT large read failed"
23883         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
23884                 error "compare $TMP/$tfile.3 failed"
23885 }
23886 run_test 248b "test short_io read and write for both small and large sizes"
23887
23888 test_248c() {
23889         $LCTL set_param llite.*.read_ahead_stats=c
23890         # This test compares whole file readahead to non-whole file readahead
23891         # The performance should be consistently slightly faster for whole file,
23892         # and the bug caused whole file readahead to be 80-100x slower, but to
23893         # account for possible test system lag, we require whole file to be
23894         # <= 1.5xnon-whole file, and require 3 failures in a row to fail the
23895         # test
23896         local time1
23897         local time2
23898         local whole_mb=$($LCTL get_param -n llite.*.max_read_ahead_whole_mb)
23899         stack_trap "$LCTL set_param llite.*.max_read_ahead_whole_mb=$whole_mb" EXIT
23900         counter=0
23901
23902         while [ $counter -lt 3 ]; do
23903                 # Increment the counter
23904                 ((counter++))
23905
23906                 $LCTL set_param llite.*.max_read_ahead_whole_mb=64
23907                 rm -f $DIR/$tfile
23908                 touch $DIR/$tfile || error "(0) failed to create file"
23909                 # 64 MiB
23910                 $TRUNCATE $DIR/$tfile 67108864 || error "(1) failed to truncate file"
23911                 time1=$(dd if=$DIR/$tfile bs=4K of=/dev/null 2>&1 | awk '/bytes/ {print $8}')
23912                 echo "whole file readahead of 64 MiB took $time1 seconds"
23913                 $LCTL get_param llite.*.read_ahead_stats
23914
23915                 $LCTL set_param llite.*.read_ahead_stats=c
23916                 $LCTL set_param llite.*.max_read_ahead_whole_mb=8
23917                 rm -f $DIR/$tfile
23918                 touch $DIR/$tfile || error "(2) failed to create file"
23919                 # 64 MiB
23920                 $TRUNCATE $DIR/$tfile 67108864 || error "(3) failed to create file"
23921                 time2=$(dd if=$DIR/$tfile bs=4K of=/dev/null 2>&1 | awk '/bytes/ {print $8}')
23922                 echo "non-whole file readahead of 64 MiB took $time2 seconds"
23923                 $LCTL get_param llite.*.read_ahead_stats
23924
23925                 # Check if time1 is not more than 1.5 times2
23926                 timecheck=$(echo "$time1 <= (1.5 * $time2)" | bc -l)
23927
23928                 if [[ $timecheck -eq 1 ]]; then
23929                         echo "Test passed on attempt $counter"
23930                         # Exit the loop
23931                         counter=4
23932                 else
23933                         echo "Attempt $counter failed: whole file readahead took: $time1, greater than non: $time2"
23934                 fi
23935         done
23936         if [ $counter -eq 3 ]; then
23937                 error "whole file readahead check failed 3 times in a row, probably not just VM lag"
23938         fi
23939
23940 }
23941 run_test 248c "verify whole file read behavior"
23942
23943 test_249() { # LU-7890
23944         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
23945                 skip "Need at least version 2.8.54"
23946
23947         rm -f $DIR/$tfile
23948         $LFS setstripe -c 1 $DIR/$tfile
23949         # Offset 2T == 4k * 512M
23950         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
23951                 error "dd to 2T offset failed"
23952 }
23953 run_test 249 "Write above 2T file size"
23954
23955 test_250() {
23956         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
23957          && skip "no 16TB file size limit on ZFS"
23958
23959         $LFS setstripe -c 1 $DIR/$tfile
23960         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
23961         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
23962         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
23963         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
23964                 conv=notrunc,fsync && error "append succeeded"
23965         return 0
23966 }
23967 run_test 250 "Write above 16T limit"
23968
23969 test_251a() {
23970         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
23971
23972         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
23973         #Skip once - writing the first stripe will succeed
23974         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23975         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
23976                 error "short write happened"
23977
23978         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23979         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
23980                 error "short read happened"
23981
23982         rm -f $DIR/$tfile
23983 }
23984 run_test 251a "Handling short read and write correctly"
23985
23986 test_251b() {
23987         dd if=/dev/zero of=$DIR/$tfile bs=1k count=4 ||
23988                 error "write $tfile failed"
23989
23990         sleep 2 && echo 12345 >> $DIR/$tfile &
23991
23992         #define OBD_FAIL_LLITE_READ_PAUSE 0x1431
23993         $LCTL set_param fail_loc=0x1431 fail_val=5
23994         # seek to 4096, 2 seconds later, file size expand to 4102, and after
23995         # 5 seconds, read 10 bytes, the short read should
23996         # report:
23997         #                start ->+ read_len -> offset_after_read read_count
23998         #     short read: 4096 ->+ 10 -> 4096 0
23999         # not:
24000         #     short read: 4096 ->+ 10 -> 4102 0
24001         local off=$($MULTIOP $DIR/$tfile oO_RDONLY:z4096r10c 2>&1 | \
24002                         awk '/short read/ { print $7 }')
24003         (( off == 4096 )) ||
24004                 error "short read should set offset at 4096, not $off"
24005 }
24006 run_test 251b "short read restore offset correctly"
24007
24008 test_252() {
24009         remote_mds_nodsh && skip "remote MDS with nodsh"
24010         remote_ost_nodsh && skip "remote OST with nodsh"
24011         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
24012                 skip_env "ldiskfs only test"
24013         fi
24014
24015         local tgt
24016         local dev
24017         local out
24018         local uuid
24019         local num
24020         local gen
24021
24022         # check lr_reader on OST0000
24023         tgt=ost1
24024         dev=$(facet_device $tgt)
24025         out=$(do_facet $tgt $LR_READER $dev)
24026         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
24027         echo "$out"
24028         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
24029         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
24030                 error "Invalid uuid returned by $LR_READER on target $tgt"
24031         echo -e "uuid returned by $LR_READER is '$uuid'\n"
24032
24033         # check lr_reader -c on MDT0000
24034         tgt=mds1
24035         dev=$(facet_device $tgt)
24036         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
24037                 skip "$LR_READER does not support additional options"
24038         fi
24039         out=$(do_facet $tgt $LR_READER -c $dev)
24040         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
24041         echo "$out"
24042         num=$(echo "$out" | grep -c "mdtlov")
24043         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
24044                 error "Invalid number of mdtlov clients returned by $LR_READER"
24045         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
24046
24047         # check lr_reader -cr on MDT0000
24048         out=$(do_facet $tgt $LR_READER -cr $dev)
24049         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
24050         echo "$out"
24051         echo "$out" | grep -q "^reply_data:$" ||
24052                 error "$LR_READER should have returned 'reply_data' section"
24053         num=$(echo "$out" | grep -c "client_generation")
24054         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
24055 }
24056 run_test 252 "check lr_reader tool"
24057
24058 test_253() {
24059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24060         remote_mds_nodsh && skip "remote MDS with nodsh"
24061         remote_mgs_nodsh && skip "remote MGS with nodsh"
24062         check_set_fallocate_or_skip
24063
24064         local ostidx=0
24065         local rc=0
24066         local ost_name=$(ostname_from_index $ostidx)
24067
24068         # on the mdt's osc
24069         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
24070         do_facet $SINGLEMDS $LCTL get_param -n \
24071                 osp.$mdtosc_proc1.reserved_mb_high ||
24072                 skip  "remote MDS does not support reserved_mb_high"
24073
24074         rm -rf $DIR/$tdir
24075         wait_mds_ost_sync
24076         wait_delete_completed
24077         mkdir $DIR/$tdir
24078         stack_trap "rm -rf $DIR/$tdir"
24079
24080         pool_add $TESTNAME || error "Pool creation failed"
24081         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
24082
24083         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
24084                 error "Setstripe failed"
24085
24086         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
24087
24088         local wms=$(ost_watermarks_get $ostidx)
24089
24090         ost_watermarks_set $ostidx 60 50
24091         stack_trap "ost_watermarks_set $ostidx $wms"
24092
24093         local free_kb=$($LFS df $MOUNT | awk "/$ost_name/ { print \$4 }")
24094         local size=$((free_kb * 1024))
24095
24096         fallocate -l $size $DIR/$tdir/fill_ost$ostidx ||
24097                 error "fallocate failed"
24098         sleep_maxage
24099
24100         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
24101                         osp.$mdtosc_proc1.prealloc_status)
24102         echo "prealloc_status $oa_status"
24103
24104         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
24105                 error "File creation should fail"
24106
24107         #object allocation was stopped, but we still able to append files
24108         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
24109                 oflag=append || error "Append failed"
24110
24111         rm -f $DIR/$tdir/$tfile.0
24112         rm -f $DIR/$tdir/fill_ost$ostidx
24113
24114         wait_delete_completed
24115         sleep_maxage
24116
24117         for i in $(seq 10 12); do
24118                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
24119                         2>/dev/null || error "File creation failed after rm"
24120         done
24121
24122         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
24123                         osp.$mdtosc_proc1.prealloc_status)
24124         echo "prealloc_status $oa_status"
24125
24126         if (( oa_status != 0 )); then
24127                 error "Object allocation still disable after rm"
24128         fi
24129 }
24130 run_test 253 "Check object allocation limit"
24131
24132 test_254() {
24133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24134         remote_mds_nodsh && skip "remote MDS with nodsh"
24135
24136         local mdt=$(facet_svc $SINGLEMDS)
24137
24138         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
24139                 skip "MDS does not support changelog_size"
24140
24141         local cl_user
24142
24143         changelog_register || error "changelog_register failed"
24144
24145         changelog_clear 0 || error "changelog_clear failed"
24146
24147         local size1=$(do_facet $SINGLEMDS \
24148                       $LCTL get_param -n mdd.$mdt.changelog_size)
24149         echo "Changelog size $size1"
24150
24151         rm -rf $DIR/$tdir
24152         $LFS mkdir -i 0 $DIR/$tdir
24153         # change something
24154         mkdir -p $DIR/$tdir/pics/2008/zachy
24155         touch $DIR/$tdir/pics/2008/zachy/timestamp
24156         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
24157         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
24158         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
24159         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
24160         rm $DIR/$tdir/pics/desktop.jpg
24161
24162         local size2=$(do_facet $SINGLEMDS \
24163                       $LCTL get_param -n mdd.$mdt.changelog_size)
24164         echo "Changelog size after work $size2"
24165
24166         (( $size2 > $size1 )) ||
24167                 error "new Changelog size=$size2 less than old size=$size1"
24168 }
24169 run_test 254 "Check changelog size"
24170
24171 ladvise_no_type()
24172 {
24173         local type=$1
24174         local file=$2
24175
24176         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
24177                 awk -F: '{print $2}' | grep $type > /dev/null
24178         if [ $? -ne 0 ]; then
24179                 return 0
24180         fi
24181         return 1
24182 }
24183
24184 ladvise_no_ioctl()
24185 {
24186         local file=$1
24187
24188         lfs ladvise -a willread $file > /dev/null 2>&1
24189         if [ $? -eq 0 ]; then
24190                 return 1
24191         fi
24192
24193         lfs ladvise -a willread $file 2>&1 |
24194                 grep "Inappropriate ioctl for device" > /dev/null
24195         if [ $? -eq 0 ]; then
24196                 return 0
24197         fi
24198         return 1
24199 }
24200
24201 percent() {
24202         bc <<<"scale=2; ($1 - $2) * 100 / $2"
24203 }
24204
24205 # run a random read IO workload
24206 # usage: random_read_iops <filename> <filesize> <iosize>
24207 random_read_iops() {
24208         local file=$1
24209         local fsize=$2
24210         local iosize=${3:-4096}
24211
24212         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
24213                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
24214 }
24215
24216 drop_file_oss_cache() {
24217         local file="$1"
24218         local nodes="$2"
24219
24220         $LFS ladvise -a dontneed $file 2>/dev/null ||
24221                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
24222 }
24223
24224 ladvise_willread_performance()
24225 {
24226         local repeat=10
24227         local average_origin=0
24228         local average_cache=0
24229         local average_ladvise=0
24230
24231         for ((i = 1; i <= $repeat; i++)); do
24232                 echo "Iter $i/$repeat: reading without willread hint"
24233                 cancel_lru_locks osc
24234                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
24235                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
24236                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
24237                 average_origin=$(bc <<<"$average_origin + $speed_origin")
24238
24239                 cancel_lru_locks osc
24240                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
24241                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
24242                 average_cache=$(bc <<<"$average_cache + $speed_cache")
24243
24244                 cancel_lru_locks osc
24245                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
24246                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
24247                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
24248                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
24249                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
24250         done
24251         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
24252         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
24253         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
24254
24255         speedup_cache=$(percent $average_cache $average_origin)
24256         speedup_ladvise=$(percent $average_ladvise $average_origin)
24257
24258         echo "Average uncached read: $average_origin"
24259         echo "Average speedup with OSS cached read:" \
24260                 "$average_cache = +$speedup_cache%"
24261         echo "Average speedup with ladvise willread:" \
24262                 "$average_ladvise = +$speedup_ladvise%"
24263
24264         local lowest_speedup=20
24265         if (( ${speedup_cache%.*} < $lowest_speedup )); then
24266                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
24267                      "got $speedup_cache%. Skipping ladvise willread check."
24268                 return 0
24269         fi
24270
24271         # the test won't work on ZFS until it supports 'ladvise dontneed', but
24272         # it is still good to run until then to exercise 'ladvise willread'
24273         ! $LFS ladvise -a dontneed $DIR/$tfile &&
24274                 [ "$ost1_FSTYPE" = "zfs" ] &&
24275                 echo "osd-zfs does not support dontneed or drop_caches" &&
24276                 return 0
24277
24278         lowest_speedup=$(bc <<<"scale=2; $speedup_cache / 2")
24279         (( ${speedup_ladvise%.*} > ${lowest_speedup%.*} )) ||
24280                 error_not_in_vm "Speedup with willread is less than " \
24281                         "$lowest_speedup%, got $speedup_ladvise%"
24282 }
24283
24284 test_255a() {
24285         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
24286                 skip "lustre < 2.8.54 does not support ladvise "
24287         remote_ost_nodsh && skip "remote OST with nodsh"
24288
24289         stack_trap "rm -f $DIR/$tfile"
24290         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
24291
24292         ladvise_no_type willread $DIR/$tfile &&
24293                 skip "willread ladvise is not supported"
24294
24295         ladvise_no_ioctl $DIR/$tfile &&
24296                 skip "ladvise ioctl is not supported"
24297
24298         local size_mb=100
24299         local size=$((size_mb * 1048576))
24300         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
24301                 error "dd to $DIR/$tfile failed"
24302
24303         lfs ladvise -a willread $DIR/$tfile ||
24304                 error "Ladvise failed with no range argument"
24305
24306         lfs ladvise -a willread -s 0 $DIR/$tfile ||
24307                 error "Ladvise failed with no -l or -e argument"
24308
24309         lfs ladvise -a willread -e 1 $DIR/$tfile ||
24310                 error "Ladvise failed with only -e argument"
24311
24312         lfs ladvise -a willread -l 1 $DIR/$tfile ||
24313                 error "Ladvise failed with only -l argument"
24314
24315         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
24316                 error "End offset should not be smaller than start offset"
24317
24318         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
24319                 error "End offset should not be equal to start offset"
24320
24321         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
24322                 error "Ladvise failed with overflowing -s argument"
24323
24324         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
24325                 error "Ladvise failed with overflowing -e argument"
24326
24327         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
24328                 error "Ladvise failed with overflowing -l argument"
24329
24330         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
24331                 error "Ladvise succeeded with conflicting -l and -e arguments"
24332
24333         echo "Synchronous ladvise should wait"
24334         local delay=8
24335 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
24336         do_nodes $(comma_list $(osts_nodes)) \
24337                 $LCTL set_param fail_val=$delay fail_loc=0x237
24338         stack_trap "do_nodes $(comma_list $(osts_nodes)) \
24339                 $LCTL set_param fail_loc=0"
24340
24341         local start_ts=$SECONDS
24342         lfs ladvise -a willread $DIR/$tfile ||
24343                 error "Ladvise failed with no range argument"
24344         local end_ts=$SECONDS
24345         local inteval_ts=$((end_ts - start_ts))
24346
24347         if [ $inteval_ts -lt $(($delay - 1)) ]; then
24348                 error "Synchronous advice didn't wait reply"
24349         fi
24350
24351         echo "Asynchronous ladvise shouldn't wait"
24352         local start_ts=$SECONDS
24353         lfs ladvise -a willread -b $DIR/$tfile ||
24354                 error "Ladvise failed with no range argument"
24355         local end_ts=$SECONDS
24356         local inteval_ts=$((end_ts - start_ts))
24357
24358         if [ $inteval_ts -gt $(($delay / 2)) ]; then
24359                 error "Asynchronous advice blocked"
24360         fi
24361
24362         ladvise_willread_performance
24363 }
24364 run_test 255a "check 'lfs ladvise -a willread'"
24365
24366 facet_meminfo() {
24367         local facet=$1
24368         local info=$2
24369
24370         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
24371 }
24372
24373 test_255b() {
24374         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
24375                 skip "lustre < 2.8.54 does not support ladvise "
24376         remote_ost_nodsh && skip "remote OST with nodsh"
24377
24378         stack_trap "rm -f $DIR/$tfile"
24379         lfs setstripe -c 1 -i 0 $DIR/$tfile
24380
24381         ladvise_no_type dontneed $DIR/$tfile &&
24382                 skip "dontneed ladvise is not supported"
24383
24384         ladvise_no_ioctl $DIR/$tfile &&
24385                 skip "ladvise ioctl is not supported"
24386
24387         ! $LFS ladvise -a dontneed $DIR/$tfile &&
24388                 [ "$ost1_FSTYPE" = "zfs" ] &&
24389                 skip "zfs-osd does not support 'ladvise dontneed'"
24390
24391         local size_mb=100
24392         local size=$((size_mb * 1048576))
24393         # In order to prevent disturbance of other processes, only check 3/4
24394         # of the memory usage
24395         local kibibytes=$((size_mb * 1024 * 3 / 4))
24396
24397         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
24398                 error "dd to $DIR/$tfile failed"
24399
24400         #force write to complete before dropping OST cache & checking memory
24401         sync
24402
24403         local total=$(facet_meminfo ost1 MemTotal)
24404         echo "Total memory: $total KiB"
24405
24406         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
24407         local before_read=$(facet_meminfo ost1 Cached)
24408         echo "Cache used before read: $before_read KiB"
24409
24410         lfs ladvise -a willread $DIR/$tfile ||
24411                 error "Ladvise willread failed"
24412         local after_read=$(facet_meminfo ost1 Cached)
24413         echo "Cache used after read: $after_read KiB"
24414
24415         lfs ladvise -a dontneed $DIR/$tfile ||
24416                 error "Ladvise dontneed again failed"
24417         local no_read=$(facet_meminfo ost1 Cached)
24418         echo "Cache used after dontneed ladvise: $no_read KiB"
24419
24420         if [ $total -lt $((before_read + kibibytes)) ]; then
24421                 echo "Memory is too small, abort checking"
24422                 return 0
24423         fi
24424
24425         if [ $((before_read + kibibytes)) -gt $after_read ]; then
24426                 error "Ladvise willread should use more memory" \
24427                         "than $kibibytes KiB"
24428         fi
24429
24430         if [ $((no_read + kibibytes)) -gt $after_read ]; then
24431                 error "Ladvise dontneed should release more memory" \
24432                         "than $kibibytes KiB"
24433         fi
24434 }
24435 run_test 255b "check 'lfs ladvise -a dontneed'"
24436
24437 test_255c() {
24438         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
24439                 skip "lustre < 2.10.50 does not support lockahead"
24440
24441         local ost1_imp=$(get_osc_import_name client ost1)
24442         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24443                          cut -d'.' -f2)
24444         local count
24445         local new_count
24446         local difference
24447         local i
24448         local rc
24449
24450         test_mkdir -p $DIR/$tdir
24451         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24452
24453         #test 10 returns only success/failure
24454         i=10
24455         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24456         rc=$?
24457         if [ $rc -eq 255 ]; then
24458                 error "Ladvise test${i} failed, ${rc}"
24459         fi
24460
24461         #test 11 counts lock enqueue requests, all others count new locks
24462         i=11
24463         count=$(do_facet ost1 \
24464                 $LCTL get_param -n ost.OSS.ost.stats)
24465         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
24466
24467         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24468         rc=$?
24469         if [ $rc -eq 255 ]; then
24470                 error "Ladvise test${i} failed, ${rc}"
24471         fi
24472
24473         new_count=$(do_facet ost1 \
24474                 $LCTL get_param -n ost.OSS.ost.stats)
24475         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
24476                    awk '{ print $2 }')
24477
24478         difference="$((new_count - count))"
24479         if [ $difference -ne $rc ]; then
24480                 error "Ladvise test${i}, bad enqueue count, returned " \
24481                       "${rc}, actual ${difference}"
24482         fi
24483
24484         for i in $(seq 12 21); do
24485                 # If we do not do this, we run the risk of having too many
24486                 # locks and starting lock cancellation while we are checking
24487                 # lock counts.
24488                 cancel_lru_locks osc
24489
24490                 count=$($LCTL get_param -n \
24491                        ldlm.namespaces.$imp_name.lock_unused_count)
24492
24493                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
24494                 rc=$?
24495                 if [ $rc -eq 255 ]; then
24496                         error "Ladvise test ${i} failed, ${rc}"
24497                 fi
24498
24499                 new_count=$($LCTL get_param -n \
24500                        ldlm.namespaces.$imp_name.lock_unused_count)
24501                 difference="$((new_count - count))"
24502
24503                 # Test 15 output is divided by 100 to map down to valid return
24504                 if [ $i -eq 15 ]; then
24505                         rc="$((rc * 100))"
24506                 fi
24507
24508                 if [ $difference -ne $rc ]; then
24509                         error "Ladvise test ${i}, bad lock count, returned " \
24510                               "${rc}, actual ${difference}"
24511                 fi
24512         done
24513
24514         #test 22 returns only success/failure
24515         i=22
24516         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24517         rc=$?
24518         if [ $rc -eq 255 ]; then
24519                 error "Ladvise test${i} failed, ${rc}"
24520         fi
24521 }
24522 run_test 255c "suite of ladvise lockahead tests"
24523
24524 test_256() {
24525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24526         remote_mds_nodsh && skip "remote MDS with nodsh"
24527         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
24528         changelog_users $SINGLEMDS | grep "^cl" &&
24529                 skip "active changelog user"
24530
24531         local cl_user
24532         local cat_sl
24533         local mdt_dev
24534
24535         mdt_dev=$(facet_device $SINGLEMDS)
24536         echo $mdt_dev
24537
24538         changelog_register || error "changelog_register failed"
24539
24540         rm -rf $DIR/$tdir
24541         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
24542
24543         changelog_clear 0 || error "changelog_clear failed"
24544
24545         # change something
24546         touch $DIR/$tdir/{1..10}
24547
24548         # stop the MDT
24549         stop $SINGLEMDS || error "Fail to stop MDT"
24550
24551         # remount the MDT
24552         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
24553                 error "Fail to start MDT"
24554
24555         #after mount new plainllog is used
24556         touch $DIR/$tdir/{11..19}
24557         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
24558         stack_trap "rm -f $tmpfile"
24559         cat_sl=$(do_facet $SINGLEMDS "sync; \
24560                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24561                  llog_reader $tmpfile | grep -c type=1064553b")
24562         do_facet $SINGLEMDS llog_reader $tmpfile
24563
24564         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
24565
24566         changelog_clear 0 || error "changelog_clear failed"
24567
24568         cat_sl=$(do_facet $SINGLEMDS "sync; \
24569                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24570                  llog_reader $tmpfile | grep -c type=1064553b")
24571
24572         if (( cat_sl == 2 )); then
24573                 error "Empty plain llog was not deleted from changelog catalog"
24574         elif (( cat_sl != 1 )); then
24575                 error "Active plain llog shouldn't be deleted from catalog"
24576         fi
24577 }
24578 run_test 256 "Check llog delete for empty and not full state"
24579
24580 test_257() {
24581         remote_mds_nodsh && skip "remote MDS with nodsh"
24582         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
24583                 skip "Need MDS version at least 2.8.55"
24584
24585         test_mkdir $DIR/$tdir
24586
24587         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
24588                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
24589         stat $DIR/$tdir
24590
24591 #define OBD_FAIL_MDS_XATTR_REP                  0x161
24592         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
24593         local facet=mds$((mdtidx + 1))
24594         set_nodes_failloc $(facet_active_host $facet) 0x80000161
24595         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
24596
24597         stop $facet || error "stop MDS failed"
24598         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
24599                 error "start MDS fail"
24600         wait_recovery_complete $facet
24601 }
24602 run_test 257 "xattr locks are not lost"
24603
24604 # Verify we take the i_mutex when security requires it
24605 test_258a() {
24606 #define OBD_FAIL_IMUTEX_SEC 0x141c
24607         $LCTL set_param fail_loc=0x141c
24608         touch $DIR/$tfile
24609         chmod u+s $DIR/$tfile
24610         chmod a+rwx $DIR/$tfile
24611         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24612         RC=$?
24613         if [ $RC -ne 0 ]; then
24614                 error "error, failed to take i_mutex, rc=$?"
24615         fi
24616         rm -f $DIR/$tfile
24617 }
24618 run_test 258a "verify i_mutex security behavior when suid attributes is set"
24619
24620 # Verify we do NOT take the i_mutex in the normal case
24621 test_258b() {
24622 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
24623         $LCTL set_param fail_loc=0x141d
24624         touch $DIR/$tfile
24625         chmod a+rwx $DIR
24626         chmod a+rw $DIR/$tfile
24627         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24628         RC=$?
24629         if [ $RC -ne 0 ]; then
24630                 error "error, took i_mutex unnecessarily, rc=$?"
24631         fi
24632         rm -f $DIR/$tfile
24633
24634 }
24635 run_test 258b "verify i_mutex security behavior"
24636
24637 test_259() {
24638         local file=$DIR/$tfile
24639         local before
24640         local after
24641
24642         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
24643
24644         stack_trap "rm -f $file" EXIT
24645
24646         wait_delete_completed
24647         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24648         echo "before: $before"
24649
24650         $LFS setstripe -i 0 -c 1 $file
24651         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
24652         sync_all_data
24653         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24654         echo "after write: $after"
24655
24656 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
24657         do_facet ost1 $LCTL set_param fail_loc=0x2301
24658         $TRUNCATE $file 0
24659         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24660         echo "after truncate: $after"
24661
24662         stop ost1
24663         do_facet ost1 $LCTL set_param fail_loc=0
24664         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
24665         sleep 2
24666         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24667         echo "after restart: $after"
24668         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
24669                 error "missing truncate?"
24670
24671         return 0
24672 }
24673 run_test 259 "crash at delayed truncate"
24674
24675 test_260() {
24676 #define OBD_FAIL_MDC_CLOSE               0x806
24677         $LCTL set_param fail_loc=0x80000806
24678         touch $DIR/$tfile
24679
24680 }
24681 run_test 260 "Check mdc_close fail"
24682
24683 ### Data-on-MDT sanity tests ###
24684 test_270a() {
24685         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24686                 skip "Need MDS version at least 2.10.55 for DoM"
24687
24688         # create DoM file
24689         local dom=$DIR/$tdir/dom_file
24690         local tmp=$DIR/$tdir/tmp_file
24691
24692         mkdir_on_mdt0 $DIR/$tdir
24693
24694         # basic checks for DoM component creation
24695         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
24696                 error "Can set MDT layout to non-first entry"
24697
24698         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
24699                 error "Can define multiple entries as MDT layout"
24700
24701         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
24702
24703         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
24704         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
24705         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
24706
24707         local mdtidx=$($LFS getstripe -m $dom)
24708         local mdtname=MDT$(printf %04x $mdtidx)
24709         local facet=mds$((mdtidx + 1))
24710         local space_check=1
24711
24712         # Skip free space checks with ZFS
24713         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
24714
24715         # write
24716         sync
24717         local size_tmp=$((65536 * 3))
24718         local mdtfree1=$(do_facet $facet \
24719                          lctl get_param -n osd*.*$mdtname.kbytesfree)
24720
24721         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24722         # check also direct IO along write
24723         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
24724         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24725         sync
24726         cmp $tmp $dom || error "file data is different"
24727         [ $(stat -c%s $dom) == $size_tmp ] ||
24728                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24729         if [ $space_check == 1 ]; then
24730                 local mdtfree2=$(do_facet $facet \
24731                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
24732
24733                 # increase in usage from by $size_tmp
24734                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24735                         error "MDT free space wrong after write: " \
24736                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24737         fi
24738
24739         # truncate
24740         local size_dom=10000
24741
24742         $TRUNCATE $dom $size_dom
24743         [ $(stat -c%s $dom) == $size_dom ] ||
24744                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
24745         if [ $space_check == 1 ]; then
24746                 mdtfree1=$(do_facet $facet \
24747                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24748                 # decrease in usage from $size_tmp to new $size_dom
24749                 [ $(($mdtfree1 - $mdtfree2)) -ge \
24750                   $(((size_tmp - size_dom) / 1024)) ] ||
24751                         error "MDT free space is wrong after truncate: " \
24752                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
24753         fi
24754
24755         # append
24756         cat $tmp >> $dom
24757         sync
24758         size_dom=$((size_dom + size_tmp))
24759         [ $(stat -c%s $dom) == $size_dom ] ||
24760                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
24761         if [ $space_check == 1 ]; then
24762                 mdtfree2=$(do_facet $facet \
24763                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24764                 # increase in usage by $size_tmp from previous
24765                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24766                         error "MDT free space is wrong after append: " \
24767                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24768         fi
24769
24770         # delete
24771         rm $dom
24772         if [ $space_check == 1 ]; then
24773                 mdtfree1=$(do_facet $facet \
24774                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24775                 # decrease in usage by $size_dom from previous
24776                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
24777                         error "MDT free space is wrong after removal: " \
24778                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
24779         fi
24780
24781         # combined striping
24782         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
24783                 error "Can't create DoM + OST striping"
24784
24785         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
24786         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24787         # check also direct IO along write
24788         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24789         sync
24790         cmp $tmp $dom || error "file data is different"
24791         [ $(stat -c%s $dom) == $size_tmp ] ||
24792                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24793         rm $dom $tmp
24794
24795         return 0
24796 }
24797 run_test 270a "DoM: basic functionality tests"
24798
24799 test_270b() {
24800         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24801                 skip "Need MDS version at least 2.10.55"
24802
24803         local dom=$DIR/$tdir/dom_file
24804         local max_size=1048576
24805
24806         mkdir -p $DIR/$tdir
24807         $LFS setstripe -E $max_size -L mdt $dom
24808
24809         # truncate over the limit
24810         $TRUNCATE $dom $(($max_size + 1)) &&
24811                 error "successful truncate over the maximum size"
24812         # write over the limit
24813         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
24814                 error "successful write over the maximum size"
24815         # append over the limit
24816         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
24817         echo "12345" >> $dom && error "successful append over the maximum size"
24818         rm $dom
24819
24820         return 0
24821 }
24822 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
24823
24824 test_270c() {
24825         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24826                 skip "Need MDS version at least 2.10.55"
24827
24828         mkdir -p $DIR/$tdir
24829         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24830
24831         # check files inherit DoM EA
24832         touch $DIR/$tdir/first
24833         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
24834                 error "bad pattern"
24835         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
24836                 error "bad stripe count"
24837         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
24838                 error "bad stripe size"
24839
24840         # check directory inherits DoM EA and uses it as default
24841         mkdir $DIR/$tdir/subdir
24842         touch $DIR/$tdir/subdir/second
24843         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
24844                 error "bad pattern in sub-directory"
24845         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
24846                 error "bad stripe count in sub-directory"
24847         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
24848                 error "bad stripe size in sub-directory"
24849         return 0
24850 }
24851 run_test 270c "DoM: DoM EA inheritance tests"
24852
24853 test_270d() {
24854         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24855                 skip "Need MDS version at least 2.10.55"
24856
24857         mkdir -p $DIR/$tdir
24858         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24859
24860         # inherit default DoM striping
24861         mkdir $DIR/$tdir/subdir
24862         touch $DIR/$tdir/subdir/f1
24863
24864         # change default directory striping
24865         $LFS setstripe -c 1 $DIR/$tdir/subdir
24866         touch $DIR/$tdir/subdir/f2
24867         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
24868                 error "wrong default striping in file 2"
24869         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
24870                 error "bad pattern in file 2"
24871         return 0
24872 }
24873 run_test 270d "DoM: change striping from DoM to RAID0"
24874
24875 test_270e() {
24876         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24877                 skip "Need MDS version at least 2.10.55"
24878
24879         mkdir -p $DIR/$tdir/dom
24880         mkdir -p $DIR/$tdir/norm
24881         DOMFILES=20
24882         NORMFILES=10
24883         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
24884         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
24885
24886         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
24887         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
24888
24889         # find DoM files by layout
24890         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
24891         [ $NUM -eq  $DOMFILES ] ||
24892                 error "lfs find -L: found $NUM, expected $DOMFILES"
24893         echo "Test 1: lfs find 20 DOM files by layout: OK"
24894
24895         # there should be 1 dir with default DOM striping
24896         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
24897         [ $NUM -eq  1 ] ||
24898                 error "lfs find -L: found $NUM, expected 1 dir"
24899         echo "Test 2: lfs find 1 DOM dir by layout: OK"
24900
24901         # find DoM files by stripe size
24902         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
24903         [ $NUM -eq  $DOMFILES ] ||
24904                 error "lfs find -S: found $NUM, expected $DOMFILES"
24905         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
24906
24907         # find files by stripe offset except DoM files
24908         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
24909         [ $NUM -eq  $NORMFILES ] ||
24910                 error "lfs find -i: found $NUM, expected $NORMFILES"
24911         echo "Test 5: lfs find no DOM files by stripe index: OK"
24912         return 0
24913 }
24914 run_test 270e "DoM: lfs find with DoM files test"
24915
24916 test_270f() {
24917         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24918                 skip "Need MDS version at least 2.10.55"
24919
24920         local mdtname=${FSNAME}-MDT0000-mdtlov
24921         local dom=$DIR/$tdir/dom_file
24922         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
24923                                                 lod.$mdtname.dom_stripesize)
24924         local dom_limit=131072
24925
24926         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
24927         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24928                                                 lod.$mdtname.dom_stripesize)
24929         [ ${dom_limit} -eq ${dom_current} ] ||
24930                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
24931
24932         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24933         $LFS setstripe -d $DIR/$tdir
24934         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
24935                 error "Can't set directory default striping"
24936
24937         # exceed maximum stripe size
24938         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24939                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
24940         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
24941                 error "Able to create DoM component size more than LOD limit"
24942
24943         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24944         dom_current=$(do_facet mds1 $LCTL get_param -n \
24945                                                 lod.$mdtname.dom_stripesize)
24946         [ 0 -eq ${dom_current} ] ||
24947                 error "Can't set zero DoM stripe limit"
24948         rm $dom
24949
24950         # attempt to create DoM file on server with disabled DoM should
24951         # remove DoM entry from layout and be succeed
24952         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
24953                 error "Can't create DoM file (DoM is disabled)"
24954         [ $($LFS getstripe -L $dom) == "mdt" ] &&
24955                 error "File has DoM component while DoM is disabled"
24956         rm $dom
24957
24958         # attempt to create DoM file with only DoM stripe should return error
24959         $LFS setstripe -E $dom_limit -L mdt $dom &&
24960                 error "Able to create DoM-only file while DoM is disabled"
24961
24962         # too low values to be aligned with smallest stripe size 64K
24963         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
24964         dom_current=$(do_facet mds1 $LCTL get_param -n \
24965                                                 lod.$mdtname.dom_stripesize)
24966         [ 30000 -eq ${dom_current} ] &&
24967                 error "Can set too small DoM stripe limit"
24968
24969         # 64K is a minimal stripe size in Lustre, expect limit of that size
24970         [ 65536 -eq ${dom_current} ] ||
24971                 error "Limit is not set to 64K but ${dom_current}"
24972
24973         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
24974         dom_current=$(do_facet mds1 $LCTL get_param -n \
24975                                                 lod.$mdtname.dom_stripesize)
24976         echo $dom_current
24977         [ 2147483648 -eq ${dom_current} ] &&
24978                 error "Can set too large DoM stripe limit"
24979
24980         do_facet mds1 $LCTL set_param -n \
24981                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
24982         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24983                 error "Can't create DoM component size after limit change"
24984         do_facet mds1 $LCTL set_param -n \
24985                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
24986         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
24987                 error "Can't create DoM file after limit decrease"
24988         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
24989                 error "Can create big DoM component after limit decrease"
24990         touch ${dom}_def ||
24991                 error "Can't create file with old default layout"
24992
24993         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
24994         return 0
24995 }
24996 run_test 270f "DoM: maximum DoM stripe size checks"
24997
24998 test_270g() {
24999         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
25000                 skip "Need MDS version at least 2.13.52"
25001         local dom=$DIR/$tdir/$tfile
25002
25003         $LFS mkdir -i 0 -c 1 $DIR/$tdir
25004         local lodname=${FSNAME}-MDT0000-mdtlov
25005
25006         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25007         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
25008         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
25009         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25010
25011         local dom_limit=1024
25012         local dom_threshold="50%"
25013
25014         $LFS setstripe -d $DIR/$tdir
25015         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
25016                 error "Can't set directory default striping"
25017
25018         do_facet mds1 $LCTL set_param -n \
25019                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
25020         # set 0 threshold and create DOM file to change tunable stripesize
25021         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
25022         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
25023                 error "Failed to create $dom file"
25024         # now tunable dom_cur_stripesize should reach maximum
25025         local dom_current=$(do_facet mds1 $LCTL get_param -n \
25026                                         lod.${lodname}.dom_stripesize_cur_kb)
25027         [[ $dom_current == $dom_limit ]] ||
25028                 error "Current DOM stripesize is not maximum"
25029         rm $dom
25030
25031         # set threshold for further tests
25032         do_facet mds1 $LCTL set_param -n \
25033                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
25034         echo "DOM threshold is $dom_threshold free space"
25035         local dom_def
25036         local dom_set
25037         # Spoof bfree to exceed threshold
25038         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
25039         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
25040         for spfree in 40 20 0 15 30 55; do
25041                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
25042                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
25043                         error "Failed to create $dom file"
25044                 dom_def=$(do_facet mds1 $LCTL get_param -n \
25045                                         lod.${lodname}.dom_stripesize_cur_kb)
25046                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
25047                 [[ $dom_def != $dom_current ]] ||
25048                         error "Default stripe size was not changed"
25049                 if (( spfree > 0 )) ; then
25050                         dom_set=$($LFS getstripe -S $dom)
25051                         (( dom_set == dom_def * 1024 )) ||
25052                                 error "DOM component size is still old"
25053                 else
25054                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
25055                                 error "DoM component is set with no free space"
25056                 fi
25057                 rm $dom
25058                 dom_current=$dom_def
25059         done
25060 }
25061 run_test 270g "DoM: default DoM stripe size depends on free space"
25062
25063 test_270h() {
25064         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
25065                 skip "Need MDS version at least 2.13.53"
25066
25067         local mdtname=${FSNAME}-MDT0000-mdtlov
25068         local dom=$DIR/$tdir/$tfile
25069         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25070
25071         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
25072         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25073
25074         $LFS mkdir -i 0 -c 1 $DIR/$tdir
25075         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
25076                 error "can't create OST file"
25077         # mirrored file with DOM entry in the second mirror
25078         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
25079                 error "can't create mirror with DoM component"
25080
25081         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
25082
25083         # DOM component in the middle and has other enries in the same mirror,
25084         # should succeed but lost DoM component
25085         $LFS setstripe --copy=${dom}_1 $dom ||
25086                 error "Can't create file from OST|DOM mirror layout"
25087         # check new file has no DoM layout after all
25088         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
25089                 error "File has DoM component while DoM is disabled"
25090 }
25091 run_test 270h "DoM: DoM stripe removal when disabled on server"
25092
25093 test_270i() {
25094         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
25095                 skip "Need MDS version at least 2.14.54"
25096
25097         mkdir $DIR/$tdir
25098         # DoM with plain layout
25099         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
25100                 error "default plain layout with DoM must fail"
25101         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
25102                 error "setstripe plain file layout with DoM must fail"
25103         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
25104                 error "default DoM layout with bad striping must fail"
25105         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
25106                 error "setstripe to DoM layout with bad striping must fail"
25107         return 0
25108 }
25109 run_test 270i "DoM: setting invalid DoM striping should fail"
25110
25111 test_270j() {
25112         (( $MDS1_VERSION >= $(version_code 2.15.55.203) )) ||
25113                 skip "Need MDS version at least 2.15.55.203"
25114
25115         local dom=$DIR/$tdir/$tfile
25116         local odv
25117         local ndv
25118
25119         mkdir -p $DIR/$tdir
25120
25121         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25122
25123         odv=$($LFS data_version $dom)
25124         chmod 666 $dom
25125         mv $dom ${dom}_moved
25126         link ${dom}_moved $dom
25127         setfattr -n user.attrx -v "some_attr" $dom
25128         ndv=$($LFS data_version $dom)
25129         (( $ndv == $odv )) ||
25130                 error "data version was changed by metadata operations"
25131
25132         dd if=/dev/urandom of=$dom bs=1M count=1 ||
25133                 error "failed to write data into $dom"
25134         cancel_lru_locks mdc
25135         ndv=$($LFS data_version $dom)
25136         (( $ndv != $odv )) ||
25137                 error "data version wasn't changed on write"
25138
25139         odv=$ndv
25140         $TRUNCATE $dom 1000 || error "failed to truncate $dom"
25141         ndv=$($LFS data_version $dom)
25142         (( $ndv != $odv )) ||
25143                 error "data version wasn't changed on truncate down"
25144
25145         odv=$ndv
25146         $TRUNCATE $dom 25000
25147         ndv=$($LFS data_version $dom)
25148         (( $ndv != $odv )) ||
25149                 error "data version wasn't changed on truncate up"
25150
25151         # check also fallocate for ldiskfs
25152         if [[ "$mds1_FSTYPE" == ldiskfs ]]; then
25153                 odv=$ndv
25154                 fallocate -l 1048576 $dom
25155                 ndv=$($LFS data_version $dom)
25156                 (( $ndv != $odv )) ||
25157                         error "data version wasn't changed on fallocate"
25158
25159                 odv=$ndv
25160                 fallocate -p --offset 4096 -l 4096 $dom
25161                 ndv=$($LFS data_version $dom)
25162                 (( $ndv != $odv )) ||
25163                         error "data version wasn't changed on fallocate punch"
25164         fi
25165 }
25166 run_test 270j "DoM migration: DOM file to the OST-striped file (plain)"
25167
25168 test_271a() {
25169         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25170                 skip "Need MDS version at least 2.10.55"
25171
25172         local dom=$DIR/$tdir/dom
25173
25174         mkdir -p $DIR/$tdir
25175
25176         $LFS setstripe -E 1024K -L mdt $dom
25177
25178         lctl set_param -n mdc.*.stats=clear
25179         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
25180         cat $dom > /dev/null
25181         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
25182         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
25183         ls $dom
25184         rm -f $dom
25185 }
25186 run_test 271a "DoM: data is cached for read after write"
25187
25188 test_271b() {
25189         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25190                 skip "Need MDS version at least 2.10.55"
25191
25192         local dom=$DIR/$tdir/dom
25193
25194         mkdir -p $DIR/$tdir
25195
25196         $LFS setstripe -E 1024K -L mdt -E EOF $dom
25197
25198         lctl set_param -n mdc.*.stats=clear
25199         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
25200         cancel_lru_locks mdc
25201         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
25202         # second stat to check size is cached on client
25203         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
25204         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
25205         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
25206         rm -f $dom
25207 }
25208 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
25209
25210 test_271ba() {
25211         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25212                 skip "Need MDS version at least 2.10.55"
25213
25214         local dom=$DIR/$tdir/dom
25215
25216         mkdir -p $DIR/$tdir
25217
25218         $LFS setstripe -E 1024K -L mdt -E EOF $dom
25219
25220         lctl set_param -n mdc.*.stats=clear
25221         lctl set_param -n osc.*.stats=clear
25222         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
25223         cancel_lru_locks mdc
25224         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
25225         # second stat to check size is cached on client
25226         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
25227         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
25228         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
25229         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
25230         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
25231         rm -f $dom
25232 }
25233 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
25234
25235
25236 get_mdc_stats() {
25237         local mdtidx=$1
25238         local param=$2
25239         local mdt=MDT$(printf %04x $mdtidx)
25240
25241         if [ -z $param ]; then
25242                 lctl get_param -n mdc.*$mdt*.stats
25243         else
25244                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
25245         fi
25246 }
25247
25248 test_271c() {
25249         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25250                 skip "Need MDS version at least 2.10.55"
25251
25252         local dom=$DIR/$tdir/dom
25253
25254         mkdir -p $DIR/$tdir
25255
25256         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25257
25258         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
25259         local facet=mds$((mdtidx + 1))
25260
25261         cancel_lru_locks mdc
25262         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
25263         createmany -o $dom 1000
25264         lctl set_param -n mdc.*.stats=clear
25265         smalliomany -w $dom 1000 200
25266         get_mdc_stats $mdtidx
25267         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
25268         # Each file has 1 open, 1 IO enqueues, total 2000
25269         # but now we have also +1 getxattr for security.capability, total 3000
25270         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
25271         unlinkmany $dom 1000
25272
25273         cancel_lru_locks mdc
25274         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
25275         createmany -o $dom 1000
25276         lctl set_param -n mdc.*.stats=clear
25277         smalliomany -w $dom 1000 200
25278         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
25279         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
25280         # for OPEN and IO lock.
25281         [ $((enq - enq_2)) -ge 1000 ] ||
25282                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
25283         unlinkmany $dom 1000
25284         return 0
25285 }
25286 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
25287
25288 cleanup_271def_tests() {
25289         trap 0
25290         rm -f $1
25291 }
25292
25293 test_271d() {
25294         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
25295                 skip "Need MDS version at least 2.10.57"
25296
25297         local dom=$DIR/$tdir/dom
25298         local tmp=$TMP/$tfile
25299         trap "cleanup_271def_tests $tmp" EXIT
25300
25301         mkdir -p $DIR/$tdir
25302
25303         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25304
25305         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
25306
25307         cancel_lru_locks mdc
25308         dd if=/dev/urandom of=$tmp bs=1000 count=1
25309         dd if=$tmp of=$dom bs=1000 count=1
25310         cancel_lru_locks mdc
25311
25312         cat /etc/hosts >> $tmp
25313         lctl set_param -n mdc.*.stats=clear
25314
25315         # append data to the same file it should update local page
25316         echo "Append to the same page"
25317         cat /etc/hosts >> $dom
25318         local num=$(get_mdc_stats $mdtidx ost_read)
25319         local ra=$(get_mdc_stats $mdtidx req_active)
25320         local rw=$(get_mdc_stats $mdtidx req_waittime)
25321
25322         [ -z $num ] || error "$num READ RPC occured"
25323         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25324         echo "... DONE"
25325
25326         # compare content
25327         cmp $tmp $dom || error "file miscompare"
25328
25329         cancel_lru_locks mdc
25330         lctl set_param -n mdc.*.stats=clear
25331
25332         echo "Open and read file"
25333         cat $dom > /dev/null
25334         local num=$(get_mdc_stats $mdtidx ost_read)
25335         local ra=$(get_mdc_stats $mdtidx req_active)
25336         local rw=$(get_mdc_stats $mdtidx req_waittime)
25337
25338         [ -z $num ] || error "$num READ RPC occured"
25339         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25340         echo "... DONE"
25341
25342         # compare content
25343         cmp $tmp $dom || error "file miscompare"
25344
25345         return 0
25346 }
25347 run_test 271d "DoM: read on open (1K file in reply buffer)"
25348
25349 test_271f() {
25350         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
25351                 skip "Need MDS version at least 2.10.57"
25352
25353         local dom=$DIR/$tdir/dom
25354         local tmp=$TMP/$tfile
25355         trap "cleanup_271def_tests $tmp" EXIT
25356
25357         mkdir -p $DIR/$tdir
25358
25359         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25360
25361         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
25362
25363         cancel_lru_locks mdc
25364         dd if=/dev/urandom of=$tmp bs=265000 count=1
25365         dd if=$tmp of=$dom bs=265000 count=1
25366         cancel_lru_locks mdc
25367         cat /etc/hosts >> $tmp
25368         lctl set_param -n mdc.*.stats=clear
25369
25370         echo "Append to the same page"
25371         cat /etc/hosts >> $dom
25372         local num=$(get_mdc_stats $mdtidx ost_read)
25373         local ra=$(get_mdc_stats $mdtidx req_active)
25374         local rw=$(get_mdc_stats $mdtidx req_waittime)
25375
25376         [ -z $num ] || error "$num READ RPC occured"
25377         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25378         echo "... DONE"
25379
25380         # compare content
25381         cmp $tmp $dom || error "file miscompare"
25382
25383         cancel_lru_locks mdc
25384         lctl set_param -n mdc.*.stats=clear
25385
25386         echo "Open and read file"
25387         cat $dom > /dev/null
25388         local num=$(get_mdc_stats $mdtidx ost_read)
25389         local ra=$(get_mdc_stats $mdtidx req_active)
25390         local rw=$(get_mdc_stats $mdtidx req_waittime)
25391
25392         [ -z $num ] && num=0
25393         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
25394         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25395         echo "... DONE"
25396
25397         # compare content
25398         cmp $tmp $dom || error "file miscompare"
25399
25400         return 0
25401 }
25402 run_test 271f "DoM: read on open (200K file and read tail)"
25403
25404 test_271g() {
25405         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
25406                 skip "Skipping due to old client or server version"
25407
25408         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
25409         # to get layout
25410         $CHECKSTAT -t file $DIR1/$tfile
25411
25412         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
25413         MULTIOP_PID=$!
25414         sleep 1
25415         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
25416         $LCTL set_param fail_loc=0x80000314
25417         rm $DIR1/$tfile || error "Unlink fails"
25418         RC=$?
25419         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
25420         [ $RC -eq 0 ] || error "Failed write to stale object"
25421 }
25422 run_test 271g "Discard DoM data vs client flush race"
25423
25424 test_272a() {
25425         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25426                 skip "Need MDS version at least 2.11.50"
25427
25428         local dom=$DIR/$tdir/dom
25429         mkdir -p $DIR/$tdir
25430
25431         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
25432         dd if=/dev/urandom of=$dom bs=512K count=1 ||
25433                 error "failed to write data into $dom"
25434         local old_md5=$(md5sum $dom)
25435
25436         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
25437                 error "failed to migrate to the same DoM component"
25438
25439         local new_md5=$(md5sum $dom)
25440
25441         [ "$old_md5" == "$new_md5" ] ||
25442                 error "md5sum differ: $old_md5, $new_md5"
25443
25444         [ $($LFS getstripe -c $dom) -eq 2 ] ||
25445                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
25446 }
25447 run_test 272a "DoM migration: new layout with the same DOM component"
25448
25449 test_272b() {
25450         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25451                 skip "Need MDS version at least 2.11.50"
25452
25453         local dom=$DIR/$tdir/dom
25454         mkdir -p $DIR/$tdir
25455         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25456         stack_trap "rm -rf $DIR/$tdir"
25457
25458         local mdtidx=$($LFS getstripe -m $dom)
25459         local mdtname=MDT$(printf %04x $mdtidx)
25460         local facet=mds$((mdtidx + 1))
25461
25462         local mdtfree1=$(do_facet $facet \
25463                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25464         dd if=/dev/urandom of=$dom bs=2M count=1 ||
25465                 error "failed to write data into $dom"
25466         local old_md5=$(md5sum $dom)
25467         cancel_lru_locks mdc
25468         local mdtfree1=$(do_facet $facet \
25469                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25470
25471         $LFS migrate -c2 $dom ||
25472                 error "failed to migrate to the new composite layout"
25473         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
25474                 error "MDT stripe was not removed"
25475         ! getfattr -n trusted.dataver $dom &> /dev/null ||
25476                 error "$dir1 shouldn't have DATAVER EA"
25477
25478         cancel_lru_locks mdc
25479         local new_md5=$(md5sum $dom)
25480         [ "$old_md5" == "$new_md5" ] ||
25481                 error "$old_md5 != $new_md5"
25482
25483         # Skip free space checks with ZFS
25484         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25485                 local mdtfree2=$(do_facet $facet \
25486                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25487                 [ $mdtfree2 -gt $mdtfree1 ] ||
25488                         error "MDT space is not freed after migration"
25489         fi
25490         return 0
25491 }
25492 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
25493
25494 test_272c() {
25495         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25496                 skip "Need MDS version at least 2.11.50"
25497
25498         local dom=$DIR/$tdir/$tfile
25499         mkdir -p $DIR/$tdir
25500         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25501         stack_trap "rm -rf $DIR/$tdir"
25502
25503         local mdtidx=$($LFS getstripe -m $dom)
25504         local mdtname=MDT$(printf %04x $mdtidx)
25505         local facet=mds$((mdtidx + 1))
25506
25507         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25508                 error "failed to write data into $dom"
25509         local old_md5=$(md5sum $dom)
25510         cancel_lru_locks mdc
25511         local mdtfree1=$(do_facet $facet \
25512                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25513
25514         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
25515                 error "failed to migrate to the new composite layout"
25516         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
25517                 error "MDT stripe was not removed"
25518
25519         cancel_lru_locks mdc
25520         local new_md5=$(md5sum $dom)
25521         [ "$old_md5" == "$new_md5" ] ||
25522                 error "$old_md5 != $new_md5"
25523
25524         # Skip free space checks with ZFS
25525         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25526                 local mdtfree2=$(do_facet $facet \
25527                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25528                 [ $mdtfree2 -gt $mdtfree1 ] ||
25529                         error "MDS space is not freed after migration"
25530         fi
25531         return 0
25532 }
25533 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
25534
25535 test_272d() {
25536         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25537                 skip "Need MDS version at least 2.12.55"
25538
25539         local dom=$DIR/$tdir/$tfile
25540         mkdir -p $DIR/$tdir
25541         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25542
25543         local mdtidx=$($LFS getstripe -m $dom)
25544         local mdtname=MDT$(printf %04x $mdtidx)
25545         local facet=mds$((mdtidx + 1))
25546
25547         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25548                 error "failed to write data into $dom"
25549         local old_md5=$(md5sum $dom)
25550         cancel_lru_locks mdc
25551         local mdtfree1=$(do_facet $facet \
25552                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25553
25554         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
25555                 error "failed mirroring to the new composite layout"
25556         $LFS mirror resync $dom ||
25557                 error "failed mirror resync"
25558         $LFS mirror split --mirror-id 1 -d $dom ||
25559                 error "failed mirror split"
25560
25561         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
25562                 error "MDT stripe was not removed"
25563
25564         cancel_lru_locks mdc
25565         local new_md5=$(md5sum $dom)
25566         [ "$old_md5" == "$new_md5" ] ||
25567                 error "$old_md5 != $new_md5"
25568
25569         # Skip free space checks with ZFS
25570         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25571                 local mdtfree2=$(do_facet $facet \
25572                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25573                 [ $mdtfree2 -gt $mdtfree1 ] ||
25574                         error "MDS space is not freed after DOM mirror deletion"
25575         fi
25576         return 0
25577 }
25578 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
25579
25580 test_272e() {
25581         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25582                 skip "Need MDS version at least 2.12.55"
25583
25584         local dom=$DIR/$tdir/$tfile
25585         mkdir -p $DIR/$tdir
25586         $LFS setstripe -c 2 $dom
25587
25588         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25589                 error "failed to write data into $dom"
25590         local old_md5=$(md5sum $dom)
25591         cancel_lru_locks
25592
25593         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
25594                 error "failed mirroring to the DOM layout"
25595         $LFS mirror resync $dom ||
25596                 error "failed mirror resync"
25597         $LFS mirror split --mirror-id 1 -d $dom ||
25598                 error "failed mirror split"
25599
25600         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25601                 error "MDT stripe wasn't set"
25602
25603         cancel_lru_locks
25604         local new_md5=$(md5sum $dom)
25605         [ "$old_md5" == "$new_md5" ] ||
25606                 error "$old_md5 != $new_md5"
25607
25608         return 0
25609 }
25610 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
25611
25612 test_272f() {
25613         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25614                 skip "Need MDS version at least 2.12.55"
25615
25616         local dom=$DIR/$tdir/$tfile
25617         mkdir -p $DIR/$tdir
25618         $LFS setstripe -c 2 $dom
25619
25620         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25621                 error "failed to write data into $dom"
25622         local old_md5=$(md5sum $dom)
25623         cancel_lru_locks
25624
25625         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
25626                 error "failed migrating to the DOM file"
25627
25628         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25629                 error "MDT stripe wasn't set"
25630
25631         cancel_lru_locks
25632         local new_md5=$(md5sum $dom)
25633         [ "$old_md5" != "$new_md5" ] &&
25634                 error "$old_md5 != $new_md5"
25635
25636         return 0
25637 }
25638 run_test 272f "DoM migration: OST-striped file to DOM file"
25639
25640 test_273a() {
25641         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25642                 skip "Need MDS version at least 2.11.50"
25643
25644         # Layout swap cannot be done if either file has DOM component,
25645         # this will never be supported, migration should be used instead
25646
25647         local dom=$DIR/$tdir/$tfile
25648         mkdir -p $DIR/$tdir
25649
25650         $LFS setstripe -c2 ${dom}_plain
25651         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
25652         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
25653                 error "can swap layout with DoM component"
25654         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
25655                 error "can swap layout with DoM component"
25656
25657         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
25658         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
25659                 error "can swap layout with DoM component"
25660         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
25661                 error "can swap layout with DoM component"
25662         return 0
25663 }
25664 run_test 273a "DoM: layout swapping should fail with DOM"
25665
25666 test_273b() {
25667         mkdir -p $DIR/$tdir
25668         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
25669
25670 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
25671         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
25672
25673         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25674 }
25675 run_test 273b "DoM: race writeback and object destroy"
25676
25677 test_273c() {
25678         mkdir -p $DIR/$tdir
25679         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
25680
25681         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
25682         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
25683
25684         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25685 }
25686 run_test 273c "race writeback and object destroy"
25687
25688 test_275() {
25689         remote_ost_nodsh && skip "remote OST with nodsh"
25690         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
25691                 skip "Need OST version >= 2.10.57"
25692
25693         local file=$DIR/$tfile
25694         local oss
25695
25696         oss=$(comma_list $(osts_nodes))
25697
25698         dd if=/dev/urandom of=$file bs=1M count=2 ||
25699                 error "failed to create a file"
25700         stack_trap "rm -f $file"
25701         cancel_lru_locks osc
25702
25703         #lock 1
25704         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25705                 error "failed to read a file"
25706
25707 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
25708         $LCTL set_param fail_loc=0x8000031f
25709
25710         cancel_lru_locks osc &
25711         sleep 1
25712
25713 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
25714         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
25715         #IO takes another lock, but matches the PENDING one
25716         #and places it to the IO RPC
25717         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25718                 error "failed to read a file with PENDING lock"
25719 }
25720 run_test 275 "Read on a canceled duplicate lock"
25721
25722 test_276() {
25723         remote_ost_nodsh && skip "remote OST with nodsh"
25724         local pid
25725
25726         do_facet ost1 "(while true; do \
25727                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
25728                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
25729         pid=$!
25730
25731         for LOOP in $(seq 20); do
25732                 stop ost1
25733                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
25734         done
25735         kill -9 $pid
25736         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
25737                 rm $TMP/sanity_276_pid"
25738 }
25739 run_test 276 "Race between mount and obd_statfs"
25740
25741 test_277() {
25742         $LCTL set_param ldlm.namespaces.*.lru_size=0
25743         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25744         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25745                           awk '/^used_mb/ { print $2 }')
25746         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
25747         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
25748                 oflag=direct conv=notrunc
25749         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25750                     awk '/^used_mb/ { print $2 }')
25751         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
25752 }
25753 run_test 277 "Direct IO shall drop page cache"
25754
25755 test_278() {
25756         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
25757         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25758         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
25759                 skip "needs the same host for mdt1 mdt2" && return
25760
25761         local pid1
25762         local pid2
25763
25764 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
25765         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
25766         stop mds2 &
25767         pid2=$!
25768
25769         stop mds1
25770
25771         echo "Starting MDTs"
25772         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
25773         wait $pid2
25774 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
25775 #will return NULL
25776         do_facet mds2 $LCTL set_param fail_loc=0
25777
25778         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
25779         wait_recovery_complete mds2
25780 }
25781 run_test 278 "Race starting MDS between MDTs stop/start"
25782
25783 test_280() {
25784         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
25785                 skip "Need MGS version at least 2.13.52"
25786         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25787         combined_mgs_mds || skip "needs combined MGS/MDT"
25788
25789         umount_client $MOUNT
25790 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
25791         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
25792
25793         mount_client $MOUNT &
25794         sleep 1
25795         stop mgs || error "stop mgs failed"
25796         #for a race mgs would crash
25797         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
25798         # make sure we unmount client before remounting
25799         wait
25800         umount_client $MOUNT
25801         mount_client $MOUNT || error "mount client failed"
25802 }
25803 run_test 280 "Race between MGS umount and client llog processing"
25804
25805 cleanup_test_300() {
25806         trap 0
25807         umask $SAVE_UMASK
25808 }
25809
25810 test_striped_dir() {
25811         local mdt_index=$1
25812         local stripe_count=$2
25813         local overstriping=$3
25814         local stripe_index
25815         local getstripe_count
25816
25817         mkdir -p $DIR/$tdir
25818
25819         SAVE_UMASK=$(umask)
25820         trap cleanup_test_300 RETURN EXIT
25821
25822         if [ -z $overstriping ]; then
25823                 $LFS setdirstripe -i $mdt_index -c $stripe_count -H all_char \
25824                                         -o 755 $DIR/$tdir/striped_dir ||
25825                         error "set striped dir error"
25826         else
25827                 $LFS setdirstripe -i $mdt_index -C $stripe_count -H all_char \
25828                                         -o 755 $DIR/$tdir/striped_dir ||
25829                         error "set striped dir error"
25830         fi
25831
25832         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
25833         [ "$mode" = "755" ] || error "expect 755 got $mode"
25834
25835         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
25836                 error "getdirstripe failed"
25837         getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
25838         if [ "$getstripe_count" != "$stripe_count" ]; then
25839                 error "1:stripe_count is $getstripe_count, expect $stripe_count"
25840         fi
25841         getstripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
25842         if [ "$getstripe_count" != "$stripe_count" ]; then
25843                 error "2:stripe_count is $getstripe_count, expect $stripe_count"
25844         fi
25845
25846         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
25847         if [ "$stripe_index" != "$mdt_index" ]; then
25848                 error "stripe_index is $stripe_index, expect $mdt_index"
25849         fi
25850
25851         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25852                 error "nlink error after create striped dir"
25853
25854         mkdir $DIR/$tdir/striped_dir/a
25855         mkdir $DIR/$tdir/striped_dir/b
25856
25857         stat $DIR/$tdir/striped_dir/a ||
25858                 error "create dir under striped dir failed"
25859         stat $DIR/$tdir/striped_dir/b ||
25860                 error "create dir under striped dir failed"
25861
25862         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
25863                 error "nlink error after mkdir"
25864
25865         rmdir $DIR/$tdir/striped_dir/a
25866         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
25867                 error "nlink error after rmdir"
25868
25869         rmdir $DIR/$tdir/striped_dir/b
25870         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25871                 error "nlink error after rmdir"
25872
25873         chattr +i $DIR/$tdir/striped_dir
25874         createmany -o $DIR/$tdir/striped_dir/f 10 &&
25875                 error "immutable flags not working under striped dir!"
25876         chattr -i $DIR/$tdir/striped_dir
25877
25878         rmdir $DIR/$tdir/striped_dir ||
25879                 error "rmdir striped dir error"
25880
25881         cleanup_test_300
25882
25883         true
25884 }
25885
25886 test_300a() {
25887         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25888                 skip "skipped for lustre < 2.7.0"
25889         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25890         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25891
25892         test_striped_dir 0 2 || error "failed on striped dir on MDT0"
25893         test_striped_dir 1 2 || error "failed on striped dir on MDT0"
25894 }
25895 run_test 300a "basic striped dir sanity test"
25896
25897 test_300b() {
25898         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25899                 skip "skipped for lustre < 2.7.0"
25900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25901         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25902
25903         local i
25904         local mtime1
25905         local mtime2
25906         local mtime3
25907
25908         test_mkdir $DIR/$tdir || error "mkdir fail"
25909         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25910                 error "set striped dir error"
25911         for i in {0..9}; do
25912                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
25913                 sleep 1
25914                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
25915                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
25916                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
25917                 sleep 1
25918                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
25919                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
25920                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
25921         done
25922         true
25923 }
25924 run_test 300b "check ctime/mtime for striped dir"
25925
25926 test_300c() {
25927         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25928                 skip "skipped for lustre < 2.7.0"
25929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25930         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25931
25932         local file_count
25933
25934         mkdir_on_mdt0 $DIR/$tdir
25935         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
25936                 error "set striped dir error"
25937
25938         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
25939                 error "chown striped dir failed"
25940
25941         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
25942                 error "create 5k files failed"
25943
25944         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
25945
25946         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
25947
25948         rm -rf $DIR/$tdir
25949 }
25950 run_test 300c "chown && check ls under striped directory"
25951
25952 test_300d() {
25953         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25954                 skip "skipped for lustre < 2.7.0"
25955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25956         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25957
25958         local stripe_count
25959         local file
25960
25961         mkdir -p $DIR/$tdir
25962         $LFS setstripe -c 2 $DIR/$tdir
25963
25964         #local striped directory
25965         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25966                 error "set striped dir error"
25967         #look at the directories for debug purposes
25968         ls -l $DIR/$tdir
25969         $LFS getdirstripe $DIR/$tdir
25970         ls -l $DIR/$tdir/striped_dir
25971         $LFS getdirstripe $DIR/$tdir/striped_dir
25972         createmany -o $DIR/$tdir/striped_dir/f 10 ||
25973                 error "create 10 files failed"
25974
25975         #remote striped directory
25976         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
25977                 error "set striped dir error"
25978         #look at the directories for debug purposes
25979         ls -l $DIR/$tdir
25980         $LFS getdirstripe $DIR/$tdir
25981         ls -l $DIR/$tdir/remote_striped_dir
25982         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
25983         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
25984                 error "create 10 files failed"
25985
25986         for file in $(find $DIR/$tdir); do
25987                 stripe_count=$($LFS getstripe -c $file)
25988                 [ $stripe_count -eq 2 ] ||
25989                         error "wrong stripe $stripe_count for $file"
25990         done
25991
25992         rm -rf $DIR/$tdir
25993 }
25994 run_test 300d "check default stripe under striped directory"
25995
25996 test_300e() {
25997         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25998                 skip "Need MDS version at least 2.7.55"
25999         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26000         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26001
26002         local stripe_count
26003         local file
26004
26005         mkdir -p $DIR/$tdir
26006
26007         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
26008                 error "set striped dir error"
26009
26010         touch $DIR/$tdir/striped_dir/a
26011         touch $DIR/$tdir/striped_dir/b
26012         touch $DIR/$tdir/striped_dir/c
26013
26014         mkdir $DIR/$tdir/striped_dir/dir_a
26015         mkdir $DIR/$tdir/striped_dir/dir_b
26016         mkdir $DIR/$tdir/striped_dir/dir_c
26017
26018         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
26019                 error "set striped adir under striped dir error"
26020
26021         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
26022                 error "set striped bdir under striped dir error"
26023
26024         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
26025                 error "set striped cdir under striped dir error"
26026
26027         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
26028                 error "rename dir under striped dir fails"
26029
26030         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
26031                 error "rename dir under different stripes fails"
26032
26033         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
26034                 error "rename file under striped dir should succeed"
26035
26036         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
26037                 error "rename dir under striped dir should succeed"
26038
26039         rm -rf $DIR/$tdir
26040 }
26041 run_test 300e "check rename under striped directory"
26042
26043 test_300f() {
26044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26045         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26046         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26047                 skip "Need MDS version at least 2.7.55"
26048
26049         local stripe_count
26050         local file
26051
26052         rm -rf $DIR/$tdir
26053         mkdir -p $DIR/$tdir
26054
26055         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
26056                 error "set striped dir error"
26057
26058         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
26059                 error "set striped dir error"
26060
26061         touch $DIR/$tdir/striped_dir/a
26062         mkdir $DIR/$tdir/striped_dir/dir_a
26063         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
26064                 error "create striped dir under striped dir fails"
26065
26066         touch $DIR/$tdir/striped_dir1/b
26067         mkdir $DIR/$tdir/striped_dir1/dir_b
26068         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
26069                 error "create striped dir under striped dir fails"
26070
26071         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
26072                 error "rename dir under different striped dir should fail"
26073
26074         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
26075                 error "rename striped dir under diff striped dir should fail"
26076
26077         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
26078                 error "rename file under diff striped dirs fails"
26079
26080         rm -rf $DIR/$tdir
26081 }
26082 run_test 300f "check rename cross striped directory"
26083
26084 test_300_check_default_striped_dir()
26085 {
26086         local dirname=$1
26087         local default_count=$2
26088         local default_index=$3
26089         local stripe_count
26090         local stripe_index
26091         local dir_stripe_index
26092         local dir
26093
26094         echo "checking $dirname $default_count $default_index"
26095         $LFS setdirstripe -D -c $default_count -i $default_index \
26096                                 -H all_char $DIR/$tdir/$dirname ||
26097                 error "set default stripe on striped dir error"
26098         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
26099         [ $stripe_count -eq $default_count ] ||
26100                 error "expect $default_count get $stripe_count for $dirname"
26101
26102         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
26103         [ $stripe_index -eq $default_index ] ||
26104                 error "expect $default_index get $stripe_index for $dirname"
26105
26106         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
26107                                                 error "create dirs failed"
26108
26109         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
26110         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
26111         for dir in $(find $DIR/$tdir/$dirname/*); do
26112                 stripe_count=$($LFS getdirstripe -c $dir)
26113                 (( $stripe_count == $default_count )) ||
26114                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
26115                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
26116                 error "stripe count $default_count != $stripe_count for $dir"
26117
26118                 stripe_index=$($LFS getdirstripe -i $dir)
26119                 [ $default_index -eq -1 ] ||
26120                         [ $stripe_index -eq $default_index ] ||
26121                         error "$stripe_index != $default_index for $dir"
26122
26123                 #check default stripe
26124                 stripe_count=$($LFS getdirstripe -D -c $dir)
26125                 [ $stripe_count -eq $default_count ] ||
26126                 error "default count $default_count != $stripe_count for $dir"
26127
26128                 stripe_index=$($LFS getdirstripe -D -i $dir)
26129                 [ $stripe_index -eq $default_index ] ||
26130                 error "default index $default_index != $stripe_index for $dir"
26131         done
26132         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
26133 }
26134
26135 test_300g() {
26136         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26137         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26138                 skip "Need MDS version at least 2.7.55"
26139
26140         local dir
26141         local stripe_count
26142         local stripe_index
26143
26144         mkdir_on_mdt0 $DIR/$tdir
26145         mkdir $DIR/$tdir/normal_dir
26146
26147         #Checking when client cache stripe index
26148         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26149         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
26150                 error "create striped_dir failed"
26151
26152         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
26153                 error "create dir0 fails"
26154         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
26155         [ $stripe_index -eq 0 ] ||
26156                 error "dir0 expect index 0 got $stripe_index"
26157
26158         mkdir $DIR/$tdir/striped_dir/dir1 ||
26159                 error "create dir1 fails"
26160         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
26161         [ $stripe_index -eq 1 ] ||
26162                 error "dir1 expect index 1 got $stripe_index"
26163
26164         #check default stripe count/stripe index
26165         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
26166         test_300_check_default_striped_dir normal_dir 1 0
26167         test_300_check_default_striped_dir normal_dir -1 1
26168         test_300_check_default_striped_dir normal_dir 2 -1
26169
26170         #delete default stripe information
26171         echo "delete default stripeEA"
26172         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
26173                 error "set default stripe on striped dir error"
26174
26175         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
26176         for dir in $(find $DIR/$tdir/normal_dir/*); do
26177                 stripe_count=$($LFS getdirstripe -c $dir)
26178                 [ $stripe_count -eq 0 ] ||
26179                         error "expect 1 get $stripe_count for $dir"
26180         done
26181 }
26182 run_test 300g "check default striped directory for normal directory"
26183
26184 test_300h() {
26185         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26186         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26187                 skip "Need MDS version at least 2.7.55"
26188
26189         local dir
26190         local stripe_count
26191
26192         mkdir $DIR/$tdir
26193         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
26194                 error "set striped dir error"
26195
26196         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
26197         test_300_check_default_striped_dir striped_dir 1 0
26198         test_300_check_default_striped_dir striped_dir -1 1
26199         test_300_check_default_striped_dir striped_dir 2 -1
26200
26201         #delete default stripe information
26202         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
26203                 error "set default stripe on striped dir error"
26204
26205         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
26206         for dir in $(find $DIR/$tdir/striped_dir/*); do
26207                 stripe_count=$($LFS getdirstripe -c $dir)
26208                 [ $stripe_count -eq 0 ] ||
26209                         error "expect 1 get $stripe_count for $dir"
26210         done
26211 }
26212 run_test 300h "check default striped directory for striped directory"
26213
26214 test_300i() {
26215         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
26216         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
26217         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
26218                 skip "Need MDS version at least 2.7.55"
26219
26220         local stripe_count
26221         local file
26222
26223         mkdir $DIR/$tdir
26224
26225         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
26226                 error "set striped dir error"
26227
26228         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
26229                 error "create files under striped dir failed"
26230
26231         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
26232                 error "set striped hashdir error"
26233
26234         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
26235                 error "create dir0 under hash dir failed"
26236         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
26237                 error "create dir1 under hash dir failed"
26238         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
26239                 error "create dir2 under hash dir failed"
26240
26241         # unfortunately, we need to umount to clear dir layout cache for now
26242         # once we fully implement dir layout, we can drop this
26243         umount_client $MOUNT || error "umount failed"
26244         mount_client $MOUNT || error "mount failed"
26245
26246         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
26247         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
26248         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
26249
26250         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
26251                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
26252                         error "create crush2 dir $tdir/hashdir/d3 failed"
26253                 $LFS find -H crush2 $DIR/$tdir/hashdir
26254                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
26255                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
26256
26257                 # mkdir with an invalid hash type (hash=fail_val) from client
26258                 # should be replaced on MDS with a valid (default) hash type
26259                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
26260                 $LCTL set_param fail_loc=0x1901 fail_val=99
26261                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
26262
26263                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
26264                 local expect=$(do_facet mds1 \
26265                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
26266                 [[ $hash == $expect ]] ||
26267                         error "d99 hash '$hash' != expected hash '$expect'"
26268         fi
26269
26270         #set the stripe to be unknown hash type on read
26271         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
26272         $LCTL set_param fail_loc=0x1901 fail_val=99
26273         for ((i = 0; i < 10; i++)); do
26274                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
26275                         error "stat f-$i failed"
26276                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
26277         done
26278
26279         touch $DIR/$tdir/striped_dir/f0 &&
26280                 error "create under striped dir with unknown hash should fail"
26281
26282         $LCTL set_param fail_loc=0
26283
26284         umount_client $MOUNT || error "umount failed"
26285         mount_client $MOUNT || error "mount failed"
26286
26287         return 0
26288 }
26289 run_test 300i "client handle unknown hash type striped directory"
26290
26291 test_300j() {
26292         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26293         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26294         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26295                 skip "Need MDS version at least 2.7.55"
26296
26297         local stripe_count
26298         local file
26299
26300         mkdir $DIR/$tdir
26301
26302         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
26303         $LCTL set_param fail_loc=0x1702
26304         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
26305                 error "set striped dir error"
26306
26307         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
26308                 error "create files under striped dir failed"
26309
26310         $LCTL set_param fail_loc=0
26311
26312         rm -rf $DIR/$tdir || error "unlink striped dir fails"
26313
26314         return 0
26315 }
26316 run_test 300j "test large update record"
26317
26318 test_300k() {
26319         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26320         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26321         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26322                 skip "Need MDS version at least 2.7.55"
26323
26324         # this test needs a huge transaction
26325         local kb
26326         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
26327              osd*.$FSNAME-MDT0000.kbytestotal")
26328         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
26329
26330         local stripe_count
26331         local file
26332
26333         mkdir $DIR/$tdir
26334
26335         #define OBD_FAIL_LARGE_STRIPE   0x1703
26336         $LCTL set_param fail_loc=0x1703
26337         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
26338                 error "set striped dir error"
26339         $LCTL set_param fail_loc=0
26340
26341         $LFS getdirstripe $DIR/$tdir/striped_dir ||
26342                 error "getstripeddir fails"
26343         rm -rf $DIR/$tdir/striped_dir ||
26344                 error "unlink striped dir fails"
26345
26346         return 0
26347 }
26348 run_test 300k "test large striped directory"
26349
26350 test_300l() {
26351         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26352         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26353         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26354                 skip "Need MDS version at least 2.7.55"
26355
26356         local stripe_index
26357
26358         test_mkdir -p $DIR/$tdir/striped_dir
26359         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
26360                         error "chown $RUNAS_ID failed"
26361         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
26362                 error "set default striped dir failed"
26363
26364         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
26365         $LCTL set_param fail_loc=0x80000158
26366         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
26367
26368         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
26369         [ $stripe_index -eq 1 ] ||
26370                 error "expect 1 get $stripe_index for $dir"
26371 }
26372 run_test 300l "non-root user to create dir under striped dir with stale layout"
26373
26374 test_300m() {
26375         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26376         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
26377         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26378                 skip "Need MDS version at least 2.7.55"
26379
26380         mkdir -p $DIR/$tdir/striped_dir
26381         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
26382                 error "set default stripes dir error"
26383
26384         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
26385
26386         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
26387         [ $stripe_count -eq 0 ] ||
26388                         error "expect 0 get $stripe_count for a"
26389
26390         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
26391                 error "set default stripes dir error"
26392
26393         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
26394
26395         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
26396         [ $stripe_count -eq 0 ] ||
26397                         error "expect 0 get $stripe_count for b"
26398
26399         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
26400                 error "set default stripes dir error"
26401
26402         mkdir $DIR/$tdir/striped_dir/c &&
26403                 error "default stripe_index is invalid, mkdir c should fails"
26404
26405         rm -rf $DIR/$tdir || error "rmdir fails"
26406 }
26407 run_test 300m "setstriped directory on single MDT FS"
26408
26409 cleanup_300n() {
26410         local list=$(comma_list $(mdts_nodes))
26411
26412         trap 0
26413         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26414 }
26415
26416 test_300n() {
26417         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26418         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26419         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26420                 skip "Need MDS version at least 2.7.55"
26421         remote_mds_nodsh && skip "remote MDS with nodsh"
26422
26423         local stripe_index
26424         local list=$(comma_list $(mdts_nodes))
26425
26426         trap cleanup_300n RETURN EXIT
26427         mkdir -p $DIR/$tdir
26428         chmod 777 $DIR/$tdir
26429         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
26430                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
26431                 error "create striped dir succeeds with gid=0"
26432
26433         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
26434         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
26435                 error "create striped dir fails with gid=-1"
26436
26437         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26438         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
26439                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
26440                 error "set default striped dir succeeds with gid=0"
26441
26442
26443         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
26444         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
26445                 error "set default striped dir fails with gid=-1"
26446
26447
26448         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26449         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
26450                                         error "create test_dir fails"
26451         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
26452                                         error "create test_dir1 fails"
26453         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
26454                                         error "create test_dir2 fails"
26455         cleanup_300n
26456 }
26457 run_test 300n "non-root user to create dir under striped dir with default EA"
26458
26459 test_300o() {
26460         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26461         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26462         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26463                 skip "Need MDS version at least 2.7.55"
26464
26465         local numfree1
26466         local numfree2
26467
26468         mkdir -p $DIR/$tdir
26469
26470         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
26471         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
26472         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
26473                 skip "not enough free inodes $numfree1 $numfree2"
26474         fi
26475
26476         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
26477         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
26478         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
26479                 skip "not enough free space $numfree1 $numfree2"
26480         fi
26481
26482         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
26483                 error "setdirstripe fails"
26484
26485         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
26486                 error "create dirs fails"
26487
26488         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
26489         ls $DIR/$tdir/striped_dir > /dev/null ||
26490                 error "ls striped dir fails"
26491         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
26492                 error "unlink big striped dir fails"
26493 }
26494 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
26495
26496 test_300p() {
26497         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26498         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26499         remote_mds_nodsh && skip "remote MDS with nodsh"
26500
26501         mkdir_on_mdt0 $DIR/$tdir
26502
26503         #define OBD_FAIL_OUT_ENOSPC     0x1704
26504         do_facet mds2 lctl set_param fail_loc=0x80001704
26505         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
26506                  && error "create striped directory should fail"
26507
26508         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
26509
26510         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
26511         true
26512 }
26513 run_test 300p "create striped directory without space"
26514
26515 test_300q() {
26516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26517         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26518
26519         local fd=$(free_fd)
26520         local cmd="exec $fd<$tdir"
26521         cd $DIR
26522         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
26523         eval $cmd
26524         cmd="exec $fd<&-"
26525         trap "eval $cmd" EXIT
26526         cd $tdir || error "cd $tdir fails"
26527         rmdir  ../$tdir || error "rmdir $tdir fails"
26528         mkdir local_dir && error "create dir succeeds"
26529         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
26530         eval $cmd
26531         return 0
26532 }
26533 run_test 300q "create remote directory under orphan directory"
26534
26535 test_300r() {
26536         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26537                 skip "Need MDS version at least 2.7.55" && return
26538         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
26539
26540         mkdir $DIR/$tdir
26541
26542         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
26543                 error "set striped dir error"
26544
26545         $LFS getdirstripe $DIR/$tdir/striped_dir ||
26546                 error "getstripeddir fails"
26547
26548         local stripe_count
26549         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
26550                       awk '/lmv_stripe_count:/ { print $2 }')
26551
26552         [ $MDSCOUNT -ne $stripe_count ] &&
26553                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
26554
26555         rm -rf $DIR/$tdir/striped_dir ||
26556                 error "unlink striped dir fails"
26557 }
26558 run_test 300r "test -1 striped directory"
26559
26560 test_300s_helper() {
26561         local count=$1
26562
26563         local stripe_dir=$DIR/$tdir/striped_dir.$count
26564
26565         $LFS mkdir -c $count $stripe_dir ||
26566                 error "lfs mkdir -c error"
26567
26568         $LFS getdirstripe $stripe_dir ||
26569                 error "lfs getdirstripe fails"
26570
26571         local stripe_count
26572         stripe_count=$($LFS getdirstripe $stripe_dir |
26573                       awk '/lmv_stripe_count:/ { print $2 }')
26574
26575         [ $count -ne $stripe_count ] &&
26576                 error_noexit "bad stripe count $stripe_count expected $count"
26577
26578         local dupe_stripes
26579         dupe_stripes=$($LFS getdirstripe $stripe_dir |
26580                 awk '/0x/ {count[$1] += 1}; END {
26581                         for (idx in count) {
26582                                 if (count[idx]>1) {
26583                                         print "index " idx " count " count[idx]
26584                                 }
26585                         }
26586                 }')
26587
26588         if [[ -n "$dupe_stripes" ]] ; then
26589                 lfs getdirstripe $stripe_dir
26590                 error_noexit "Dupe MDT above: $dupe_stripes "
26591         fi
26592
26593         rm -rf $stripe_dir ||
26594                 error_noexit "unlink $stripe_dir fails"
26595 }
26596
26597 test_300s() {
26598         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26599                 skip "Need MDS version at least 2.7.55" && return
26600         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
26601
26602         mkdir $DIR/$tdir
26603         for count in $(seq 2 $MDSCOUNT); do
26604                 test_300s_helper $count
26605         done
26606 }
26607 run_test 300s "test lfs mkdir -c without -i"
26608
26609 test_300t() {
26610         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
26611                 skip "need MDS 2.14.55 or later"
26612         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
26613
26614         local testdir="$DIR/$tdir/striped_dir"
26615         local dir1=$testdir/dir1
26616         local dir2=$testdir/dir2
26617
26618         mkdir -p $testdir
26619
26620         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
26621                 error "failed to set default stripe count for $testdir"
26622
26623         mkdir $dir1
26624         local stripe_count=$($LFS getdirstripe -c $dir1)
26625
26626         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
26627
26628         local max_count=$((MDSCOUNT - 1))
26629         local mdts=$(comma_list $(mdts_nodes))
26630
26631         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
26632         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
26633
26634         mkdir $dir2
26635         stripe_count=$($LFS getdirstripe -c $dir2)
26636
26637         (( $stripe_count == $max_count )) || error "wrong stripe count"
26638 }
26639 run_test 300t "test max_mdt_stripecount"
26640
26641 MDT_OVSTRP_VER="2.15.60"
26642 # 300u family tests MDT overstriping
26643 test_300ua() {
26644         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26645
26646         local setcount=$((MDSCOUNT * 2))
26647
26648         local expected_count
26649
26650         mkdir $DIR/$tdir
26651         $LFS setdirstripe -C $setcount $DIR/$tdir/${tdir}.0 ||
26652                 error "(0) failed basic overstriped dir creation test"
26653         local getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.0)
26654
26655         # This does a basic interop test - if the MDS does not support mdt
26656         # overstriping, we should get stripes == number of MDTs
26657         if (( $MDS1_VERSION < $(version_code $MDT_OVSTRP_VER) )); then
26658                 expected_count=$MDSCOUNT
26659         else
26660                 expected_count=$setcount
26661         fi
26662         (( getstripe_count == expected_count )) ||
26663                 error "(1) incorrect stripe count for simple overstriped dir"
26664
26665         rm -rf $DIR/$tdir/${tdir}.0 ||
26666                 error "(2) unable to rm overstriped dir"
26667
26668         # Tests after this require overstriping support
26669         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26670                 { echo "skipped for MDS < $MDT_OVSTRP_VER"; return 0; }
26671
26672         test_striped_dir 0 $setcount true ||
26673                 error "(3)failed on overstriped dir"
26674         test_striped_dir 1 $setcount true ||
26675                 error "(4)failed on overstriped dir"
26676
26677         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26678
26679         test_striped_dir 0 $setcount true ||
26680                 error "(5)failed on overstriped dir"
26681 }
26682 run_test 300ua "basic overstriped dir sanity test"
26683
26684 test_300ub() {
26685         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26686                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26687         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26688
26689         mkdir $DIR/$tdir
26690
26691         echo "Testing invalid stripe count, failure expected"
26692         local setcount=$((MDSCOUNT * 2))
26693
26694         $LFS setdirstripe -c $setcount $DIR/$tdir/${tdir}.0
26695         local getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.0)
26696
26697         (( getstripe_count <= MDSCOUNT )) ||
26698                 error "(0)stripe count ($setcount) > MDT count ($MDSCOUNT) succeeded with -c"
26699
26700         # When a user requests > LMV_MAX_STRIPES_PER_MDT, we reduce to that
26701         setcount=$((MDSCOUNT * 2 * LMV_MAX_STRIPES_PER_MDT))
26702         $LFS setdirstripe -C $setcount $DIR/$tdir/${tdir}.1
26703
26704         local maxcount=$((MDSCOUNT * LMV_MAX_STRIPES_PER_MDT))
26705
26706         getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.1)
26707         (( getstripe_count == maxcount )) ||
26708                 error "(1)stripe_count is $getstripe_count, expect $maxcount"
26709
26710         # Test specific striping with -i
26711         $LFS setdirstripe -i 0,0,0,0 $DIR/$tdir/${tdir}.2
26712
26713         getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.2)
26714         (( getstripe_count == 4 )) ||
26715                 error "(2)stripe_count is $getstripe_count, expect 4"
26716
26717         local nonzeroindices=$($LFS getdirstripe $DIR/$tdir/${tdir}.2 | grep "\[" | \
26718                                grep -v mdtidx | awk '{print $1}' | grep -c -v 0)
26719
26720         [[ -n "$nonzeroindices" ]] ||
26721                 error "(3) stripes indices not all 0: $nonzeroindices"
26722
26723         # Test specific striping with too many stripes on one MDT
26724         echo "Testing invalid striping, failure expected"
26725         $LFS setdirstripe -i 0,1,0,1,0,1,0,1,0,1,0 $DIR/$tdir/${tdir}.3
26726         $LFS getdirstripe $DIR/$tdir/${tdir}.3
26727         getstripe_count=$($LFS getdirstripe $DIR/$tdir/${tdir}.3 | grep "\[" | \
26728                           grep -v mdtidx | awk '{print $1}' | grep -c '0')
26729         echo "stripes on MDT0: $getstripe_count"
26730         (( getstripe_count <= LMV_MAX_STRIPES_PER_MDT )) ||
26731                 error "(4) setstripe with too many stripes on MDT0 succeeded"
26732
26733         setcount=$((MDSCOUNT * 2))
26734         $LFS setdirstripe -C $setcount -H all_char $DIR/${tdir}.4 ||
26735                 error "(5) can't setdirstripe with manually set hash function"
26736
26737         getstripe_count=$($LFS getdirstripe -c $DIR/${tdir}.4)
26738         (( getstripe_count == setcount )) ||
26739                 error "(6)stripe_count is $getstripe_count, expect $setcount"
26740
26741         setcount=$((MDSCOUNT * 2))
26742         mkdir $DIR/${tdir}.5
26743         $LFS setdirstripe -C $setcount -D -H crush $DIR/${tdir}.5 ||
26744                 error "(7) can't setdirstripe with manually set hash function"
26745         mkdir $DIR/${tdir}.5/${tdir}.6
26746
26747         getstripe_count=$($LFS getdirstripe -c $DIR/${tdir}.5/${tdir}.6)
26748         (( getstripe_count == setcount )) ||
26749                 error "(8)stripe_count is $getstripe_count, expect $setcount"
26750 }
26751 run_test 300ub "test MDT overstriping interface & limits"
26752
26753 test_300uc() {
26754         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26755                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26756         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26757
26758         mkdir $DIR/$tdir
26759
26760         local setcount=$((MDSCOUNT * 2))
26761
26762         $LFS setdirstripe -D -C $setcount $DIR/$tdir
26763
26764         mkdir $DIR/$tdir/${tdir}.1
26765
26766         local getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.1)
26767
26768         (( getstripe_count == setcount )) ||
26769                 error "(0)stripe_count is $getstripe_count, expect $setcount"
26770
26771         mkdir $DIR/$tdir/${tdir}.1/${tdir}.2
26772
26773         local getstripe_count=$($LFS getdirstripe -c \
26774                                 $DIR/$tdir/${tdir}.1/${tdir}.2)
26775
26776         (( getstripe_count == setcount )) ||
26777                 error "(1)stripe_count is $getstripe_count, expect $setcount"
26778 }
26779 run_test 300uc "test MDT overstriping as default & inheritance"
26780
26781 test_300ud() {
26782         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26783                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26784         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26785
26786         local mdts=$(comma_list $(mdts_nodes))
26787         local timeout=100
26788
26789         local restripe_status
26790         local delta
26791         local i
26792
26793         [[ $mds1_FSTYPE == zfs ]] && timeout=300
26794
26795         # in case "crush" hash type is not set
26796         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
26797
26798         restripe_status=$(do_facet mds1 $LCTL get_param -n \
26799                            mdt.*MDT0000.enable_dir_restripe)
26800         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
26801         stack_trap "do_nodes $mdts $LCTL set_param \
26802                     mdt.*.enable_dir_restripe=$restripe_status"
26803
26804         mkdir $DIR/$tdir
26805         createmany -m $DIR/$tdir/f $((50 * MDSCOUNT)) ||
26806                 error "create files under remote dir failed $i"
26807         createmany -d $DIR/$tdir/d $((50 * MDSCOUNT)) ||
26808                 error "create dirs under remote dir failed $i"
26809
26810         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26811
26812         (( setcount < 13 )) || setcount=12
26813         for i in $(seq 2 $setcount); do
26814                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
26815                 $LFS setdirstripe -C $i $DIR/$tdir ||
26816                         error "split -C $i $tdir failed"
26817                 wait_update $HOSTNAME \
26818                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
26819                         error "dir split not finished"
26820                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
26821                         awk '/migrate/ {sum += $2} END { print sum }')
26822                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
26823                 # delta is around total_files/stripe_count, deviation 3%
26824                 (( delta < 100 * MDSCOUNT / i + 3 * MDSCOUNT )) ||
26825                         error "$delta files migrated >= $((100 * MDSCOUNT / i + 3 * MDSCOUNT))"
26826         done
26827 }
26828 run_test 300ud "dir split"
26829
26830 test_300ue() {
26831         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26832                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26833         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26834
26835         local mdts=$(comma_list $(mdts_nodes))
26836         local timeout=100
26837
26838         local restripe_status
26839         local delta
26840         local c
26841
26842         [[ $mds1_FSTYPE == zfs ]] && timeout=300
26843
26844         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
26845
26846         restripe_status=$(do_facet mds1 $LCTL get_param -n \
26847                            mdt.*MDT0000.enable_dir_restripe)
26848         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
26849         stack_trap "do_nodes $mdts $LCTL set_param \
26850                     mdt.*.enable_dir_restripe=$restripe_status"
26851
26852         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26853
26854         (( setcount < 13 )) || setcount=12
26855         test_mkdir -C $setcount -H crush $DIR/$tdir
26856         createmany -m $DIR/$tdir/f $((50 * MDSCOUNT)) ||
26857                 error "create files under remote dir failed"
26858         createmany -d $DIR/$tdir/d $((50 * MDSCOUNT)) ||
26859                 error "create dirs under remote dir failed"
26860
26861         for c in $(seq $((setcount - 1)) -1 1); do
26862                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
26863                 $LFS setdirstripe -C $c $DIR/$tdir ||
26864                         error "split -C $c $tdir failed"
26865                 wait_update $HOSTNAME \
26866                         "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" $timeout ||
26867                         error "dir merge not finished"
26868                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
26869                         awk '/migrate/ {sum += $2} END { print sum }')
26870                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
26871                 # delta is around total_files/stripe_count, deviation 3%
26872                 (( delta < 100 * MDSCOUNT / c + 3 * MDSCOUNT )) ||
26873                         error "$delta files migrated >= $((100 * MDSCOUNT / c + 3 * MDSCOUNT))"
26874         done
26875 }
26876 run_test 300ue "dir merge"
26877
26878 test_300uf() {
26879         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26880                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26881         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26882
26883         # maximum amount of local locks:
26884         # parent striped dir - 2 locks
26885         # new stripe in parent to migrate to - 1 lock
26886         # source and target - 2 locks
26887         # Total 5 locks for regular file
26888         #
26889         # NB: Overstriping should add several extra local locks
26890         # FIXME: Remove this once understood
26891         #lctl set_param *debug=-1 debug_mb=10000
26892         lctl clear
26893         lctl mark "touch/create"
26894         mkdir -p $DIR/$tdir
26895         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26896         local setcount=$((MDSCOUNT * 5))
26897
26898         $LFS mkdir -i1 -C $setcount $DIR/$tdir/dir1
26899         touch $DIR/$tdir/dir1/eee
26900
26901         lctl mark "hardlinks"
26902         # create 4 hardlink for 4 more locks
26903         # Total: 9 locks > RS_MAX_LOCKS (8)
26904         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
26905         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
26906         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
26907         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
26908         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
26909         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
26910         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
26911         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
26912
26913         lctl mark "cancel lru"
26914         cancel_lru_locks mdc
26915
26916         lctl mark "migrate"
26917         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
26918                 error "migrate dir fails"
26919
26920         rm -rf $DIR/$tdir || error "rm dir failed after migration"
26921 }
26922 run_test 300uf "migrate with too many local locks"
26923
26924 test_300ug() {
26925         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26926                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26927         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26928
26929         mkdir -p $DIR/$tdir
26930         local migrate_dir=$DIR/$tdir/migrate_dir
26931         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26932         local setcount2=$((setcount - 2))
26933
26934         $LFS setdirstripe -c 2 $migrate_dir ||
26935                 error "(0) failed to create striped directory"
26936
26937         $LFS migrate -m 0 -C $setcount $migrate_dir ||
26938                 error "(1)failed to migrate to overstriped directory"
26939         local getstripe_count=$($LFS getdirstripe -c $migrate_dir)
26940
26941         (( getstripe_count == setcount )) ||
26942                 error "(2)stripe_count is $getstripe_count, expect $setcount"
26943         touch $DIR/$tdir/migrate_dir/$tfile ||
26944                 error "(3)failed to create file in overstriped directory"
26945         $LFS migrate -m 0 -C $setcount2 $migrate_dir ||
26946                 error "(4)failed to migrate overstriped directory"
26947         # Check stripe count after migration
26948         $LFS getdirstripe $migrate_dir
26949         getstripe_count=$($LFS getdirstripe -c $migrate_dir)
26950         (( getstripe_count == setcount2 )) ||
26951                 error "(5)stripe_count is $getstripe_count, expect $setcount2"
26952
26953         rm -rf $migrate_dir || error "(6) unable to rm overstriped dir"
26954 }
26955 run_test 300ug "migrate overstriped dirs"
26956
26957 prepare_remote_file() {
26958         mkdir $DIR/$tdir/src_dir ||
26959                 error "create remote source failed"
26960
26961         cp /etc/hosts $DIR/$tdir/src_dir/a ||
26962                  error "cp to remote source failed"
26963         touch $DIR/$tdir/src_dir/a
26964
26965         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
26966                 error "create remote target dir failed"
26967
26968         touch $DIR/$tdir/tgt_dir/b
26969
26970         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
26971                 error "rename dir cross MDT failed!"
26972
26973         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
26974                 error "src_child still exists after rename"
26975
26976         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
26977                 error "missing file(a) after rename"
26978
26979         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
26980                 error "diff after rename"
26981 }
26982
26983 test_310a() {
26984         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
26985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26986
26987         local remote_file=$DIR/$tdir/tgt_dir/b
26988
26989         mkdir -p $DIR/$tdir
26990
26991         prepare_remote_file || error "prepare remote file failed"
26992
26993         #open-unlink file
26994         $OPENUNLINK $remote_file $remote_file ||
26995                 error "openunlink $remote_file failed"
26996         $CHECKSTAT -a $remote_file || error "$remote_file exists"
26997 }
26998 run_test 310a "open unlink remote file"
26999
27000 test_310b() {
27001         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
27002         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27003
27004         local remote_file=$DIR/$tdir/tgt_dir/b
27005
27006         mkdir -p $DIR/$tdir
27007
27008         prepare_remote_file || error "prepare remote file failed"
27009
27010         ln $remote_file $DIR/$tfile || error "link failed for remote file"
27011         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
27012         $CHECKSTAT -t file $remote_file || error "check file failed"
27013 }
27014 run_test 310b "unlink remote file with multiple links while open"
27015
27016 test_310c() {
27017         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27018         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
27019
27020         local remote_file=$DIR/$tdir/tgt_dir/b
27021
27022         mkdir -p $DIR/$tdir
27023
27024         prepare_remote_file || error "prepare remote file failed"
27025
27026         ln $remote_file $DIR/$tfile || error "link failed for remote file"
27027         multiop_bg_pause $remote_file O_uc ||
27028                         error "mulitop failed for remote file"
27029         MULTIPID=$!
27030         $MULTIOP $DIR/$tfile Ouc
27031         kill -USR1 $MULTIPID
27032         wait $MULTIPID
27033 }
27034 run_test 310c "open-unlink remote file with multiple links"
27035
27036 #LU-4825
27037 test_311() {
27038         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27039         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
27040         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
27041                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
27042         remote_mds_nodsh && skip "remote MDS with nodsh"
27043
27044         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
27045         local mdts=$(comma_list $(mdts_nodes))
27046
27047         mkdir -p $DIR/$tdir
27048         $LFS setstripe -i 0 -c 1 $DIR/$tdir
27049         createmany -o $DIR/$tdir/$tfile. 1000
27050
27051         # statfs data is not real time, let's just calculate it
27052         old_iused=$((old_iused + 1000))
27053
27054         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27055                         osp.*OST0000*MDT0000.create_count")
27056         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27057                                 osp.*OST0000*MDT0000.max_create_count")
27058         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
27059
27060         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
27061         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
27062         [ $index -ne 0 ] || error "$tfile stripe index is 0"
27063
27064         unlinkmany $DIR/$tdir/$tfile. 1000
27065
27066         do_nodes $mdts "$LCTL set_param -n \
27067                         osp.*OST0000*.max_create_count=$max_count"
27068         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
27069                 do_nodes $mdts "$LCTL set_param -n \
27070                                 osp.*OST0000*.create_count=$count"
27071         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
27072                         grep "=0" && error "create_count is zero"
27073
27074         local new_iused
27075         for i in $(seq 120); do
27076                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
27077                 # system may be too busy to destroy all objs in time, use
27078                 # a somewhat small value to not fail autotest
27079                 [ $((old_iused - new_iused)) -gt 400 ] && break
27080                 sleep 1
27081         done
27082
27083         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
27084         [ $((old_iused - new_iused)) -gt 400 ] ||
27085                 error "objs not destroyed after unlink"
27086 }
27087 run_test 311 "disable OSP precreate, and unlink should destroy objs"
27088
27089 zfs_get_objid()
27090 {
27091         local ost=$1
27092         local tf=$2
27093         local fid=($($LFS getstripe $tf | grep 0x))
27094         local seq=${fid[3]#0x}
27095         local objid=${fid[1]}
27096
27097         local vdevdir=$(dirname $(facet_vdevice $ost))
27098         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
27099         local zfs_zapid=$(do_facet $ost $cmd |
27100                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
27101                           awk '/Object/{getline; print $1}')
27102         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
27103                           awk "/$objid = /"'{printf $3}')
27104
27105         echo $zfs_objid
27106 }
27107
27108 zfs_object_blksz() {
27109         local ost=$1
27110         local objid=$2
27111
27112         local vdevdir=$(dirname $(facet_vdevice $ost))
27113         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
27114         local blksz=$(do_facet $ost $cmd $objid |
27115                       awk '/dblk/{getline; printf $4}')
27116
27117         case "${blksz: -1}" in
27118                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
27119                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
27120                 *) ;;
27121         esac
27122
27123         echo $blksz
27124 }
27125
27126 test_312() { # LU-4856
27127         remote_ost_nodsh && skip "remote OST with nodsh"
27128         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
27129
27130         local max_blksz=$(do_facet ost1 \
27131                           $ZFS get -p recordsize $(facet_device ost1) |
27132                           awk '!/VALUE/{print $3}')
27133         local tf=$DIR/$tfile
27134
27135         $LFS setstripe -c1 $tf
27136         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
27137
27138         # Get ZFS object id
27139         local zfs_objid=$(zfs_get_objid $facet $tf)
27140         # block size change by sequential overwrite
27141         local bs
27142
27143         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
27144                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
27145
27146                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
27147                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
27148         done
27149         rm -f $tf
27150
27151         $LFS setstripe -c1 $tf
27152         facet="ost$(($($LFS getstripe -i $tf) + 1))"
27153
27154         # block size change by sequential append write
27155         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
27156         zfs_objid=$(zfs_get_objid $facet $tf)
27157         local count
27158
27159         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
27160                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
27161                         oflag=sync conv=notrunc
27162
27163                 blksz=$(zfs_object_blksz $facet $zfs_objid)
27164                 (( $blksz == 2 * count * PAGE_SIZE )) ||
27165                         error "blksz error, actual $blksz, " \
27166                                 "expected: 2 * $count * $PAGE_SIZE"
27167         done
27168         rm -f $tf
27169
27170         # random write
27171         $LFS setstripe -c1 $tf
27172         facet="ost$(($($LFS getstripe -i $tf) + 1))"
27173         zfs_objid=$(zfs_get_objid $facet $tf)
27174
27175         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
27176         blksz=$(zfs_object_blksz $facet $zfs_objid)
27177         (( blksz == PAGE_SIZE )) ||
27178                 error "blksz error: $blksz, expected: $PAGE_SIZE"
27179
27180         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
27181         blksz=$(zfs_object_blksz $facet $zfs_objid)
27182         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
27183
27184         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
27185         blksz=$(zfs_object_blksz $facet $zfs_objid)
27186         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
27187 }
27188 run_test 312 "make sure ZFS adjusts its block size by write pattern"
27189
27190 test_313() {
27191         remote_ost_nodsh && skip "remote OST with nodsh"
27192
27193         local file=$DIR/$tfile
27194
27195         rm -f $file
27196         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
27197
27198         # define OBD_FAIL_TGT_RCVD_EIO           0x720
27199         do_facet ost1 "$LCTL set_param fail_loc=0x720"
27200         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
27201                 error "write should failed"
27202         do_facet ost1 "$LCTL set_param fail_loc=0"
27203         rm -f $file
27204 }
27205 run_test 313 "io should fail after last_rcvd update fail"
27206
27207 test_314() {
27208         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
27209
27210         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
27211         do_facet ost1 "$LCTL set_param fail_loc=0x720"
27212         rm -f $DIR/$tfile
27213         wait_delete_completed
27214         do_facet ost1 "$LCTL set_param fail_loc=0"
27215 }
27216 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
27217
27218 test_315() { # LU-618
27219         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
27220
27221         local file=$DIR/$tfile
27222         rm -f $file
27223
27224         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
27225                 error "multiop file write failed"
27226         $MULTIOP $file oO_RDONLY:r4063232_c &
27227         PID=$!
27228
27229         sleep 2
27230
27231         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
27232         kill -USR1 $PID
27233
27234         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
27235         rm -f $file
27236 }
27237 run_test 315 "read should be accounted"
27238
27239 test_316() {
27240         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
27241         large_xattr_enabled || skip "ea_inode feature disabled"
27242
27243         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27244         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
27245         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
27246         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
27247
27248         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
27249 }
27250 run_test 316 "lfs migrate of file with large_xattr enabled"
27251
27252 test_317() {
27253         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
27254                 skip "Need MDS version at least 2.11.53"
27255         if [ "$ost1_FSTYPE" == "zfs" ]; then
27256                 skip "LU-10370: no implementation for ZFS"
27257         fi
27258
27259         local trunc_sz
27260         local grant_blk_size
27261
27262         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
27263                         awk '/grant_block_size:/ { print $2; exit; }')
27264         #
27265         # Create File of size 5M. Truncate it to below size's and verify
27266         # blocks count.
27267         #
27268         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
27269                 error "Create file $DIR/$tfile failed"
27270         stack_trap "rm -f $DIR/$tfile" EXIT
27271
27272         for trunc_sz in 2097152 4097 4000 509 0; do
27273                 $TRUNCATE $DIR/$tfile $trunc_sz ||
27274                         error "truncate $tfile to $trunc_sz failed"
27275                 local sz=$(stat --format=%s $DIR/$tfile)
27276                 local blk=$(stat --format=%b $DIR/$tfile)
27277                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
27278                                      grant_blk_size) * 8))
27279
27280                 if [[ $blk -ne $trunc_blk ]]; then
27281                         $(which stat) $DIR/$tfile
27282                         error "Expected Block $trunc_blk got $blk for $tfile"
27283                 fi
27284
27285                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
27286                         error "Expected Size $trunc_sz got $sz for $tfile"
27287         done
27288
27289         #
27290         # sparse file test
27291         # Create file with a hole and write actual 65536 bytes which aligned
27292         # with 4K and 64K PAGE_SIZE. Block count must be 128.
27293         #
27294         local bs=65536
27295         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
27296                 error "Create file : $DIR/$tfile"
27297
27298         #
27299         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
27300         # blocks. The block count must drop to 8.
27301         #
27302         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
27303                 ((bs - grant_blk_size) + 1)))
27304         $TRUNCATE $DIR/$tfile $trunc_sz ||
27305                 error "truncate $tfile to $trunc_sz failed"
27306
27307         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
27308         sz=$(stat --format=%s $DIR/$tfile)
27309         blk=$(stat --format=%b $DIR/$tfile)
27310
27311         if [[ $blk -ne $trunc_bsz ]]; then
27312                 $(which stat) $DIR/$tfile
27313                 error "Expected Block $trunc_bsz got $blk for $tfile"
27314         fi
27315
27316         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
27317                 error "Expected Size $trunc_sz got $sz for $tfile"
27318 }
27319 run_test 317 "Verify blocks get correctly update after truncate"
27320
27321 test_318() {
27322         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
27323         local old_max_active=$($LCTL get_param -n \
27324                             ${llite_name}.max_read_ahead_async_active \
27325                             2>/dev/null)
27326
27327         $LCTL set_param llite.*.max_read_ahead_async_active=256
27328         local max_active=$($LCTL get_param -n \
27329                            ${llite_name}.max_read_ahead_async_active \
27330                            2>/dev/null)
27331         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
27332
27333         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
27334                 error "set max_read_ahead_async_active should succeed"
27335
27336         $LCTL set_param llite.*.max_read_ahead_async_active=512
27337         max_active=$($LCTL get_param -n \
27338                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
27339         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
27340
27341         # restore @max_active
27342         [ $old_max_active -ne 0 ] && $LCTL set_param \
27343                 llite.*.max_read_ahead_async_active=$old_max_active
27344
27345         local old_threshold=$($LCTL get_param -n \
27346                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
27347         local max_per_file_mb=$($LCTL get_param -n \
27348                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
27349
27350         local invalid=$(($max_per_file_mb + 1))
27351         $LCTL set_param \
27352                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
27353                         && error "set $invalid should fail"
27354
27355         local valid=$(($invalid - 1))
27356         $LCTL set_param \
27357                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
27358                         error "set $valid should succeed"
27359         local threshold=$($LCTL get_param -n \
27360                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
27361         [ $threshold -eq $valid ] || error \
27362                 "expect threshold $valid got $threshold"
27363         $LCTL set_param \
27364                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
27365 }
27366 run_test 318 "Verify async readahead tunables"
27367
27368 test_319() {
27369         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
27370
27371         local before=$(date +%s)
27372         local evict
27373         local mdir=$DIR/$tdir
27374         local file=$mdir/xxx
27375
27376         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
27377         touch $file
27378
27379 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
27380         $LCTL set_param fail_val=5 fail_loc=0x8000032c
27381         $LFS migrate -m1 $mdir &
27382
27383         sleep 1
27384         dd if=$file of=/dev/null
27385         wait
27386         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
27387           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
27388
27389         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
27390 }
27391 run_test 319 "lost lease lock on migrate error"
27392
27393 test_350() {
27394         local mdts=$(comma_list $(mdts_nodes))
27395
27396         mkdir $DIR/$tdir || error "mkdir $DIR/$tdir failed"
27397         stack_trap "rm -r $DIR/$tdir"
27398
27399         #force 1/100 of replies to take "NID mismatch" codepath
27400         #define CFS_FAIL_MATCH_MD_NID 0xe001  CFS_FAIL_SOME 0x10000000
27401         do_nodes $mdts $LCTL set_param fail_loc=0x1000e001 fail_val=100
27402
27403         while ls -lR $DIR/$tdir > /dev/null; do :; done &
27404         stack_trap "killall -9 ls || killall -9 ls"
27405
27406         cp -a /etc $DIR/$tdir || error "cp failed"
27407 }
27408 run_test 350 "force NID mismatch path to be exercised"
27409
27410 test_360() {
27411         (( $OST1_VERSION >= $(version_code 2.15.58.96) )) ||
27412                 skip "Need OST version at least 2.15.58.96"
27413         [[ "$ost1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
27414
27415         check_set_fallocate_or_skip
27416         local param="osd-ldiskfs.delayed_unlink_mb"
27417         local old=($(do_facet ost1 "$LCTL get_param -n $param"))
27418
27419         do_facet ost1 "$LCTL set_param $param=1MiB"
27420         stack_trap "do_facet ost1 $LCTL set_param $param=${old[0]}"
27421
27422         mkdir $DIR/$tdir/
27423         do_facet ost1 $LCTL set_param debug=+inode
27424         do_facet ost1 $LCTL clear
27425         local files=100
27426
27427         for ((i = 0; i < $files; i++)); do
27428                 fallocate -l 1280k $DIR/$tdir/$tfile.$i ||
27429                         error "fallocate 1280k $DIR/$tdir/$tfile.$i failed"
27430         done
27431         local min=$(($($LFS find $DIR/$tdir --ost 0 | wc -l) / 2))
27432
27433         for ((i = 0; i < $files; i++)); do
27434                 unlink $DIR/$tdir/$tfile.$i ||
27435                         error "unlink $DIR/$tdir/$tfile.$i failed"
27436         done
27437
27438         local count=0
27439         local loop
27440
27441         for (( loop = 0; loop < 30 && count < min; loop++)); do
27442                 sleep 1
27443                 (( count += $(do_facet ost1 $LCTL dk | grep -c "delayed iput")))
27444                 echo "Count[$loop]: $count"
27445         done
27446         (( count >= min )) || error "$count < $min delayed iput after $loop s"
27447 }
27448 run_test 360 "ldiskfs unlink in a separate thread"
27449
27450 test_398a() { # LU-4198
27451         local ost1_imp=$(get_osc_import_name client ost1)
27452         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27453                          cut -d'.' -f2)
27454
27455         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27456         stack_trap "rm -f $DIR/$tfile"
27457         $LCTL set_param ldlm.namespaces.*.lru_size=clear
27458
27459         # request a new lock on client
27460         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27461
27462         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
27463         local lock_count=$($LCTL get_param -n \
27464                            ldlm.namespaces.$imp_name.lru_size)
27465         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
27466
27467         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
27468
27469         # no lock cached, should use lockless DIO and not enqueue new lock
27470         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
27471         lock_count=$($LCTL get_param -n \
27472                      ldlm.namespaces.$imp_name.lru_size)
27473         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
27474
27475         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
27476
27477         # no lock cached, should use locked DIO append
27478         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
27479                 conv=notrunc || error "DIO append failed"
27480         lock_count=$($LCTL get_param -n \
27481                      ldlm.namespaces.$imp_name.lru_size)
27482         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
27483 }
27484 run_test 398a "direct IO should cancel lock otherwise lockless"
27485
27486 test_398b() { # LU-4198
27487         local before=$(date +%s)
27488         local njobs=4
27489         local size=48
27490
27491         which fio || skip_env "no fio installed"
27492         $LFS setstripe -c -1 -S 1M $DIR/$tfile
27493         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
27494
27495         # Single page, multiple pages, stripe size, 4*stripe size
27496         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
27497                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
27498                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
27499                         --numjobs=$njobs --fallocate=none \
27500                         --iodepth=16 --allow_file_create=0 \
27501                         --size=$((size/njobs))M \
27502                         --filename=$DIR/$tfile &
27503                 bg_pid=$!
27504
27505                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
27506                 fio --name=rand-rw --rw=randrw --bs=$bsize \
27507                         --numjobs=$njobs --fallocate=none \
27508                         --iodepth=16 --allow_file_create=0 \
27509                         --size=$((size/njobs))M \
27510                         --filename=$DIR/$tfile || true
27511                 wait $bg_pid
27512         done
27513
27514         evict=$(do_facet client $LCTL get_param \
27515                 osc.$FSNAME-OST*-osc-*/state |
27516             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
27517
27518         [ -z "$evict" ] || [[ $evict -le $before ]] ||
27519                 (do_facet client $LCTL get_param \
27520                         osc.$FSNAME-OST*-osc-*/state;
27521                     error "eviction happened: $evict before:$before")
27522
27523         rm -f $DIR/$tfile
27524 }
27525 run_test 398b "DIO and buffer IO race"
27526
27527 test_398c() { # LU-4198
27528         local ost1_imp=$(get_osc_import_name client ost1)
27529         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27530                          cut -d'.' -f2)
27531
27532         which fio || skip_env "no fio installed"
27533
27534         saved_debug=$($LCTL get_param -n debug)
27535         $LCTL set_param debug=0
27536
27537         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
27538         ((size /= 1024)) # by megabytes
27539         ((size /= 2)) # write half of the OST at most
27540         [ $size -gt 40 ] && size=40 #reduce test time anyway
27541
27542         $LFS setstripe -c 1 $DIR/$tfile
27543
27544         # it seems like ldiskfs reserves more space than necessary if the
27545         # writing blocks are not mapped, so it extends the file firstly
27546         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
27547         cancel_lru_locks osc
27548
27549         # clear and verify rpc_stats later
27550         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
27551
27552         local njobs=4
27553         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
27554         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
27555                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
27556                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
27557                 --filename=$DIR/$tfile
27558         [ $? -eq 0 ] || error "fio write error"
27559
27560         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
27561                 error "Locks were requested while doing AIO"
27562
27563         # get the percentage of 1-page I/O
27564         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
27565                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
27566                 awk '{print $7}')
27567         (( $pct <= 50 )) || {
27568                 $LCTL get_param osc.${imp_name}.rpc_stats
27569                 error "$pct% of I/O are 1-page"
27570         }
27571
27572         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
27573         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
27574                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
27575                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
27576                 --filename=$DIR/$tfile
27577         [ $? -eq 0 ] || error "fio mixed read write error"
27578
27579         echo "AIO with large block size ${size}M"
27580         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
27581                 --numjobs=1 --fallocate=none --ioengine=libaio \
27582                 --iodepth=16 --allow_file_create=0 --size=${size}M \
27583                 --filename=$DIR/$tfile
27584         [ $? -eq 0 ] || error "fio large block size failed"
27585
27586         rm -f $DIR/$tfile
27587         $LCTL set_param debug="$saved_debug"
27588 }
27589 run_test 398c "run fio to test AIO"
27590
27591 test_398d() { #  LU-13846
27592         which aiocp || skip_env "no aiocp installed"
27593         local aio_file=$DIR/$tfile.aio
27594
27595         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
27596
27597         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
27598         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
27599         stack_trap "rm -f $DIR/$tfile $aio_file"
27600
27601         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
27602
27603         # test memory unaligned aio
27604         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file ||
27605                 error "unaligned aio failed"
27606         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
27607
27608         rm -f $DIR/$tfile $aio_file
27609 }
27610 run_test 398d "run aiocp to verify block size > stripe size"
27611
27612 test_398e() {
27613         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
27614         touch $DIR/$tfile.new
27615         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
27616 }
27617 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
27618
27619 test_398f() { #  LU-14687
27620         which aiocp || skip_env "no aiocp installed"
27621         local aio_file=$DIR/$tfile.aio
27622
27623         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
27624
27625         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
27626         stack_trap "rm -f $DIR/$tfile $aio_file"
27627
27628         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
27629         $LCTL set_param fail_loc=0x1418
27630         # make sure we don't crash and fail properly
27631         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
27632                 error "aio with page allocation failure succeeded"
27633         $LCTL set_param fail_loc=0
27634         diff $DIR/$tfile $aio_file
27635         [[ $? != 0 ]] || error "no diff after failed aiocp"
27636 }
27637 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
27638
27639 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
27640 # stripe and i/o size must be > stripe size
27641 # Old style synchronous DIO waits after submitting each chunk, resulting in a
27642 # single RPC in flight.  This test shows async DIO submission is working by
27643 # showing multiple RPCs in flight.
27644 test_398g() { #  LU-13798
27645         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
27646
27647         # We need to do some i/o first to acquire enough grant to put our RPCs
27648         # in flight; otherwise a new connection may not have enough grant
27649         # available
27650         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27651                 error "parallel dio failed"
27652         stack_trap "rm -f $DIR/$tfile"
27653
27654         # Reduce RPC size to 1M to avoid combination in to larger RPCs
27655         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
27656         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
27657         stack_trap "$LCTL set_param -n $pages_per_rpc"
27658
27659         # Recreate file so it's empty
27660         rm -f $DIR/$tfile
27661         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
27662         #Pause rpc completion to guarantee we see multiple rpcs in flight
27663         #define OBD_FAIL_OST_BRW_PAUSE_BULK
27664         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
27665         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
27666
27667         # Clear rpc stats
27668         $LCTL set_param osc.*.rpc_stats=c
27669
27670         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27671                 error "parallel dio failed"
27672         stack_trap "rm -f $DIR/$tfile"
27673
27674         $LCTL get_param osc.*-OST0000-*.rpc_stats
27675         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
27676                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
27677                 grep "8:" | awk '{print $8}')
27678         # We look at the "8 rpcs in flight" field, and verify A) it is present
27679         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
27680         # as expected for an 8M DIO to a file with 1M stripes.
27681         # NB: There is occasionally a mystery extra write RPC to a different
27682         # file.  I can't identify why that's happening, so we set up a margin
27683         # of 1 RPC here, ie, 8/9 RPCs at this size, or ~88%
27684         [ $pct -gt 87 ] || error "we should see 8 RPCs in flight"
27685
27686         # Verify turning off parallel dio works as expected
27687         # Clear rpc stats
27688         $LCTL set_param osc.*.rpc_stats=c
27689         $LCTL set_param llite.*.parallel_dio=0
27690         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
27691
27692         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27693                 error "dio with parallel dio disabled failed"
27694
27695         # Ideally, we would see only one RPC in flight here, but there is an
27696         # unavoidable race between i/o completion and RPC in flight counting,
27697         # so while only 1 i/o is in flight at a time, the RPC in flight counter
27698         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
27699         # So instead we just verify it's always < 8.
27700         $LCTL get_param osc.*-OST0000-*.rpc_stats
27701         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
27702                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
27703                 grep '^$' -B1 | grep . | awk '{print $1}')
27704         [ $ret != "8:" ] ||
27705                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
27706 }
27707 run_test 398g "verify parallel dio async RPC submission"
27708
27709 test_398h() { #  LU-13798
27710         local dio_file=$DIR/$tfile.dio
27711
27712         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
27713
27714         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27715         stack_trap "rm -f $DIR/$tfile $dio_file"
27716
27717         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
27718                 error "parallel dio failed"
27719         diff $DIR/$tfile $dio_file
27720         [[ $? == 0 ]] || error "file diff after aiocp"
27721 }
27722 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
27723
27724 test_398i() { #  LU-13798
27725         local dio_file=$DIR/$tfile.dio
27726
27727         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
27728
27729         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27730         stack_trap "rm -f $DIR/$tfile $dio_file"
27731
27732         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
27733         $LCTL set_param fail_loc=0x1418
27734         # make sure we don't crash and fail properly
27735         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
27736                 error "parallel dio page allocation failure succeeded"
27737         diff $DIR/$tfile $dio_file
27738         [[ $? != 0 ]] || error "no diff after failed aiocp"
27739 }
27740 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
27741
27742 test_398j() { #  LU-13798
27743         # Stripe size > RPC size but less than i/o size tests split across
27744         # stripes and RPCs for individual i/o op
27745         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
27746
27747         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
27748         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
27749         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
27750         stack_trap "$LCTL set_param -n $pages_per_rpc"
27751
27752         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27753                 error "parallel dio write failed"
27754         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
27755
27756         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
27757                 error "parallel dio read failed"
27758         diff $DIR/$tfile $DIR/$tfile.2
27759         [[ $? == 0 ]] || error "file diff after parallel dio read"
27760 }
27761 run_test 398j "test parallel dio where stripe size > rpc_size"
27762
27763 test_398k() { #  LU-13798
27764         wait_delete_completed
27765         wait_mds_ost_sync
27766
27767         # 4 stripe file; we will cause out of space on OST0
27768         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
27769
27770         # Fill OST0 (if it's not too large)
27771         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
27772                    head -n1)
27773         if [[ $ORIGFREE -gt $MAXFREE ]]; then
27774                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
27775         fi
27776         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
27777         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
27778                 error "dd should fill OST0"
27779         stack_trap "rm -f $DIR/$tfile.1"
27780
27781         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27782         err=$?
27783
27784         ls -la $DIR/$tfile
27785         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
27786                 error "file is not 0 bytes in size"
27787
27788         # dd above should not succeed, but don't error until here so we can
27789         # get debug info above
27790         [[ $err != 0 ]] ||
27791                 error "parallel dio write with enospc succeeded"
27792         stack_trap "rm -f $DIR/$tfile"
27793 }
27794 run_test 398k "test enospc on first stripe"
27795
27796 test_398l() { #  LU-13798
27797         wait_delete_completed
27798         wait_mds_ost_sync
27799
27800         # 4 stripe file; we will cause out of space on OST0
27801         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
27802         # happens on the second i/o chunk we issue
27803         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
27804
27805         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
27806         stack_trap "rm -f $DIR/$tfile"
27807
27808         # Fill OST0 (if it's not too large)
27809         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
27810                    head -n1)
27811         if [[ $ORIGFREE -gt $MAXFREE ]]; then
27812                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
27813         fi
27814         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
27815         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
27816                 error "dd should fill OST0"
27817         stack_trap "rm -f $DIR/$tfile.1"
27818
27819         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
27820         err=$?
27821         stack_trap "rm -f $DIR/$tfile.2"
27822
27823         # Check that short write completed as expected
27824         ls -la $DIR/$tfile.2
27825         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
27826                 error "file is not 1M in size"
27827
27828         # dd above should not succeed, but don't error until here so we can
27829         # get debug info above
27830         [[ $err != 0 ]] ||
27831                 error "parallel dio write with enospc succeeded"
27832
27833         # Truncate source file to same length as output file and diff them
27834         $TRUNCATE $DIR/$tfile 1048576
27835         diff $DIR/$tfile $DIR/$tfile.2
27836         [[ $? == 0 ]] || error "data incorrect after short write"
27837 }
27838 run_test 398l "test enospc on intermediate stripe/RPC"
27839
27840 test_398m() { #  LU-13798
27841         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
27842
27843         # Set up failure on OST0, the first stripe:
27844         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
27845         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
27846         # OST0 is on ost1, OST1 is on ost2.
27847         # So this fail_val specifies OST0
27848         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
27849         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
27850
27851         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
27852                 error "parallel dio write with failure on first stripe succeeded"
27853         stack_trap "rm -f $DIR/$tfile"
27854         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
27855
27856         # Place data in file for read
27857         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27858                 error "parallel dio write failed"
27859
27860         # Fail read on OST0, first stripe
27861         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
27862         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
27863         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
27864                 error "parallel dio read with error on first stripe succeeded"
27865         rm -f $DIR/$tfile.2
27866         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
27867
27868         # Switch to testing on OST1, second stripe
27869         # Clear file contents, maintain striping
27870         echo > $DIR/$tfile
27871         # Set up failure on OST1, second stripe:
27872         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
27873         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
27874
27875         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
27876                 error "parallel dio write with failure on second stripe succeeded"
27877         stack_trap "rm -f $DIR/$tfile"
27878         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
27879
27880         # Place data in file for read
27881         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27882                 error "parallel dio write failed"
27883
27884         # Fail read on OST1, second stripe
27885         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
27886         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
27887         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
27888                 error "parallel dio read with error on second stripe succeeded"
27889         rm -f $DIR/$tfile.2
27890         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
27891 }
27892 run_test 398m "test RPC failures with parallel dio"
27893
27894 # Parallel submission of DIO should not cause problems for append, but it's
27895 # important to verify.
27896 test_398n() { #  LU-13798
27897         $LFS setstripe -C 2 -S 1M $DIR/$tfile
27898
27899         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
27900                 error "dd to create source file failed"
27901         stack_trap "rm -f $DIR/$tfile"
27902
27903         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
27904                 error "parallel dio write with failure on second stripe succeeded"
27905         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
27906         diff $DIR/$tfile $DIR/$tfile.1
27907         [[ $? == 0 ]] || error "data incorrect after append"
27908
27909 }
27910 run_test 398n "test append with parallel DIO"
27911
27912 test_398o() {
27913         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
27914 }
27915 run_test 398o "right kms with DIO"
27916
27917 test_398p()
27918 {
27919         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
27920         which aiocp || skip_env "no aiocp installed"
27921
27922         local stripe_size=$((1024 * 1024)) #1 MiB
27923         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
27924         local file_size=$((25 * stripe_size))
27925
27926         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
27927         stack_trap "rm -f $DIR/$tfile*"
27928         # Just a bit bigger than the largest size in the test set below
27929         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
27930                 error "buffered i/o to create file failed"
27931
27932         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
27933                 $((stripe_size * 4)); do
27934
27935                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
27936
27937                 echo "bs: $bs, file_size $file_size"
27938                 aiocp -a $PAGE_SIZE -b $bs -s $file_size -f O_DIRECT \
27939                         $DIR/$tfile.1 $DIR/$tfile.2 &
27940                 pid_dio1=$!
27941                 # Buffered I/O with similar but not the same block size
27942                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
27943                         conv=notrunc &
27944                 pid_bio2=$!
27945                 wait $pid_dio1
27946                 rc1=$?
27947                 wait $pid_bio2
27948                 rc2=$?
27949                 if (( rc1 != 0 )); then
27950                         error "aio copy 1 w/bsize $bs failed: $rc1"
27951                 fi
27952                 if (( rc2 != 0 )); then
27953                         error "buffered copy 2 w/bsize $bs failed: $rc2"
27954                 fi
27955
27956                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
27957                         error "size incorrect"
27958                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
27959                         error "files differ, bsize $bs"
27960                 rm -f $DIR/$tfile.2
27961         done
27962 }
27963 run_test 398p "race aio with buffered i/o"
27964
27965 test_398q()
27966 {
27967         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
27968
27969         local stripe_size=$((1024 * 1024)) #1 MiB
27970         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
27971         local file_size=$((25 * stripe_size))
27972
27973         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
27974         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
27975
27976         # Just a bit bigger than the largest size in the test set below
27977         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
27978                 error "buffered i/o to create file failed"
27979
27980         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
27981                 $((stripe_size * 4)); do
27982
27983                 echo "bs: $bs, file_size $file_size"
27984                 dd if=$DIR/$tfile.1 bs=$((bs *2 )) of=$DIR/$tfile.2 \
27985                         conv=notrunc oflag=direct iflag=direct &
27986                 pid_dio1=$!
27987                 # Buffered I/O with similar but not the same block size
27988                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
27989                         conv=notrunc &
27990                 pid_bio2=$!
27991                 wait $pid_dio1
27992                 rc1=$?
27993                 wait $pid_bio2
27994                 rc2=$?
27995                 if (( rc1 != 0 )); then
27996                         error "dio copy 1 w/bsize $bs failed: $rc1"
27997                 fi
27998                 if (( rc2 != 0 )); then
27999                         error "buffered copy 2 w/bsize $bs failed: $rc2"
28000                 fi
28001
28002                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
28003                         error "size incorrect"
28004                 diff $DIR/$tfile.1 $DIR/$tfile.2 ||
28005                         error "files differ, bsize $bs"
28006         done
28007
28008         rm -f $DIR/$tfile*
28009 }
28010 run_test 398q "race dio with buffered i/o"
28011
28012 test_398r() {
28013         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
28014         echo "hello, world" > $DIR/$tfile
28015
28016         cancel_lru_locks osc
28017
28018 #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
28019         do_facet ost1 $LCTL set_param fail_loc=0x20f
28020         cat $DIR/$tfile > /dev/null && error "cat should fail"
28021         return 0
28022 }
28023 run_test 398r "i/o error on file read"
28024
28025 test_398s() {
28026         [[ $OSTCOUNT -ge 2 && "$ost1_HOST" = "$ost2_HOST" ]] ||
28027                 skip "remote OST"
28028
28029         $LFS mirror create -N -i 0 -c 1 -N -i 1 -c 1 $DIR/$tfile ||
28030                 error "mirror create failed"
28031
28032         echo "hello, world" > $DIR/$tfile
28033         $LFS mirror resync $DIR/$tfile || error "mirror resync failed"
28034
28035         cancel_lru_locks osc
28036
28037 #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
28038         do_facet ost1 $LCTL set_param fail_loc=0x20f
28039         cat $DIR/$tfile > /dev/null && error "cat should fail"
28040         return 0
28041 }
28042 run_test 398s "i/o error on mirror file read"
28043
28044 test_fake_rw() {
28045         local read_write=$1
28046         if [ "$read_write" = "write" ]; then
28047                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
28048         elif [ "$read_write" = "read" ]; then
28049                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
28050         else
28051                 error "argument error"
28052         fi
28053
28054         # turn off debug for performance testing
28055         local saved_debug=$($LCTL get_param -n debug)
28056         $LCTL set_param debug=0
28057
28058         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28059
28060         # get ost1 size - $FSNAME-OST0000
28061         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
28062         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
28063         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
28064
28065         if [ "$read_write" = "read" ]; then
28066                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
28067         fi
28068
28069         local start_time=$(date +%s.%N)
28070         $dd_cmd bs=1M count=$blocks oflag=sync ||
28071                 error "real dd $read_write error"
28072         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
28073
28074         if [ "$read_write" = "write" ]; then
28075                 rm -f $DIR/$tfile
28076         fi
28077
28078         # define OBD_FAIL_OST_FAKE_RW           0x238
28079         do_facet ost1 $LCTL set_param fail_loc=0x238
28080
28081         local start_time=$(date +%s.%N)
28082         $dd_cmd bs=1M count=$blocks oflag=sync ||
28083                 error "fake dd $read_write error"
28084         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
28085
28086         if [ "$read_write" = "write" ]; then
28087                 # verify file size
28088                 cancel_lru_locks osc
28089                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
28090                         error "$tfile size not $blocks MB"
28091         fi
28092         do_facet ost1 $LCTL set_param fail_loc=0
28093
28094         echo "fake $read_write $duration_fake vs. normal $read_write" \
28095                 "$duration in seconds"
28096         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
28097                 error_not_in_vm "fake write is slower"
28098
28099         $LCTL set_param -n debug="$saved_debug"
28100         rm -f $DIR/$tfile
28101 }
28102 test_399a() { # LU-7655 for OST fake write
28103         remote_ost_nodsh && skip "remote OST with nodsh"
28104
28105         test_fake_rw write
28106 }
28107 run_test 399a "fake write should not be slower than normal write"
28108
28109 test_399b() { # LU-8726 for OST fake read
28110         remote_ost_nodsh && skip "remote OST with nodsh"
28111         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
28112                 skip_env "ldiskfs only test"
28113         fi
28114
28115         test_fake_rw read
28116 }
28117 run_test 399b "fake read should not be slower than normal read"
28118
28119 test_400a() { # LU-1606, was conf-sanity test_74
28120         if ! which $CC > /dev/null 2>&1; then
28121                 skip_env "$CC is not installed"
28122         fi
28123
28124         local extra_flags=''
28125         local out=$TMP/$tfile
28126         local prefix=/usr/include/lustre
28127         local prog
28128
28129         # Oleg removes .c files in his test rig so test if any c files exist
28130         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
28131                 skip_env "Needed .c test files are missing"
28132
28133         if ! [[ -d $prefix ]]; then
28134                 # Assume we're running in tree and fixup the include path.
28135                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
28136                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
28137                 extra_flags+=" -L$LUSTRE/utils/.libs"
28138         fi
28139
28140         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
28141                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
28142                         error "client api broken"
28143         done
28144         rm -f $out
28145 }
28146 run_test 400a "Lustre client api program can compile and link"
28147
28148 test_400b() { # LU-1606, LU-5011
28149         local header
28150         local out=$TMP/$tfile
28151         local prefix=/usr/include/linux/lustre
28152
28153         # We use a hard coded prefix so that this test will not fail
28154         # when run in tree. There are headers in lustre/include/lustre/
28155         # that are not packaged (like lustre_idl.h) and have more
28156         # complicated include dependencies (like config.h and lnet/types.h).
28157         # Since this test about correct packaging we just skip them when
28158         # they don't exist (see below) rather than try to fixup cppflags.
28159
28160         if ! which $CC > /dev/null 2>&1; then
28161                 skip_env "$CC is not installed"
28162         fi
28163
28164         for header in $prefix/*.h; do
28165                 if ! [[ -f "$header" ]]; then
28166                         continue
28167                 fi
28168
28169                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
28170                         continue # lustre_ioctl.h is internal header
28171                 fi
28172
28173                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
28174                         error "cannot compile '$header'"
28175         done
28176         rm -f $out
28177 }
28178 run_test 400b "packaged headers can be compiled"
28179
28180 test_401a() { #LU-7437
28181         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
28182         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
28183
28184         #count the number of parameters by "list_param -R"
28185         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
28186         #count the number of parameters by listing proc files
28187         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
28188         echo "proc_dirs='$proc_dirs'"
28189         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
28190         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
28191                       sort -u | wc -l)
28192
28193         [ $params -eq $procs ] ||
28194                 error "found $params parameters vs. $procs proc files"
28195
28196         # test the list_param -D option only returns directories
28197         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
28198         #count the number of parameters by listing proc directories
28199         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
28200                 sort -u | wc -l)
28201
28202         [ $params -eq $procs ] ||
28203                 error "found $params parameters vs. $procs proc files"
28204 }
28205 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
28206
28207 test_401b() {
28208         # jobid_var may not allow arbitrary values, so use jobid_name
28209         # if available
28210         if $LCTL list_param jobid_name > /dev/null 2>&1; then
28211                 local testname=jobid_name tmp='testing%p'
28212         else
28213                 local testname=jobid_var tmp=testing
28214         fi
28215
28216         local save=$($LCTL get_param -n $testname)
28217
28218         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
28219                 error "no error returned when setting bad parameters"
28220
28221         local jobid_new=$($LCTL get_param -n foe $testname baz)
28222         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
28223
28224         $LCTL set_param -n fog=bam $testname=$save bat=fog
28225         local jobid_old=$($LCTL get_param -n foe $testname bag)
28226         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
28227 }
28228 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
28229
28230 test_401c() {
28231         # jobid_var may not allow arbitrary values, so use jobid_name
28232         # if available
28233         if $LCTL list_param jobid_name > /dev/null 2>&1; then
28234                 local testname=jobid_name
28235         else
28236                 local testname=jobid_var
28237         fi
28238
28239         local jobid_var_old=$($LCTL get_param -n $testname)
28240         local jobid_var_new
28241
28242         $LCTL set_param $testname= &&
28243                 error "no error returned for 'set_param a='"
28244
28245         jobid_var_new=$($LCTL get_param -n $testname)
28246         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
28247                 error "$testname was changed by setting without value"
28248
28249         $LCTL set_param $testname &&
28250                 error "no error returned for 'set_param a'"
28251
28252         jobid_var_new=$($LCTL get_param -n $testname)
28253         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
28254                 error "$testname was changed by setting without value"
28255 }
28256 run_test 401c "Verify 'lctl set_param' without value fails in either format."
28257
28258 test_401d() {
28259         # jobid_var may not allow arbitrary values, so use jobid_name
28260         # if available
28261         if $LCTL list_param jobid_name > /dev/null 2>&1; then
28262                 local testname=jobid_name new_value='foo=bar%p'
28263         else
28264                 local testname=jobid_var new_valuie=foo=bar
28265         fi
28266
28267         local jobid_var_old=$($LCTL get_param -n $testname)
28268         local jobid_var_new
28269
28270         $LCTL set_param $testname=$new_value ||
28271                 error "'set_param a=b' did not accept a value containing '='"
28272
28273         jobid_var_new=$($LCTL get_param -n $testname)
28274         [[ "$jobid_var_new" == "$new_value" ]] ||
28275                 error "'set_param a=b' failed on a value containing '='"
28276
28277         # Reset the $testname to test the other format
28278         $LCTL set_param $testname=$jobid_var_old
28279         jobid_var_new=$($LCTL get_param -n $testname)
28280         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
28281                 error "failed to reset $testname"
28282
28283         $LCTL set_param $testname $new_value ||
28284                 error "'set_param a b' did not accept a value containing '='"
28285
28286         jobid_var_new=$($LCTL get_param -n $testname)
28287         [[ "$jobid_var_new" == "$new_value" ]] ||
28288                 error "'set_param a b' failed on a value containing '='"
28289
28290         $LCTL set_param $testname $jobid_var_old
28291         jobid_var_new=$($LCTL get_param -n $testname)
28292         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
28293                 error "failed to reset $testname"
28294 }
28295 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
28296
28297 test_401e() { # LU-14779
28298         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
28299                 error "lctl list_param MGC* failed"
28300         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
28301         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
28302                 error "lctl get_param lru_size failed"
28303 }
28304 run_test 401e "verify 'lctl get_param' works with NID in parameter"
28305
28306 test_402() {
28307         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
28308         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
28309                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
28310         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
28311                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
28312                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
28313         remote_mds_nodsh && skip "remote MDS with nodsh"
28314
28315         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
28316 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
28317         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
28318         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
28319                 echo "Touch failed - OK"
28320 }
28321 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
28322
28323 test_403() {
28324         local file1=$DIR/$tfile.1
28325         local file2=$DIR/$tfile.2
28326         local tfile=$TMP/$tfile
28327
28328         rm -f $file1 $file2 $tfile
28329
28330         touch $file1
28331         ln $file1 $file2
28332
28333         # 30 sec OBD_TIMEOUT in ll_getattr()
28334         # right before populating st_nlink
28335         $LCTL set_param fail_loc=0x80001409
28336         stat -c %h $file1 > $tfile &
28337
28338         # create an alias, drop all locks and reclaim the dentry
28339         < $file2
28340         cancel_lru_locks mdc
28341         cancel_lru_locks osc
28342         sysctl -w vm.drop_caches=2
28343
28344         wait
28345
28346         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
28347
28348         rm -f $tfile $file1 $file2
28349 }
28350 run_test 403 "i_nlink should not drop to zero due to aliasing"
28351
28352 test_404() { # LU-6601
28353         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
28354                 skip "Need server version newer than 2.8.52"
28355         remote_mds_nodsh && skip "remote MDS with nodsh"
28356
28357         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
28358                 awk '/osp .*-osc-MDT/ { print $4}')
28359
28360         local osp
28361         for osp in $mosps; do
28362                 echo "Deactivate: " $osp
28363                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
28364                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
28365                         awk -vp=$osp '$4 == p { print $2 }')
28366                 [ $stat = IN ] || {
28367                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
28368                         error "deactivate error"
28369                 }
28370                 echo "Activate: " $osp
28371                 do_facet $SINGLEMDS $LCTL --device %$osp activate
28372                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
28373                         awk -vp=$osp '$4 == p { print $2 }')
28374                 [ $stat = UP ] || {
28375                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
28376                         error "activate error"
28377                 }
28378         done
28379 }
28380 run_test 404 "validate manual {de}activated works properly for OSPs"
28381
28382 test_405() {
28383         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
28384         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
28385                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
28386                         skip "Layout swap lock is not supported"
28387
28388         check_swap_layouts_support
28389         check_swap_layout_no_dom $DIR
28390
28391         test_mkdir $DIR/$tdir
28392         swap_lock_test -d $DIR/$tdir ||
28393                 error "One layout swap locked test failed"
28394 }
28395 run_test 405 "Various layout swap lock tests"
28396
28397 test_406() {
28398         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
28399         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
28400         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
28401         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28402         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
28403                 skip "Need MDS version at least 2.8.50"
28404
28405         local def_stripe_size=$($LFS getstripe -S $MOUNT)
28406         local test_pool=$TESTNAME
28407
28408         pool_add $test_pool || error "pool_add failed"
28409         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
28410                 error "pool_add_targets failed"
28411
28412         save_layout_restore_at_exit $MOUNT
28413
28414         # parent set default stripe count only, child will stripe from both
28415         # parent and fs default
28416         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
28417                 error "setstripe $MOUNT failed"
28418         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
28419         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
28420         for i in $(seq 10); do
28421                 local f=$DIR/$tdir/$tfile.$i
28422                 touch $f || error "touch failed"
28423                 local count=$($LFS getstripe -c $f)
28424                 [ $count -eq $OSTCOUNT ] ||
28425                         error "$f stripe count $count != $OSTCOUNT"
28426                 local offset=$($LFS getstripe -i $f)
28427                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
28428                 local size=$($LFS getstripe -S $f)
28429                 [ $size -eq $((def_stripe_size * 2)) ] ||
28430                         error "$f stripe size $size != $((def_stripe_size * 2))"
28431                 local pool=$($LFS getstripe -p $f)
28432                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
28433         done
28434
28435         # change fs default striping, delete parent default striping, now child
28436         # will stripe from new fs default striping only
28437         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
28438                 error "change $MOUNT default stripe failed"
28439         $LFS setstripe -c 0 $DIR/$tdir ||
28440                 error "delete $tdir default stripe failed"
28441         for i in $(seq 11 20); do
28442                 local f=$DIR/$tdir/$tfile.$i
28443                 touch $f || error "touch $f failed"
28444                 local count=$($LFS getstripe -c $f)
28445                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
28446                 local offset=$($LFS getstripe -i $f)
28447                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
28448                 local size=$($LFS getstripe -S $f)
28449                 [ $size -eq $def_stripe_size ] ||
28450                         error "$f stripe size $size != $def_stripe_size"
28451                 local pool=$($LFS getstripe -p $f)
28452                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
28453         done
28454
28455         unlinkmany $DIR/$tdir/$tfile. 1 20
28456
28457         local f=$DIR/$tdir/$tfile
28458         pool_remove_all_targets $test_pool $f
28459         pool_remove $test_pool $f
28460 }
28461 run_test 406 "DNE support fs default striping"
28462
28463 test_407() {
28464         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
28465         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
28466                 skip "Need MDS version at least 2.8.55"
28467         remote_mds_nodsh && skip "remote MDS with nodsh"
28468
28469         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
28470                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
28471         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
28472                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
28473         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
28474
28475         #define OBD_FAIL_DT_TXN_STOP    0x2019
28476         for idx in $(seq $MDSCOUNT); do
28477                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
28478         done
28479         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
28480         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
28481                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
28482         true
28483 }
28484 run_test 407 "transaction fail should cause operation fail"
28485
28486 test_408() {
28487         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
28488
28489         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
28490         lctl set_param fail_loc=0x8000040a
28491         # let ll_prepare_partial_page() fail
28492         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
28493
28494         rm -f $DIR/$tfile
28495
28496         # create at least 100 unused inodes so that
28497         # shrink_icache_memory(0) should not return 0
28498         touch $DIR/$tfile-{0..100}
28499         rm -f $DIR/$tfile-{0..100}
28500         sync
28501
28502         echo 2 > /proc/sys/vm/drop_caches
28503 }
28504 run_test 408 "drop_caches should not hang due to page leaks"
28505
28506 test_409()
28507 {
28508         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28509
28510         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
28511         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
28512         touch $DIR/$tdir/guard || error "(2) Fail to create"
28513
28514         local PREFIX=$(str_repeat 'A' 128)
28515         echo "Create 1K hard links start at $(date)"
28516         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
28517                 error "(3) Fail to hard link"
28518
28519         echo "Links count should be right although linkEA overflow"
28520         stat $DIR/$tdir/guard || error "(4) Fail to stat"
28521         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
28522         [ $linkcount -eq 1001 ] ||
28523                 error "(5) Unexpected hard links count: $linkcount"
28524
28525         echo "List all links start at $(date)"
28526         ls -l $DIR/$tdir/foo > /dev/null ||
28527                 error "(6) Fail to list $DIR/$tdir/foo"
28528
28529         echo "Unlink hard links start at $(date)"
28530         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
28531                 error "(7) Fail to unlink"
28532         echo "Unlink hard links finished at $(date)"
28533 }
28534 run_test 409 "Large amount of cross-MDTs hard links on the same file"
28535
28536 test_410()
28537 {
28538         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
28539                 skip "Need client version at least 2.9.59"
28540
28541         # Create a file, and stat it from the kernel
28542         local testfile=$DIR/$tfile
28543         touch $testfile
28544
28545         local run_id=$RANDOM
28546         local my_ino=$(stat --format "%i" $testfile)
28547
28548         # Try to insert the module.
28549         load_module kunit/kinode run_id=$run_id fname=$testfile ||
28550                 error "load_module failed"
28551
28552         # Anything but success is a test failure
28553         dmesg | grep -q \
28554             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
28555             error "no inode match"
28556
28557         # Remove the test module
28558         rmmod -v kinode ||
28559                 error "rmmod failed (may trigger a failure in a later test)"
28560 }
28561 run_test 410 "Test inode number returned from kernel thread"
28562
28563 cleanup_test411_cgroup() {
28564         trap 0
28565         cat $1/memory.stat
28566         rmdir "$1"
28567 }
28568
28569 test_411a() {
28570         local cg_basedir=/sys/fs/cgroup/memory
28571         # LU-9966
28572         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
28573                 skip "no setup for cgroup"
28574
28575         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
28576                 error "test file creation failed"
28577         cancel_lru_locks osc
28578
28579         # Create a very small memory cgroup to force a slab allocation error
28580         local cgdir=$cg_basedir/osc_slab_alloc
28581         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
28582         trap "cleanup_test411_cgroup $cgdir" EXIT
28583         echo 2M > $cgdir/memory.kmem.limit_in_bytes
28584         echo 1M > $cgdir/memory.limit_in_bytes
28585
28586         # Should not LBUG, just be killed by oom-killer
28587         # dd will return 0 even allocation failure in some environment.
28588         # So don't check return value
28589         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
28590         cleanup_test411_cgroup $cgdir
28591
28592         return 0
28593 }
28594 run_test 411a "Slab allocation error with cgroup does not LBUG"
28595
28596 test_411b() {
28597         local cg_basedir=/sys/fs/cgroup/memory
28598         # LU-9966
28599         [ -e "$cg_basedir/memory.kmem.limit_in_bytes" ] ||
28600                 skip "no setup for cgroup"
28601         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
28602         # (x86) testing suggests we can't reliably avoid OOM with a 64M-256M
28603         # limit, so we have 384M in cgroup
28604         # (arm) this seems to hit OOM more often than x86, so 1024M
28605         if [[ $(uname -m) = aarch64 ]]; then
28606                 local memlimit_mb=1024
28607         else
28608                 local memlimit_mb=384
28609         fi
28610
28611         # Create a cgroup and set memory limit
28612         # (tfile is used as an easy way to get a recognizable cgroup name)
28613         local cgdir=$cg_basedir/$tfile
28614         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
28615         stack_trap "cleanup_test411_cgroup $cgdir" EXIT
28616         echo $((memlimit_mb * 1024 * 1024)) > $cgdir/memory.limit_in_bytes
28617
28618         echo "writing first file"
28619         # Write a file 4x the memory limit in size
28620         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=1M count=$((memlimit_mb * 4))" ||
28621                 error "(1) failed to write successfully"
28622
28623         sync
28624         cancel_lru_locks osc
28625
28626         rm -f $DIR/$tfile
28627         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
28628
28629         # Try writing at a larger block size
28630         # NB: if block size is >= 1/2 cgroup size, we sometimes get OOM killed
28631         # so test with 1/4 cgroup size (this seems reasonable to me - we do
28632         # need *some* memory to do IO in)
28633         echo "writing at larger block size"
28634         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=64M count=$((memlimit_mb * 4 / 128))" ||
28635                 error "(3) failed to write successfully"
28636
28637         sync
28638         cancel_lru_locks osc
28639         rm -f $DIR/$tfile
28640         $LFS setstripe -c 2 $DIR/$tfile.{1..4} || error "unable to setstripe"
28641
28642         # Try writing multiple files at once
28643         echo "writing multiple files"
28644         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.1 bs=32M count=$((memlimit_mb * 4 / 64))" &
28645         local pid1=$!
28646         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.2 bs=32M count=$((memlimit_mb * 4 / 64))" &
28647         local pid2=$!
28648         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.3 bs=32M count=$((memlimit_mb * 4 / 64))" &
28649         local pid3=$!
28650         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.4 bs=32M count=$((memlimit_mb * 4 / 64))" &
28651         local pid4=$!
28652
28653         wait $pid1
28654         local rc1=$?
28655         wait $pid2
28656         local rc2=$?
28657         wait $pid3
28658         local rc3=$?
28659         wait $pid4
28660         local rc4=$?
28661         if (( rc1 != 0)); then
28662                 error "error $rc1 writing to file from $pid1"
28663         fi
28664         if (( rc2 != 0)); then
28665                 error "error $rc2 writing to file from $pid2"
28666         fi
28667         if (( rc3 != 0)); then
28668                 error "error $rc3 writing to file from $pid3"
28669         fi
28670         if (( rc4 != 0)); then
28671                 error "error $rc4 writing to file from $pid4"
28672         fi
28673
28674         sync
28675         cancel_lru_locks osc
28676
28677         # These files can be large-ish (~1 GiB total), so delete them rather
28678         # than leave for later cleanup
28679         rm -f $DIR/$tfile.*
28680         return 0
28681 }
28682 run_test 411b "confirm Lustre can avoid OOM with reasonable cgroups limits"
28683
28684 test_412() {
28685         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
28686         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
28687                 skip "Need server version at least 2.10.55"
28688
28689         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
28690                 error "mkdir failed"
28691         $LFS getdirstripe $DIR/$tdir
28692         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
28693         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
28694                 error "expect $((MDSCOUT - 1)) get $stripe_index"
28695         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
28696         [ $stripe_count -eq 2 ] ||
28697                 error "expect 2 get $stripe_count"
28698
28699         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
28700
28701         local index
28702         local index2
28703
28704         # subdirs should be on the same MDT as parent
28705         for i in $(seq 0 $((MDSCOUNT - 1))); do
28706                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
28707                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
28708                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
28709                 (( index == i )) || error "mdt$i/sub on MDT$index"
28710         done
28711
28712         # stripe offset -1, ditto
28713         for i in {1..10}; do
28714                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
28715                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
28716                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
28717                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
28718                 (( index == index2 )) ||
28719                         error "qos$i on MDT$index, sub on MDT$index2"
28720         done
28721
28722         local testdir=$DIR/$tdir/inherit
28723
28724         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
28725         # inherit 2 levels
28726         for i in 1 2; do
28727                 testdir=$testdir/s$i
28728                 mkdir $testdir || error "mkdir $testdir failed"
28729                 index=$($LFS getstripe -m $testdir)
28730                 (( index == 1 )) ||
28731                         error "$testdir on MDT$index"
28732         done
28733
28734         # not inherit any more
28735         testdir=$testdir/s3
28736         mkdir $testdir || error "mkdir $testdir failed"
28737         getfattr -d -m dmv $testdir | grep dmv &&
28738                 error "default LMV set on $testdir" || true
28739 }
28740 run_test 412 "mkdir on specific MDTs"
28741
28742 TEST413_COUNT=${TEST413_COUNT:-200}
28743
28744 #
28745 # set_maxage() is used by test_413 only.
28746 # This is a helper function to set maxage. Does not return any value.
28747 # Input: maxage to set
28748 #
28749 set_maxage() {
28750         local lmv_qos_maxage
28751         local lod_qos_maxage
28752         local new_maxage=$1
28753
28754         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
28755         $LCTL set_param lmv.*.qos_maxage=$new_maxage
28756         stack_trap "$LCTL set_param \
28757                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
28758         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
28759                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
28760         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28761                 lod.*.mdt_qos_maxage=$new_maxage
28762         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28763                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
28764 }
28765
28766 generate_uneven_mdts() {
28767         local threshold=$1
28768         local ffree
28769         local bavail
28770         local max
28771         local min
28772         local max_index
28773         local min_index
28774         local tmp
28775         local i
28776
28777         echo
28778         echo "Check for uneven MDTs: "
28779
28780         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28781         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28782         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28783
28784         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28785         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28786         max_index=0
28787         min_index=0
28788         for ((i = 1; i < ${#ffree[@]}; i++)); do
28789                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28790                 if [ $tmp -gt $max ]; then
28791                         max=$tmp
28792                         max_index=$i
28793                 fi
28794                 if [ $tmp -lt $min ]; then
28795                         min=$tmp
28796                         min_index=$i
28797                 fi
28798         done
28799
28800         (( min > 0 )) || skip "low space on MDT$min_index"
28801         (( ${ffree[min_index]} > 0 )) ||
28802                 skip "no free files on MDT$min_index"
28803         (( ${ffree[min_index]} < 10000000 )) ||
28804                 skip "too many free files on MDT$min_index"
28805
28806         # Check if we need to generate uneven MDTs
28807         local diff=$(((max - min) * 100 / min))
28808         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
28809         local testdir # individual folder within $testdirp
28810         local start
28811         local cmd
28812
28813         # fallocate is faster to consume space on MDT, if available
28814         if check_fallocate_supported mds$((min_index + 1)); then
28815                 cmd="fallocate -l 128K "
28816         else
28817                 cmd="dd if=/dev/zero bs=128K count=1 of="
28818         fi
28819
28820         echo "using cmd $cmd"
28821         for (( i = 0; diff < threshold; i++ )); do
28822                 testdir=${testdirp}/$i
28823                 [ -d $testdir ] && continue
28824
28825                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
28826
28827                 mkdir -p $testdirp
28828                 # generate uneven MDTs, create till $threshold% diff
28829                 echo -n "weight diff=$diff% must be > $threshold% ..."
28830                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
28831                 $LFS mkdir -i $min_index $testdir ||
28832                         error "mkdir $testdir failed"
28833                 $LFS setstripe -E 1M -L mdt $testdir ||
28834                         error "setstripe $testdir failed"
28835                 start=$SECONDS
28836                 for (( f = 0; f < TEST413_COUNT; f++ )); do
28837                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
28838                 done
28839                 sync; sleep 1; sync
28840
28841                 # wait for QOS to update
28842                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
28843
28844                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
28845                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
28846                 max=$(((${ffree[max_index]} >> 8) *
28847                         (${bavail[max_index]} * bsize >> 16)))
28848                 min=$(((${ffree[min_index]} >> 8) *
28849                         (${bavail[min_index]} * bsize >> 16)))
28850                 (( min > 0 )) || skip "low space on MDT$min_index"
28851                 diff=$(((max - min) * 100 / min))
28852         done
28853
28854         echo "MDT filesfree available: ${ffree[*]}"
28855         echo "MDT blocks available: ${bavail[*]}"
28856         echo "weight diff=$diff%"
28857 }
28858
28859 test_qos_mkdir() {
28860         local mkdir_cmd=$1
28861         local stripe_count=$2
28862         local mdts=$(comma_list $(mdts_nodes))
28863
28864         local testdir
28865         local lmv_qos_prio_free
28866         local lmv_qos_threshold_rr
28867         local lod_qos_prio_free
28868         local lod_qos_threshold_rr
28869         local total
28870         local count
28871         local i
28872
28873         # @total is total directories created if it's testing plain
28874         # directories, otherwise it's total stripe object count for
28875         # striped directories test.
28876         # remote/striped directory unlinking is slow on zfs and may
28877         # timeout, test with fewer directories
28878         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
28879
28880         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
28881         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
28882         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
28883                 head -n1)
28884         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
28885         stack_trap "$LCTL set_param \
28886                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
28887         stack_trap "$LCTL set_param \
28888                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
28889
28890         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
28891                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
28892         lod_qos_prio_free=${lod_qos_prio_free%%%}
28893         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
28894                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
28895         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
28896         stack_trap "do_nodes $mdts $LCTL set_param \
28897                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
28898         stack_trap "do_nodes $mdts $LCTL set_param \
28899                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
28900
28901         # decrease statfs age, so that it can be updated in time
28902         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
28903         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
28904
28905         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
28906         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
28907
28908         testdir=$DIR/$tdir-s$stripe_count/rr
28909
28910         local stripe_index=$($LFS getstripe -m $testdir)
28911         local test_mkdir_rr=true
28912
28913         getfattr -d -m dmv -e hex $testdir | grep dmv
28914         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
28915                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
28916                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
28917                         test_mkdir_rr=false
28918         fi
28919
28920         echo
28921         $test_mkdir_rr &&
28922                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
28923                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
28924
28925         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
28926         for (( i = 0; i < total / stripe_count; i++ )); do
28927                 eval $mkdir_cmd $testdir/subdir$i ||
28928                         error "$mkdir_cmd subdir$i failed"
28929         done
28930
28931         for (( i = 0; i < $MDSCOUNT; i++ )); do
28932                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
28933                 echo "$count directories created on MDT$i"
28934                 if $test_mkdir_rr; then
28935                         (( count == total / stripe_count / MDSCOUNT )) ||
28936                                 error "subdirs are not evenly distributed"
28937                 elif (( i == stripe_index )); then
28938                         (( count == total / stripe_count )) ||
28939                                 error "$count subdirs created on MDT$i"
28940                 else
28941                         (( count == 0 )) ||
28942                                 error "$count subdirs created on MDT$i"
28943                 fi
28944
28945                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
28946                         count=$($LFS getdirstripe $testdir/* |
28947                                 grep -c -P "^\s+$i\t")
28948                         echo "$count stripes created on MDT$i"
28949                         # deviation should < 5% of average
28950                         delta=$((count - total / MDSCOUNT))
28951                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
28952                                 error "stripes are not evenly distributed"
28953                 fi
28954         done
28955
28956         echo
28957         echo "Check for uneven MDTs: "
28958
28959         local ffree
28960         local bavail
28961         local max
28962         local min
28963         local max_index
28964         local min_index
28965         local tmp
28966
28967         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28968         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28969         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28970
28971         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28972         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28973         max_index=0
28974         min_index=0
28975         for ((i = 1; i < ${#ffree[@]}; i++)); do
28976                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28977                 if [ $tmp -gt $max ]; then
28978                         max=$tmp
28979                         max_index=$i
28980                 fi
28981                 if [ $tmp -lt $min ]; then
28982                         min=$tmp
28983                         min_index=$i
28984                 fi
28985         done
28986         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
28987
28988         (( min > 0 )) || skip "low space on MDT$min_index"
28989         (( ${ffree[min_index]} < 10000000 )) ||
28990                 skip "too many free files on MDT$min_index"
28991
28992         generate_uneven_mdts 120
28993
28994         echo "MDT filesfree available: ${ffree[*]}"
28995         echo "MDT blocks available: ${bavail[*]}"
28996         echo "weight diff=$(((max - min) * 100 / min))%"
28997         echo
28998         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
28999
29000         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
29001         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
29002         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
29003         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
29004
29005         sleep 1
29006
29007         testdir=$DIR/$tdir-s$stripe_count/qos
29008
29009         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
29010         for (( i = 0; i < total / stripe_count; i++ )); do
29011                 eval $mkdir_cmd $testdir/subdir$i ||
29012                         error "$mkdir_cmd subdir$i failed"
29013         done
29014
29015         max=0
29016         for (( i = 0; i < $MDSCOUNT; i++ )); do
29017                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
29018                 (( count > max )) && max=$count
29019                 echo "$count directories created on MDT$i : curmax=$max"
29020         done
29021
29022         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
29023
29024         # D-value should > 10% of average
29025         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
29026                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
29027
29028         # ditto for stripes
29029         if (( stripe_count > 1 )); then
29030                 max=0
29031                 for (( i = 0; i < $MDSCOUNT; i++ )); do
29032                         count=$($LFS getdirstripe $testdir/* |
29033                                 grep -c -P "^\s+$i\t")
29034                         (( count > max )) && max=$count
29035                         echo "$count stripes created on MDT$i"
29036                 done
29037
29038                 min=$($LFS getdirstripe $testdir/* |
29039                         grep -c -P "^\s+$min_index\t")
29040                 (( max - min > total / MDSCOUNT / 10 )) ||
29041                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
29042         fi
29043 }
29044
29045 most_full_mdt() {
29046         local ffree
29047         local bavail
29048         local bsize
29049         local min
29050         local min_index
29051         local tmp
29052
29053         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
29054         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
29055         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
29056
29057         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
29058         min_index=0
29059         for ((i = 1; i < ${#ffree[@]}; i++)); do
29060                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
29061                 (( tmp < min )) && min=$tmp && min_index=$i
29062         done
29063
29064         echo -n $min_index
29065 }
29066
29067 test_413a() {
29068         [ $MDSCOUNT -lt 2 ] &&
29069                 skip "We need at least 2 MDTs for this test"
29070
29071         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
29072                 skip "Need server version at least 2.12.52"
29073
29074         local stripe_max=$((MDSCOUNT - 1))
29075         local stripe_count
29076
29077         # let caller set maxage for latest result
29078         set_maxage 1
29079
29080         # fill MDT unevenly
29081         generate_uneven_mdts 120
29082
29083         # test 4-stripe directory at most, otherwise it's too slow
29084         # We are being very defensive. Although Autotest uses 4 MDTs.
29085         # We make sure stripe_max does not go over 4.
29086         (( stripe_max > 4 )) && stripe_max=4
29087         # unlinking striped directory is slow on zfs, and may timeout, only test
29088         # plain directory
29089         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
29090         for stripe_count in $(seq 1 $stripe_max); do
29091                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
29092                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
29093                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
29094                         error "mkdir failed"
29095                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
29096         done
29097 }
29098 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
29099
29100 test_413b() {
29101         [ $MDSCOUNT -lt 2 ] &&
29102                 skip "We need at least 2 MDTs for this test"
29103
29104         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
29105                 skip "Need server version at least 2.12.52"
29106
29107         local stripe_max=$((MDSCOUNT - 1))
29108         local testdir
29109         local stripe_count
29110
29111         # let caller set maxage for latest result
29112         set_maxage 1
29113
29114         # fill MDT unevenly
29115         generate_uneven_mdts 120
29116
29117         # test 4-stripe directory at most, otherwise it's too slow
29118         # We are being very defensive. Although Autotest uses 4 MDTs.
29119         # We make sure stripe_max does not go over 4.
29120         (( stripe_max > 4 )) && stripe_max=4
29121         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
29122         for stripe_count in $(seq 1 $stripe_max); do
29123                 testdir=$DIR/$tdir-s$stripe_count
29124                 mkdir $testdir || error "mkdir $testdir failed"
29125                 mkdir $testdir/rr || error "mkdir rr failed"
29126                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
29127                         error "mkdir qos failed"
29128                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
29129                         $testdir/rr || error "setdirstripe rr failed"
29130                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
29131                         error "setdirstripe failed"
29132                 test_qos_mkdir "mkdir" $stripe_count
29133         done
29134 }
29135 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
29136
29137 test_413c() {
29138         (( $MDSCOUNT >= 2 )) ||
29139                 skip "We need at least 2 MDTs for this test"
29140
29141         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
29142                 skip "Need server version at least 2.14.51"
29143
29144         local testdir
29145         local inherit
29146         local inherit_rr
29147         local lmv_qos_maxage
29148         local lod_qos_maxage
29149
29150         # let caller set maxage for latest result
29151         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
29152         $LCTL set_param lmv.*.qos_maxage=1
29153         stack_trap "$LCTL set_param \
29154                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
29155         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
29156                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
29157         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
29158                 lod.*.mdt_qos_maxage=1
29159         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
29160                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
29161
29162         # fill MDT unevenly
29163         generate_uneven_mdts 120
29164
29165         testdir=$DIR/${tdir}-s1
29166         mkdir $testdir || error "mkdir $testdir failed"
29167         mkdir $testdir/rr || error "mkdir rr failed"
29168         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
29169         # default max_inherit is -1, default max_inherit_rr is 0
29170         $LFS setdirstripe -D -c 1 $testdir/rr ||
29171                 error "setdirstripe rr failed"
29172         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
29173                 error "setdirstripe qos failed"
29174         test_qos_mkdir "mkdir" 1
29175
29176         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
29177         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
29178         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
29179         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
29180         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
29181
29182         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
29183         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
29184         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
29185         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
29186         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
29187         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
29188         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
29189                 error "level2 shouldn't have default LMV" || true
29190 }
29191 run_test 413c "mkdir with default LMV max inherit rr"
29192
29193 test_413d() {
29194         (( MDSCOUNT >= 2 )) ||
29195                 skip "We need at least 2 MDTs for this test"
29196
29197         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
29198                 skip "Need server version at least 2.14.51"
29199
29200         local lmv_qos_threshold_rr
29201
29202         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
29203                 head -n1)
29204         stack_trap "$LCTL set_param \
29205                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
29206
29207         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
29208         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
29209         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
29210                 error "$tdir shouldn't have default LMV"
29211         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
29212                 error "mkdir sub failed"
29213
29214         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
29215
29216         (( count == 100 )) || error "$count subdirs on MDT0"
29217 }
29218 run_test 413d "inherit ROOT default LMV"
29219
29220 test_413e() {
29221         (( MDSCOUNT >= 2 )) ||
29222                 skip "We need at least 2 MDTs for this test"
29223         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
29224                 skip "Need server version at least 2.14.55"
29225
29226         local testdir=$DIR/$tdir
29227         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
29228         local max_inherit
29229         local sub_max_inherit
29230
29231         mkdir -p $testdir || error "failed to create $testdir"
29232
29233         # set default max-inherit to -1 if stripe count is 0 or 1
29234         $LFS setdirstripe -D -c 1 $testdir ||
29235                 error "failed to set default LMV"
29236         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
29237         (( max_inherit == -1 )) ||
29238                 error "wrong max_inherit value $max_inherit"
29239
29240         # set default max_inherit to a fixed value if stripe count is not 0 or 1
29241         $LFS setdirstripe -D -c -1 $testdir ||
29242                 error "failed to set default LMV"
29243         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
29244         (( max_inherit > 0 )) ||
29245                 error "wrong max_inherit value $max_inherit"
29246
29247         # and the subdir will decrease the max_inherit by 1
29248         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
29249         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
29250         (( sub_max_inherit == max_inherit - 1)) ||
29251                 error "wrong max-inherit of subdir $sub_max_inherit"
29252
29253         # check specified --max-inherit and warning message
29254         stack_trap "rm -f $tmpfile"
29255         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
29256                 error "failed to set default LMV"
29257         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
29258         (( max_inherit == -1 )) ||
29259                 error "wrong max_inherit value $max_inherit"
29260
29261         # check the warning messages
29262         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
29263                 error "failed to detect warning string"
29264         fi
29265 }
29266 run_test 413e "check default max-inherit value"
29267
29268 test_fs_dmv_inherit()
29269 {
29270         local testdir=$DIR/$tdir
29271
29272         local count
29273         local inherit
29274         local inherit_rr
29275
29276         for i in 1 2; do
29277                 mkdir $testdir || error "mkdir $testdir failed"
29278                 count=$($LFS getdirstripe -D -c $testdir)
29279                 (( count == 1 )) ||
29280                         error "$testdir default LMV count mismatch $count != 1"
29281                 inherit=$($LFS getdirstripe -D -X $testdir)
29282                 (( inherit == 3 - i )) ||
29283                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
29284                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
29285                 (( inherit_rr == 3 - i )) ||
29286                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
29287                 testdir=$testdir/sub
29288         done
29289
29290         mkdir $testdir || error "mkdir $testdir failed"
29291         count=$($LFS getdirstripe -D -c $testdir)
29292         (( count == 0 )) ||
29293                 error "$testdir default LMV count not zero: $count"
29294 }
29295
29296 test_413f() {
29297         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
29298
29299         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
29300                 skip "Need server version at least 2.14.55"
29301
29302         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
29303                 error "dump $DIR default LMV failed"
29304         stack_trap "setfattr --restore=$TMP/dmv.ea"
29305
29306         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
29307                 error "set $DIR default LMV failed"
29308
29309         test_fs_dmv_inherit
29310 }
29311 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
29312
29313 test_413g() {
29314         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
29315
29316         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
29317         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
29318                 error "dump $DIR default LMV failed"
29319         stack_trap "setfattr --restore=$TMP/dmv.ea"
29320
29321         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
29322                 error "set $DIR default LMV failed"
29323
29324         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
29325                 error "mount $MOUNT2 failed"
29326         stack_trap "umount_client $MOUNT2"
29327
29328         local saved_DIR=$DIR
29329
29330         export DIR=$MOUNT2
29331
29332         stack_trap "export DIR=$saved_DIR"
29333
29334         # first check filesystem-wide default LMV inheritance
29335         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
29336
29337         # then check subdirs are spread to all MDTs
29338         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
29339
29340         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
29341
29342         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
29343 }
29344 run_test 413g "enforce ROOT default LMV on subdir mount"
29345
29346 test_413h() {
29347         (( MDSCOUNT >= 2 )) ||
29348                 skip "We need at least 2 MDTs for this test"
29349
29350         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
29351                 skip "Need server version at least 2.15.50.6"
29352
29353         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
29354
29355         stack_trap "$LCTL set_param \
29356                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
29357         $LCTL set_param lmv.*.qos_maxage=1
29358
29359         local depth=5
29360         local rr_depth=4
29361         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
29362         local count=$((MDSCOUNT * 20))
29363
29364         generate_uneven_mdts 50
29365
29366         mkdir -p $dir || error "mkdir $dir failed"
29367         stack_trap "rm -rf $dir"
29368         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
29369                 --max-inherit-rr=$rr_depth $dir
29370
29371         for ((d=0; d < depth + 2; d++)); do
29372                 log "dir=$dir:"
29373                 for ((sub=0; sub < count; sub++)); do
29374                         mkdir $dir/d$sub
29375                 done
29376                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
29377                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
29378                 # subdirs within $rr_depth should be created round-robin
29379                 if (( d < rr_depth )); then
29380                         (( ${num[0]} != count )) ||
29381                                 error "all objects created on MDT ${num[1]}"
29382                 fi
29383
29384                 dir=$dir/d0
29385         done
29386 }
29387 run_test 413h "don't stick to parent for round-robin dirs"
29388
29389 test_413i() {
29390         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
29391
29392         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
29393                 skip "Need server version at least 2.14.55"
29394
29395         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
29396                 error "dump $DIR default LMV failed"
29397         stack_trap "setfattr --restore=$TMP/dmv.ea"
29398
29399         local testdir=$DIR/$tdir
29400         local def_max_rr=1
29401         local def_max=3
29402         local count
29403
29404         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
29405                 --max-inherit-rr=$def_max_rr $DIR ||
29406                 error "set $DIR default LMV failed"
29407
29408         for i in $(seq 2 3); do
29409                 def_max=$((def_max - 1))
29410                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
29411
29412                 mkdir $testdir
29413                 # RR is decremented and keeps zeroed once exhausted
29414                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
29415                 (( count == def_max_rr )) ||
29416                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
29417
29418                 # max-inherit is decremented
29419                 count=$($LFS getdirstripe -D --max-inherit $testdir)
29420                 (( count == def_max )) ||
29421                         error_noexit "$testdir: max-inherit $count != $def_max"
29422
29423                 testdir=$testdir/d$i
29424         done
29425
29426         # d3 is the last inherited from ROOT, no inheritance anymore
29427         # i.e. no the default layout anymore
29428         mkdir -p $testdir/d4/d5
29429         count=$($LFS getdirstripe -D --max-inherit $testdir)
29430         (( count == -1 )) ||
29431                 error_noexit "$testdir: max-inherit $count != -1"
29432
29433         local p_count=$($LFS getdirstripe -i $testdir)
29434
29435         for i in $(seq 4 5); do
29436                 testdir=$testdir/d$i
29437
29438                 # the root default layout is not applied once exhausted
29439                 count=$($LFS getdirstripe -i $testdir)
29440                 (( count == p_count )) ||
29441                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
29442         done
29443
29444         $LFS setdirstripe -i 0 $DIR/d2
29445         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
29446         (( count == -1 )) ||
29447                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
29448 }
29449 run_test 413i "check default layout inheritance"
29450
29451 test_413j()
29452 {
29453         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
29454
29455         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
29456         $LFS setdirstripe -D -c2 --max-inherit=2 $DIR/$tdir ||
29457                 error "setdirstripe $tdir failed"
29458
29459         local value=$(getfattr -n trusted.dmv $DIR/$tdir | \
29460                       grep "trusted.dmv" |sed -e 's/[^=]\+=//')
29461
29462         mkdir -p $DIR/$tdir/sub || error "mkdir sub failed"
29463         # setfattr dmv calls setdirstripe -D
29464         setfattr -n trusted.dmv -v $value $DIR/$tdir/sub ||
29465                 error "setfattr sub failed"
29466         local value2=$(getfattr -n trusted.dmv $DIR/$tdir/sub | \
29467                        grep "trusted.dmv" |sed -e 's/[^=]\+=//')
29468
29469         [ $value == $value2 ] || error "dmv mismatch"
29470
29471         (( MDS1_VERSION >= $(version_code 2.15.58) )) || return 0
29472
29473         # do not allow remove dmv by setfattr -x
29474         do_nodes $(comma_list $(mdts_nodes)) \
29475                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=0"
29476         setfattr -x trusted.dmv $DIR/$tdir/sub || error "setfattr sub failed"
29477         getfattr -n trusted.dmv $DIR/$tdir/sub || error "default LMV deleted"
29478
29479         # allow remove dmv by setfattr -x
29480         do_nodes $(comma_list $(mdts_nodes)) \
29481                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=1"
29482         setfattr -x trusted.dmv $DIR/$tdir/sub || error "setfattr sub failed"
29483         getfattr -n trusted.dmv $DIR/$tdir/sub && error "default LMV exists"
29484         do_nodes $(comma_list $(mdts_nodes)) \
29485                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=0"
29486 }
29487 run_test 413j "set default LMV by setxattr"
29488
29489 test_413k() {
29490         (( $MDS1_VERSION >= $(version_code 2.15.60) )) ||
29491                 skip "Need server version at least 2.15.60"
29492
29493         local index1
29494         local index2
29495         local old=$($LCTL get_param -n lmv.*.qos_exclude_prefixes)
29496         local count=$($LCTL get_param -n lmv.*.qos_exclude_prefixes | wc -l)
29497         local prefixes="abc:123:foo bar"
29498
29499         # add prefixes
29500         stack_trap "$LCTL set_param lmv.*.qos_exclude_prefixes=\"$old\""
29501         $LCTL set_param lmv.*.qos_exclude_prefixes="+$prefixes"
29502
29503         mkdir $DIR/$tdir || error "mkdir $tdir failed"
29504         index1=$($LFS getstripe -m $DIR/$tdir)
29505         for dname in _temporary _temporary.XXXXXX abc 123 "foo bar"; do
29506                 mkdir "$DIR/$tdir/$dname" || error "mkdir $dname failed"
29507                 index2=$($LFS getstripe -m "$DIR/$tdir/$dname")
29508                 ((index1 == index2)) ||
29509                         error "$tdir on MDT$index1, $dname on MDT$index2"
29510         done
29511
29512         # remove prefixes
29513         $LCTL set_param lmv.*.qos_exclude_prefixes="-$prefixes"
29514
29515         # total prefixes length > PAGE_SIZE can be printed correctly
29516         for c in {a..z}; do
29517                 prefixes=$(str_repeat $c 255)
29518                 $LCTL set_param lmv.*.qos_exclude_prefixes="+$prefixes" >/dev/null
29519         done
29520         local count2=$($LCTL get_param -n lmv.*.qos_exclude_prefixes | wc -l)
29521         ((count2 == count + 26)) ||
29522                 error "prefixes count $count2 != $((count + 26))"
29523 }
29524 run_test 413k "QoS mkdir exclude prefixes"
29525
29526 test_413z() {
29527         local pids=""
29528         local subdir
29529         local pid
29530
29531         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
29532                 unlinkmany $subdir/f. $TEST413_COUNT &
29533                 pids="$pids $!"
29534         done
29535
29536         for pid in $pids; do
29537                 wait $pid
29538         done
29539
29540         true
29541 }
29542 run_test 413z "413 test cleanup"
29543
29544 test_414() {
29545 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
29546         $LCTL set_param fail_loc=0x80000521
29547         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
29548         rm -f $DIR/$tfile
29549 }
29550 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
29551
29552 test_415() {
29553         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
29554         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
29555                 skip "Need server version at least 2.11.52"
29556
29557         # LU-11102
29558         local total=500
29559         local max=120
29560
29561         # this test may be slow on ZFS
29562         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
29563
29564         # though this test is designed for striped directory, let's test normal
29565         # directory too since lock is always saved as CoS lock.
29566         test_mkdir $DIR/$tdir || error "mkdir $tdir"
29567         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
29568         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
29569         # if looping with ONLY_REPEAT, wait for previous deletions to finish
29570         wait_delete_completed_mds
29571
29572         # run a loop without concurrent touch to measure rename duration.
29573         # only for test debug/robustness, NOT part of COS functional test.
29574         local start_time=$SECONDS
29575         for ((i = 0; i < total; i++)); do
29576                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
29577                         > /dev/null
29578         done
29579         local baseline=$((SECONDS - start_time))
29580         echo "rename $total files without 'touch' took $baseline sec"
29581
29582         (
29583                 while true; do
29584                         touch $DIR/$tdir
29585                 done
29586         ) &
29587         local setattr_pid=$!
29588
29589         # rename files back to original name so unlinkmany works
29590         start_time=$SECONDS
29591         for ((i = 0; i < total; i++)); do
29592                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
29593                         > /dev/null
29594         done
29595         local duration=$((SECONDS - start_time))
29596
29597         kill -9 $setattr_pid
29598
29599         echo "rename $total files with 'touch' took $duration sec"
29600         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
29601         (( duration <= max )) ||
29602                 error_not_in_vm "rename took $duration > $max sec"
29603 }
29604 run_test 415 "lock revoke is not missing"
29605
29606 test_416() {
29607         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
29608                 skip "Need server version at least 2.11.55"
29609
29610         # define OBD_FAIL_OSD_TXN_START    0x19a
29611         do_facet mds1 lctl set_param fail_loc=0x19a
29612
29613         lfs mkdir -c $MDSCOUNT $DIR/$tdir
29614
29615         true
29616 }
29617 run_test 416 "transaction start failure won't cause system hung"
29618
29619 cleanup_417() {
29620         trap 0
29621         do_nodes $(comma_list $(mdts_nodes)) \
29622                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
29623         do_nodes $(comma_list $(mdts_nodes)) \
29624                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
29625         do_nodes $(comma_list $(mdts_nodes)) \
29626                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
29627 }
29628
29629 test_417() {
29630         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
29631         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
29632                 skip "Need MDS version at least 2.11.56"
29633
29634         trap cleanup_417 RETURN EXIT
29635
29636         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
29637         do_nodes $(comma_list $(mdts_nodes)) \
29638                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
29639         $LFS migrate -m 0 $DIR/$tdir.1 &&
29640                 error "migrate dir $tdir.1 should fail"
29641
29642         do_nodes $(comma_list $(mdts_nodes)) \
29643                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
29644         $LFS mkdir -i 1 $DIR/$tdir.2 &&
29645                 error "create remote dir $tdir.2 should fail"
29646
29647         do_nodes $(comma_list $(mdts_nodes)) \
29648                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
29649         $LFS mkdir -c 2 $DIR/$tdir.3 &&
29650                 error "create striped dir $tdir.3 should fail"
29651         true
29652 }
29653 run_test 417 "disable remote dir, striped dir and dir migration"
29654
29655 # Checks that the outputs of df [-i] and lfs df [-i] match
29656 #
29657 # usage: check_lfs_df <blocks | inodes> <mountpoint>
29658 check_lfs_df() {
29659         local dir=$2
29660         local inodes
29661         local df_out
29662         local lfs_df_out
29663         local count
29664         local passed=false
29665
29666         # blocks or inodes
29667         [ "$1" == "blocks" ] && inodes= || inodes="-i"
29668
29669         for count in {1..100}; do
29670                 do_nodes "$CLIENTS" \
29671                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
29672                 sync; sleep 0.2
29673
29674                 # read the lines of interest
29675                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
29676                         error "df $inodes $dir | tail -n +2 failed"
29677                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
29678                         error "lfs df $inodes $dir | grep summary: failed"
29679
29680                 # skip first substrings of each output as they are different
29681                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
29682                 # compare the two outputs
29683                 passed=true
29684                 #  skip "available" on MDT until LU-13997 is fixed.
29685                 #for i in {1..5}; do
29686                 for i in 1 2 4 5; do
29687                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
29688                 done
29689                 $passed && break
29690         done
29691
29692         if ! $passed; then
29693                 df -P $inodes $dir
29694                 echo
29695                 lfs df $inodes $dir
29696                 error "df and lfs df $1 output mismatch: "      \
29697                       "df ${inodes}: ${df_out[*]}, "            \
29698                       "lfs df ${inodes}: ${lfs_df_out[*]}"
29699         fi
29700 }
29701
29702 test_418() {
29703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29704
29705         local dir=$DIR/$tdir
29706         local numfiles=$((RANDOM % 4096 + 2))
29707         local numblocks=$((RANDOM % 256 + 1))
29708
29709         wait_delete_completed
29710         test_mkdir $dir
29711
29712         # check block output
29713         check_lfs_df blocks $dir
29714         # check inode output
29715         check_lfs_df inodes $dir
29716
29717         # create a single file and retest
29718         echo "Creating a single file and testing"
29719         createmany -o $dir/$tfile- 1 &>/dev/null ||
29720                 error "creating 1 file in $dir failed"
29721         check_lfs_df blocks $dir
29722         check_lfs_df inodes $dir
29723
29724         # create a random number of files
29725         echo "Creating $((numfiles - 1)) files and testing"
29726         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
29727                 error "creating $((numfiles - 1)) files in $dir failed"
29728
29729         # write a random number of blocks to the first test file
29730         echo "Writing $numblocks 4K blocks and testing"
29731         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
29732                 count=$numblocks &>/dev/null ||
29733                 error "dd to $dir/${tfile}-0 failed"
29734
29735         # retest
29736         check_lfs_df blocks $dir
29737         check_lfs_df inodes $dir
29738
29739         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
29740                 error "unlinking $numfiles files in $dir failed"
29741 }
29742 run_test 418 "df and lfs df outputs match"
29743
29744 test_419()
29745 {
29746         local dir=$DIR/$tdir
29747
29748         mkdir -p $dir
29749         touch $dir/file
29750
29751         cancel_lru_locks mdc
29752
29753         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
29754         $LCTL set_param fail_loc=0x1410
29755         cat $dir/file
29756         $LCTL set_param fail_loc=0
29757         rm -rf $dir
29758 }
29759 run_test 419 "Verify open file by name doesn't crash kernel"
29760
29761 test_420()
29762 {
29763         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
29764                 skip "Need MDS version at least 2.12.53"
29765
29766         local SAVE_UMASK=$(umask)
29767         local dir=$DIR/$tdir
29768         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
29769
29770         mkdir -p $dir
29771         umask 0000
29772         mkdir -m03777 $dir/testdir
29773         ls -dn $dir/testdir
29774         # Need to remove trailing '.' when SELinux is enabled
29775         local dirperms=$(ls -dn $dir/testdir |
29776                          awk '{ sub(/\.$/, "", $1); print $1}')
29777         [ $dirperms == "drwxrwsrwt" ] ||
29778                 error "incorrect perms on $dir/testdir"
29779
29780         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
29781                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
29782         ls -n $dir/testdir/testfile
29783         local fileperms=$(ls -n $dir/testdir/testfile |
29784                           awk '{ sub(/\.$/, "", $1); print $1}')
29785         [ $fileperms == "-rwxr-xr-x" ] ||
29786                 error "incorrect perms on $dir/testdir/testfile"
29787
29788         umask $SAVE_UMASK
29789 }
29790 run_test 420 "clear SGID bit on non-directories for non-members"
29791
29792 test_421a() {
29793         local cnt
29794         local fid1
29795         local fid2
29796
29797         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29798                 skip "Need MDS version at least 2.12.54"
29799
29800         test_mkdir $DIR/$tdir
29801         createmany -o $DIR/$tdir/f 3
29802         cnt=$(ls -1 $DIR/$tdir | wc -l)
29803         [ $cnt != 3 ] && error "unexpected #files: $cnt"
29804
29805         fid1=$(lfs path2fid $DIR/$tdir/f1)
29806         fid2=$(lfs path2fid $DIR/$tdir/f2)
29807         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
29808
29809         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
29810         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
29811
29812         cnt=$(ls -1 $DIR/$tdir | wc -l)
29813         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
29814
29815         rm -f $DIR/$tdir/f3 || error "can't remove f3"
29816         createmany -o $DIR/$tdir/f 3
29817         cnt=$(ls -1 $DIR/$tdir | wc -l)
29818         [ $cnt != 3 ] && error "unexpected #files: $cnt"
29819
29820         fid1=$(lfs path2fid $DIR/$tdir/f1)
29821         fid2=$(lfs path2fid $DIR/$tdir/f2)
29822         echo "remove using fsname $FSNAME"
29823         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
29824
29825         cnt=$(ls -1 $DIR/$tdir | wc -l)
29826         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
29827 }
29828 run_test 421a "simple rm by fid"
29829
29830 test_421b() {
29831         local cnt
29832         local FID1
29833         local FID2
29834
29835         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29836                 skip "Need MDS version at least 2.12.54"
29837
29838         test_mkdir $DIR/$tdir
29839         createmany -o $DIR/$tdir/f 3
29840         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
29841         MULTIPID=$!
29842
29843         FID1=$(lfs path2fid $DIR/$tdir/f1)
29844         FID2=$(lfs path2fid $DIR/$tdir/f2)
29845         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
29846
29847         kill -USR1 $MULTIPID
29848         wait
29849
29850         cnt=$(ls $DIR/$tdir | wc -l)
29851         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
29852 }
29853 run_test 421b "rm by fid on open file"
29854
29855 test_421c() {
29856         local cnt
29857         local FIDS
29858
29859         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29860                 skip "Need MDS version at least 2.12.54"
29861
29862         test_mkdir $DIR/$tdir
29863         createmany -o $DIR/$tdir/f 3
29864         touch $DIR/$tdir/$tfile
29865         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
29866         cnt=$(ls -1 $DIR/$tdir | wc -l)
29867         [ $cnt != 184 ] && error "unexpected #files: $cnt"
29868
29869         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
29870         $LFS rmfid $DIR $FID1 || error "rmfid failed"
29871
29872         cnt=$(ls $DIR/$tdir | wc -l)
29873         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
29874 }
29875 run_test 421c "rm by fid against hardlinked files"
29876
29877 test_421d() {
29878         local cnt
29879         local FIDS
29880
29881         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29882                 skip "Need MDS version at least 2.12.54"
29883
29884         test_mkdir $DIR/$tdir
29885         createmany -o $DIR/$tdir/f 4097
29886         cnt=$(ls -1 $DIR/$tdir | wc -l)
29887         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
29888
29889         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
29890         $LFS rmfid $DIR $FIDS || error "rmfid failed"
29891
29892         cnt=$(ls $DIR/$tdir | wc -l)
29893         rm -rf $DIR/$tdir
29894         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
29895 }
29896 run_test 421d "rmfid en masse"
29897
29898 test_421e() {
29899         local cnt
29900         local FID
29901
29902         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
29903         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29904                 skip "Need MDS version at least 2.12.54"
29905
29906         mkdir -p $DIR/$tdir
29907         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
29908         createmany -o $DIR/$tdir/striped_dir/f 512
29909         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
29910         [ $cnt != 512 ] && error "unexpected #files: $cnt"
29911
29912         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
29913                 sed "s/[/][^:]*://g")
29914         $LFS rmfid $DIR $FIDS || error "rmfid failed"
29915
29916         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
29917         rm -rf $DIR/$tdir
29918         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
29919 }
29920 run_test 421e "rmfid in DNE"
29921
29922 test_421f() {
29923         local cnt
29924         local FID
29925
29926         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29927                 skip "Need MDS version at least 2.12.54"
29928
29929         test_mkdir $DIR/$tdir
29930         touch $DIR/$tdir/f
29931         cnt=$(ls -1 $DIR/$tdir | wc -l)
29932         [ $cnt != 1 ] && error "unexpected #files: $cnt"
29933
29934         FID=$(lfs path2fid $DIR/$tdir/f)
29935         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
29936         # rmfid should fail
29937         cnt=$(ls -1 $DIR/$tdir | wc -l)
29938         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
29939
29940         chmod a+rw $DIR/$tdir
29941         ls -la $DIR/$tdir
29942         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
29943         # rmfid should fail
29944         cnt=$(ls -1 $DIR/$tdir | wc -l)
29945         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
29946
29947         rm -f $DIR/$tdir/f
29948         $RUNAS touch $DIR/$tdir/f
29949         FID=$(lfs path2fid $DIR/$tdir/f)
29950         echo "rmfid as root"
29951         $LFS rmfid $DIR $FID || error "rmfid as root failed"
29952         cnt=$(ls -1 $DIR/$tdir | wc -l)
29953         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
29954
29955         rm -f $DIR/$tdir/f
29956         $RUNAS touch $DIR/$tdir/f
29957         cnt=$(ls -1 $DIR/$tdir | wc -l)
29958         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
29959         FID=$(lfs path2fid $DIR/$tdir/f)
29960         # rmfid w/o user_fid2path mount option should fail
29961         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
29962         cnt=$(ls -1 $DIR/$tdir | wc -l)
29963         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
29964
29965         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
29966         stack_trap "rmdir $tmpdir"
29967         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
29968                 error "failed to mount client'"
29969         stack_trap "umount_client $tmpdir"
29970
29971         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
29972         # rmfid should succeed
29973         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
29974         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
29975
29976         # rmfid shouldn't allow to remove files due to dir's permission
29977         chmod a+rwx $tmpdir/$tdir
29978         touch $tmpdir/$tdir/f
29979         ls -la $tmpdir/$tdir
29980         FID=$(lfs path2fid $tmpdir/$tdir/f)
29981         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
29982         return 0
29983 }
29984 run_test 421f "rmfid checks permissions"
29985
29986 test_421g() {
29987         local cnt
29988         local FIDS
29989
29990         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
29991         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29992                 skip "Need MDS version at least 2.12.54"
29993
29994         mkdir -p $DIR/$tdir
29995         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
29996         createmany -o $DIR/$tdir/striped_dir/f 512
29997         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
29998         [ $cnt != 512 ] && error "unexpected #files: $cnt"
29999
30000         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
30001                 sed "s/[/][^:]*://g")
30002
30003         rm -f $DIR/$tdir/striped_dir/f1*
30004         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
30005         removed=$((512 - cnt))
30006
30007         # few files have been just removed, so we expect
30008         # rmfid to fail on their fids
30009         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
30010         [ $removed != $errors ] && error "$errors != $removed"
30011
30012         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
30013         rm -rf $DIR/$tdir
30014         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
30015 }
30016 run_test 421g "rmfid to return errors properly"
30017
30018 test_421h() {
30019         local mount_other
30020         local mount_ret
30021         local rmfid_ret
30022         local old_fid
30023         local fidA
30024         local fidB
30025         local fidC
30026         local fidD
30027
30028         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
30029                 skip "Need MDS version at least 2.15.53"
30030
30031         test_mkdir $DIR/$tdir
30032         test_mkdir $DIR/$tdir/subdir
30033         touch $DIR/$tdir/subdir/file0
30034         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
30035         echo File $DIR/$tdir/subdir/file0 FID $old_fid
30036         rm -f $DIR/$tdir/subdir/file0
30037         touch $DIR/$tdir/subdir/fileA
30038         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
30039         echo File $DIR/$tdir/subdir/fileA FID $fidA
30040         touch $DIR/$tdir/subdir/fileB
30041         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
30042         echo File $DIR/$tdir/subdir/fileB FID $fidB
30043         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
30044         touch $DIR/$tdir/subdir/fileC
30045         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
30046         echo File $DIR/$tdir/subdir/fileC FID $fidC
30047         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
30048         touch $DIR/$tdir/fileD
30049         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
30050         echo File $DIR/$tdir/fileD FID $fidD
30051
30052         # mount another client mount point with subdirectory mount
30053         export FILESET=/$tdir/subdir
30054         mount_other=${MOUNT}_other
30055         mount_client $mount_other ${MOUNT_OPTS}
30056         mount_ret=$?
30057         export FILESET=""
30058         (( mount_ret == 0 )) || error "mount $mount_other failed"
30059
30060         echo Removing FIDs:
30061         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
30062         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
30063         rmfid_ret=$?
30064
30065         umount_client $mount_other || error "umount $mount_other failed"
30066
30067         (( rmfid_ret != 0 )) || error "rmfid should have failed"
30068
30069         # fileA should have been deleted
30070         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
30071
30072         # fileB should have been deleted
30073         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
30074
30075         # fileC should not have been deleted, fid also exists outside of fileset
30076         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
30077
30078         # fileD should not have been deleted, it exists outside of fileset
30079         stat $DIR/$tdir/fileD || error "fileD deleted"
30080 }
30081 run_test 421h "rmfid with fileset mount"
30082
30083 test_422() {
30084         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
30085         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
30086         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
30087         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
30088         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
30089
30090         local amc=$(at_max_get client)
30091         local amo=$(at_max_get mds1)
30092         local timeout=`lctl get_param -n timeout`
30093
30094         at_max_set 0 client
30095         at_max_set 0 mds1
30096
30097 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
30098         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
30099                         fail_val=$(((2*timeout + 10)*1000))
30100         touch $DIR/$tdir/d3/file &
30101         sleep 2
30102 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
30103         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
30104                         fail_val=$((2*timeout + 5))
30105         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
30106         local pid=$!
30107         sleep 1
30108         kill -9 $pid
30109         sleep $((2 * timeout))
30110         echo kill $pid
30111         kill -9 $pid
30112         lctl mark touch
30113         touch $DIR/$tdir/d2/file3
30114         touch $DIR/$tdir/d2/file4
30115         touch $DIR/$tdir/d2/file5
30116
30117         wait
30118         at_max_set $amc client
30119         at_max_set $amo mds1
30120
30121         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
30122         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
30123                 error "Watchdog is always throttled"
30124 }
30125 run_test 422 "kill a process with RPC in progress"
30126
30127 stat_test() {
30128     df -h $MOUNT &
30129     df -h $MOUNT &
30130     df -h $MOUNT &
30131     df -h $MOUNT &
30132     df -h $MOUNT &
30133     df -h $MOUNT &
30134 }
30135
30136 test_423() {
30137     local _stats
30138     # ensure statfs cache is expired
30139     sleep 2;
30140
30141     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
30142     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
30143
30144     return 0
30145 }
30146 run_test 423 "statfs should return a right data"
30147
30148 test_424() {
30149 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | CFS_FAIL_ONCE
30150         $LCTL set_param fail_loc=0x80000522
30151         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
30152         rm -f $DIR/$tfile
30153 }
30154 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
30155
30156 test_425() {
30157         test_mkdir -c -1 $DIR/$tdir
30158         $LFS setstripe -c -1 $DIR/$tdir
30159
30160         lru_resize_disable "" 100
30161         stack_trap "lru_resize_enable" EXIT
30162
30163         sleep 5
30164
30165         for i in $(seq $((MDSCOUNT * 125))); do
30166                 local t=$DIR/$tdir/$tfile_$i
30167
30168                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
30169                         error_noexit "Create file $t"
30170         done
30171         stack_trap "rm -rf $DIR/$tdir" EXIT
30172
30173         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
30174                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
30175                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
30176
30177                 [ $lock_count -le $lru_size ] ||
30178                         error "osc lock count $lock_count > lru size $lru_size"
30179         done
30180
30181         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
30182                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
30183                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
30184
30185                 [ $lock_count -le $lru_size ] ||
30186                         error "mdc lock count $lock_count > lru size $lru_size"
30187         done
30188 }
30189 run_test 425 "lock count should not exceed lru size"
30190
30191 test_426() {
30192         splice-test -r $DIR/$tfile
30193         splice-test -rd $DIR/$tfile
30194         splice-test $DIR/$tfile
30195         splice-test -d $DIR/$tfile
30196 }
30197 run_test 426 "splice test on Lustre"
30198
30199 test_427() {
30200         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
30201         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
30202                 skip "Need MDS version at least 2.12.4"
30203         local log
30204
30205         mkdir $DIR/$tdir
30206         mkdir $DIR/$tdir/1
30207         mkdir $DIR/$tdir/2
30208         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
30209         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
30210
30211         $LFS getdirstripe $DIR/$tdir/1/dir
30212
30213         #first setfattr for creating updatelog
30214         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
30215
30216 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
30217         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
30218         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
30219         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
30220
30221         sleep 2
30222         fail mds2
30223         wait_recovery_complete mds2 $((2*TIMEOUT))
30224
30225         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
30226         echo $log | grep "get update log failed" &&
30227                 error "update log corruption is detected" || true
30228 }
30229 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
30230
30231 test_428() {
30232         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30233         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
30234                               awk '/^max_cached_mb/ { print $2 }')
30235         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
30236
30237         $LCTL set_param -n llite.*.max_cached_mb=64
30238
30239         mkdir $DIR/$tdir
30240         $LFS setstripe -c 1 $DIR/$tdir
30241         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
30242         stack_trap "rm -f $DIR/$tdir/$tfile.*"
30243         #test write
30244         for f in $(seq 4); do
30245                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
30246         done
30247         wait
30248
30249         cancel_lru_locks osc
30250         # Test read
30251         for f in $(seq 4); do
30252                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
30253         done
30254         wait
30255 }
30256 run_test 428 "large block size IO should not hang"
30257
30258 test_429() { # LU-7915 / LU-10948
30259         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
30260         local testfile=$DIR/$tfile
30261         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
30262         local new_flag=1
30263         local first_rpc
30264         local second_rpc
30265         local third_rpc
30266
30267         $LCTL get_param $ll_opencache_threshold_count ||
30268                 skip "client does not have opencache parameter"
30269
30270         set_opencache $new_flag
30271         stack_trap "restore_opencache"
30272         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
30273                 error "enable opencache failed"
30274         touch $testfile
30275         # drop MDC DLM locks
30276         cancel_lru_locks mdc
30277         # clear MDC RPC stats counters
30278         $LCTL set_param $mdc_rpcstats=clear
30279
30280         # According to the current implementation, we need to run 3 times
30281         # open & close file to verify if opencache is enabled correctly.
30282         # 1st, RPCs are sent for lookup/open and open handle is released on
30283         #      close finally.
30284         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
30285         #      so open handle won't be released thereafter.
30286         # 3rd, No RPC is sent out.
30287         $MULTIOP $testfile oc || error "multiop failed"
30288         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
30289         echo "1st: $first_rpc RPCs in flight"
30290
30291         $MULTIOP $testfile oc || error "multiop failed"
30292         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
30293         echo "2nd: $second_rpc RPCs in flight"
30294
30295         $MULTIOP $testfile oc || error "multiop failed"
30296         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
30297         echo "3rd: $third_rpc RPCs in flight"
30298
30299         #verify no MDC RPC is sent
30300         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
30301 }
30302 run_test 429 "verify if opencache flag on client side does work"
30303
30304 lseek_test_430() {
30305         local offset
30306         local file=$1
30307
30308         # data at [200K, 400K)
30309         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
30310                 error "256K->512K dd fails"
30311         # data at [2M, 3M)
30312         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
30313                 error "2M->3M dd fails"
30314         # data at [4M, 5M)
30315         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
30316                 error "4M->5M dd fails"
30317         echo "Data at 256K...512K, 2M...3M and 4M...5M"
30318         # start at first component hole #1
30319         printf "Seeking hole from 1000 ... "
30320         offset=$(lseek_test -l 1000 $file)
30321         echo $offset
30322         [[ $offset == 1000 ]] || error "offset $offset != 1000"
30323         printf "Seeking data from 1000 ... "
30324         offset=$(lseek_test -d 1000 $file)
30325         echo $offset
30326         [[ $offset == 262144 ]] || error "offset $offset != 262144"
30327
30328         # start at first component data block
30329         printf "Seeking hole from 300000 ... "
30330         offset=$(lseek_test -l 300000 $file)
30331         echo $offset
30332         [[ $offset == 524288 ]] || error "offset $offset != 524288"
30333         printf "Seeking data from 300000 ... "
30334         offset=$(lseek_test -d 300000 $file)
30335         echo $offset
30336         [[ $offset == 300000 ]] || error "offset $offset != 300000"
30337
30338         # start at the first component but beyond end of object size
30339         printf "Seeking hole from 1000000 ... "
30340         offset=$(lseek_test -l 1000000 $file)
30341         echo $offset
30342         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
30343         printf "Seeking data from 1000000 ... "
30344         offset=$(lseek_test -d 1000000 $file)
30345         echo $offset
30346         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
30347
30348         # start at second component stripe 2 (empty file)
30349         printf "Seeking hole from 1500000 ... "
30350         offset=$(lseek_test -l 1500000 $file)
30351         echo $offset
30352         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
30353         printf "Seeking data from 1500000 ... "
30354         offset=$(lseek_test -d 1500000 $file)
30355         echo $offset
30356         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
30357
30358         # start at second component stripe 1 (all data)
30359         printf "Seeking hole from 3000000 ... "
30360         offset=$(lseek_test -l 3000000 $file)
30361         echo $offset
30362         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
30363         printf "Seeking data from 3000000 ... "
30364         offset=$(lseek_test -d 3000000 $file)
30365         echo $offset
30366         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
30367
30368         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
30369                 error "2nd dd fails"
30370         echo "Add data block at 640K...1280K"
30371
30372         # start at before new data block, in hole
30373         printf "Seeking hole from 600000 ... "
30374         offset=$(lseek_test -l 600000 $file)
30375         echo $offset
30376         [[ $offset == 600000 ]] || error "offset $offset != 600000"
30377         printf "Seeking data from 600000 ... "
30378         offset=$(lseek_test -d 600000 $file)
30379         echo $offset
30380         [[ $offset == 655360 ]] || error "offset $offset != 655360"
30381
30382         # start at the first component new data block
30383         printf "Seeking hole from 1000000 ... "
30384         offset=$(lseek_test -l 1000000 $file)
30385         echo $offset
30386         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
30387         printf "Seeking data from 1000000 ... "
30388         offset=$(lseek_test -d 1000000 $file)
30389         echo $offset
30390         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
30391
30392         # start at second component stripe 2, new data
30393         printf "Seeking hole from 1200000 ... "
30394         offset=$(lseek_test -l 1200000 $file)
30395         echo $offset
30396         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
30397         printf "Seeking data from 1200000 ... "
30398         offset=$(lseek_test -d 1200000 $file)
30399         echo $offset
30400         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
30401
30402         # start beyond file end
30403         printf "Using offset > filesize ... "
30404         lseek_test -l 4000000 $file && error "lseek should fail"
30405         printf "Using offset > filesize ... "
30406         lseek_test -d 4000000 $file && error "lseek should fail"
30407
30408         printf "Done\n\n"
30409 }
30410
30411 test_430a() {
30412         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
30413                 skip "MDT does not support SEEK_HOLE"
30414
30415         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
30416                 skip "OST does not support SEEK_HOLE"
30417
30418         local file=$DIR/$tdir/$tfile
30419
30420         mkdir -p $DIR/$tdir
30421
30422         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
30423         # OST stripe #1 will have continuous data at [1M, 3M)
30424         # OST stripe #2 is empty
30425         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
30426         lseek_test_430 $file
30427         rm $file
30428         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
30429         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
30430         lseek_test_430 $file
30431         rm $file
30432         $LFS setstripe -c2 -S 512K $file
30433         echo "Two stripes, stripe size 512K"
30434         lseek_test_430 $file
30435         rm $file
30436         # FLR with stale mirror
30437         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
30438                        -N -c2 -S 1M $file
30439         echo "Mirrored file:"
30440         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
30441         echo "Plain 2 stripes 1M"
30442         lseek_test_430 $file
30443         rm $file
30444 }
30445 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
30446
30447 test_430b() {
30448         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
30449                 skip "OST does not support SEEK_HOLE"
30450
30451         local offset
30452         local file=$DIR/$tdir/$tfile
30453
30454         mkdir -p $DIR/$tdir
30455         # Empty layout lseek should fail
30456         $MCREATE $file
30457         # seek from 0
30458         printf "Seeking hole from 0 ... "
30459         lseek_test -l 0 $file && error "lseek should fail"
30460         printf "Seeking data from 0 ... "
30461         lseek_test -d 0 $file && error "lseek should fail"
30462         rm $file
30463
30464         # 1M-hole file
30465         $LFS setstripe -E 1M -c2 -E eof $file
30466         $TRUNCATE $file 1048576
30467         printf "Seeking hole from 1000000 ... "
30468         offset=$(lseek_test -l 1000000 $file)
30469         echo $offset
30470         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
30471         printf "Seeking data from 1000000 ... "
30472         lseek_test -d 1000000 $file && error "lseek should fail"
30473         rm $file
30474
30475         # full component followed by non-inited one
30476         $LFS setstripe -E 1M -c2 -E eof $file
30477         dd if=/dev/urandom of=$file bs=1M count=1
30478         printf "Seeking hole from 1000000 ... "
30479         offset=$(lseek_test -l 1000000 $file)
30480         echo $offset
30481         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
30482         printf "Seeking hole from 1048576 ... "
30483         lseek_test -l 1048576 $file && error "lseek should fail"
30484         # init second component and truncate back
30485         echo "123" >> $file
30486         $TRUNCATE $file 1048576
30487         printf "Seeking hole from 1000000 ... "
30488         offset=$(lseek_test -l 1000000 $file)
30489         echo $offset
30490         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
30491         printf "Seeking hole from 1048576 ... "
30492         lseek_test -l 1048576 $file && error "lseek should fail"
30493         # boundary checks for big values
30494         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
30495         offset=$(lseek_test -d 0 $file.10g)
30496         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
30497         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
30498         offset=$(lseek_test -d 0 $file.100g)
30499         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
30500         return 0
30501 }
30502 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
30503
30504 test_430c() {
30505         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
30506                 skip "OST does not support SEEK_HOLE"
30507
30508         local file=$DIR/$tdir/$tfile
30509         local start
30510
30511         mkdir -p $DIR/$tdir
30512         stack_trap "rm -f $file $file.tmp"
30513         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M || error "dd failed"
30514
30515         # cp version 8.33+ prefers lseek over fiemap
30516         local ver=$(cp --version | awk '{ print $4; exit; }')
30517
30518         echo "cp $ver installed"
30519         if (( $(version_code $ver) >= $(version_code 8.33) )); then
30520                 start=$SECONDS
30521                 time cp -v $file $file.tmp || error "cp $file failed"
30522                 (( SECONDS - start < 5 )) || {
30523                         strace cp $file $file.tmp |&
30524                                 grep -E "open|read|seek|FIEMAP" |
30525                                 grep -A 100 $file
30526                         error "cp: too long runtime $((SECONDS - start))"
30527                 }
30528         else
30529                 echo "cp test skipped due to $ver < 8.33"
30530         fi
30531
30532         # tar version 1.29+ supports SEEK_HOLE/DATA
30533         ver=$(tar --version | awk '{ print $4; exit; }')
30534         echo "tar $ver installed"
30535         if (( $(version_code $ver) >= $(version_code 1.29) )); then
30536                 start=$SECONDS
30537                 time tar cvf $file.tmp --sparse $file || error "tar $file error"
30538                 (( SECONDS - start < 5 )) || {
30539                         strace tar cf $file.tmp --sparse $file |&
30540                                 grep -E "open|read|seek|FIEMAP" |
30541                                 grep -A 100 $file
30542                         error "tar: too long runtime $((SECONDS - start))"
30543                 }
30544         else
30545                 echo "tar test skipped due to $ver < 1.29"
30546         fi
30547 }
30548 run_test 430c "lseek: external tools check"
30549
30550 test_431() { # LU-14187
30551         local file=$DIR/$tdir/$tfile
30552
30553         mkdir -p $DIR/$tdir
30554         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
30555         dd if=/dev/urandom of=$file bs=4k count=1
30556         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
30557         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
30558         #define OBD_FAIL_OST_RESTART_IO 0x251
30559         do_facet ost1 "$LCTL set_param fail_loc=0x251"
30560         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
30561         cp $file $file.0
30562         cancel_lru_locks
30563         sync_all_data
30564         echo 3 > /proc/sys/vm/drop_caches
30565         diff  $file $file.0 || error "data diff"
30566 }
30567 run_test 431 "Restart transaction for IO"
30568
30569 cleanup_test_432() {
30570         do_facet mgs $LCTL nodemap_activate 0
30571         wait_nm_sync active
30572 }
30573
30574 test_432() {
30575         local tmpdir=$TMP/dir432
30576
30577         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
30578                 skip "Need MDS version at least 2.14.52"
30579
30580         stack_trap cleanup_test_432 EXIT
30581         mkdir $DIR/$tdir
30582         mkdir $tmpdir
30583
30584         do_facet mgs $LCTL nodemap_activate 1
30585         wait_nm_sync active
30586         do_facet mgs $LCTL nodemap_modify --name default \
30587                 --property admin --value 1
30588         do_facet mgs $LCTL nodemap_modify --name default \
30589                 --property trusted --value 1
30590         cancel_lru_locks mdc
30591         wait_nm_sync default admin_nodemap
30592         wait_nm_sync default trusted_nodemap
30593
30594         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
30595                grep -ci "Operation not permitted") -ne 0 ]; then
30596                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
30597         fi
30598 }
30599 run_test 432 "mv dir from outside Lustre"
30600
30601 test_433() {
30602         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30603
30604         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
30605                 skip "inode cache not supported"
30606
30607         $LCTL set_param llite.*.inode_cache=0
30608         stack_trap "$LCTL set_param llite.*.inode_cache=1"
30609
30610         local count=256
30611         local before
30612         local after
30613
30614         cancel_lru_locks mdc
30615         test_mkdir $DIR/$tdir || error "mkdir $tdir"
30616         createmany -m $DIR/$tdir/f $count
30617         createmany -d $DIR/$tdir/d $count
30618         ls -l $DIR/$tdir > /dev/null
30619         stack_trap "rm -rf $DIR/$tdir"
30620
30621         before=$(num_objects)
30622         cancel_lru_locks mdc
30623         after=$(num_objects)
30624
30625         # sometimes even @before is less than 2 * count
30626         while (( before - after < count )); do
30627                 sleep 1
30628                 after=$(num_objects)
30629                 wait=$((wait + 1))
30630                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
30631                 if (( wait > 60 )); then
30632                         error "inode slab grew from $before to $after"
30633                 fi
30634         done
30635
30636         echo "lustre_inode_cache $before objs before lock cancel, $after after"
30637 }
30638 run_test 433 "ldlm lock cancel releases dentries and inodes"
30639
30640 test_434() {
30641         local file
30642         local getxattr_count
30643         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
30644         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30645
30646         [[ $(getenforce) == "Disabled" ]] ||
30647                 skip "lsm selinux module have to be disabled for this test"
30648
30649         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
30650                 error "fail to create $DIR/$tdir/ on MDT0000"
30651
30652         touch $DIR/$tdir/$tfile-{001..100}
30653
30654         # disable the xattr cache
30655         save_lustre_params client "llite.*.xattr_cache" > $p
30656         lctl set_param llite.*.xattr_cache=0
30657         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
30658
30659         # clear clients mdc stats
30660         clear_stats $mdc_stat_param ||
30661                 error "fail to clear stats on mdc MDT0000"
30662
30663         for file in $DIR/$tdir/$tfile-{001..100}; do
30664                 getfattr -n security.selinux $file |&
30665                         grep -q "Operation not supported" ||
30666                         error "getxattr on security.selinux should return EOPNOTSUPP"
30667         done
30668
30669         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
30670         (( getxattr_count < 100 )) ||
30671                 error "client sent $getxattr_count getxattr RPCs to the MDS"
30672 }
30673 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
30674
30675 test_440() {
30676         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
30677                 source $LUSTRE/scripts/bash-completion/lustre
30678         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
30679                 source /usr/share/bash-completion/completions/lustre
30680         else
30681                 skip "bash completion scripts not found"
30682         fi
30683
30684         local lctl_completions
30685         local lfs_completions
30686
30687         lctl_completions=$(_lustre_cmds lctl)
30688         if [[ ! $lctl_completions =~ "get_param" ]]; then
30689                 error "lctl bash completion failed"
30690         fi
30691
30692         lfs_completions=$(_lustre_cmds lfs)
30693         if [[ ! $lfs_completions =~ "setstripe" ]]; then
30694                 error "lfs bash completion failed"
30695         fi
30696 }
30697 run_test 440 "bash completion for lfs, lctl"
30698
30699 test_442() {
30700         local pid1
30701         local pid2
30702         mkdir -p $DIR/$tdir
30703         multiop $DIR/$tdir/$tfile.1 O_w1 & pid1=$!
30704         multiop $DIR/$tdir/$tfile.1 O_w1 & pid2=$!
30705         sleep 1
30706         touch $DIR/$tdir/$tfile.2
30707         $LFS swap_layouts -n $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
30708         $LCTL set_param fail_loc=0x1430
30709         kill -USR1 $pid1
30710         sleep 1
30711         kill -USR1 $pid2
30712         wait
30713 }
30714 run_test 442 "truncate vs read/write should not panic"
30715
30716 test_460d() {
30717         verify_yaml_available || skip_env "YAML verification not installed"
30718         $LCTL get_param -n sptlrpc.page_pools
30719         $LCTL get_param -n sptlrpc.page_pools | verify_yaml ||
30720                 error "The output of encrypt_page_pools is not an valid YAML"
30721 }
30722 run_test 460d "Check encrypt pools output"
30723
30724 prep_801() {
30725         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
30726         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
30727                 skip "Need server version at least 2.9.55"
30728
30729         start_full_debug_logging
30730 }
30731
30732 post_801() {
30733         stop_full_debug_logging
30734 }
30735
30736 barrier_stat() {
30737         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
30738                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
30739                            awk '/The barrier for/ { print $7 }')
30740                 echo $st
30741         else
30742                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
30743                 echo \'$st\'
30744         fi
30745 }
30746
30747 barrier_expired() {
30748         local expired
30749
30750         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
30751                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
30752                           awk '/will be expired/ { print $7 }')
30753         else
30754                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
30755         fi
30756
30757         echo $expired
30758 }
30759
30760 test_801a() {
30761         prep_801
30762
30763         echo "Start barrier_freeze at: $(date)"
30764         #define OBD_FAIL_BARRIER_DELAY          0x2202
30765         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
30766         # Do not reduce barrier time - See LU-11873
30767         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
30768
30769         sleep 2
30770         local b_status=$(barrier_stat)
30771         echo "Got barrier status at: $(date)"
30772         [ "$b_status" = "'freezing_p1'" ] ||
30773                 error "(1) unexpected barrier status $b_status"
30774
30775         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
30776         wait
30777         b_status=$(barrier_stat)
30778         [ "$b_status" = "'frozen'" ] ||
30779                 error "(2) unexpected barrier status $b_status"
30780
30781         local expired=$(barrier_expired)
30782         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
30783         sleep $((expired + 3))
30784
30785         b_status=$(barrier_stat)
30786         [ "$b_status" = "'expired'" ] ||
30787                 error "(3) unexpected barrier status $b_status"
30788
30789         # Do not reduce barrier time - See LU-11873
30790         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
30791                 error "(4) fail to freeze barrier"
30792
30793         b_status=$(barrier_stat)
30794         [ "$b_status" = "'frozen'" ] ||
30795                 error "(5) unexpected barrier status $b_status"
30796
30797         echo "Start barrier_thaw at: $(date)"
30798         #define OBD_FAIL_BARRIER_DELAY          0x2202
30799         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
30800         do_facet mgs $LCTL barrier_thaw $FSNAME &
30801
30802         sleep 2
30803         b_status=$(barrier_stat)
30804         echo "Got barrier status at: $(date)"
30805         [ "$b_status" = "'thawing'" ] ||
30806                 error "(6) unexpected barrier status $b_status"
30807
30808         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
30809         wait
30810         b_status=$(barrier_stat)
30811         [ "$b_status" = "'thawed'" ] ||
30812                 error "(7) unexpected barrier status $b_status"
30813
30814         #define OBD_FAIL_BARRIER_FAILURE        0x2203
30815         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
30816         do_facet mgs $LCTL barrier_freeze $FSNAME
30817
30818         b_status=$(barrier_stat)
30819         [ "$b_status" = "'failed'" ] ||
30820                 error "(8) unexpected barrier status $b_status"
30821
30822         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
30823         do_facet mgs $LCTL barrier_thaw $FSNAME
30824
30825         post_801
30826 }
30827 run_test 801a "write barrier user interfaces and stat machine"
30828
30829 test_801b() {
30830         prep_801
30831
30832         mkdir $DIR/$tdir || error "(1) fail to mkdir"
30833         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
30834         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
30835         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
30836         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
30837
30838         cancel_lru_locks mdc
30839
30840         # 180 seconds should be long enough
30841         do_facet mgs $LCTL barrier_freeze $FSNAME 180
30842
30843         local b_status=$(barrier_stat)
30844         [ "$b_status" = "'frozen'" ] ||
30845                 error "(6) unexpected barrier status $b_status"
30846
30847         mkdir $DIR/$tdir/d0/d10 &
30848         mkdir_pid=$!
30849
30850         touch $DIR/$tdir/d1/f13 &
30851         touch_pid=$!
30852
30853         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
30854         ln_pid=$!
30855
30856         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
30857         mv_pid=$!
30858
30859         rm -f $DIR/$tdir/d4/f12 &
30860         rm_pid=$!
30861
30862         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
30863
30864         # To guarantee taht the 'stat' is not blocked
30865         b_status=$(barrier_stat)
30866         [ "$b_status" = "'frozen'" ] ||
30867                 error "(8) unexpected barrier status $b_status"
30868
30869         # let above commands to run at background
30870         sleep 5
30871
30872         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
30873         ps -p $touch_pid || error "(10) touch should be blocked"
30874         ps -p $ln_pid || error "(11) link should be blocked"
30875         ps -p $mv_pid || error "(12) rename should be blocked"
30876         ps -p $rm_pid || error "(13) unlink should be blocked"
30877
30878         b_status=$(barrier_stat)
30879         [ "$b_status" = "'frozen'" ] ||
30880                 error "(14) unexpected barrier status $b_status"
30881
30882         do_facet mgs $LCTL barrier_thaw $FSNAME
30883         b_status=$(barrier_stat)
30884         [ "$b_status" = "'thawed'" ] ||
30885                 error "(15) unexpected barrier status $b_status"
30886
30887         wait $mkdir_pid || error "(16) mkdir should succeed"
30888         wait $touch_pid || error "(17) touch should succeed"
30889         wait $ln_pid || error "(18) link should succeed"
30890         wait $mv_pid || error "(19) rename should succeed"
30891         wait $rm_pid || error "(20) unlink should succeed"
30892
30893         post_801
30894 }
30895 run_test 801b "modification will be blocked by write barrier"
30896
30897 test_801c() {
30898         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30899
30900         prep_801
30901
30902         stop mds2 || error "(1) Fail to stop mds2"
30903
30904         do_facet mgs $LCTL barrier_freeze $FSNAME 30
30905
30906         local b_status=$(barrier_stat)
30907         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
30908                 do_facet mgs $LCTL barrier_thaw $FSNAME
30909                 error "(2) unexpected barrier status $b_status"
30910         }
30911
30912         do_facet mgs $LCTL barrier_rescan $FSNAME ||
30913                 error "(3) Fail to rescan barrier bitmap"
30914
30915         # Do not reduce barrier time - See LU-11873
30916         do_facet mgs $LCTL barrier_freeze $FSNAME 20
30917
30918         b_status=$(barrier_stat)
30919         [ "$b_status" = "'frozen'" ] ||
30920                 error "(4) unexpected barrier status $b_status"
30921
30922         do_facet mgs $LCTL barrier_thaw $FSNAME
30923         b_status=$(barrier_stat)
30924         [ "$b_status" = "'thawed'" ] ||
30925                 error "(5) unexpected barrier status $b_status"
30926
30927         local devname=$(mdsdevname 2)
30928
30929         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
30930
30931         do_facet mgs $LCTL barrier_rescan $FSNAME ||
30932                 error "(7) Fail to rescan barrier bitmap"
30933
30934         post_801
30935 }
30936 run_test 801c "rescan barrier bitmap"
30937
30938 test_802b() {
30939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30940         remote_mds_nodsh && skip "remote MDS with nodsh"
30941
30942         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
30943                 skip "readonly option not available"
30944
30945         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
30946
30947         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
30948                 error "(2) Fail to copy"
30949
30950         # write back all cached data before setting MDT to readonly
30951         cancel_lru_locks
30952         sync_all_data
30953
30954         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
30955         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
30956
30957         echo "Modify should be refused"
30958         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
30959
30960         echo "Read should be allowed"
30961         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
30962                 error "(7) Read should succeed under ro mode"
30963
30964         # disable readonly
30965         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
30966 }
30967 run_test 802b "be able to set MDTs to readonly"
30968
30969 test_803a() {
30970         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30971         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
30972                 skip "MDS needs to be newer than 2.10.54"
30973
30974         mkdir_on_mdt0 $DIR/$tdir
30975         # Create some objects on all MDTs to trigger related logs objects
30976         for idx in $(seq $MDSCOUNT); do
30977                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
30978                         $DIR/$tdir/dir${idx} ||
30979                         error "Fail to create $DIR/$tdir/dir${idx}"
30980         done
30981
30982         wait_delete_completed # ensure old test cleanups are finished
30983         sleep 3
30984         echo "before create:"
30985         $LFS df -i $MOUNT
30986         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
30987
30988         for i in {1..10}; do
30989                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
30990                         error "Fail to create $DIR/$tdir/foo$i"
30991         done
30992
30993         # sync ZFS-on-MDS to refresh statfs data
30994         wait_zfs_commit mds1
30995         sleep 3
30996         echo "after create:"
30997         $LFS df -i $MOUNT
30998         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
30999
31000         # allow for an llog to be cleaned up during the test
31001         [ $after_used -ge $((before_used + 10 - 1)) ] ||
31002                 error "before ($before_used) + 10 > after ($after_used)"
31003
31004         for i in {1..10}; do
31005                 rm -rf $DIR/$tdir/foo$i ||
31006                         error "Fail to remove $DIR/$tdir/foo$i"
31007         done
31008
31009         # sync ZFS-on-MDS to refresh statfs data
31010         wait_zfs_commit mds1
31011         wait_delete_completed
31012         sleep 3 # avoid MDT return cached statfs
31013         echo "after unlink:"
31014         $LFS df -i $MOUNT
31015         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
31016
31017         # allow for an llog to be created during the test
31018         [ $after_used -le $((before_used + 1)) ] ||
31019                 error "after ($after_used) > before ($before_used) + 1"
31020 }
31021 run_test 803a "verify agent object for remote object"
31022
31023 test_803b() {
31024         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
31025         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
31026                 skip "MDS needs to be newer than 2.13.56"
31027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31028
31029         for i in $(seq 0 $((MDSCOUNT - 1))); do
31030                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
31031         done
31032
31033         local before=0
31034         local after=0
31035
31036         local tmp
31037
31038         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
31039         for i in $(seq 0 $((MDSCOUNT - 1))); do
31040                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
31041                         awk '/getattr/ { print $2 }')
31042                 before=$((before + tmp))
31043         done
31044         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
31045         for i in $(seq 0 $((MDSCOUNT - 1))); do
31046                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
31047                         awk '/getattr/ { print $2 }')
31048                 after=$((after + tmp))
31049         done
31050
31051         [ $before -eq $after ] || error "getattr count $before != $after"
31052 }
31053 run_test 803b "remote object can getattr from cache"
31054
31055 test_804() {
31056         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
31057         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
31058                 skip "MDS needs to be newer than 2.10.54"
31059         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
31060
31061         mkdir -p $DIR/$tdir
31062         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
31063                 error "Fail to create $DIR/$tdir/dir0"
31064
31065         local fid=$($LFS path2fid $DIR/$tdir/dir0)
31066         local dev=$(mdsdevname 2)
31067
31068         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
31069                 grep ${fid} || error "NOT found agent entry for dir0"
31070
31071         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
31072                 error "Fail to create $DIR/$tdir/dir1"
31073
31074         touch $DIR/$tdir/dir1/foo0 ||
31075                 error "Fail to create $DIR/$tdir/dir1/foo0"
31076         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
31077         local rc=0
31078
31079         for idx in $(seq $MDSCOUNT); do
31080                 dev=$(mdsdevname $idx)
31081                 do_facet mds${idx} \
31082                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
31083                         grep ${fid} && rc=$idx
31084         done
31085
31086         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
31087                 error "Fail to rename foo0 to foo1"
31088         if [ $rc -eq 0 ]; then
31089                 for idx in $(seq $MDSCOUNT); do
31090                         dev=$(mdsdevname $idx)
31091                         do_facet mds${idx} \
31092                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
31093                         grep ${fid} && rc=$idx
31094                 done
31095         fi
31096
31097         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
31098                 error "Fail to rename foo1 to foo2"
31099         if [ $rc -eq 0 ]; then
31100                 for idx in $(seq $MDSCOUNT); do
31101                         dev=$(mdsdevname $idx)
31102                         do_facet mds${idx} \
31103                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
31104                         grep ${fid} && rc=$idx
31105                 done
31106         fi
31107
31108         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
31109
31110         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
31111                 error "Fail to link to $DIR/$tdir/dir1/foo2"
31112         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
31113                 error "Fail to rename foo2 to foo0"
31114         unlink $DIR/$tdir/dir1/foo0 ||
31115                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
31116         rm -rf $DIR/$tdir/dir0 ||
31117                 error "Fail to rm $DIR/$tdir/dir0"
31118
31119         for idx in $(seq $MDSCOUNT); do
31120                 rc=0
31121
31122                 stop mds${idx}
31123                 dev=$(mdsdevname $idx)
31124                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
31125                         rc=$?
31126                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
31127                         error "mount mds$idx failed"
31128                 df $MOUNT > /dev/null 2>&1
31129
31130                 # e2fsck should not return error
31131                 [ $rc -eq 0 ] ||
31132                         error "e2fsck detected error on MDT${idx}: rc=$rc"
31133         done
31134 }
31135 run_test 804 "verify agent entry for remote entry"
31136
31137 cleanup_805() {
31138         do_facet $SINGLEMDS zfs set quota=$old $fsset
31139         unlinkmany $DIR/$tdir/f- 1000000
31140         trap 0
31141 }
31142
31143 test_805() {
31144         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
31145         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
31146         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
31147                 skip "netfree not implemented before 0.7"
31148         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
31149                 skip "Need MDS version at least 2.10.57"
31150
31151         local fsset
31152         local freekb
31153         local usedkb
31154         local old
31155         local quota
31156         local pref="osd-zfs.$FSNAME-MDT0000."
31157
31158         # limit available space on MDS dataset to meet nospace issue
31159         # quickly. then ZFS 0.7.2 can use reserved space if asked
31160         # properly (using netfree flag in osd_declare_destroy()
31161         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
31162         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
31163                 gawk '{print $3}')
31164         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
31165         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
31166         let "usedkb=usedkb-freekb"
31167         let "freekb=freekb/2"
31168         if let "freekb > 5000"; then
31169                 let "freekb=5000"
31170         fi
31171         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
31172         trap cleanup_805 EXIT
31173         mkdir_on_mdt0 $DIR/$tdir
31174         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
31175                 error "Can't set PFL layout"
31176         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
31177         rm -rf $DIR/$tdir || error "not able to remove"
31178         do_facet $SINGLEMDS zfs set quota=$old $fsset
31179         trap 0
31180 }
31181 run_test 805 "ZFS can remove from full fs"
31182
31183 # Size-on-MDS test
31184 check_lsom_data()
31185 {
31186         local file=$1
31187         local expect=$(stat -c %s $file)
31188
31189         check_lsom_size $1 $expect
31190
31191         local blocks=$($LFS getsom -b $file)
31192         expect=$(stat -c %b $file)
31193         [[ $blocks == $expect ]] ||
31194                 error "$file expected blocks: $expect, got: $blocks"
31195 }
31196
31197 check_lsom_size()
31198 {
31199         local size
31200         local expect=$2
31201
31202         cancel_lru_locks mdc
31203
31204         size=$($LFS getsom -s $1)
31205         [[ $size == $expect ]] ||
31206                 error "$file expected size: $expect, got: $size"
31207 }
31208
31209 test_806() {
31210         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
31211                 skip "Need MDS version at least 2.11.52"
31212
31213         local bs=1048576
31214
31215         $LFS setstripe -c-1 $DIR/$tfile || error "setstripe $tfile failed"
31216
31217         disable_opencache
31218         stack_trap "restore_opencache"
31219
31220         # single-threaded write
31221         echo "Test SOM for single-threaded write"
31222         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
31223                 error "write $tfile failed"
31224         check_lsom_size $DIR/$tfile $bs
31225
31226         local num=32
31227         local size=$(($num * $bs))
31228         local offset=0
31229         local i
31230
31231         echo "Test SOM for single client multi-threaded($num) write"
31232         $TRUNCATE $DIR/$tfile 0
31233         for ((i = 0; i < $num; i++)); do
31234                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31235                 local pids[$i]=$!
31236                 offset=$((offset + $bs))
31237         done
31238         for (( i=0; i < $num; i++ )); do
31239                 wait ${pids[$i]}
31240         done
31241         check_lsom_size $DIR/$tfile $size
31242
31243         $TRUNCATE $DIR/$tfile 0
31244         for ((i = 0; i < $num; i++)); do
31245                 offset=$((offset - $bs))
31246                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31247                 local pids[$i]=$!
31248         done
31249         for (( i=0; i < $num; i++ )); do
31250                 wait ${pids[$i]}
31251         done
31252         check_lsom_size $DIR/$tfile $size
31253
31254         # multi-client writes
31255         num=$(get_node_count ${CLIENTS//,/ })
31256         size=$(($num * $bs))
31257         offset=0
31258         i=0
31259
31260         echo "Test SOM for multi-client ($num) writes"
31261         $TRUNCATE $DIR/$tfile 0
31262         for client in ${CLIENTS//,/ }; do
31263                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31264                 local pids[$i]=$!
31265                 i=$((i + 1))
31266                 offset=$((offset + $bs))
31267         done
31268         for (( i=0; i < $num; i++ )); do
31269                 wait ${pids[$i]}
31270         done
31271         check_lsom_size $DIR/$tfile $offset
31272
31273         i=0
31274         $TRUNCATE $DIR/$tfile 0
31275         for client in ${CLIENTS//,/ }; do
31276                 offset=$((offset - $bs))
31277                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31278                 local pids[$i]=$!
31279                 i=$((i + 1))
31280         done
31281         for (( i=0; i < $num; i++ )); do
31282                 wait ${pids[$i]}
31283         done
31284         check_lsom_size $DIR/$tfile $size
31285
31286         # verify SOM blocks count
31287         echo "Verify SOM block count"
31288         $TRUNCATE $DIR/$tfile 0
31289         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs))YSc ||
31290                 error "failed to write file $tfile with fdatasync and fstat"
31291         check_lsom_data $DIR/$tfile
31292
31293         $TRUNCATE $DIR/$tfile 0
31294         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs * 2))Yc ||
31295                 error "failed to write file $tfile with fdatasync"
31296         check_lsom_data $DIR/$tfile
31297
31298         $TRUNCATE $DIR/$tfile 0
31299         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:O_SYNC:w$((bs * 3))c ||
31300                 error "failed to write file $tfile with sync IO"
31301         check_lsom_data $DIR/$tfile
31302
31303         # verify truncate
31304         echo "Test SOM for truncate"
31305         # use ftruncate to sync blocks on close request
31306         $MULTIOP $DIR/$tfile oO_WRONLY:T16384c
31307         check_lsom_size $DIR/$tfile 16384
31308         check_lsom_data $DIR/$tfile
31309
31310         $TRUNCATE $DIR/$tfile 1234
31311         check_lsom_size $DIR/$tfile 1234
31312         # sync blocks on the MDT
31313         $MULTIOP $DIR/$tfile oc
31314         check_lsom_data $DIR/$tfile
31315 }
31316 run_test 806 "Verify Lazy Size on MDS"
31317
31318 test_807() {
31319         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
31320         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
31321                 skip "Need MDS version at least 2.11.52"
31322
31323         # Registration step
31324         changelog_register || error "changelog_register failed"
31325         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
31326         changelog_users $SINGLEMDS | grep -q $cl_user ||
31327                 error "User $cl_user not found in changelog_users"
31328
31329         rm -rf $DIR/$tdir || error "rm $tdir failed"
31330         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
31331         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
31332         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
31333         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
31334                 error "truncate $tdir/trunc failed"
31335
31336         local bs=1048576
31337         echo "Test SOM for single-threaded write with fsync"
31338         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
31339                 error "write $tfile failed"
31340         sync;sync;sync
31341
31342         # multi-client wirtes
31343         local num=$(get_node_count ${CLIENTS//,/ })
31344         local offset=0
31345         local i=0
31346
31347         echo "Test SOM for multi-client ($num) writes"
31348         touch $DIR/$tfile || error "touch $tfile failed"
31349         $TRUNCATE $DIR/$tfile 0
31350         for client in ${CLIENTS//,/ }; do
31351                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31352                 local pids[$i]=$!
31353                 i=$((i + 1))
31354                 offset=$((offset + $bs))
31355         done
31356         for (( i=0; i < $num; i++ )); do
31357                 wait ${pids[$i]}
31358         done
31359
31360         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
31361         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
31362         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
31363         check_lsom_data $DIR/$tdir/trunc
31364         check_lsom_data $DIR/$tdir/single_dd
31365         check_lsom_data $DIR/$tfile
31366
31367         rm -rf $DIR/$tdir
31368         # Deregistration step
31369         changelog_deregister || error "changelog_deregister failed"
31370 }
31371 run_test 807 "verify LSOM syncing tool"
31372
31373 check_som_nologged()
31374 {
31375         local lines=$($LFS changelog $FSNAME-MDT0000 |
31376                 grep 'x=trusted.som' | wc -l)
31377         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
31378 }
31379
31380 test_808() {
31381         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
31382                 skip "Need MDS version at least 2.11.55"
31383
31384         # Registration step
31385         changelog_register || error "changelog_register failed"
31386
31387         touch $DIR/$tfile || error "touch $tfile failed"
31388         check_som_nologged
31389
31390         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
31391                 error "write $tfile failed"
31392         check_som_nologged
31393
31394         $TRUNCATE $DIR/$tfile 1234
31395         check_som_nologged
31396
31397         $TRUNCATE $DIR/$tfile 1048576
31398         check_som_nologged
31399
31400         # Deregistration step
31401         changelog_deregister || error "changelog_deregister failed"
31402 }
31403 run_test 808 "Check trusted.som xattr not logged in Changelogs"
31404
31405 check_som_nodata()
31406 {
31407         $LFS getsom $1
31408         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
31409 }
31410
31411 test_809() {
31412         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
31413                 skip "Need MDS version at least 2.11.56"
31414
31415         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
31416                 error "failed to create DoM-only file $DIR/$tfile"
31417         touch $DIR/$tfile || error "touch $tfile failed"
31418         check_som_nodata $DIR/$tfile
31419
31420         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
31421                 error "write $tfile failed"
31422         check_som_nodata $DIR/$tfile
31423
31424         $TRUNCATE $DIR/$tfile 1234
31425         check_som_nodata $DIR/$tfile
31426
31427         $TRUNCATE $DIR/$tfile 4097
31428         check_som_nodata $DIR/$file
31429 }
31430 run_test 809 "Verify no SOM xattr store for DoM-only files"
31431
31432 test_810() {
31433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31434         $GSS && skip_env "could not run with gss"
31435         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
31436                 skip "OST < 2.12.58 doesn't align checksum"
31437
31438         set_checksums 1
31439         stack_trap "set_checksums $ORIG_CSUM" EXIT
31440         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
31441
31442         local csum
31443         local before
31444         local after
31445         for csum in $CKSUM_TYPES; do
31446                 #define OBD_FAIL_OSC_NO_GRANT   0x411
31447                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
31448                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
31449                         eval set -- $i
31450                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
31451                         before=$(md5sum $DIR/$tfile)
31452                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
31453                         after=$(md5sum $DIR/$tfile)
31454                         [ "$before" == "$after" ] ||
31455                                 error "$csum: $before != $after bs=$1 seek=$2"
31456                 done
31457         done
31458 }
31459 run_test 810 "partial page writes on ZFS (LU-11663)"
31460
31461 test_812a() {
31462         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
31463                 skip "OST < 2.12.51 doesn't support this fail_loc"
31464         local old
31465
31466         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
31467         $LCTL set_param osc.*.idle_timeout=10
31468         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
31469
31470         $LFS setstripe -c 1 -i 0 $DIR/$tfile
31471         # ensure ost1 is connected
31472         stat $DIR/$tfile >/dev/null || error "can't stat"
31473         wait_osc_import_state client ost1 FULL
31474         # no locks, no reqs to let the connection idle
31475         cancel_lru_locks osc
31476
31477         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
31478 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
31479         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
31480         wait_osc_import_state client ost1 CONNECTING
31481         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
31482
31483         stat $DIR/$tfile >/dev/null || error "can't stat file"
31484 }
31485 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
31486
31487 test_812b() { # LU-12378
31488         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
31489                 skip "OST < 2.12.51 doesn't support this fail_loc"
31490         local old
31491
31492         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
31493         $LCTL set_param osc.*.idle_timeout=10
31494         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
31495
31496         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
31497         # ensure ost1 is connected
31498         stat $DIR/$tfile >/dev/null || error "can't stat"
31499         wait_osc_import_state client ost1 FULL
31500         # no locks, no reqs to let the connection idle
31501         cancel_lru_locks osc
31502
31503         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
31504 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
31505         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
31506         wait_osc_import_state client ost1 CONNECTING
31507         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
31508
31509         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
31510         wait_osc_import_state client ost1 IDLE
31511 }
31512 run_test 812b "do not drop no resend request for idle connect"
31513
31514 test_812c() {
31515         local old
31516
31517         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
31518
31519         $LFS setstripe -c 1 -o 0 $DIR/$tfile
31520         $LFS getstripe $DIR/$tfile
31521         $LCTL set_param osc.*.idle_timeout=10
31522         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
31523         # ensure ost1 is connected
31524         stat $DIR/$tfile >/dev/null || error "can't stat"
31525         wait_osc_import_state client ost1 FULL
31526         # no locks, no reqs to let the connection idle
31527         cancel_lru_locks osc
31528
31529 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
31530         $LCTL set_param fail_loc=0x80000533
31531         sleep 15
31532         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
31533 }
31534 run_test 812c "idle import vs lock enqueue race"
31535
31536 test_813() {
31537         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
31538         [ -z "$file_heat_sav" ] && skip "no file heat support"
31539
31540         local readsample
31541         local writesample
31542         local readbyte
31543         local writebyte
31544         local readsample1
31545         local writesample1
31546         local readbyte1
31547         local writebyte1
31548
31549         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
31550         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
31551
31552         $LCTL set_param -n llite.*.file_heat=1
31553         echo "Turn on file heat"
31554         echo "Period second: $period_second, Decay percentage: $decay_pct"
31555
31556         echo "QQQQ" > $DIR/$tfile
31557         echo "QQQQ" > $DIR/$tfile
31558         echo "QQQQ" > $DIR/$tfile
31559         cat $DIR/$tfile > /dev/null
31560         cat $DIR/$tfile > /dev/null
31561         cat $DIR/$tfile > /dev/null
31562         cat $DIR/$tfile > /dev/null
31563
31564         local out=$($LFS heat_get $DIR/$tfile)
31565
31566         $LFS heat_get $DIR/$tfile
31567         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31568         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31569         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31570         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31571
31572         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
31573         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
31574         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
31575         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
31576
31577         sleep $((period_second + 3))
31578         echo "Sleep $((period_second + 3)) seconds..."
31579         # The recursion formula to calculate the heat of the file f is as
31580         # follow:
31581         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
31582         # Where Hi is the heat value in the period between time points i*I and
31583         # (i+1)*I; Ci is the access count in the period; the symbol P refers
31584         # to the weight of Ci.
31585         out=$($LFS heat_get $DIR/$tfile)
31586         $LFS heat_get $DIR/$tfile
31587         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31588         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31589         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31590         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31591
31592         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
31593                 error "read sample ($readsample) is wrong"
31594         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
31595                 error "write sample ($writesample) is wrong"
31596         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
31597                 error "read bytes ($readbyte) is wrong"
31598         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
31599                 error "write bytes ($writebyte) is wrong"
31600
31601         echo "QQQQ" > $DIR/$tfile
31602         echo "QQQQ" > $DIR/$tfile
31603         echo "QQQQ" > $DIR/$tfile
31604         cat $DIR/$tfile > /dev/null
31605         cat $DIR/$tfile > /dev/null
31606         cat $DIR/$tfile > /dev/null
31607         cat $DIR/$tfile > /dev/null
31608
31609         sleep $((period_second + 3))
31610         echo "Sleep $((period_second + 3)) seconds..."
31611
31612         out=$($LFS heat_get $DIR/$tfile)
31613         $LFS heat_get $DIR/$tfile
31614         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31615         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31616         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31617         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31618
31619         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
31620                 4 * $decay_pct) / 100") -eq 1 ] ||
31621                 error "read sample ($readsample1) is wrong"
31622         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
31623                 3 * $decay_pct) / 100") -eq 1 ] ||
31624                 error "write sample ($writesample1) is wrong"
31625         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
31626                 20 * $decay_pct) / 100") -eq 1 ] ||
31627                 error "read bytes ($readbyte1) is wrong"
31628         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
31629                 15 * $decay_pct) / 100") -eq 1 ] ||
31630                 error "write bytes ($writebyte1) is wrong"
31631
31632         echo "Turn off file heat for the file $DIR/$tfile"
31633         $LFS heat_set -o $DIR/$tfile
31634
31635         echo "QQQQ" > $DIR/$tfile
31636         echo "QQQQ" > $DIR/$tfile
31637         echo "QQQQ" > $DIR/$tfile
31638         cat $DIR/$tfile > /dev/null
31639         cat $DIR/$tfile > /dev/null
31640         cat $DIR/$tfile > /dev/null
31641         cat $DIR/$tfile > /dev/null
31642
31643         out=$($LFS heat_get $DIR/$tfile)
31644         $LFS heat_get $DIR/$tfile
31645         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31646         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31647         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31648         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31649
31650         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
31651         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
31652         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
31653         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
31654
31655         echo "Trun on file heat for the file $DIR/$tfile"
31656         $LFS heat_set -O $DIR/$tfile
31657
31658         echo "QQQQ" > $DIR/$tfile
31659         echo "QQQQ" > $DIR/$tfile
31660         echo "QQQQ" > $DIR/$tfile
31661         cat $DIR/$tfile > /dev/null
31662         cat $DIR/$tfile > /dev/null
31663         cat $DIR/$tfile > /dev/null
31664         cat $DIR/$tfile > /dev/null
31665
31666         out=$($LFS heat_get $DIR/$tfile)
31667         $LFS heat_get $DIR/$tfile
31668         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31669         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31670         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31671         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31672
31673         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
31674         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
31675         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
31676         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
31677
31678         $LFS heat_set -c $DIR/$tfile
31679         $LCTL set_param -n llite.*.file_heat=0
31680         echo "Turn off file heat support for the Lustre filesystem"
31681
31682         echo "QQQQ" > $DIR/$tfile
31683         echo "QQQQ" > $DIR/$tfile
31684         echo "QQQQ" > $DIR/$tfile
31685         cat $DIR/$tfile > /dev/null
31686         cat $DIR/$tfile > /dev/null
31687         cat $DIR/$tfile > /dev/null
31688         cat $DIR/$tfile > /dev/null
31689
31690         out=$($LFS heat_get $DIR/$tfile)
31691         $LFS heat_get $DIR/$tfile
31692         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31693         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31694         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31695         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31696
31697         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
31698         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
31699         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
31700         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
31701
31702         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
31703         rm -f $DIR/$tfile
31704 }
31705 run_test 813 "File heat verfication"
31706
31707 test_814()
31708 {
31709         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
31710         echo -n y >> $DIR/$tfile
31711         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
31712         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
31713 }
31714 run_test 814 "sparse cp works as expected (LU-12361)"
31715
31716 test_815()
31717 {
31718         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
31719         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
31720 }
31721 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
31722
31723 test_816() {
31724         local ost1_imp=$(get_osc_import_name client ost1)
31725         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
31726                          cut -d'.' -f2)
31727         local old
31728
31729         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
31730         $LCTL set_param osc.*.idle_timeout=10
31731         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
31732
31733         $LFS setstripe -c 1 -i 0 $DIR/$tfile
31734         # ensure ost1 is connected
31735
31736         stat $DIR/$tfile >/dev/null || error "can't stat"
31737         wait_osc_import_state client ost1 FULL
31738         # no locks, no reqs to let the connection idle
31739         cancel_lru_locks osc
31740         lru_resize_disable osc
31741         local before
31742         local now
31743         before=$($LCTL get_param -n \
31744                  ldlm.namespaces.$imp_name.lru_size)
31745
31746         wait_osc_import_state client ost1 IDLE
31747         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
31748         now=$($LCTL get_param -n \
31749               ldlm.namespaces.$imp_name.lru_size)
31750         [ $before == $now ] || error "lru_size changed $before != $now"
31751 }
31752 run_test 816 "do not reset lru_resize on idle reconnect"
31753
31754 cleanup_817() {
31755         umount $tmpdir
31756         exportfs -u localhost:$DIR/nfsexp
31757         rm -rf $DIR/nfsexp
31758 }
31759
31760 test_817() {
31761         systemctl restart nfs-server.service || skip "failed to restart nfsd"
31762
31763         mkdir -p $DIR/nfsexp
31764         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
31765                 error "failed to export nfs"
31766
31767         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
31768         stack_trap cleanup_817 EXIT
31769
31770         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
31771                 error "failed to mount nfs to $tmpdir"
31772
31773         cp /bin/true $tmpdir
31774         $DIR/nfsexp/true || error "failed to execute 'true' command"
31775 }
31776 run_test 817 "nfsd won't cache write lock for exec file"
31777
31778 test_818() {
31779         test_mkdir -i0 -c1 $DIR/$tdir
31780         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
31781         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
31782         stop $SINGLEMDS
31783
31784         # restore osp-syn threads
31785         stack_trap "fail $SINGLEMDS"
31786
31787         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
31788         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
31789         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
31790                 error "start $SINGLEMDS failed"
31791         rm -rf $DIR/$tdir
31792
31793         local testid=$(echo $TESTNAME | tr '_' ' ')
31794
31795         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
31796                 grep "run LFSCK" || error "run LFSCK is not suggested"
31797 }
31798 run_test 818 "unlink with failed llog"
31799
31800 test_819a() {
31801         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
31802         cancel_lru_locks osc
31803         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
31804         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
31805         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
31806         rm -f $TDIR/$tfile
31807 }
31808 run_test 819a "too big niobuf in read"
31809
31810 test_819b() {
31811         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
31812         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
31813         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
31814         cancel_lru_locks osc
31815         sleep 1
31816         rm -f $TDIR/$tfile
31817 }
31818 run_test 819b "too big niobuf in write"
31819
31820
31821 function test_820_start_ost() {
31822         sleep 5
31823
31824         for num in $(seq $OSTCOUNT); do
31825                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
31826         done
31827 }
31828
31829 test_820() {
31830         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
31831
31832         mkdir $DIR/$tdir
31833         umount_client $MOUNT || error "umount failed"
31834         for num in $(seq $OSTCOUNT); do
31835                 stop ost$num
31836         done
31837
31838         # mount client with no active OSTs
31839         # so that the client can't initialize max LOV EA size
31840         # from OSC notifications
31841         mount_client $MOUNT || error "mount failed"
31842         # delay OST starting to keep this 0 max EA size for a while
31843         test_820_start_ost &
31844
31845         # create a directory on MDS2
31846         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
31847                 error "Failed to create directory"
31848         # open intent should update default EA size
31849         # see mdc_update_max_ea_from_body()
31850         # notice this is the very first RPC to MDS2
31851         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
31852         ret=$?
31853         echo $out
31854         # With SSK, this situation can lead to -EPERM being returned.
31855         # In that case, simply retry.
31856         if [ $ret -ne 0 ] && $SHARED_KEY; then
31857                 if echo "$out" | grep -q "not permitted"; then
31858                         cp /etc/services $DIR/$tdir/mds2
31859                         ret=$?
31860                 fi
31861         fi
31862         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
31863 }
31864 run_test 820 "update max EA from open intent"
31865
31866 test_823() {
31867         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
31868         local OST_MAX_PRECREATE=20000
31869
31870         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
31871                 skip "Need MDS version at least 2.14.56"
31872
31873         save_lustre_params mds1 \
31874                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
31875         do_facet $SINGLEMDS "$LCTL set_param -n \
31876                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
31877         do_facet $SINGLEMDS "$LCTL set_param -n \
31878                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
31879
31880         stack_trap "restore_lustre_params < $p; rm $p"
31881
31882         do_facet $SINGLEMDS "$LCTL set_param -n \
31883                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
31884
31885         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
31886                       osp.$FSNAME-OST0000*MDT0000.create_count")
31887         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
31888                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
31889         local expect_count=$(((($max/2)/256) * 256))
31890
31891         log "setting create_count to 100200:"
31892         log " -result- count: $count with max: $max, expecting: $expect_count"
31893
31894         [[ $count -eq expect_count ]] ||
31895                 error "Create count not set to max precreate."
31896 }
31897 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
31898
31899 test_831() {
31900         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
31901                 skip "Need MDS version 2.14.56"
31902
31903         local sync_changes=$(do_facet $SINGLEMDS \
31904                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
31905
31906         [ "$sync_changes" -gt 100 ] &&
31907                 skip "Sync changes $sync_changes > 100 already"
31908
31909         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
31910
31911         $LFS mkdir -i 0 $DIR/$tdir
31912         $LFS setstripe -c 1 -i 0 $DIR/$tdir
31913
31914         save_lustre_params mds1 \
31915                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
31916         save_lustre_params mds1 \
31917                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
31918
31919         do_facet mds1 "$LCTL set_param -n \
31920                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
31921                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
31922         stack_trap "restore_lustre_params < $p" EXIT
31923
31924         createmany -o $DIR/$tdir/f- 1000
31925         unlinkmany $DIR/$tdir/f- 1000 &
31926         local UNLINK_PID=$!
31927
31928         while sleep 1; do
31929                 sync_changes=$(do_facet mds1 \
31930                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
31931                 # the check in the code is racy, fail the test
31932                 # if the value above the limit by 10.
31933                 [ $sync_changes -gt 110 ] && {
31934                         kill -2 $UNLINK_PID
31935                         wait
31936                         error "osp changes throttling failed, $sync_changes>110"
31937                 }
31938                 kill -0 $UNLINK_PID 2> /dev/null || break
31939         done
31940         wait
31941 }
31942 run_test 831 "throttling unlink/setattr queuing on OSP"
31943
31944 test_832() {
31945         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
31946         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
31947                 skip "Need MDS version 2.15.52+"
31948         is_rmentry_supported || skip "rm_entry not supported"
31949
31950         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
31951         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
31952         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
31953                 error "mkdir remote_dir failed"
31954         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
31955                 error "mkdir striped_dir failed"
31956         touch $DIR/$tdir/file || error "touch file failed"
31957         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
31958         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
31959 }
31960 run_test 832 "lfs rm_entry"
31961
31962 test_833() {
31963         local file=$DIR/$tfile
31964
31965         stack_trap "rm -f $file" EXIT
31966         dd if=/dev/zero of=$file bs=1M count=50 || error "Write $file failed"
31967
31968         local wpid
31969         local rpid
31970         local rpid2
31971
31972         # Buffered I/O write
31973         (
31974                 while [ ! -e $DIR/sanity.833.lck ]; do
31975                         dd if=/dev/zero of=$file bs=1M count=50 conv=notrunc ||
31976                                 error "failed to write $file"
31977                         sleep 0.$((RANDOM % 4 + 1))
31978                 done
31979         )&
31980         wpid=$!
31981
31982         # Buffered I/O read
31983         (
31984                 while [ ! -e $DIR/sanity.833.lck ]; do
31985                         dd if=$file of=/dev/null bs=1M count=50 ||
31986                                 error "failed to read $file"
31987                         sleep 0.$((RANDOM % 4 + 1))
31988                 done
31989         )&
31990         rpid=$!
31991
31992         # Direct I/O read
31993         (
31994                 while [ ! -e $DIR/sanity.833.lck ]; do
31995                         dd if=$file of=/dev/null bs=1M count=50 iflag=direct ||
31996                                 error "failed to read $file in direct I/O mode"
31997                         sleep 0.$((RANDOM % 4 + 1))
31998                 done
31999         )&
32000         rpid2=$!
32001
32002         sleep 30
32003         touch $DIR/sanity.833.lck
32004         wait $wpid || error "$?: buffered write failed"
32005         wait $rpid || error "$?: buffered read failed"
32006         wait $rpid2 || error "$?: direct read failed"
32007 }
32008 run_test 833 "Mixed buffered/direct read and write should not return -EIO"
32009
32010 test_850() {
32011         local dir=$DIR/$tdir
32012         local file=$dir/$tfile
32013         local statsfile=$dir/all_job_stats.txt
32014
32015         test_mkdir -p $dir || error "failed to create dir $dir"
32016         echo "abcdefg" > $file || error "failed to create file $file"
32017
32018         # read job_stats in the living system
32019         lljobstat -n 1 ||
32020                 error "failed to run lljobstat on living system"
32021
32022         $LCTL get_param *.*.job_stats > $statsfile
32023         lljobstat --statsfile=$statsfile ||
32024                 error "failed to run lljobstat on file $statsfile"
32025 }
32026 run_test 850 "lljobstat can parse living and aggregated job_stats"
32027
32028 test_851() {
32029         local dir=$DIR/$tdir
32030         local file=$dir/f_test_851_$$
32031         local report=/tmp/report_test_851_$$
32032         local fanotify_prog=monitor_lustrefs
32033         local pid
32034
32035         test_mkdir $dir || error "failed to create dir $dir"
32036
32037         $fanotify_prog $DIR > $report &
32038         pid=$!
32039
32040         sleep 1
32041         if ! kill -0 $pid; then
32042                 error "failed to start $fanoify_prog"
32043         fi
32044
32045         stack_trap "kill $pid"
32046         stack_trap "rm -f $report"
32047
32048         echo "1234567890" > $file
32049         wait_update_cond localhost "stat -c %s $report" "-gt" "0" 30 ||
32050                 error "fanotify did not report anything after 30 seconds"
32051         grep -a -E "open.*:$file:" $report ||
32052                 error "no open event for writing $file"
32053         grep -a -E "write.*:$file:" $report ||
32054                 error "no write event for writing $file"
32055         grep -a -E "close.*:$file:" $report ||
32056                 error "no close event for writing $file"
32057
32058         > $report
32059         cat $file
32060         wait_update_cond localhost "stat -c %s $report" "-gt" "0" 30 ||
32061                 error "fanotify did not report anything after 30 seconds"
32062         grep -a -E "open.*:$file:" $report ||
32063                 error "no open event for reading $file"
32064         grep -a -E "read.*:$file:" $report ||
32065                 error "no write event for reading $file"
32066         grep -a -E "close.*:$file:" $report ||
32067                 error "no close event for reading $file"
32068 }
32069 run_test 851 "fanotify can monitor open/read/write/close events for lustre fs"
32070
32071 #
32072 # tests that do cleanup/setup should be run at the end
32073 #
32074
32075 test_900() {
32076         [ $PARALLEL == "yes" ] && skip "skip parallel run"
32077         local ls
32078
32079         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
32080         $LCTL set_param fail_loc=0x903
32081
32082         cancel_lru_locks MGC
32083
32084         FAIL_ON_ERROR=true cleanup
32085         FAIL_ON_ERROR=true setup
32086 }
32087 run_test 900 "umount should not race with any mgc requeue thread"
32088
32089 # LUS-6253/LU-11185
32090 test_901() {
32091         local old
32092         local count
32093         local oldc
32094         local newc
32095         local olds
32096         local news
32097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
32098
32099         # some get_param have a bug to handle dot in param name
32100         cancel_lru_locks MGC
32101         old=$(mount -t lustre | wc -l)
32102         # 1 config+sptlrpc
32103         # 2 params
32104         # 3 nodemap
32105         # 4 IR
32106         old=$((old * 4))
32107         oldc=0
32108         count=0
32109         while [ $old -ne $oldc ]; do
32110                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
32111                 sleep 1
32112                 ((count++))
32113                 if [ $count -ge $TIMEOUT ]; then
32114                         error "too large timeout"
32115                 fi
32116         done
32117         umount_client $MOUNT || error "umount failed"
32118         mount_client $MOUNT || error "mount failed"
32119         cancel_lru_locks MGC
32120         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
32121
32122         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
32123
32124         return 0
32125 }
32126 run_test 901 "don't leak a mgc lock on client umount"
32127
32128 # LU-13377
32129 test_902() {
32130         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
32131                 skip "client does not have LU-13377 fix"
32132         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
32133         $LCTL set_param fail_loc=0x1415
32134         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
32135         cancel_lru_locks osc
32136         rm -f $DIR/$tfile
32137 }
32138 run_test 902 "test short write doesn't hang lustre"
32139
32140 # LU-14711
32141 test_903() {
32142         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
32143         echo "blah" > $DIR/${tfile}-2
32144         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
32145         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
32146         $LCTL set_param fail_loc=0x417 fail_val=20
32147
32148         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
32149         sleep 1 # To start the destroy
32150         wait_destroy_complete 150 || error "Destroy taking too long"
32151         cat $DIR/$tfile > /dev/null || error "Evicted"
32152 }
32153 run_test 903 "Test long page discard does not cause evictions"
32154
32155 test_904() {
32156         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
32157         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
32158                 grep -q project || skip "skip project quota not supported"
32159
32160         local testfile="$DIR/$tdir/$tfile"
32161         local xattr="trusted.projid"
32162         local projid
32163         local mdts=$(comma_list $(mdts_nodes))
32164         local saved=$(do_facet mds1 $LCTL get_param -n \
32165                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
32166
32167         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
32168         stack_trap "do_nodes $mdts $LCTL set_param \
32169                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
32170
32171         mkdir -p $DIR/$tdir
32172         touch $testfile
32173         #hide projid xattr on server
32174         $LFS project -p 1 $testfile ||
32175                 error "set $testfile project id failed"
32176         getfattr -m - $testfile | grep $xattr &&
32177                 error "do not show trusted.projid when disabled on server"
32178         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
32179         #should be hidden when projid is 0
32180         $LFS project -p 0 $testfile ||
32181                 error "set $testfile project id failed"
32182         getfattr -m - $testfile | grep $xattr &&
32183                 error "do not show trusted.projid with project ID 0"
32184
32185         #still can getxattr explicitly
32186         projid=$(getfattr -n $xattr $testfile |
32187                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
32188         [ $projid == "0" ] ||
32189                 error "projid expected 0 not $projid"
32190
32191         #set the projid via setxattr
32192         setfattr -n $xattr -v "1000" $testfile ||
32193                 error "setattr failed with $?"
32194         projid=($($LFS project $testfile))
32195         [ ${projid[0]} == "1000" ] ||
32196                 error "projid expected 1000 not $projid"
32197
32198         #check the new projid via getxattr
32199         $LFS project -p 1001 $testfile ||
32200                 error "set $testfile project id failed"
32201         getfattr -m - $testfile | grep $xattr ||
32202                 error "should show trusted.projid when project ID != 0"
32203         projid=$(getfattr -n $xattr $testfile |
32204                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
32205         [ $projid == "1001" ] ||
32206                 error "projid expected 1001 not $projid"
32207
32208         #try to set invalid projid
32209         setfattr -n $xattr -v "4294967295" $testfile &&
32210                 error "set invalid projid should fail"
32211
32212         #remove the xattr means setting projid to 0
32213         setfattr -x $xattr $testfile ||
32214                 error "setfattr failed with $?"
32215         projid=($($LFS project $testfile))
32216         [ ${projid[0]} == "0" ] ||
32217                 error "projid expected 0 not $projid"
32218
32219         #should be hidden when parent has inherit flag and same projid
32220         $LFS project -srp 1002 $DIR/$tdir ||
32221                 error "set $tdir project id failed"
32222         getfattr -m - $testfile | grep $xattr &&
32223                 error "do not show trusted.projid with inherit flag"
32224
32225         #still can getxattr explicitly
32226         projid=$(getfattr -n $xattr $testfile |
32227                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
32228         [ $projid == "1002" ] ||
32229                 error "projid expected 1002 not $projid"
32230 }
32231 run_test 904 "virtual project ID xattr"
32232
32233 # LU-8582
32234 test_905() {
32235         (( $OST1_VERSION >= $(version_code 2.15.50.220) )) ||
32236                 skip "need OST version >= 2.15.50.220 for fail_loc"
32237
32238         remote_ost_nodsh && skip "remote OST with nodsh"
32239         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
32240
32241         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
32242
32243         #define OBD_FAIL_OST_OPCODE 0x253
32244         # OST_LADVISE = 21
32245         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
32246         $LFS ladvise -a willread $DIR/$tfile &&
32247                 error "unexpected success of ladvise with fault injection"
32248         $LFS ladvise -a willread $DIR/$tfile |&
32249                 grep -q "Operation not supported"
32250         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
32251 }
32252 run_test 905 "bad or new opcode should not stuck client"
32253
32254 test_906() {
32255         grep -q io_uring_setup /proc/kallsyms ||
32256                 skip "Client OS does not support io_uring I/O engine"
32257         io_uring_probe || skip "kernel does not support io_uring fully"
32258         which fio || skip_env "no fio installed"
32259         fio --enghelp | grep -q io_uring ||
32260                 skip_env "fio does not support io_uring I/O engine"
32261
32262         local file=$DIR/$tfile
32263         local ioengine="io_uring"
32264         local numjobs=2
32265         local size=50M
32266
32267         fio --name=seqwrite --ioengine=$ioengine        \
32268                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
32269                 --iodepth=64 --size=$size --filename=$file --rw=write ||
32270                 error "fio seqwrite $file failed"
32271
32272         fio --name=seqread --ioengine=$ioengine \
32273                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
32274                 --iodepth=64 --size=$size --filename=$file --rw=read ||
32275                 error "fio seqread $file failed"
32276
32277         rm -f $file || error "rm -f $file failed"
32278 }
32279 run_test 906 "Simple test for io_uring I/O engine via fio"
32280
32281 test_907() {
32282         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
32283
32284         # set stripe size to max rpc size
32285         $LFS setstripe -i 0 -c 2 -S $((max_pages * PAGE_SIZE)) $DIR/$tfile
32286         $LFS getstripe $DIR/$tfile
32287 #define OBD_FAIL_OST_EROFS               0x216
32288         do_facet ost1 "$LCTL set_param fail_val=3 fail_loc=0x80000216"
32289
32290         local bs=$((max_pages * PAGE_SIZE / 16))
32291
32292         # write full one stripe and one block
32293         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=17 || error "dd failed"
32294
32295         rm $DIR/$tfile || error "rm failed"
32296 }
32297 run_test 907 "write rpc error during unlink"
32298
32299
32300 complete_test $SECONDS
32301 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
32302 check_and_cleanup_lustre
32303 if [ "$I_MOUNTED" != "yes" ]; then
32304         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
32305 fi
32306 exit_status