Whamcloud - gitweb
LU-17713 mdd: validate the length of mdd append_pool name
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 SOCKETSERVER=${SOCKETSERVER:-socketserver}
23 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
24 MEMHOG=${MEMHOG:-memhog}
25 DIRECTIO=${DIRECTIO:-directio}
26 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
27 DEF_STRIPE_COUNT=-1
28 CHECK_GRANT=${CHECK_GRANT:-"yes"}
29 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
30
31 TRACE=${TRACE:-""}
32 LUSTRE=${LUSTRE:-$(dirname $0)/..}
33 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
34 . $LUSTRE/tests/test-framework.sh
35 init_test_env "$@"
36
37 init_logging
38
39 ALWAYS_EXCEPT="$SANITY_EXCEPT "
40 always_except LU-9693  42a 42c
41 always_except LU-6493  42b
42 always_except LU-16515 118c 118d
43 always_except LU-8411  407
44
45 if $SHARED_KEY; then
46         always_except LU-14181 64e 64f
47         always_except LU-17127 39o
48 fi
49
50 # skip the grant tests for ARM until they are fixed
51 if [[ $(uname -m) = aarch64 ]]; then
52         always_except LU-11671 45
53 fi
54
55 # skip nfs tests on kernels >= 4.12.0 until they are fixed
56 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
57         always_except LU-12661 817
58 fi
59 # skip cgroup tests on RHEL8.1 kernels until they are fixed
60 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
61       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
62         always_except LU-13063 411a
63 fi
64
65 # skip cgroup tests for kernels < v4.18.0
66 if (( $LINUX_VERSION_CODE < $(version_code 4.18.0) )); then
67         always_except LU-13063 411b
68 fi
69
70 # minutes runtime:                   5              12     8   12   15   10
71 [[ "$SLOW" = "no" ]] && EXCEPT_SLOW="27m 60i 64b 68 71 135 136 230d 300o 842"
72
73 if [[ "$mds1_FSTYPE" == "zfs" ]]; then
74         #                                               13    (min)"
75         [[ "$SLOW" == "no" ]] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
76 fi
77
78 if [[ "$ost1_FSTYPE" = "zfs" ]]; then
79         always_except LU-1941 130b 130c 130d 130e 130f 130g
80         always_except LU-9054 312
81 fi
82
83 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
84
85 # Get the SLES distro version
86 #
87 # Returns a version string that should only be used in comparing
88 # strings returned by version_code()
89 sles_version_code()
90 {
91         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
92
93         # All SuSE Linux versions have one decimal. version_code expects two
94         local sles_version=$version.0
95         version_code $sles_version
96 }
97
98 # Check if we are running on Ubuntu or SLES so we can make decisions on
99 # what tests to run
100 if [ -r /etc/SuSE-release ] || [ -r /etc/SUSE-brand ]; then
101         sles_version=$(sles_version_code)
102         (( $sles_version >= $(version_code 11.4.0) )) ||
103                 always_except LU-4341 170
104
105         (( $sles_version >= $(version_code 12.0.0) )) ||
106                 always_except LU-3703 234
107 elif [ -r /etc/redhat-release ]; then
108         rhel_version=$(cat /etc/redhat-release |
109                 sed -e 's/^[^0-9.]*//g' | sed -e 's/[ ].*//')
110         if (( $(version_code $rhel_version) >= $(version_code 9.3.0) )); then
111                 # disable test_906 temporarily until rhel9.3 solves the
112                 # failure on fio io_uring I/O engine.
113                 always_except LU-17289 906
114         fi
115 fi
116
117 build_test_filter
118 FAIL_ON_ERROR=false
119
120 cleanup() {
121         echo -n "cln.."
122         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
123         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
124 }
125 setup() {
126         echo -n "mnt.."
127         load_modules
128         setupall || exit 10
129         echo "done"
130 }
131
132 check_swap_layouts_support()
133 {
134         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
135                 skip "Does not support layout lock."
136 }
137
138 check_swap_layout_no_dom()
139 {
140         local FOLDER=$1
141         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
142         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
143 }
144
145 check_and_setup_lustre
146 DIR=${DIR:-$MOUNT}
147 assert_DIR
148
149 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
150
151 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
152 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
153 rm -rf $DIR/[Rdfs][0-9]*
154
155 # $RUNAS_ID may get set incorrectly somewhere else
156 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
157         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
158
159 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
160
161 if [ "${ONLY}" = "MOUNT" ] ; then
162         echo "Lustre is up, please go on"
163         exit
164 fi
165
166 echo "preparing for tests involving mounts"
167 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
168 touch $EXT2_DEV
169 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
170 echo # add a newline after mke2fs.
171
172 umask 077
173
174 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
175
176 # ensure all internal functions know we want full debug
177 export PTLDEBUG=all
178 lctl set_param debug=$PTLDEBUG 2> /dev/null || true
179
180 test_0a() {
181         touch $DIR/$tfile
182         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
183         rm $DIR/$tfile
184         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
185 }
186 run_test 0a "touch; rm ====================="
187
188 test_0b() {
189         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
190         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
191 }
192 run_test 0b "chmod 0755 $DIR ============================="
193
194 test_0c() {
195         $LCTL get_param mdc.*.import | grep "state: FULL" ||
196                 error "import not FULL"
197         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
198                 error "bad target"
199 }
200 run_test 0c "check import proc"
201
202 test_0d() { # LU-3397
203         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
204                 skip "proc exports not supported before 2.10.57"
205
206         local mgs_exp="mgs.MGS.exports"
207         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
208         local exp_client_nid
209         local exp_client_version
210         local exp_val
211         local imp_val
212         local temp_imp=$DIR/$tfile.import
213         local temp_exp=$DIR/$tfile.export
214
215         # save mgc import file to $temp_imp
216         $LCTL get_param mgc.*.import | tee $temp_imp
217         # Check if client uuid is found in MGS export
218         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
219                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
220                         $client_uuid ] &&
221                         break;
222         done
223         # save mgs export file to $temp_exp
224         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
225
226         # Compare the value of field "connect_flags"
227         imp_val=$(grep "connect_flags" $temp_imp)
228         exp_val=$(grep "connect_flags" $temp_exp)
229         [ "$exp_val" == "$imp_val" ] ||
230                 error "export flags '$exp_val' != import flags '$imp_val'"
231
232         # Compare client versions.  Only compare top-3 fields for compatibility
233         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
234         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
235         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
236         [ "$exp_val" == "$imp_val" ] ||
237                 error "exp version '$exp_client_version'($exp_val) != " \
238                         "'$(lustre_build_version client)'($imp_val)"
239 }
240 run_test 0d "check export proc ============================="
241
242 test_0e() { # LU-13417
243         (( $MDSCOUNT > 1 )) ||
244                 skip "We need at least 2 MDTs for this test"
245
246         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
247                 skip "Need server version at least 2.14.51"
248
249         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
250         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
251
252         [ $default_lmv_count -eq 1 ] ||
253                 error "$MOUNT default stripe count $default_lmv_count"
254
255         [ $default_lmv_index -eq -1 ] ||
256                 error "$MOUNT default stripe index $default_lmv_index"
257
258         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
259         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
260
261         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
262         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
263
264         [ $mdt_index1 -eq $mdt_index2 ] &&
265                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
266
267         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
268 }
269 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
270
271 test_0f() { # LU-17471
272         (( $MDS1_VERSION < $(version_code 2.17.53) )) ||
273                 skip "MDS >= 2.17.53 removes /proc/.../brw_stats symlink"
274         (( $MDS1_VERSION < $(version_code 2.14.55-100-g8a84c7f9c7) ||
275            $MDS1_VERSION > $(version_code 2.15.60-25) )) ||
276                 skip "MDS was missing /proc/.../brw_stats value"
277
278         local path="lustre/osd-$FSTYPE/$FSNAME-MDT0000/brw_stats"
279         local out_proc=$(do_facet mds1 grep snapshot_time /proc/fs/$path)
280
281         [[ -n "$out_proc" ]] || error "brw_stats /proc/fs/$path not found"
282 }
283 run_test 0f "Symlink to /sys/kernel/debug/*/*/brw_stats should work properly"
284
285 test_1() {
286         test_mkdir $DIR/$tdir
287         test_mkdir $DIR/$tdir/d2
288         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
289         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
290         rmdir $DIR/$tdir/d2
291         rmdir $DIR/$tdir
292         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
293 }
294 run_test 1 "mkdir; remkdir; rmdir"
295
296 test_2() {
297         test_mkdir $DIR/$tdir
298         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
299         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
300         rm -r $DIR/$tdir
301         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
302 }
303 run_test 2 "mkdir; touch; rmdir; check file"
304
305 test_3() {
306         test_mkdir $DIR/$tdir
307         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
308         touch $DIR/$tdir/$tfile
309         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
310         rm -r $DIR/$tdir
311         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
312 }
313 run_test 3 "mkdir; touch; rmdir; check dir"
314
315 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
316 test_4() {
317         test_mkdir -i 1 $DIR/$tdir
318
319         touch $DIR/$tdir/$tfile ||
320                 error "Create file under remote directory failed"
321
322         rmdir $DIR/$tdir &&
323                 error "Expect error removing in-use dir $DIR/$tdir"
324
325         test -d $DIR/$tdir || error "Remote directory disappeared"
326
327         rm -rf $DIR/$tdir || error "remove remote dir error"
328 }
329 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
330
331 test_5() {
332         test_mkdir $DIR/$tdir
333         test_mkdir $DIR/$tdir/d2
334         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
335         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
336         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
337 }
338 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
339
340 test_6a() {
341         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
342         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
343         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
344                 error "$tfile does not have perm 0666 or UID $UID"
345         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
346         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
347                 error "$tfile should be 0666 and owned by UID $UID"
348 }
349 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
350
351 test_6c() {
352         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
353
354         touch $DIR/$tfile
355         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
356         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
357                 error "$tfile should be owned by UID $RUNAS_ID"
358         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
359         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
360                 error "$tfile should be owned by UID $RUNAS_ID"
361 }
362 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
363
364 test_6e() {
365         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
366
367         touch $DIR/$tfile
368         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
369         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
370                 error "$tfile should be owned by GID $UID"
371         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
372         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
373                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
374 }
375 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
376
377 test_6g() {
378         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
379
380         test_mkdir $DIR/$tdir
381         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
382         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
383         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
384         test_mkdir $DIR/$tdir/d/subdir
385         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
386                 error "$tdir/d/subdir should be GID $RUNAS_GID"
387         if [[ $MDSCOUNT -gt 1 ]]; then
388                 # check remote dir sgid inherite
389                 $LFS mkdir -i 0 $DIR/$tdir.local ||
390                         error "mkdir $tdir.local failed"
391                 chmod g+s $DIR/$tdir.local ||
392                         error "chmod $tdir.local failed"
393                 chgrp $RUNAS_GID $DIR/$tdir.local ||
394                         error "chgrp $tdir.local failed"
395                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
396                         error "mkdir $tdir.remote failed"
397                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
398                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
399                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
400                         error "$tdir.remote should be mode 02755"
401         fi
402 }
403 run_test 6g "verify new dir in sgid dir inherits group"
404
405 test_6h() { # bug 7331
406         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
407
408         touch $DIR/$tfile || error "touch failed"
409         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
410         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
411                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
412         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
413                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
414 }
415 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
416
417 test_7a() {
418         test_mkdir $DIR/$tdir
419         $MCREATE $DIR/$tdir/$tfile
420         chmod 0666 $DIR/$tdir/$tfile
421         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
422                 error "$tdir/$tfile should be mode 0666"
423 }
424 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
425
426 test_7b() {
427         if [ ! -d $DIR/$tdir ]; then
428                 test_mkdir $DIR/$tdir
429         fi
430         $MCREATE $DIR/$tdir/$tfile
431         echo -n foo > $DIR/$tdir/$tfile
432         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
433         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
434 }
435 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
436
437 test_8() {
438         test_mkdir $DIR/$tdir
439         touch $DIR/$tdir/$tfile
440         chmod 0666 $DIR/$tdir/$tfile
441         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
442                 error "$tfile mode not 0666"
443 }
444 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
445
446 test_9() {
447         test_mkdir $DIR/$tdir
448         test_mkdir $DIR/$tdir/d2
449         test_mkdir $DIR/$tdir/d2/d3
450         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
451 }
452 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
453
454 test_10() {
455         test_mkdir $DIR/$tdir
456         test_mkdir $DIR/$tdir/d2
457         touch $DIR/$tdir/d2/$tfile
458         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
459                 error "$tdir/d2/$tfile not a file"
460 }
461 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
462
463 test_11() {
464         test_mkdir $DIR/$tdir
465         test_mkdir $DIR/$tdir/d2
466         chmod 0666 $DIR/$tdir/d2
467         chmod 0705 $DIR/$tdir/d2
468         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
469                 error "$tdir/d2 mode not 0705"
470 }
471 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
472
473 test_12() {
474         test_mkdir $DIR/$tdir
475         touch $DIR/$tdir/$tfile
476         chmod 0666 $DIR/$tdir/$tfile
477         chmod 0654 $DIR/$tdir/$tfile
478         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
479                 error "$tdir/d2 mode not 0654"
480 }
481 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
482
483 test_13() {
484         test_mkdir $DIR/$tdir
485         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
486         >  $DIR/$tdir/$tfile
487         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
488                 error "$tdir/$tfile size not 0 after truncate"
489 }
490 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
491
492 test_14() {
493         test_mkdir $DIR/$tdir
494         touch $DIR/$tdir/$tfile
495         rm $DIR/$tdir/$tfile
496         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
497 }
498 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
499
500 test_15() {
501         test_mkdir $DIR/$tdir
502         touch $DIR/$tdir/$tfile
503         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
504         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
505                 error "$tdir/${tfile_2} not a file after rename"
506         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
507 }
508 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
509
510 test_16() {
511         test_mkdir $DIR/$tdir
512         touch $DIR/$tdir/$tfile
513         rm -rf $DIR/$tdir/$tfile
514         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
515 }
516 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
517
518 test_17a() {
519         test_mkdir $DIR/$tdir
520         touch $DIR/$tdir/$tfile
521         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
522         ls -l $DIR/$tdir
523         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
524                 error "$tdir/l-exist not a symlink"
525         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
526                 error "$tdir/l-exist not referencing a file"
527         rm -f $DIR/$tdir/l-exist
528         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
529 }
530 run_test 17a "symlinks: create, remove (real)"
531
532 test_17b() {
533         test_mkdir $DIR/$tdir
534         ln -s no-such-file $DIR/$tdir/l-dangle
535         ls -l $DIR/$tdir
536         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
537                 error "$tdir/l-dangle not referencing no-such-file"
538         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
539                 error "$tdir/l-dangle not referencing non-existent file"
540         rm -f $DIR/$tdir/l-dangle
541         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
542 }
543 run_test 17b "symlinks: create, remove (dangling)"
544
545 test_17c() { # bug 3440 - don't save failed open RPC for replay
546         test_mkdir $DIR/$tdir
547         ln -s foo $DIR/$tdir/$tfile
548         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
549 }
550 run_test 17c "symlinks: open dangling (should return error)"
551
552 test_17d() {
553         test_mkdir $DIR/$tdir
554         ln -s foo $DIR/$tdir/$tfile
555         touch $DIR/$tdir/$tfile || error "creating to new symlink"
556 }
557 run_test 17d "symlinks: create dangling"
558
559 test_17e() {
560         test_mkdir $DIR/$tdir
561         local foo=$DIR/$tdir/$tfile
562         ln -s $foo $foo || error "create symlink failed"
563         ls -l $foo || error "ls -l failed"
564         ls $foo && error "ls not failed" || true
565 }
566 run_test 17e "symlinks: create recursive symlink (should return error)"
567
568 test_17f() {
569         test_mkdir $DIR/$tdir
570         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
571         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
572         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
573         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
574         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
575         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
576         ls -l  $DIR/$tdir
577 }
578 run_test 17f "symlinks: long and very long symlink name"
579
580 # str_repeat(S, N) generate a string that is string S repeated N times
581 str_repeat() {
582         local s=$1
583         local n=$2
584         local ret=''
585         while [ $((n -= 1)) -ge 0 ]; do
586                 ret=$ret$s
587         done
588         echo $ret
589 }
590
591 # Long symlinks and LU-2241
592 test_17g() {
593         test_mkdir $DIR/$tdir
594         local TESTS="59 60 61 4094 4095"
595
596         # Fix for inode size boundary in 2.1.4
597         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
598                 TESTS="4094 4095"
599
600         # Patch not applied to 2.2 or 2.3 branches
601         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
602         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
603                 TESTS="4094 4095"
604
605         for i in $TESTS; do
606                 local SYMNAME=$(str_repeat 'x' $i)
607                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
608                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
609         done
610 }
611 run_test 17g "symlinks: really long symlink name and inode boundaries"
612
613 test_17h() { #bug 17378
614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
615         remote_mds_nodsh && skip "remote MDS with nodsh"
616
617         local mdt_idx
618
619         test_mkdir $DIR/$tdir
620         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
621         $LFS setstripe -c -1 $DIR/$tdir
622         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
623         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
624         touch $DIR/$tdir/$tfile || true
625 }
626 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
627
628 test_17i() { #bug 20018
629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
630         remote_mds_nodsh && skip "remote MDS with nodsh"
631
632         local foo=$DIR/$tdir/$tfile
633         local mdt_idx
634
635         test_mkdir -c1 $DIR/$tdir
636         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
637         ln -s $foo $foo || error "create symlink failed"
638 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
639         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
640         ls -l $foo && error "error not detected"
641         return 0
642 }
643 run_test 17i "don't panic on short symlink (should return error)"
644
645 test_17k() { #bug 22301
646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
647         [[ -z "$(which rsync 2>/dev/null)" ]] &&
648                 skip "no rsync command"
649         rsync --help | grep -q xattr ||
650                 skip_env "$(rsync --version | head -n1) does not support xattrs"
651         test_mkdir $DIR/$tdir
652         test_mkdir $DIR/$tdir.new
653         touch $DIR/$tdir/$tfile
654         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
655         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
656                 error "rsync failed with xattrs enabled"
657 }
658 run_test 17k "symlinks: rsync with xattrs enabled"
659
660 test_17l() { # LU-279
661         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
662                 skip "no getfattr command"
663
664         test_mkdir $DIR/$tdir
665         touch $DIR/$tdir/$tfile
666         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
667         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
668                 # -h to not follow symlinks. -m '' to list all the xattrs.
669                 # grep to remove first line: '# file: $path'.
670                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
671                 do
672                         lgetxattr_size_check $path $xattr ||
673                                 error "lgetxattr_size_check $path $xattr failed"
674                 done
675         done
676 }
677 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
678
679 # LU-1540
680 test_17m() {
681         [ $PARALLEL == "yes" ] && skip "skip parallel run"
682         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
683         remote_mds_nodsh && skip "remote MDS with nodsh"
684         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
685         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
686                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
687
688         local short_sym="0123456789"
689         local wdir=$DIR/$tdir
690         local i
691
692         test_mkdir $wdir
693         long_sym=$short_sym
694         # create a long symlink file
695         for ((i = 0; i < 4; ++i)); do
696                 long_sym=${long_sym}${long_sym}
697         done
698
699         echo "create 512 short and long symlink files under $wdir"
700         for ((i = 0; i < 256; ++i)); do
701                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
702                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
703         done
704
705         echo "erase them"
706         rm -f $wdir/*
707         sync
708         wait_delete_completed
709
710         echo "recreate the 512 symlink files with a shorter string"
711         for ((i = 0; i < 512; ++i)); do
712                 # rewrite the symlink file with a shorter string
713                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
714                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
715         done
716
717         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
718
719         echo "stop and checking mds${mds_index}:"
720         # e2fsck should not return error
721         stop mds${mds_index}
722         local devname=$(mdsdevname $mds_index)
723         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
724         rc=$?
725
726         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
727                 error "start mds${mds_index} failed"
728         df $MOUNT > /dev/null 2>&1
729         [ $rc -eq 0 ] ||
730                 error "e2fsck detected error for short/long symlink: rc=$rc"
731         rm -f $wdir/*
732 }
733 run_test 17m "run e2fsck against MDT which contains short/long symlink"
734
735 check_fs_consistency_17n() {
736         local mdt_index
737         local rc=0
738
739         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
740         # so it only check MDT1/MDT2 instead of all of MDTs.
741         for mdt_index in 1 2; do
742                 # e2fsck should not return error
743                 stop mds${mdt_index}
744                 local devname=$(mdsdevname $mdt_index)
745                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
746                         rc=$((rc + $?))
747
748                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
749                         error "mount mds$mdt_index failed"
750                 df $MOUNT > /dev/null 2>&1
751         done
752         return $rc
753 }
754
755 test_17n() {
756         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
757         [ $PARALLEL == "yes" ] && skip "skip parallel run"
758         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
759         remote_mds_nodsh && skip "remote MDS with nodsh"
760         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
761         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
762                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
763
764         local i
765
766         test_mkdir $DIR/$tdir
767         for ((i=0; i<10; i++)); do
768                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
769                         error "create remote dir error $i"
770                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
771                         error "create files under remote dir failed $i"
772         done
773
774         check_fs_consistency_17n ||
775                 error "e2fsck report error after create files under remote dir"
776
777         for ((i = 0; i < 10; i++)); do
778                 rm -rf $DIR/$tdir/remote_dir_${i} ||
779                         error "destroy remote dir error $i"
780         done
781
782         check_fs_consistency_17n ||
783                 error "e2fsck report error after unlink files under remote dir"
784
785         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
786                 skip "lustre < 2.4.50 does not support migrate mv"
787
788         for ((i = 0; i < 10; i++)); do
789                 mkdir -p $DIR/$tdir/remote_dir_${i}
790                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
791                         error "create files under remote dir failed $i"
792                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
793                         error "migrate remote dir error $i"
794         done
795         check_fs_consistency_17n || error "e2fsck report error after migration"
796
797         for ((i = 0; i < 10; i++)); do
798                 rm -rf $DIR/$tdir/remote_dir_${i} ||
799                         error "destroy remote dir error $i"
800         done
801
802         check_fs_consistency_17n || error "e2fsck report error after unlink"
803 }
804 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
805
806 test_17o() {
807         remote_mds_nodsh && skip "remote MDS with nodsh"
808         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
809                 skip "Need MDS version at least 2.3.64"
810
811         local wdir=$DIR/${tdir}o
812         local mdt_index
813         local rc=0
814
815         test_mkdir $wdir
816         touch $wdir/$tfile
817         mdt_index=$($LFS getstripe -m $wdir/$tfile)
818         mdt_index=$((mdt_index + 1))
819
820         cancel_lru_locks mdc
821         #fail mds will wait the failover finish then set
822         #following fail_loc to avoid interfer the recovery process.
823         fail mds${mdt_index}
824
825         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
826         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
827         ls -l $wdir/$tfile && rc=1
828         do_facet mds${mdt_index} lctl set_param fail_loc=0
829         [[ $rc -eq 0 ]] || error "stat file should fail"
830 }
831 run_test 17o "stat file with incompat LMA feature"
832
833 test_18() {
834         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
835         ls $DIR || error "Failed to ls $DIR: $?"
836 }
837 run_test 18 "touch .../f ; ls ... =============================="
838
839 test_19a() {
840         touch $DIR/$tfile
841         ls -l $DIR
842         rm $DIR/$tfile
843         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
844 }
845 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
846
847 test_19b() {
848         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
849 }
850 run_test 19b "ls -l .../f19 (should return error) =============="
851
852 test_19c() {
853         [ $RUNAS_ID -eq $UID ] &&
854                 skip_env "RUNAS_ID = UID = $UID -- skipping"
855
856         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
857 }
858 run_test 19c "$RUNAS touch .../f19 (should return error) =="
859
860 test_19d() {
861         cat $DIR/f19 && error || true
862 }
863 run_test 19d "cat .../f19 (should return error) =============="
864
865 test_20() {
866         touch $DIR/$tfile
867         rm $DIR/$tfile
868         touch $DIR/$tfile
869         rm $DIR/$tfile
870         touch $DIR/$tfile
871         rm $DIR/$tfile
872         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
873 }
874 run_test 20 "touch .../f ; ls -l ..."
875
876 test_21() {
877         test_mkdir $DIR/$tdir
878         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
879         ln -s dangle $DIR/$tdir/link
880         echo foo >> $DIR/$tdir/link
881         cat $DIR/$tdir/dangle
882         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
883         $CHECKSTAT -f -t file $DIR/$tdir/link ||
884                 error "$tdir/link not linked to a file"
885 }
886 run_test 21 "write to dangling link"
887
888 test_22() {
889         local wdir=$DIR/$tdir
890         test_mkdir $wdir
891         chown $RUNAS_ID:$RUNAS_GID $wdir
892         (cd $wdir || error "cd $wdir failed";
893                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
894                 $RUNAS tar xf -)
895         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
896         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
897         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
898                 error "checkstat -u failed"
899 }
900 run_test 22 "unpack tar archive as non-root user"
901
902 # was test_23
903 test_23a() {
904         test_mkdir $DIR/$tdir
905         local file=$DIR/$tdir/$tfile
906
907         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
908         openfile -f O_CREAT:O_EXCL $file &&
909                 error "$file recreate succeeded" || true
910 }
911 run_test 23a "O_CREAT|O_EXCL in subdir"
912
913 test_23b() { # bug 18988
914         test_mkdir $DIR/$tdir
915         local file=$DIR/$tdir/$tfile
916
917         rm -f $file
918         echo foo > $file || error "write filed"
919         echo bar >> $file || error "append filed"
920         $CHECKSTAT -s 8 $file || error "wrong size"
921         rm $file
922 }
923 run_test 23b "O_APPEND check"
924
925 # LU-9409, size with O_APPEND and tiny writes
926 test_23c() {
927         local file=$DIR/$tfile
928
929         # single dd
930         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
931         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
932         rm -f $file
933
934         # racing tiny writes
935         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
936         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
937         wait
938         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
939         rm -f $file
940
941         #racing tiny & normal writes
942         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
943         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
944         wait
945         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
946         rm -f $file
947
948         #racing tiny & normal writes 2, ugly numbers
949         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
950         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
951         wait
952         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
953         rm -f $file
954 }
955 run_test 23c "O_APPEND size checks for tiny writes"
956
957 # LU-11069 file offset is correct after appending writes
958 test_23d() {
959         local file=$DIR/$tfile
960         local offset
961
962         echo CentaurHauls > $file
963         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
964         if ((offset != 26)); then
965                 error "wrong offset, expected 26, got '$offset'"
966         fi
967 }
968 run_test 23d "file offset is correct after appending writes"
969
970 # rename sanity
971 test_24a() {
972         echo '-- same directory rename'
973         test_mkdir $DIR/$tdir
974         touch $DIR/$tdir/$tfile.1
975         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
976         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
977 }
978 run_test 24a "rename file to non-existent target"
979
980 test_24b() {
981         test_mkdir $DIR/$tdir
982         touch $DIR/$tdir/$tfile.{1,2}
983         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
984         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
985         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
986 }
987 run_test 24b "rename file to existing target"
988
989 test_24c() {
990         test_mkdir $DIR/$tdir
991         test_mkdir $DIR/$tdir/d$testnum.1
992         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
993         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
994         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
995 }
996 run_test 24c "rename directory to non-existent target"
997
998 test_24d() {
999         test_mkdir -c1 $DIR/$tdir
1000         test_mkdir -c1 $DIR/$tdir/d$testnum.1
1001         test_mkdir -c1 $DIR/$tdir/d$testnum.2
1002         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
1003         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
1004         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
1005 }
1006 run_test 24d "rename directory to existing target"
1007
1008 test_24e() {
1009         echo '-- cross directory renames --'
1010         test_mkdir $DIR/R5a
1011         test_mkdir $DIR/R5b
1012         touch $DIR/R5a/f
1013         mv $DIR/R5a/f $DIR/R5b/g
1014         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
1015         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
1016 }
1017 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
1018
1019 test_24f() {
1020         test_mkdir $DIR/R6a
1021         test_mkdir $DIR/R6b
1022         touch $DIR/R6a/f $DIR/R6b/g
1023         mv $DIR/R6a/f $DIR/R6b/g
1024         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1025         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1026 }
1027 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1028
1029 test_24g() {
1030         test_mkdir $DIR/R7a
1031         test_mkdir $DIR/R7b
1032         test_mkdir $DIR/R7a/d
1033         mv $DIR/R7a/d $DIR/R7b/e
1034         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1035         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1036 }
1037 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1038
1039 test_24h() {
1040         test_mkdir -c1 $DIR/R8a
1041         test_mkdir -c1 $DIR/R8b
1042         test_mkdir -c1 $DIR/R8a/d
1043         test_mkdir -c1 $DIR/R8b/e
1044         mrename $DIR/R8a/d $DIR/R8b/e
1045         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1046         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1047 }
1048 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1049
1050 test_24i() {
1051         echo "-- rename error cases"
1052         test_mkdir $DIR/R9
1053         test_mkdir $DIR/R9/a
1054         touch $DIR/R9/f
1055         mrename $DIR/R9/f $DIR/R9/a
1056         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1057         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1058         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1059 }
1060 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1061
1062 test_24j() {
1063         test_mkdir $DIR/R10
1064         mrename $DIR/R10/f $DIR/R10/g
1065         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1066         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1067         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1068 }
1069 run_test 24j "source does not exist ============================"
1070
1071 test_24k() {
1072         test_mkdir $DIR/R11a
1073         test_mkdir $DIR/R11a/d
1074         touch $DIR/R11a/f
1075         mv $DIR/R11a/f $DIR/R11a/d
1076         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1077         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1078 }
1079 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1080
1081 # bug 2429 - rename foo foo foo creates invalid file
1082 test_24l() {
1083         f="$DIR/f24l"
1084         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1085 }
1086 run_test 24l "Renaming a file to itself ========================"
1087
1088 test_24m() {
1089         f="$DIR/f24m"
1090         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1091         # on ext3 this does not remove either the source or target files
1092         # though the "expected" operation would be to remove the source
1093         $CHECKSTAT -t file ${f} || error "${f} missing"
1094         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1095 }
1096 run_test 24m "Renaming a file to a hard link to itself ========="
1097
1098 test_24n() {
1099     f="$DIR/f24n"
1100     # this stats the old file after it was renamed, so it should fail
1101     touch ${f}
1102     $CHECKSTAT ${f} || error "${f} missing"
1103     mv ${f} ${f}.rename
1104     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1105     $CHECKSTAT -a ${f} || error "${f} exists"
1106 }
1107 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1108
1109 test_24o() {
1110         test_mkdir $DIR/$tdir
1111         rename_many -s random -v -n 10 $DIR/$tdir
1112 }
1113 run_test 24o "rename of files during htree split"
1114
1115 test_24p() {
1116         test_mkdir $DIR/R12a
1117         test_mkdir $DIR/R12b
1118         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1119         mrename $DIR/R12a $DIR/R12b
1120         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1121         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1122         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1123         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1124 }
1125 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1126
1127 cleanup_multiop_pause() {
1128         trap 0
1129         kill -USR1 $MULTIPID
1130 }
1131
1132 test_24q() {
1133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1134
1135         test_mkdir $DIR/R13a
1136         test_mkdir $DIR/R13b
1137         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1138         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1139         MULTIPID=$!
1140
1141         trap cleanup_multiop_pause EXIT
1142         mrename $DIR/R13a $DIR/R13b
1143         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1144         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1145         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1146         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1147         cleanup_multiop_pause
1148         wait $MULTIPID || error "multiop close failed"
1149 }
1150 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1151
1152 test_24r() { #bug 3789
1153         test_mkdir $DIR/R14a
1154         test_mkdir $DIR/R14a/b
1155         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1156         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1157         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1158 }
1159 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1160
1161 test_24s() {
1162         test_mkdir $DIR/R15a
1163         test_mkdir $DIR/R15a/b
1164         test_mkdir $DIR/R15a/b/c
1165         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1166         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1167         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1168 }
1169 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1170
1171 test_24t() {
1172         test_mkdir $DIR/R16a
1173         test_mkdir $DIR/R16a/b
1174         test_mkdir $DIR/R16a/b/c
1175         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1176         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1177         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1178 }
1179 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1180
1181 test_24u() { # bug12192
1182         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1183         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1184 }
1185 run_test 24u "create stripe file"
1186
1187 simple_cleanup_common() {
1188         local createmany=$1
1189         local rc=0
1190
1191         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1192
1193         local start=$SECONDS
1194
1195         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1196         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1197         rc=$?
1198         wait_delete_completed
1199         echo "cleanup time $((SECONDS - start))"
1200         return $rc
1201 }
1202
1203 max_pages_per_rpc() {
1204         local mdtname="$(printf "MDT%04x" ${1:-0})"
1205         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1206 }
1207
1208 test_24v() {
1209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1210
1211         local nrfiles=${COUNT:-100000}
1212         local fname="$DIR/$tdir/$tfile"
1213
1214         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1215         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1216
1217         test_mkdir "$(dirname $fname)"
1218         # assume MDT0000 has the fewest inodes
1219         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1220         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1221         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1222
1223         stack_trap "simple_cleanup_common $nrfiles"
1224
1225         createmany -m "$fname" $nrfiles
1226
1227         cancel_lru_locks mdc
1228         lctl set_param mdc.*.stats clear
1229
1230         # was previously test_24D: LU-6101
1231         # readdir() returns correct number of entries after cursor reload
1232         local num_ls=$(ls $DIR/$tdir | wc -l)
1233         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1234         local num_all=$(ls -a $DIR/$tdir | wc -l)
1235         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1236                 [ $num_all -ne $((nrfiles + 2)) ]; then
1237                         error "Expected $nrfiles files, got $num_ls " \
1238                                 "($num_uniq unique $num_all .&..)"
1239         fi
1240         # LU-5 large readdir
1241         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1242         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1243         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1244         # take into account of overhead in lu_dirpage header and end mark in
1245         # each page, plus one in rpc_num calculation.
1246         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1247         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1248         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1249         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1250         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1251         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1252         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1253         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1254                 error "large readdir doesn't take effect: " \
1255                       "$mds_readpage should be about $rpc_max"
1256 }
1257 run_test 24v "list large directory (test hash collision, b=17560)"
1258
1259 test_24w() { # bug21506
1260         SZ1=234852
1261         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1262         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1263         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1264         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1265         [[ "$SZ1" -eq "$SZ2" ]] ||
1266                 error "Error reading at the end of the file $tfile"
1267 }
1268 run_test 24w "Reading a file larger than 4Gb"
1269
1270 test_24x() {
1271         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1273         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1274                 skip "Need MDS version at least 2.7.56"
1275
1276         local MDTIDX=1
1277         local remote_dir=$DIR/$tdir/remote_dir
1278
1279         test_mkdir $DIR/$tdir
1280         $LFS mkdir -i $MDTIDX $remote_dir ||
1281                 error "create remote directory failed"
1282
1283         test_mkdir $DIR/$tdir/src_dir
1284         touch $DIR/$tdir/src_file
1285         test_mkdir $remote_dir/tgt_dir
1286         touch $remote_dir/tgt_file
1287
1288         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1289                 error "rename dir cross MDT failed!"
1290
1291         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1292                 error "rename file cross MDT failed!"
1293
1294         touch $DIR/$tdir/ln_file
1295         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1296                 error "ln file cross MDT failed"
1297
1298         rm -rf $DIR/$tdir || error "Can not delete directories"
1299 }
1300 run_test 24x "cross MDT rename/link"
1301
1302 test_24y() {
1303         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1304         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1305
1306         local remote_dir=$DIR/$tdir/remote_dir
1307         local mdtidx=1
1308
1309         test_mkdir $DIR/$tdir
1310         $LFS mkdir -i $mdtidx $remote_dir ||
1311                 error "create remote directory failed"
1312
1313         test_mkdir $remote_dir/src_dir
1314         touch $remote_dir/src_file
1315         test_mkdir $remote_dir/tgt_dir
1316         touch $remote_dir/tgt_file
1317
1318         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1319                 error "rename subdir in the same remote dir failed!"
1320
1321         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1322                 error "rename files in the same remote dir failed!"
1323
1324         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1325                 error "link files in the same remote dir failed!"
1326
1327         rm -rf $DIR/$tdir || error "Can not delete directories"
1328 }
1329 run_test 24y "rename/link on the same dir should succeed"
1330
1331 test_24z() {
1332         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1333         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1334                 skip "Need MDS version at least 2.12.51"
1335
1336         local index
1337
1338         for index in 0 1; do
1339                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1340                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1341         done
1342
1343         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1344
1345         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1346         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1347
1348         local mdts=$(comma_list $(mdts_nodes))
1349
1350         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1351         stack_trap "do_nodes $mdts $LCTL \
1352                 set_param mdt.*.enable_remote_rename=1" EXIT
1353
1354         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1355
1356         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1357         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1358 }
1359 run_test 24z "cross-MDT rename is done as cp"
1360
1361 test_24A() { # LU-3182
1362         local NFILES=5000
1363
1364         test_mkdir $DIR/$tdir
1365         stack_trap "simple_cleanup_common $NFILES"
1366         createmany -m $DIR/$tdir/$tfile $NFILES
1367         local t=$(ls $DIR/$tdir | wc -l)
1368         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1369         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1370
1371         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1372                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1373 }
1374 run_test 24A "readdir() returns correct number of entries."
1375
1376 test_24B() { # LU-4805
1377         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1378
1379         local count
1380
1381         test_mkdir $DIR/$tdir
1382         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir/ ||
1383                 error "create striped dir failed"
1384
1385         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1386         [ $count -eq 2 ] || error "Expected 2, got $count"
1387
1388         touch $DIR/$tdir/striped_dir/a
1389
1390         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1391         [ $count -eq 3 ] || error "Expected 3, got $count"
1392
1393         touch $DIR/$tdir/striped_dir/.f
1394
1395         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1396         [ $count -eq 4 ] || error "Expected 4, got $count"
1397
1398         rm -rf $DIR/$tdir || error "Can not delete directories"
1399 }
1400 run_test 24B "readdir for striped dir return correct number of entries"
1401
1402 test_24C() {
1403         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1404
1405         mkdir $DIR/$tdir
1406         mkdir $DIR/$tdir/d0
1407         mkdir $DIR/$tdir/d1
1408
1409         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1410                 error "create striped dir failed"
1411
1412         cd $DIR/$tdir/d0/striped_dir
1413
1414         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1415         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1416         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1417
1418         [ "$d0_ino" = "$parent_ino" ] ||
1419                 error ".. wrong, expect $d0_ino, get $parent_ino"
1420
1421         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1422                 error "mv striped dir failed"
1423
1424         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1425
1426         [ "$d1_ino" = "$parent_ino" ] ||
1427                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1428 }
1429 run_test 24C "check .. in striped dir"
1430
1431 test_24E() {
1432         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1434
1435         mkdir -p $DIR/$tdir
1436         mkdir $DIR/$tdir/src_dir
1437         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1438                 error "create remote source failed"
1439
1440         touch $DIR/$tdir/src_dir/src_child/a
1441
1442         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1443                 error "create remote target dir failed"
1444
1445         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1446                 error "create remote target child failed"
1447
1448         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1449                 error "rename dir cross MDT failed!"
1450
1451         find $DIR/$tdir
1452
1453         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1454                 error "src_child still exists after rename"
1455
1456         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1457                 error "missing file(a) after rename"
1458
1459         rm -rf $DIR/$tdir || error "Can not delete directories"
1460 }
1461 run_test 24E "cross MDT rename/link"
1462
1463 test_24F () {
1464         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1465
1466         local repeats=1000
1467         [ "$SLOW" = "no" ] && repeats=100
1468
1469         mkdir -p $DIR/$tdir
1470
1471         echo "$repeats repeats"
1472         for ((i = 0; i < repeats; i++)); do
1473                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1474                 touch $DIR/$tdir/test/a || error "touch fails"
1475                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1476                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1477         done
1478
1479         true
1480 }
1481 run_test 24F "hash order vs readdir (LU-11330)"
1482
1483 test_24G () {
1484         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1485
1486         local ino1
1487         local ino2
1488
1489         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1490         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1491         touch $DIR/$tdir-0/f1 || error "touch f1"
1492         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1493         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1494         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1495         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1496         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1497 }
1498 run_test 24G "migrate symlink in rename"
1499
1500 test_24H() {
1501         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1502         [[ $(hostname) != $(facet_active_host mds2) ]] ||
1503                 skip "MDT1 should be on another node"
1504
1505         test_mkdir -i 1 -c 1 $DIR/$tdir
1506 #define OBD_FAIL_FLD_QUERY_REQ           0x1103
1507         do_facet mds2 $LCTL set_param fail_loc=0x80001103
1508         touch $DIR/$tdir/$tfile || error "touch failed"
1509 }
1510 run_test 24H "repeat FLD_QUERY rpc"
1511
1512 test_25a() {
1513         echo '== symlink sanity ============================================='
1514
1515         test_mkdir $DIR/d25
1516         ln -s d25 $DIR/s25
1517         touch $DIR/s25/foo ||
1518                 error "File creation in symlinked directory failed"
1519 }
1520 run_test 25a "create file in symlinked directory ==============="
1521
1522 test_25b() {
1523         [ ! -d $DIR/d25 ] && test_25a
1524         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1525 }
1526 run_test 25b "lookup file in symlinked directory ==============="
1527
1528 test_26a() {
1529         test_mkdir $DIR/d26
1530         test_mkdir $DIR/d26/d26-2
1531         ln -s d26/d26-2 $DIR/s26
1532         touch $DIR/s26/foo || error "File creation failed"
1533 }
1534 run_test 26a "multiple component symlink ======================="
1535
1536 test_26b() {
1537         test_mkdir -p $DIR/$tdir/d26-2
1538         ln -s $tdir/d26-2/foo $DIR/s26-2
1539         touch $DIR/s26-2 || error "File creation failed"
1540 }
1541 run_test 26b "multiple component symlink at end of lookup ======"
1542
1543 test_26c() {
1544         test_mkdir $DIR/d26.2
1545         touch $DIR/d26.2/foo
1546         ln -s d26.2 $DIR/s26.2-1
1547         ln -s s26.2-1 $DIR/s26.2-2
1548         ln -s s26.2-2 $DIR/s26.2-3
1549         chmod 0666 $DIR/s26.2-3/foo
1550 }
1551 run_test 26c "chain of symlinks"
1552
1553 # recursive symlinks (bug 439)
1554 test_26d() {
1555         ln -s d26-3/foo $DIR/d26-3
1556 }
1557 run_test 26d "create multiple component recursive symlink"
1558
1559 test_26e() {
1560         [ ! -h $DIR/d26-3 ] && test_26d
1561         rm $DIR/d26-3
1562 }
1563 run_test 26e "unlink multiple component recursive symlink"
1564
1565 # recursive symlinks (bug 7022)
1566 test_26f() {
1567         test_mkdir $DIR/$tdir
1568         test_mkdir $DIR/$tdir/$tfile
1569         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1570         test_mkdir -p lndir/bar1
1571         test_mkdir $DIR/$tdir/$tfile/$tfile
1572         cd $tfile                || error "cd $tfile failed"
1573         ln -s .. dotdot          || error "ln dotdot failed"
1574         ln -s dotdot/lndir lndir || error "ln lndir failed"
1575         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1576         output=`ls $tfile/$tfile/lndir/bar1`
1577         [ "$output" = bar1 ] && error "unexpected output"
1578         rm -r $tfile             || error "rm $tfile failed"
1579         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1580 }
1581 run_test 26f "rm -r of a directory which has recursive symlink"
1582
1583 test_27a() {
1584         test_mkdir $DIR/$tdir
1585         $LFS getstripe $DIR/$tdir
1586         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1587         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1588         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1589 }
1590 run_test 27a "one stripe file"
1591
1592 test_27b() {
1593         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1594
1595         test_mkdir $DIR/$tdir
1596         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1597         $LFS getstripe -c $DIR/$tdir/$tfile
1598         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1599                 error "two-stripe file doesn't have two stripes"
1600
1601         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1602 }
1603 run_test 27b "create and write to two stripe file"
1604
1605 # 27c family tests specific striping, setstripe -o
1606 test_27ca() {
1607         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1608         test_mkdir -p $DIR/$tdir
1609         local osts="1"
1610
1611         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1612         $LFS getstripe -i $DIR/$tdir/$tfile
1613         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1614                 error "stripe not on specified OST"
1615
1616         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1617 }
1618 run_test 27ca "one stripe on specified OST"
1619
1620 test_27cb() {
1621         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1622         test_mkdir -p $DIR/$tdir
1623         local osts="1,0"
1624         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1625         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1626         echo "$getstripe"
1627
1628         # Strip getstripe output to a space separated list of OSTs
1629         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1630                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1631         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1632                 error "stripes not on specified OSTs"
1633
1634         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1635 }
1636 run_test 27cb "two stripes on specified OSTs"
1637
1638 test_27cc() {
1639         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1640         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1641                 skip "server does not support overstriping"
1642
1643         test_mkdir -p $DIR/$tdir
1644         local osts="0,0"
1645         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1646         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1647         echo "$getstripe"
1648
1649         # Strip getstripe output to a space separated list of OSTs
1650         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1651                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1652         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1653                 error "stripes not on specified OSTs"
1654
1655         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1656 }
1657 run_test 27cc "two stripes on the same OST"
1658
1659 test_27cd() {
1660         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1661         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1662                 skip "server does not support overstriping"
1663         test_mkdir -p $DIR/$tdir
1664         local osts="0,1,1,0"
1665         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1666         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1667         echo "$getstripe"
1668
1669         # Strip getstripe output to a space separated list of OSTs
1670         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1671                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1672         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1673                 error "stripes not on specified OSTs"
1674
1675         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1676 }
1677 run_test 27cd "four stripes on two OSTs"
1678
1679 test_27ce() {
1680         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1681                 skip_env "too many osts, skipping"
1682         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1683                 skip "server does not support overstriping"
1684         # We do one more stripe than we have OSTs
1685         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1686                 skip_env "ea_inode feature disabled"
1687
1688         test_mkdir -p $DIR/$tdir
1689         local osts=""
1690         for i in $(seq 0 $OSTCOUNT);
1691         do
1692                 osts=$osts"0"
1693                 if [ $i -ne $OSTCOUNT ]; then
1694                         osts=$osts","
1695                 fi
1696         done
1697         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1698         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1699         echo "$getstripe"
1700
1701         # Strip getstripe output to a space separated list of OSTs
1702         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1703                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1704         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1705                 error "stripes not on specified OSTs"
1706
1707         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1708 }
1709 run_test 27ce "more stripes than OSTs with -o"
1710
1711 test_27cf() {
1712         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1713         local pid=0
1714
1715         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1716         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1717         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1718         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1719                 error "failed to set $osp_proc=0"
1720
1721         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1722         pid=$!
1723         sleep 1
1724         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1725         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1726                 error "failed to set $osp_proc=1"
1727         wait $pid
1728         [[ $pid -ne 0 ]] ||
1729                 error "should return error due to $osp_proc=0"
1730 }
1731 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1732
1733 test_27cg() {
1734         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1735                 skip "server does not support overstriping"
1736         [[ $mds1_FSTYPE != "ldiskfs" ]] && skip_env "ldiskfs only test"
1737         large_xattr_enabled || skip_env "ea_inode feature disabled"
1738
1739         local osts="0"
1740
1741         for ((i=1;i<1000;i++)); do
1742                 osts+=",$((i % OSTCOUNT))"
1743         done
1744
1745         local mdts=$(comma_list $(mdts_nodes))
1746         local before=$(do_nodes $mdts \
1747                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1748                 awk '/many credits/{print $3}' |
1749                 calc_sum)
1750
1751         $LFS setstripe -o $osts $DIR/$tfile || error "setstripe failed"
1752         $LFS getstripe $DIR/$tfile | grep stripe
1753
1754         rm -f $DIR/$tfile || error "can't unlink"
1755
1756         after=$(do_nodes $mdts \
1757                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1758                 awk '/many credits/{print $3}' |
1759                 calc_sum)
1760
1761         (( before == after )) ||
1762                 error "too many credits happened: $after > $before"
1763 }
1764 run_test 27cg "1000 shouldn't cause too many credits"
1765
1766 test_27d() {
1767         test_mkdir $DIR/$tdir
1768         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1769                 error "setstripe failed"
1770         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1771         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1772 }
1773 run_test 27d "create file with default settings"
1774
1775 test_27e() {
1776         # LU-5839 adds check for existed layout before setting it
1777         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1778                 skip "Need MDS version at least 2.7.56"
1779
1780         test_mkdir $DIR/$tdir
1781         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1782         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1783         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1784 }
1785 run_test 27e "setstripe existing file (should return error)"
1786
1787 test_27f() {
1788         test_mkdir $DIR/$tdir
1789         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1790                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1791         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1792                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1793         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1794         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1795 }
1796 run_test 27f "setstripe with bad stripe size (should return error)"
1797
1798 test_27g() {
1799         test_mkdir $DIR/$tdir
1800         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1801         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1802                 error "$DIR/$tdir/$tfile has object"
1803 }
1804 run_test 27g "$LFS getstripe with no objects"
1805
1806 test_27ga() {
1807         test_mkdir $DIR/$tdir
1808         touch $DIR/$tdir/$tfile || error "touch failed"
1809         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1810         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1811         local rc=$?
1812         (( rc == 2 )) || error "getstripe did not return ENOENT"
1813
1814         local err_msg=$($LFS getstripe $DIR/$tdir/typo $DIR/$tdir/$tfile \
1815                         2>&1 > /dev/null)
1816         [[ $err_msg =~ "typo" ]] ||
1817                 error "expected message with correct filename, got '$err_msg'"
1818 }
1819 run_test 27ga "$LFS getstripe with missing file (should return error)"
1820
1821 test_27i() {
1822         test_mkdir $DIR/$tdir
1823         touch $DIR/$tdir/$tfile || error "touch failed"
1824         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1825                 error "missing objects"
1826 }
1827 run_test 27i "$LFS getstripe with some objects"
1828
1829 test_27j() {
1830         test_mkdir $DIR/$tdir
1831         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1832                 error "setstripe failed" || true
1833 }
1834 run_test 27j "setstripe with bad stripe offset (should return error)"
1835
1836 test_27k() { # bug 2844
1837         test_mkdir $DIR/$tdir
1838         local file=$DIR/$tdir/$tfile
1839         local ll_max_blksize=$((4 * 1024 * 1024))
1840         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1841         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1842         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1843         dd if=/dev/zero of=$file bs=4k count=1
1844         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1845         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1846 }
1847 run_test 27k "limit i_blksize for broken user apps"
1848
1849 test_27l() {
1850         mcreate $DIR/$tfile || error "creating file"
1851         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1852                 error "setstripe should have failed" || true
1853 }
1854 run_test 27l "check setstripe permissions (should return error)"
1855
1856 test_27m() {
1857         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1858
1859         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1860                 skip_env "multiple clients -- skipping"
1861
1862         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1863                    head -n1)
1864         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1865                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1866         fi
1867         stack_trap simple_cleanup_common
1868         test_mkdir $DIR/$tdir
1869         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1870         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1871                 error "dd should fill OST0"
1872         i=2
1873         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1874                 i=$((i + 1))
1875                 [ $i -gt 256 ] && break
1876         done
1877         i=$((i + 1))
1878         touch $DIR/$tdir/$tfile.$i
1879         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1880             awk '{print $1}'| grep -w "0") ] &&
1881                 error "OST0 was full but new created file still use it"
1882         i=$((i + 1))
1883         touch $DIR/$tdir/$tfile.$i
1884         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1885             awk '{print $1}'| grep -w "0") ] &&
1886                 error "OST0 was full but new created file still use it" || true
1887 }
1888 run_test 27m "create file while OST0 was full"
1889
1890 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1891 # if the OST isn't full anymore.
1892 reset_enospc() {
1893         local ostidx=${1:-""}
1894         local delay
1895         local ready
1896         local get_prealloc
1897
1898         local list=$(comma_list $(osts_nodes))
1899         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1900
1901         do_nodes $list lctl set_param fail_loc=0
1902         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1903         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1904                 awk '{print $1 * 2;exit;}')
1905         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1906                         grep -v \"^0$\""
1907         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1908 }
1909
1910 test_27n() {
1911         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1913         remote_mds_nodsh && skip "remote MDS with nodsh"
1914         remote_ost_nodsh && skip "remote OST with nodsh"
1915
1916         reset_enospc
1917         rm -f $DIR/$tdir/$tfile
1918         exhaust_precreations 0 0x80000215
1919         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1920         touch $DIR/$tdir/$tfile || error "touch failed"
1921         $LFS getstripe $DIR/$tdir/$tfile
1922         reset_enospc
1923 }
1924 run_test 27n "create file with some full OSTs"
1925
1926 test_27o() {
1927         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1929         remote_mds_nodsh && skip "remote MDS with nodsh"
1930         remote_ost_nodsh && skip "remote OST with nodsh"
1931
1932         reset_enospc
1933         rm -f $DIR/$tdir/$tfile
1934         exhaust_all_precreations 0x215
1935
1936         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1937
1938         reset_enospc
1939         rm -rf $DIR/$tdir/*
1940 }
1941 run_test 27o "create file with all full OSTs (should error)"
1942
1943 function create_and_checktime() {
1944         local fname=$1
1945         local loops=$2
1946         local i
1947
1948         for ((i=0; i < $loops; i++)); do
1949                 local start=$SECONDS
1950                 multiop $fname-$i Oc
1951                 ((SECONDS-start < TIMEOUT)) ||
1952                         error "creation took " $((SECONDS-$start)) && return 1
1953         done
1954 }
1955
1956 test_27oo() {
1957         local mdts=$(comma_list $(mdts_nodes))
1958
1959         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1960                 skip "Need MDS version at least 2.13.57"
1961
1962         local f0=$DIR/${tfile}-0
1963         local f1=$DIR/${tfile}-1
1964
1965         wait_delete_completed
1966
1967         # refill precreated objects
1968         $LFS setstripe -i0 -c1 $f0
1969
1970         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1971         # force QoS allocation policy
1972         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1973         stack_trap "do_nodes $mdts $LCTL set_param \
1974                 lov.*.qos_threshold_rr=$saved" EXIT
1975         sleep_maxage
1976
1977         # one OST is unavailable, but still have few objects preallocated
1978         stop ost1
1979         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1980                 rm -rf $f1 $DIR/$tdir*" EXIT
1981
1982         for ((i=0; i < 7; i++)); do
1983                 mkdir $DIR/$tdir$i || error "can't create dir"
1984                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1985                         error "can't set striping"
1986         done
1987         for ((i=0; i < 7; i++)); do
1988                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1989         done
1990         wait
1991 }
1992 run_test 27oo "don't let few threads to reserve too many objects"
1993
1994 test_27p() {
1995         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1997         remote_mds_nodsh && skip "remote MDS with nodsh"
1998         remote_ost_nodsh && skip "remote OST with nodsh"
1999
2000         reset_enospc
2001         rm -f $DIR/$tdir/$tfile
2002         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
2003
2004         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
2005         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
2006         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
2007
2008         exhaust_precreations 0 0x80000215
2009         echo foo >> $DIR/$tdir/$tfile || error "append failed"
2010         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
2011         $LFS getstripe $DIR/$tdir/$tfile
2012
2013         reset_enospc
2014 }
2015 run_test 27p "append to a truncated file with some full OSTs"
2016
2017 test_27q() {
2018         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2019         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2020         remote_mds_nodsh && skip "remote MDS with nodsh"
2021         remote_ost_nodsh && skip "remote OST with nodsh"
2022
2023         reset_enospc
2024         rm -f $DIR/$tdir/$tfile
2025
2026         mkdir_on_mdt0 $DIR/$tdir
2027         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
2028         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
2029                 error "truncate $DIR/$tdir/$tfile failed"
2030         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
2031
2032         exhaust_all_precreations 0x215
2033
2034         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
2035         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
2036
2037         reset_enospc
2038 }
2039 run_test 27q "append to truncated file with all OSTs full (should error)"
2040
2041 test_27r() {
2042         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2044         remote_mds_nodsh && skip "remote MDS with nodsh"
2045         remote_ost_nodsh && skip "remote OST with nodsh"
2046
2047         reset_enospc
2048         rm -f $DIR/$tdir/$tfile
2049         exhaust_precreations 0 0x80000215
2050
2051         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2052
2053         reset_enospc
2054 }
2055 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2056
2057 test_27s() { # bug 10725
2058         test_mkdir $DIR/$tdir
2059         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2060         local stripe_count=0
2061         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2062         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2063                 error "stripe width >= 2^32 succeeded" || true
2064
2065 }
2066 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2067
2068 test_27t() { # bug 10864
2069         WDIR=$(pwd)
2070         WLFS=$(which lfs)
2071         cd $DIR
2072         touch $tfile
2073         $WLFS getstripe $tfile
2074         cd $WDIR
2075 }
2076 run_test 27t "check that utils parse path correctly"
2077
2078 test_27u() { # bug 4900
2079         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2080         remote_mds_nodsh && skip "remote MDS with nodsh"
2081
2082         local index
2083         local list=$(comma_list $(mdts_nodes))
2084
2085 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2086         do_nodes $list $LCTL set_param fail_loc=0x139
2087         test_mkdir -p $DIR/$tdir
2088         stack_trap "simple_cleanup_common 1000"
2089         createmany -o $DIR/$tdir/$tfile 1000
2090         do_nodes $list $LCTL set_param fail_loc=0
2091
2092         TLOG=$TMP/$tfile.getstripe
2093         $LFS getstripe $DIR/$tdir > $TLOG
2094         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2095         [[ $OBJS -gt 0 ]] &&
2096                 error "$OBJS objects created on OST-0. See $TLOG" ||
2097                 rm -f $TLOG
2098 }
2099 run_test 27u "skip object creation on OSC w/o objects"
2100
2101 test_27v() { # bug 4900
2102         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2104         remote_mds_nodsh && skip "remote MDS with nodsh"
2105         remote_ost_nodsh && skip "remote OST with nodsh"
2106
2107         exhaust_all_precreations 0x215
2108         reset_enospc
2109
2110         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2111
2112         touch $DIR/$tdir/$tfile
2113         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2114         # all except ost1
2115         for (( i=1; i < OSTCOUNT; i++ )); do
2116                 do_facet ost$i lctl set_param fail_loc=0x705
2117         done
2118         local START=`date +%s`
2119         createmany -o $DIR/$tdir/$tfile 32
2120
2121         local FINISH=`date +%s`
2122         local TIMEOUT=`lctl get_param -n timeout`
2123         local PROCESS=$((FINISH - START))
2124         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2125                error "$FINISH - $START >= $TIMEOUT / 2"
2126         sleep $((TIMEOUT / 2 - PROCESS))
2127         reset_enospc
2128 }
2129 run_test 27v "skip object creation on slow OST"
2130
2131 test_27w() { # bug 10997
2132         test_mkdir $DIR/$tdir
2133         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2134         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2135                 error "stripe size $size != 65536" || true
2136         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2137                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2138 }
2139 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2140
2141 test_27wa() {
2142         [[ $OSTCOUNT -lt 2 ]] &&
2143                 skip_env "skipping multiple stripe count/offset test"
2144
2145         test_mkdir $DIR/$tdir
2146         for i in $(seq 1 $OSTCOUNT); do
2147                 offset=$((i - 1))
2148                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2149                         error "setstripe -c $i -i $offset failed"
2150                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2151                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2152                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2153                 [ $index -ne $offset ] &&
2154                         error "stripe offset $index != $offset" || true
2155         done
2156 }
2157 run_test 27wa "check $LFS setstripe -c -i options"
2158
2159 test_27x() {
2160         remote_ost_nodsh && skip "remote OST with nodsh"
2161         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2163
2164         OFFSET=$(($OSTCOUNT - 1))
2165         OSTIDX=0
2166         local OST=$(ostname_from_index $OSTIDX)
2167
2168         test_mkdir $DIR/$tdir
2169         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2170         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2171         sleep_maxage
2172         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2173         for i in $(seq 0 $OFFSET); do
2174                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2175                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2176                 error "OST0 was degraded but new created file still use it"
2177         done
2178         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2179 }
2180 run_test 27x "create files while OST0 is degraded"
2181
2182 test_27y() {
2183         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2184         remote_mds_nodsh && skip "remote MDS with nodsh"
2185         remote_ost_nodsh && skip "remote OST with nodsh"
2186         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2187
2188         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2189         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2190                 osp.$mdtosc.prealloc_last_id)
2191         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2192                 osp.$mdtosc.prealloc_next_id)
2193         local fcount=$((last_id - next_id))
2194         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2195         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2196
2197         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2198                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2199         local OST_DEACTIVE_IDX=-1
2200         local OSC
2201         local OSTIDX
2202         local OST
2203
2204         for OSC in $MDS_OSCS; do
2205                 OST=$(osc_to_ost $OSC)
2206                 OSTIDX=$(index_from_ostuuid $OST)
2207                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2208                         OST_DEACTIVE_IDX=$OSTIDX
2209                 fi
2210                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2211                         echo $OSC "is Deactivated:"
2212                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2213                 fi
2214         done
2215
2216         OSTIDX=$(index_from_ostuuid $OST)
2217         test_mkdir $DIR/$tdir
2218         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2219
2220         for OSC in $MDS_OSCS; do
2221                 OST=$(osc_to_ost $OSC)
2222                 OSTIDX=$(index_from_ostuuid $OST)
2223                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2224                         echo $OST "is degraded:"
2225                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2226                                                 obdfilter.$OST.degraded=1
2227                 fi
2228         done
2229
2230         sleep_maxage
2231         createmany -o $DIR/$tdir/$tfile $fcount
2232
2233         for OSC in $MDS_OSCS; do
2234                 OST=$(osc_to_ost $OSC)
2235                 OSTIDX=$(index_from_ostuuid $OST)
2236                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2237                         echo $OST "is recovered from degraded:"
2238                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2239                                                 obdfilter.$OST.degraded=0
2240                 else
2241                         do_facet $SINGLEMDS lctl --device %$OSC activate
2242                 fi
2243         done
2244
2245         # all osp devices get activated, hence -1 stripe count restored
2246         local stripe_count=0
2247
2248         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2249         # devices get activated.
2250         sleep_maxage
2251         $LFS setstripe -c -1 $DIR/$tfile
2252         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2253         rm -f $DIR/$tfile
2254         [ $stripe_count -ne $OSTCOUNT ] &&
2255                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2256         return 0
2257 }
2258 run_test 27y "create files while OST0 is degraded and the rest inactive"
2259
2260 check_seq_oid()
2261 {
2262         log "check file $1"
2263
2264         lmm_count=$($LFS getstripe -c $1)
2265         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2266         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2267
2268         local old_ifs="$IFS"
2269         IFS=$'[:]'
2270         fid=($($LFS path2fid $1))
2271         IFS="$old_ifs"
2272
2273         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2274         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2275
2276         # compare lmm_seq and lu_fid->f_seq
2277         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2278         # compare lmm_object_id and lu_fid->oid
2279         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2280
2281         # check the trusted.fid attribute of the OST objects of the file
2282         local have_obdidx=false
2283         local stripe_nr=0
2284         $LFS getstripe $1 | while read obdidx oid hex seq; do
2285                 # skip lines up to and including "obdidx"
2286                 [ -z "$obdidx" ] && break
2287                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2288                 $have_obdidx || continue
2289
2290                 local ost=$((obdidx + 1))
2291                 local dev=$(ostdevname $ost)
2292                 local oid_hex
2293
2294                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2295
2296                 seq=$(echo $seq | sed -e "s/^0x//g")
2297                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2298                         oid_hex=$(echo $oid)
2299                 else
2300                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2301                 fi
2302                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2303
2304                 local ff=""
2305                 #
2306                 # Don't unmount/remount the OSTs if we don't need to do that.
2307                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2308                 # update too, until that use mount/ll_decode_filter_fid/mount.
2309                 # Re-enable when debugfs will understand new filter_fid.
2310                 #
2311                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2312                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2313                                 $dev 2>/dev/null" | grep "parent=")
2314                 fi
2315                 if [ -z "$ff" ]; then
2316                         stop ost$ost
2317                         mount_fstype ost$ost
2318                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2319                                 $(facet_mntpt ost$ost)/$obj_file)
2320                         unmount_fstype ost$ost
2321                         start ost$ost $dev $OST_MOUNT_OPTS
2322                         clients_up
2323                 fi
2324
2325                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2326
2327                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2328
2329                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2330                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2331                 #
2332                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2333                 #       stripe_size=1048576 component_id=1 component_start=0 \
2334                 #       component_end=33554432
2335                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2336                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2337                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2338                 local ff_pstripe
2339                 if grep -q 'stripe=' <<<$ff; then
2340                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2341                 else
2342                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2343                         # into f_ver in this case.  See comment on ff_parent.
2344                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2345                 fi
2346
2347                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2348                 [ $ff_pseq = $lmm_seq ] ||
2349                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2350                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2351                 [ $ff_poid = $lmm_oid ] ||
2352                         error "FF parent OID $ff_poid != $lmm_oid"
2353                 (($ff_pstripe == $stripe_nr)) ||
2354                         error "FF stripe $ff_pstripe != $stripe_nr"
2355
2356                 stripe_nr=$((stripe_nr + 1))
2357                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2358                         continue
2359                 if grep -q 'stripe_count=' <<<$ff; then
2360                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2361                                             -e 's/ .*//' <<<$ff)
2362                         [ $lmm_count = $ff_scnt ] ||
2363                                 error "FF stripe count $lmm_count != $ff_scnt"
2364                 fi
2365         done
2366 }
2367
2368 test_27z() {
2369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2370         remote_ost_nodsh && skip "remote OST with nodsh"
2371
2372         test_mkdir $DIR/$tdir
2373         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2374                 { error "setstripe -c -1 failed"; return 1; }
2375         # We need to send a write to every object to get parent FID info set.
2376         # This _should_ also work for setattr, but does not currently.
2377         # touch $DIR/$tdir/$tfile-1 ||
2378         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2379                 { error "dd $tfile-1 failed"; return 2; }
2380         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2381                 { error "setstripe -c -1 failed"; return 3; }
2382         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2383                 { error "dd $tfile-2 failed"; return 4; }
2384
2385         # make sure write RPCs have been sent to OSTs
2386         sync; sleep 5; sync
2387
2388         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2389         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2390 }
2391 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2392
2393 test_27A() { # b=19102
2394         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2395
2396         save_layout_restore_at_exit $MOUNT
2397         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2398         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2399                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2400         local default_size=$($LFS getstripe -S $MOUNT)
2401         local default_offset=$($LFS getstripe -i $MOUNT)
2402         local dsize=$(do_facet $SINGLEMDS \
2403                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2404         [ $default_size -eq $dsize ] ||
2405                 error "stripe size $default_size != $dsize"
2406         [ $default_offset -eq -1 ] ||
2407                 error "stripe offset $default_offset != -1"
2408 }
2409 run_test 27A "check filesystem-wide default LOV EA values"
2410
2411 test_27B() { # LU-2523
2412         test_mkdir $DIR/$tdir
2413         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2414         touch $DIR/$tdir/f0
2415         # open f1 with O_LOV_DELAY_CREATE
2416         # rename f0 onto f1
2417         # call setstripe ioctl on open file descriptor for f1
2418         # close
2419         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2420                 $DIR/$tdir/f0
2421
2422         rm -f $DIR/$tdir/f1
2423         # open f1 with O_LOV_DELAY_CREATE
2424         # unlink f1
2425         # call setstripe ioctl on open file descriptor for f1
2426         # close
2427         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2428
2429         # Allow multiop to fail in imitation of NFS's busted semantics.
2430         true
2431 }
2432 run_test 27B "call setstripe on open unlinked file/rename victim"
2433
2434 # 27C family tests full striping and overstriping
2435 test_27Ca() { #LU-2871
2436         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2437
2438         declare -a ost_idx
2439         local index
2440         local found
2441         local i
2442         local j
2443
2444         test_mkdir $DIR/$tdir
2445         cd $DIR/$tdir
2446         for i in $(seq 0 $((OSTCOUNT - 1))); do
2447                 # set stripe across all OSTs starting from OST$i
2448                 $LFS setstripe -i $i -c -1 $tfile$i
2449                 # get striping information
2450                 ost_idx=($($LFS getstripe $tfile$i |
2451                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2452                 echo "OST Index: ${ost_idx[*]}"
2453
2454                 # check the layout
2455                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2456                         error "${#ost_idx[@]} != $OSTCOUNT"
2457
2458                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2459                         found=0
2460                         for j in "${ost_idx[@]}"; do
2461                                 if [ $index -eq $j ]; then
2462                                         found=1
2463                                         break
2464                                 fi
2465                         done
2466                         [ $found = 1 ] ||
2467                                 error "Can not find $index in ${ost_idx[*]}"
2468                 done
2469         done
2470 }
2471 run_test 27Ca "check full striping across all OSTs"
2472
2473 test_27Cb() {
2474         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2475                 skip "server does not support overstriping"
2476         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2477                 skip_env "too many osts, skipping"
2478
2479         test_mkdir -p $DIR/$tdir
2480         local setcount=$(($OSTCOUNT * 2))
2481         [ $setcount -lt 160 ] || large_xattr_enabled ||
2482                 skip_env "ea_inode feature disabled"
2483
2484         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2485                 error "setstripe failed"
2486
2487         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2488         [ $count -eq $setcount ] ||
2489                 error "stripe count $count, should be $setcount"
2490
2491         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2492                 error "overstriped should be set in pattern"
2493
2494         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2495                 error "dd failed"
2496 }
2497 run_test 27Cb "more stripes than OSTs with -C"
2498
2499 test_27Cc() {
2500         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2501                 skip "server does not support overstriping"
2502         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2503
2504         test_mkdir -p $DIR/$tdir
2505         local setcount=$(($OSTCOUNT - 1))
2506
2507         [ $setcount -lt 160 ] || large_xattr_enabled ||
2508                 skip_env "ea_inode feature disabled"
2509
2510         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2511                 error "setstripe failed"
2512
2513         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2514         [ $count -eq $setcount ] ||
2515                 error "stripe count $count, should be $setcount"
2516
2517         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2518                 error "overstriped should not be set in pattern"
2519
2520         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2521                 error "dd failed"
2522 }
2523 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2524
2525 test_27Cd() {
2526         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2527                 skip "server does not support overstriping"
2528         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2529         large_xattr_enabled || skip_env "ea_inode feature disabled"
2530
2531         force_new_seq_all
2532
2533         test_mkdir -p $DIR/$tdir
2534         local setcount=$LOV_MAX_STRIPE_COUNT
2535
2536         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2537                 error "setstripe failed"
2538
2539         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2540         [ $count -eq $setcount ] ||
2541                 error "stripe count $count, should be $setcount"
2542
2543         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2544                 error "overstriped should be set in pattern"
2545
2546         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2547                 error "dd failed"
2548
2549         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2550 }
2551 run_test 27Cd "test maximum stripe count"
2552
2553 test_27Ce() {
2554         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2555                 skip "server does not support overstriping"
2556         test_mkdir -p $DIR/$tdir
2557
2558         pool_add $TESTNAME || error "Pool creation failed"
2559         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2560
2561         local setcount=8
2562
2563         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2564                 error "setstripe failed"
2565
2566         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2567         [ $count -eq $setcount ] ||
2568                 error "stripe count $count, should be $setcount"
2569
2570         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2571                 error "overstriped should be set in pattern"
2572
2573         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2574                 error "dd failed"
2575
2576         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2577 }
2578 run_test 27Ce "test pool with overstriping"
2579
2580 test_27Cf() {
2581         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2582                 skip "server does not support overstriping"
2583         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2584                 skip_env "too many osts, skipping"
2585
2586         test_mkdir -p $DIR/$tdir
2587
2588         local setcount=$(($OSTCOUNT * 2))
2589         [ $setcount -lt 160 ] || large_xattr_enabled ||
2590                 skip_env "ea_inode feature disabled"
2591
2592         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2593                 error "setstripe failed"
2594
2595         echo 1 > $DIR/$tdir/$tfile
2596
2597         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2598         [ $count -eq $setcount ] ||
2599                 error "stripe count $count, should be $setcount"
2600
2601         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2602                 error "overstriped should be set in pattern"
2603
2604         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2605                 error "dd failed"
2606
2607         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2608 }
2609 run_test 27Cf "test default inheritance with overstriping"
2610
2611 test_27Cg() {
2612         (( MDS1_VERSION >= $(version_code v2_15_55-80-gd96b98ee6b) )) ||
2613                 skip "need MDS version at least v2_15_55-80-gd96b98ee6b for fix"
2614
2615         $LFS setstripe -o 0,$OSTCOUNT $DIR/$tfile
2616         (( $? != 0 )) || error "must be an error for not existent OST#"
2617 }
2618 run_test 27Cg "test setstripe with wrong OST idx"
2619
2620 test_27Ci() {
2621         local tf=$DIR/$tfile
2622
2623         stack_trap "rm -f $DIR/$tfile"
2624
2625         $LFS setstripe -E1M $tf || error "create $tf failed"
2626         $LFS setstripe -Eeof --component-add -C 100 $tf ||
2627                 error "add component failed"
2628
2629         $LFS getstripe -I2 $tf | awk '/lmm_pattern/ { print $2 }' |
2630                 grep "overstriped" || {
2631                 $LFS getstripe $tf
2632                 echo "lose overstriping setting"
2633         }
2634         sc=$($LFS getstripe -I2 --stripe-count $tf)
2635         (( $sc == 100 )) || {
2636                 $LFS getstripe $tf
2637                 echo "lose overstriping setting"
2638         }
2639
2640         stack_trap "rm -f $tf"
2641         dd if=/dev/zero of=$tf bs=1M count=10 || error "write $tf"
2642         sc=$($LFS getstripe -I2 --stripe-count $tf)
2643         (( $sc == 100 )) || {
2644                 $LFS getstripe $tf
2645                 echo "lose overstriping setting after instantiation"
2646         }
2647 }
2648 run_test 27Ci "add an overstriping component"
2649
2650 test_27D() {
2651         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2652         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2653         remote_mds_nodsh && skip "remote MDS with nodsh"
2654
2655         local POOL=${POOL:-testpool}
2656         local first_ost=0
2657         local last_ost=$(($OSTCOUNT - 1))
2658         local ost_step=1
2659         local ost_list=$(seq $first_ost $ost_step $last_ost)
2660         local ost_range="$first_ost $last_ost $ost_step"
2661
2662         test_mkdir $DIR/$tdir
2663         pool_add $POOL || error "pool_add failed"
2664         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2665
2666         local skip27D
2667         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2668                 skip27D+="-s 29"
2669         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2670                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2671                         skip27D+=" -s 30,31"
2672         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2673           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2674                 skip27D+=" -s 32,33"
2675         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2676                 skip27D+=" -s 34"
2677         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2678                 error "llapi_layout_test failed"
2679
2680         destroy_test_pools || error "destroy test pools failed"
2681 }
2682 run_test 27D "validate llapi_layout API"
2683
2684 # Verify that default_easize is increased from its initial value after
2685 # accessing a widely striped file.
2686 test_27E() {
2687         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2688         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2689                 skip "client does not have LU-3338 fix"
2690
2691         # 72 bytes is the minimum space required to store striping
2692         # information for a file striped across one OST:
2693         # (sizeof(struct lov_user_md_v3) +
2694         #  sizeof(struct lov_user_ost_data_v1))
2695         local min_easize=72
2696         $LCTL set_param -n llite.*.default_easize $min_easize ||
2697                 error "lctl set_param failed"
2698         local easize=$($LCTL get_param -n llite.*.default_easize)
2699
2700         [ $easize -eq $min_easize ] ||
2701                 error "failed to set default_easize"
2702
2703         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2704                 error "setstripe failed"
2705         # In order to ensure stat() call actually talks to MDS we need to
2706         # do something drastic to this file to shake off all lock, e.g.
2707         # rename it (kills lookup lock forcing cache cleaning)
2708         mv $DIR/$tfile $DIR/${tfile}-1
2709         ls -l $DIR/${tfile}-1
2710         rm $DIR/${tfile}-1
2711
2712         easize=$($LCTL get_param -n llite.*.default_easize)
2713
2714         [ $easize -gt $min_easize ] ||
2715                 error "default_easize not updated"
2716 }
2717 run_test 27E "check that default extended attribute size properly increases"
2718
2719 test_27F() { # LU-5346/LU-7975
2720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2721         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2722         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2723                 skip "Need MDS version at least 2.8.51"
2724         remote_ost_nodsh && skip "remote OST with nodsh"
2725
2726         test_mkdir $DIR/$tdir
2727         rm -f $DIR/$tdir/f0
2728         $LFS setstripe -c 2 $DIR/$tdir
2729
2730         # stop all OSTs to reproduce situation for LU-7975 ticket
2731         for num in $(seq $OSTCOUNT); do
2732                 stop ost$num
2733         done
2734
2735         # open/create f0 with O_LOV_DELAY_CREATE
2736         # truncate f0 to a non-0 size
2737         # close
2738         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2739
2740         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2741         # open/write it again to force delayed layout creation
2742         cat /etc/hosts > $DIR/$tdir/f0 &
2743         catpid=$!
2744
2745         # restart OSTs
2746         for num in $(seq $OSTCOUNT); do
2747                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2748                         error "ost$num failed to start"
2749         done
2750
2751         wait $catpid || error "cat failed"
2752
2753         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2754         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2755                 error "wrong stripecount"
2756
2757 }
2758 run_test 27F "Client resend delayed layout creation with non-zero size"
2759
2760 test_27G() { #LU-10629
2761         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2762                 skip "Need MDS version at least 2.11.51"
2763         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2764         remote_mds_nodsh && skip "remote MDS with nodsh"
2765         local POOL=${POOL:-testpool}
2766         local ostrange="0 0 1"
2767
2768         test_mkdir $DIR/$tdir
2769         touch $DIR/$tdir/$tfile.nopool
2770         pool_add $POOL || error "pool_add failed"
2771         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2772         $LFS setstripe -p $POOL $DIR/$tdir
2773
2774         local pool=$($LFS getstripe -p $DIR/$tdir)
2775
2776         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2777         touch $DIR/$tdir/$tfile.default
2778         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2779         $LFS find $DIR/$tdir -type f --pool $POOL
2780         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2781         [[ "$found" == "2" ]] ||
2782                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2783
2784         $LFS setstripe -d $DIR/$tdir
2785
2786         pool=$($LFS getstripe -p -d $DIR/$tdir)
2787
2788         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2789 }
2790 run_test 27G "Clear OST pool from stripe"
2791
2792 test_27H() {
2793         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2794                 skip "Need MDS version newer than 2.11.54"
2795         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2796         test_mkdir $DIR/$tdir
2797         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2798         touch $DIR/$tdir/$tfile
2799         $LFS getstripe -c $DIR/$tdir/$tfile
2800         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2801                 error "two-stripe file doesn't have two stripes"
2802
2803         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2804         $LFS getstripe -y $DIR/$tdir/$tfile
2805         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2806              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2807                 error "expected l_ost_idx: [02]$ not matched"
2808
2809         # make sure ost list has been cleared
2810         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2811         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2812                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2813         touch $DIR/$tdir/f3
2814         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2815 }
2816 run_test 27H "Set specific OSTs stripe"
2817
2818 test_27I() {
2819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2820         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2821         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2822                 skip "Need MDS version newer than 2.12.52"
2823         local pool=$TESTNAME
2824         local ostrange="1 1 1"
2825
2826         save_layout_restore_at_exit $MOUNT
2827         $LFS setstripe -c 2 -i 0 $MOUNT
2828         pool_add $pool || error "pool_add failed"
2829         pool_add_targets $pool $ostrange ||
2830                 error "pool_add_targets failed"
2831         test_mkdir $DIR/$tdir
2832         $LFS setstripe -p $pool $DIR/$tdir
2833         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2834         $LFS getstripe $DIR/$tdir/$tfile
2835 }
2836 run_test 27I "check that root dir striping does not break parent dir one"
2837
2838 test_27J() {
2839         (( $MDS1_VERSION > $(version_code 2.12.51) )) ||
2840                 skip "Need MDS version newer than 2.12.51"
2841
2842         # skip basic ops on file with foreign LOV tests on 5.12-6.2 kernels
2843         # until the filemap_read() issue is fixed by v6.2-rc4-61-g5956592ce337
2844         (( $LINUX_VERSION_CODE < $(version_code 5.12.0) ||
2845            $LINUX_VERSION_CODE >= $(version_code 6.2.0) )) ||
2846                 skip "Need kernel < 5.12.0 or >= 6.2.0 for filemap_read() fix"
2847
2848         test_mkdir $DIR/$tdir
2849         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2850         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2851
2852         # create foreign file (raw way)
2853         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2854                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2855
2856         ! $LFS setstripe --foreign --flags foo \
2857                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2858                         error "creating $tfile with '--flags foo' should fail"
2859
2860         ! $LFS setstripe --foreign --flags 0xffffffff \
2861                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2862                         error "creating $tfile w/ 0xffffffff flags should fail"
2863
2864         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2865                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2866
2867         # verify foreign file (raw way)
2868         parse_foreign_file -f $DIR/$tdir/$tfile |
2869                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2870                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2871         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2872                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2873         parse_foreign_file -f $DIR/$tdir/$tfile |
2874                 grep "lov_foreign_size: 73" ||
2875                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2876         parse_foreign_file -f $DIR/$tdir/$tfile |
2877                 grep "lov_foreign_type: 1" ||
2878                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2879         parse_foreign_file -f $DIR/$tdir/$tfile |
2880                 grep "lov_foreign_flags: 0x0000DA08" ||
2881                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2882         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2883                 grep "lov_foreign_value: 0x" |
2884                 sed -e 's/lov_foreign_value: 0x//')
2885         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2886         [[ $lov = ${lov2// /} ]] ||
2887                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2888
2889         # create foreign file (lfs + API)
2890         $LFS setstripe --foreign=none --flags 0xda08 \
2891                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2892                 error "$DIR/$tdir/${tfile}2: create failed"
2893
2894         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2895                 grep "lfm_magic:.*0x0BD70BD0" ||
2896                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2897         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2898         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2899                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2900         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2901                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2902         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2903                 grep "lfm_flags:.*0x0000DA08" ||
2904                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2905         $LFS getstripe $DIR/$tdir/${tfile}2 |
2906                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2907                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2908
2909         # modify striping should fail
2910         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2911                 error "$DIR/$tdir/$tfile: setstripe should fail"
2912         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2913                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2914
2915         # R/W should fail
2916         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2917         cat $DIR/$tdir/${tfile}2 &&
2918                 error "$DIR/$tdir/${tfile}2: read should fail"
2919         cat /etc/passwd > $DIR/$tdir/$tfile &&
2920                 error "$DIR/$tdir/$tfile: write should fail"
2921         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2922                 error "$DIR/$tdir/${tfile}2: write should fail"
2923
2924         # chmod should work
2925         chmod 222 $DIR/$tdir/$tfile ||
2926                 error "$DIR/$tdir/$tfile: chmod failed"
2927         chmod 222 $DIR/$tdir/${tfile}2 ||
2928                 error "$DIR/$tdir/${tfile}2: chmod failed"
2929
2930         # chown should work
2931         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2932                 error "$DIR/$tdir/$tfile: chown failed"
2933         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2934                 error "$DIR/$tdir/${tfile}2: chown failed"
2935
2936         # rename should work
2937         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2938                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2939         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2940                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2941
2942         #remove foreign file
2943         rm $DIR/$tdir/${tfile}.new ||
2944                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2945         rm $DIR/$tdir/${tfile}2.new ||
2946                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2947 }
2948 run_test 27J "basic ops on file with foreign LOV"
2949
2950 test_27K() {
2951         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2952                 skip "Need MDS version newer than 2.12.49"
2953
2954         test_mkdir $DIR/$tdir
2955         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2956         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2957
2958         # create foreign dir (raw way)
2959         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2960                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2961
2962         ! $LFS setdirstripe --foreign --flags foo \
2963                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2964                         error "creating $tdir with '--flags foo' should fail"
2965
2966         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2967                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2968                         error "creating $tdir w/ 0xffffffff flags should fail"
2969
2970         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2971                 error "create_foreign_dir FAILED"
2972
2973         # verify foreign dir (raw way)
2974         parse_foreign_dir -d $DIR/$tdir/$tdir |
2975                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2976                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2977         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2978                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2979         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2980                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2981         parse_foreign_dir -d $DIR/$tdir/$tdir |
2982                 grep "lmv_foreign_flags: 55813$" ||
2983                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2984         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2985                 grep "lmv_foreign_value: 0x" |
2986                 sed 's/lmv_foreign_value: 0x//')
2987         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2988                 sed 's/ //g')
2989         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2990
2991         # create foreign dir (lfs + API)
2992         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2993                 $DIR/$tdir/${tdir}2 ||
2994                 error "$DIR/$tdir/${tdir}2: create failed"
2995
2996         $LFS getdirstripe -v $DIR/$tdir/${tdir}2
2997
2998         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2999                 grep "lfm_magic:.*0x0CD50CD0" ||
3000                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
3001         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
3002         # - sizeof(lfm_type) - sizeof(lfm_flags)
3003         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
3004                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
3005         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
3006                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
3007         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
3008                 grep "lfm_flags:.*0x0000DA05" ||
3009                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
3010         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
3011                 grep "lfm_value.*${uuid1}@${uuid2}" ||
3012                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
3013
3014         # file create in dir should fail
3015         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3016         touch $DIR/$tdir/${tdir}2/$tfile &&
3017                 error "$DIR/${tdir}2: file create should fail"
3018
3019         # chmod should work
3020         chmod 777 $DIR/$tdir/$tdir ||
3021                 error "$DIR/$tdir: chmod failed"
3022         chmod 777 $DIR/$tdir/${tdir}2 ||
3023                 error "$DIR/${tdir}2: chmod failed"
3024
3025         # chown should work
3026         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
3027                 error "$DIR/$tdir: chown failed"
3028         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
3029                 error "$DIR/${tdir}2: chown failed"
3030
3031         # rename should work
3032         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3033                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
3034         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
3035                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
3036
3037         #remove foreign dir
3038         rmdir $DIR/$tdir/${tdir}.new ||
3039                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
3040         rmdir $DIR/$tdir/${tdir}2.new ||
3041                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
3042 }
3043 run_test 27K "basic ops on dir with foreign LMV"
3044
3045 test_27L() {
3046         remote_mds_nodsh && skip "remote MDS with nodsh"
3047
3048         local POOL=${POOL:-$TESTNAME}
3049
3050         pool_add $POOL || error "pool_add failed"
3051
3052         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
3053                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
3054                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
3055 }
3056 run_test 27L "lfs pool_list gives correct pool name"
3057
3058 test_27M() {
3059         (( $MDS1_VERSION >= $(version_code 2.12.57) )) ||
3060                 skip "Need MDS version >= than 2.12.57"
3061         remote_mds_nodsh && skip "remote MDS with nodsh"
3062         (( $OSTCOUNT > 1 )) || skip "need > 1 OST"
3063
3064         # Set default striping on directory
3065         local setcount=4
3066         local stripe_opt
3067         local mdts=$(comma_list $(mdts_nodes))
3068
3069         # if we run against a 2.12 server which lacks overstring support
3070         # then the connect_flag will not report overstriping, even if client
3071         # is 2.14+
3072         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
3073                 stripe_opt="-C $setcount"
3074         elif (( $OSTCOUNT >= $setcount )); then
3075                 stripe_opt="-c $setcount"
3076         else
3077                 skip "server does not support overstriping"
3078         fi
3079
3080         test_mkdir $DIR/$tdir
3081
3082         # Validate existing append_* params and ensure restore
3083         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3084         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3085         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3086
3087         # Validate append_pool name length
3088         (( $MDS1_VERSION >= $(version_code 2.15.61) )) &&
3089                 do_nodes $mdts $LCTL \
3090                         set_param mdd.*.append_pool="LOV_MAXPOOLNAME*" &&
3091                         error "Wrong pool name length should report error"
3092
3093         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3094         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
3095         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
3096
3097         $LFS setstripe $stripe_opt $DIR/$tdir
3098
3099         echo 1 > $DIR/$tdir/${tfile}.1
3100         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
3101         (( $count == $setcount )) ||
3102                 error "(1) stripe count $count, should be $setcount"
3103
3104         local appendcount=$orig_count
3105         echo 1 >> $DIR/$tdir/${tfile}.2_append
3106         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3107         (( $count == $appendcount )) ||
3108                 error "(2)stripe count $count, should be $appendcount for append"
3109
3110         # Disable O_APPEND striping, verify it works
3111         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3112
3113         # Should now get the default striping, which is 4
3114         setcount=4
3115         echo 1 >> $DIR/$tdir/${tfile}.3_append
3116         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3117         (( $count == $setcount )) ||
3118                 error "(3) stripe count $count, should be $setcount"
3119
3120         # Try changing the stripe count for append files
3121         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3122
3123         # Append striping is now 2 (directory default is still 4)
3124         appendcount=2
3125         echo 1 >> $DIR/$tdir/${tfile}.4_append
3126         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3127         (( $count == $appendcount )) ||
3128                 error "(4) stripe count $count, should be $appendcount for append"
3129
3130         # Test append stripe count of -1
3131         # Exercise LU-16872 patch with specific striping, only if MDS has fix
3132         (( $MDS1_VERSION > $(version_code 2.15.56.46) )) &&
3133                 $LFS setstripe -o 0,$((OSTCOUNT - 1)) $DIR/$tdir &&
3134                 touch $DIR/$tdir/$tfile.specific.{1..128}
3135         stack_trap "rm -f $DIR/$tdir/$tfile.*"
3136
3137         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3138         appendcount=$OSTCOUNT
3139         echo 1 >> $DIR/$tdir/${tfile}.5
3140         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3141         (( $count == $appendcount )) ||
3142                 error "(5) stripe count $count, should be $appendcount for append"
3143
3144         # Set append striping back to default of 1
3145         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3146
3147         # Try a new default striping, PFL + DOM
3148         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3149
3150         # Create normal DOM file, DOM returns stripe count == 0
3151         setcount=0
3152         touch $DIR/$tdir/${tfile}.6
3153         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3154         (( $count == $setcount )) ||
3155                 error "(6) stripe count $count, should be $setcount"
3156
3157         # Show
3158         appendcount=1
3159         echo 1 >> $DIR/$tdir/${tfile}.7_append
3160         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3161         (( $count == $appendcount )) ||
3162                 error "(7) stripe count $count, should be $appendcount for append"
3163
3164         # Clean up DOM layout
3165         $LFS setstripe -d $DIR/$tdir
3166
3167         save_layout_restore_at_exit $MOUNT
3168         # Now test that append striping works when layout is from root
3169         $LFS setstripe -c 2 $MOUNT
3170         # Make a special directory for this
3171         mkdir $DIR/${tdir}/${tdir}.2
3172
3173         # Verify for normal file
3174         setcount=2
3175         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3176         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3177         (( $count == $setcount )) ||
3178                 error "(8) stripe count $count, should be $setcount"
3179
3180         appendcount=1
3181         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3182         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3183         (( $count == $appendcount )) ||
3184                 error "(9) stripe count $count, should be $appendcount for append"
3185
3186         # Now test O_APPEND striping with pools
3187         pool_add $TESTNAME || error "pool creation failed"
3188         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3189         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3190
3191         echo 1 >> $DIR/$tdir/${tfile}.10_append
3192
3193         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3194         [[ "$pool" == "$TESTNAME" ]] || error "(10) incorrect pool: $pool"
3195
3196         # Check that count is still correct
3197         appendcount=1
3198         echo 1 >> $DIR/$tdir/${tfile}.11_append
3199         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3200         (( $count == $appendcount )) ||
3201                 error "(11) stripe count $count, should be $appendcount for append"
3202
3203         # Disable O_APPEND stripe count, verify pool works separately
3204         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3205
3206         echo 1 >> $DIR/$tdir/${tfile}.12_append
3207
3208         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3209         [[ "$pool" == "$TESTNAME" ]] || error "(12) incorrect pool: $pool"
3210
3211         # Remove pool setting, verify it's not applied
3212         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3213
3214         echo 1 >> $DIR/$tdir/${tfile}.13_append
3215
3216         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3217         [[ -z "$pool" ]] || error "(13) pool found: $pool"
3218 }
3219 run_test 27M "test O_APPEND striping"
3220
3221 test_27N() {
3222         combined_mgs_mds && skip "needs separate MGS/MDT"
3223
3224         pool_add $TESTNAME || error "pool_add failed"
3225         do_facet mgs "$LCTL pool_list $FSNAME" |
3226                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3227                 error "lctl pool_list on MGS failed"
3228 }
3229 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3230
3231 clean_foreign_symlink() {
3232         trap 0
3233         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3234         for i in $DIR/$tdir/* ; do
3235                 $LFS unlink_foreign $i || true
3236         done
3237 }
3238
3239 test_27O() {
3240         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3241                 skip "Need MDS version newer than 2.12.51"
3242
3243         test_mkdir $DIR/$tdir
3244         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3245         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3246
3247         trap clean_foreign_symlink EXIT
3248
3249         # enable foreign_symlink behaviour
3250         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3251
3252         # foreign symlink LOV format is a partial path by default
3253
3254         # create foreign file (lfs + API)
3255         $LFS setstripe --foreign=symlink --flags 0xda05 \
3256                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3257                 error "$DIR/$tdir/${tfile}: create failed"
3258
3259         $LFS getstripe -v $DIR/$tdir/${tfile} |
3260                 grep "lfm_magic:.*0x0BD70BD0" ||
3261                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3262         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3263                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3264         $LFS getstripe -v $DIR/$tdir/${tfile} |
3265                 grep "lfm_flags:.*0x0000DA05" ||
3266                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3267         $LFS getstripe $DIR/$tdir/${tfile} |
3268                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3269                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3270
3271         # modify striping should fail
3272         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3273                 error "$DIR/$tdir/$tfile: setstripe should fail"
3274
3275         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3276         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3277         cat /etc/passwd > $DIR/$tdir/$tfile &&
3278                 error "$DIR/$tdir/$tfile: write should fail"
3279
3280         # rename should succeed
3281         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3282                 error "$DIR/$tdir/$tfile: rename has failed"
3283
3284         #remove foreign_symlink file should fail
3285         rm $DIR/$tdir/${tfile}.new &&
3286                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3287
3288         #test fake symlink
3289         mkdir /tmp/${uuid1} ||
3290                 error "/tmp/${uuid1}: mkdir has failed"
3291         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3292                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3293         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3294         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3295                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3296         #read should succeed now
3297         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3298                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3299         #write should succeed now
3300         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3301                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3302         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3303                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3304         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3305                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3306
3307         #check that getstripe still works
3308         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3309                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3310
3311         # chmod should still succeed
3312         chmod 644 $DIR/$tdir/${tfile}.new ||
3313                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3314
3315         # chown should still succeed
3316         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3317                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3318
3319         # rename should still succeed
3320         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3321                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3322
3323         #remove foreign_symlink file should still fail
3324         rm $DIR/$tdir/${tfile} &&
3325                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3326
3327         #use special ioctl() to unlink foreign_symlink file
3328         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3329                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3330
3331 }
3332 run_test 27O "basic ops on foreign file of symlink type"
3333
3334 test_27P() {
3335         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3336                 skip "Need MDS version newer than 2.12.49"
3337
3338         test_mkdir $DIR/$tdir
3339         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3340         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3341
3342         trap clean_foreign_symlink EXIT
3343
3344         # enable foreign_symlink behaviour
3345         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3346
3347         # foreign symlink LMV format is a partial path by default
3348
3349         # create foreign dir (lfs + API)
3350         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3351                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3352                 error "$DIR/$tdir/${tdir}: create failed"
3353
3354         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3355
3356         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3357                 grep "lfm_magic:.*0x0CD50CD0" ||
3358                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3359         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3360                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3361         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3362                 grep "lfm_flags:.*0x0000DA05" ||
3363                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3364         $LFS getdirstripe $DIR/$tdir/${tdir} |
3365                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3366                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3367
3368         # file create in dir should fail
3369         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3370         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3371
3372         # rename should succeed
3373         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3374                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3375
3376         #remove foreign_symlink dir should fail
3377         rmdir $DIR/$tdir/${tdir}.new &&
3378                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3379
3380         #test fake symlink
3381         mkdir -p /tmp/${uuid1}/${uuid2} ||
3382                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3383         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3384                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3385         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3386         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3387                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3388         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3389                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3390
3391         #check that getstripe fails now that foreign_symlink enabled
3392         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3393                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3394
3395         # file create in dir should work now
3396         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3397                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3398         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3399                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3400         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3401                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3402
3403         # chmod should still succeed
3404         chmod 755 $DIR/$tdir/${tdir}.new ||
3405                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3406
3407         # chown should still succeed
3408         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3409                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3410
3411         # rename should still succeed
3412         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3413                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3414
3415         #remove foreign_symlink dir should still fail
3416         rmdir $DIR/$tdir/${tdir} &&
3417                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3418
3419         #use special ioctl() to unlink foreign_symlink file
3420         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3421                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3422
3423         #created file should still exist
3424         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3425                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3426         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3427                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3428 }
3429 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3430
3431 test_27Q() {
3432         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3433         stack_trap "rm -f $TMP/$tfile*"
3434
3435         test_mkdir $DIR/$tdir-1
3436         test_mkdir $DIR/$tdir-2
3437
3438         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3439         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3440
3441         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3442         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3443
3444         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3445         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3446
3447         # Create some bad symlinks and ensure that we don't loop
3448         # forever or something. These should return ELOOP (40) and
3449         # ENOENT (2) but I don't want to test for that because there's
3450         # always some weirdo architecture that needs to ruin
3451         # everything by defining these error numbers differently.
3452
3453         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3454         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3455
3456         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3457         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3458
3459         return 0
3460 }
3461 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3462
3463 test_27R() {
3464         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3465                 skip "need MDS 2.14.55 or later"
3466         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3467
3468         local testdir="$DIR/$tdir"
3469         test_mkdir -p $testdir
3470         stack_trap "rm -rf $testdir"
3471         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3472
3473         local f1="$testdir/f1"
3474         touch $f1 || error "failed to touch $f1"
3475         local count=$($LFS getstripe -c $f1)
3476         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3477
3478         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3479         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3480
3481         local maxcount=$(($OSTCOUNT - 1))
3482         local mdts=$(comma_list $(mdts_nodes))
3483         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3484         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3485
3486         local f2="$testdir/f2"
3487         touch $f2 || error "failed to touch $f2"
3488         local count=$($LFS getstripe -c $f2)
3489         (( $count == $maxcount )) || error "wrong stripe count"
3490 }
3491 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3492
3493 test_27T() {
3494         [ $(facet_host client) == $(facet_host ost1) ] &&
3495                 skip "need ost1 and client on different nodes"
3496
3497 #define OBD_FAIL_OSC_NO_GRANT            0x411
3498         $LCTL set_param fail_loc=0x20000411 fail_val=1
3499 #define OBD_FAIL_OST_ENOSPC              0x215
3500         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3501         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3502         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3503                 error "multiop failed"
3504 }
3505 run_test 27T "no eio on close on partial write due to enosp"
3506
3507 test_27U() {
3508         local dir=$DIR/$tdir
3509         local file=$dir/$tfile
3510         local append_pool=${TESTNAME}-append
3511         local normal_pool=${TESTNAME}-normal
3512         local pool
3513         local stripe_count
3514         local stripe_count2
3515         local mdts=$(comma_list $(mdts_nodes))
3516
3517         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
3518                 skip "Need MDS version at least 2.15.51 for append pool feature"
3519
3520         # Validate existing append_* params and ensure restore
3521         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3522         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3523         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3524
3525         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3526         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3527         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3528
3529         pool_add $append_pool || error "pool creation failed"
3530         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3531
3532         pool_add $normal_pool || error "pool creation failed"
3533         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3534
3535         test_mkdir $dir
3536         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3537
3538         echo XXX >> $file.1
3539         $LFS getstripe $file.1
3540
3541         pool=$($LFS getstripe -p $file.1)
3542         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3543
3544         stripe_count2=$($LFS getstripe -c $file.1)
3545         ((stripe_count2 == stripe_count)) ||
3546                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3547
3548         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3549
3550         echo XXX >> $file.2
3551         $LFS getstripe $file.2
3552
3553         pool=$($LFS getstripe -p $file.2)
3554         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3555
3556         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3557
3558         echo XXX >> $file.3
3559         $LFS getstripe $file.3
3560
3561         stripe_count2=$($LFS getstripe -c $file.3)
3562         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3563 }
3564 run_test 27U "append pool and stripe count work with composite default layout"
3565
3566 test_27V() {
3567         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3568         (( $OSTCOUNT >= 4 )) || skip_env "needs >= 4 OSTs"
3569
3570         local dir=$DIR/$tdir
3571         local osp_param=osp.$FSNAME-OST0000-osc-MDT0000.max_create_count
3572         local lod_param=lod.$FSNAME-MDT0000-mdtlov.qos_threshold_rr
3573         local saved_max=$(do_facet mds1 $LCTL get_param -n $osp_param)
3574         local saved_qos=$(do_facet mds1 $LCTL get_param -n $lod_param)
3575         local pid
3576
3577         stack_trap "do_facet mds1 $LCTL set_param $osp_param=$saved_max"
3578
3579         do_facet mds1 $LCTL set_param $lod_param=0
3580         stack_trap "do_facet mds1 $LCTL set_param $lod_param=$saved_qos"
3581
3582         $LFS setdirstripe --mdt-count=1 --mdt-index=0 $dir
3583         stack_trap "rm -rf $dir"
3584
3585         # exercise race in LU-16981 with deactivating OST while creating a file
3586         (
3587                 while true; do
3588                         do_facet mds1 $LCTL set_param $osp_param=0 > /dev/null
3589                         sleep 0.1
3590                         do_facet mds1 \
3591                                 $LCTL set_param $osp_param=$saved_max > /dev/null
3592                 done
3593         ) &
3594
3595         pid=$!
3596         stack_trap "kill -9 $pid"
3597
3598         # errors here are OK so ignore them (just don't want to crash)
3599         $LFS setstripe -c -1 $dir/f.{1..200} 2> /dev/null
3600
3601         return 0
3602 }
3603 run_test 27V "creating widely striped file races with deactivating OST"
3604
3605 # createtest also checks that device nodes are created and
3606 # then visible correctly (#2091)
3607 test_28() { # bug 2091
3608         test_mkdir $DIR/d28
3609         $CREATETEST $DIR/d28/ct || error "createtest failed"
3610 }
3611 run_test 28 "create/mknod/mkdir with bad file types ============"
3612
3613 test_29() {
3614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3615
3616         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3617                 disable_opencache
3618                 stack_trap "restore_opencache"
3619         }
3620
3621         sync; sleep 1; sync # flush out any dirty pages from previous tests
3622         cancel_lru_locks
3623         test_mkdir $DIR/d29
3624         touch $DIR/d29/foo
3625         log 'first d29'
3626         ls -l $DIR/d29
3627
3628         local locks_orig=$(total_used_locks mdc)
3629         (( $locks_orig != 0 )) || error "No mdc lock count"
3630
3631         local locks_unused_orig=$(total_unused_locks mdc)
3632
3633         log 'second d29'
3634         ls -l $DIR/d29
3635         log 'done'
3636
3637         local locks_current=$(total_used_locks mdc)
3638
3639         local locks_unused_current=$(total_unused_locks mdc)
3640
3641         if (( $locks_current > $locks_orig )); then
3642                 $LCTL set_param -n ldlm.dump_namespaces ""
3643                 error "CURRENT: $locks_current > $locks_orig"
3644         fi
3645         if (( $locks_unused_current > $locks_unused_orig )); then
3646                 error "UNUSED: $locks_unused_current > $locks_unused_orig"
3647         fi
3648 }
3649 run_test 29 "IT_GETATTR regression  ============================"
3650
3651 test_30a() { # was test_30
3652         cp $(which ls) $DIR || cp /bin/ls $DIR
3653         $DIR/ls / || error "Can't execute binary from lustre"
3654         rm $DIR/ls
3655 }
3656 run_test 30a "execute binary from Lustre (execve) =============="
3657
3658 test_30b() {
3659         cp `which ls` $DIR || cp /bin/ls $DIR
3660         chmod go+rx $DIR/ls
3661         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3662         rm $DIR/ls
3663 }
3664 run_test 30b "execute binary from Lustre as non-root ==========="
3665
3666 test_30c() { # b=22376
3667         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3668
3669         cp $(which ls) $DIR || cp /bin/ls $DIR
3670         chmod a-rw $DIR/ls
3671         cancel_lru_locks mdc
3672         cancel_lru_locks osc
3673         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3674         rm -f $DIR/ls
3675 }
3676 run_test 30c "execute binary from Lustre without read perms ===="
3677
3678 test_30d() {
3679         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3680
3681         for i in {1..10}; do
3682                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3683                 local PID=$!
3684                 sleep 1
3685                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3686                 wait $PID || error "executing dd from Lustre failed"
3687                 rm -f $DIR/$tfile
3688         done
3689
3690         rm -f $DIR/dd
3691 }
3692 run_test 30d "execute binary from Lustre while clear locks"
3693
3694 test_31a() {
3695         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3696         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3697 }
3698 run_test 31a "open-unlink file =================================="
3699
3700 test_31b() {
3701         touch $DIR/f31 || error "touch $DIR/f31 failed"
3702         ln $DIR/f31 $DIR/f31b || error "ln failed"
3703         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3704         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3705 }
3706 run_test 31b "unlink file with multiple links while open ======="
3707
3708 test_31c() {
3709         touch $DIR/f31 || error "touch $DIR/f31 failed"
3710         ln $DIR/f31 $DIR/f31c || error "ln failed"
3711         multiop_bg_pause $DIR/f31 O_uc ||
3712                 error "multiop_bg_pause for $DIR/f31 failed"
3713         MULTIPID=$!
3714         $MULTIOP $DIR/f31c Ouc
3715         kill -USR1 $MULTIPID
3716         wait $MULTIPID
3717 }
3718 run_test 31c "open-unlink file with multiple links ============="
3719
3720 test_31d() {
3721         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3722         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3723 }
3724 run_test 31d "remove of open directory ========================="
3725
3726 test_31e() { # bug 2904
3727         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3728 }
3729 run_test 31e "remove of open non-empty directory ==============="
3730
3731 test_31f() { # bug 4554
3732         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3733
3734         set -vx
3735         test_mkdir $DIR/d31f
3736         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3737         cp /etc/hosts $DIR/d31f
3738         ls -l $DIR/d31f
3739         $LFS getstripe $DIR/d31f/hosts
3740         multiop_bg_pause $DIR/d31f D_c || return 1
3741         MULTIPID=$!
3742
3743         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3744         test_mkdir $DIR/d31f
3745         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3746         cp /etc/hosts $DIR/d31f
3747         ls -l $DIR/d31f
3748         $LFS getstripe $DIR/d31f/hosts
3749         multiop_bg_pause $DIR/d31f D_c || return 1
3750         MULTIPID2=$!
3751
3752         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3753         wait $MULTIPID || error "first opendir $MULTIPID failed"
3754
3755         sleep 6
3756
3757         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3758         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3759         set +vx
3760 }
3761 run_test 31f "remove of open directory with open-unlink file ==="
3762
3763 test_31g() {
3764         echo "-- cross directory link --"
3765         test_mkdir -c1 $DIR/${tdir}ga
3766         test_mkdir -c1 $DIR/${tdir}gb
3767         touch $DIR/${tdir}ga/f
3768         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3769         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3770         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3771         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3772         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3773 }
3774 run_test 31g "cross directory link==============="
3775
3776 test_31h() {
3777         echo "-- cross directory link --"
3778         test_mkdir -c1 $DIR/${tdir}
3779         test_mkdir -c1 $DIR/${tdir}/dir
3780         touch $DIR/${tdir}/f
3781         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3782         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3783         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3784         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3785         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3786 }
3787 run_test 31h "cross directory link under child==============="
3788
3789 test_31i() {
3790         echo "-- cross directory link --"
3791         test_mkdir -c1 $DIR/$tdir
3792         test_mkdir -c1 $DIR/$tdir/dir
3793         touch $DIR/$tdir/dir/f
3794         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3795         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3796         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3797         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3798         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3799 }
3800 run_test 31i "cross directory link under parent==============="
3801
3802 test_31j() {
3803         test_mkdir -c1 -p $DIR/$tdir
3804         test_mkdir -c1 -p $DIR/$tdir/dir1
3805         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3806         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3807         link $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "link to the same dir"
3808         return 0
3809 }
3810 run_test 31j "link for directory"
3811
3812 test_31k() {
3813         test_mkdir -c1 -p $DIR/$tdir
3814         touch $DIR/$tdir/s
3815         touch $DIR/$tdir/exist
3816         link $DIR/$tdir/s $DIR/$tdir/t || error "link"
3817         link $DIR/$tdir/s $DIR/$tdir/exist && error "link to exist file"
3818         link $DIR/$tdir/s $DIR/$tdir/s && error "link to the same file"
3819         link $DIR/$tdir/s $DIR/$tdir && error "link to parent dir"
3820         link $DIR/$tdir $DIR/$tdir/s && error "link parent dir to target"
3821         link $DIR/$tdir/not-exist $DIR/$tdir/foo && error "link non-existing to new"
3822         link $DIR/$tdir/not-exist $DIR/$tdir/s && error "link non-existing to exist"
3823         return 0
3824 }
3825 run_test 31k "link to file: the same, non-existing, dir"
3826
3827 test_31l() {
3828         local ln_ver=$(ln --version | awk '/coreutils/ { print $4 }')
3829
3830         (( $(version_code $ln_ver) < $(version_code 8.31) )) ||
3831         (( $(version_code $(uname -r)) >= $(version_code 5.18) )) ||
3832                 skip "need coreutils < 8.31 or kernel >= 5.18 for ln"
3833
3834         touch $DIR/$tfile || error "create failed"
3835         mkdir $DIR/$tdir || error "mkdir failed"
3836         ln $DIR/$tfile $DIR/$tdir/ || error "ln to '$tdir/' failed"
3837 }
3838 run_test 31l "link to file: target dir has trailing slash"
3839
3840 test_31m() {
3841         mkdir $DIR/d31m
3842         touch $DIR/d31m/s
3843         mkdir $DIR/d31m2
3844         touch $DIR/d31m2/exist
3845         link $DIR/d31m/s $DIR/d31m2/t || error "link"
3846         link $DIR/d31m/s $DIR/d31m2/exist && error "link to exist file"
3847         link $DIR/d31m/s $DIR/d31m2 && error "link to parent dir"
3848         link $DIR/d31m2 $DIR/d31m/s && error "link parent dir to target"
3849         link $DIR/d31m/not-exist $DIR/d31m2/foo && error "link non-existing to new"
3850         link $DIR/d31m/not-exist $DIR/d31m2/s && error "link non-existing to exist"
3851         return 0
3852 }
3853 run_test 31m "link to file: the same, non-existing, dir"
3854
3855 test_31n() {
3856         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3857         nlink=$(stat --format=%h $DIR/$tfile)
3858         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3859         local fd=$(free_fd)
3860         local cmd="exec $fd<$DIR/$tfile"
3861         eval $cmd
3862         cmd="exec $fd<&-"
3863         trap "eval $cmd" EXIT
3864         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3865         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3866         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3867         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3868         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3869         eval $cmd
3870 }
3871 run_test 31n "check link count of unlinked file"
3872
3873 link_one() {
3874         local tempfile=$(mktemp $1_XXXXXX)
3875         link $tempfile $1 2> /dev/null &&
3876                 echo "$BASHPID: link $tempfile to $1 succeeded"
3877         unlink $tempfile
3878 }
3879
3880 test_31o() { # LU-2901
3881         test_mkdir $DIR/$tdir
3882         for LOOP in $(seq 100); do
3883                 rm -f $DIR/$tdir/$tfile*
3884                 for THREAD in $(seq 8); do
3885                         link_one $DIR/$tdir/$tfile.$LOOP &
3886                 done
3887                 wait
3888                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3889                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3890                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3891                         break || true
3892         done
3893 }
3894 run_test 31o "duplicate hard links with same filename"
3895
3896 test_31p() {
3897         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3898
3899         test_mkdir $DIR/$tdir
3900         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3901         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3902
3903         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3904                 error "open unlink test1 failed"
3905         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3906                 error "open unlink test2 failed"
3907
3908         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3909                 error "test1 still exists"
3910         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3911                 error "test2 still exists"
3912 }
3913 run_test 31p "remove of open striped directory"
3914
3915 test_31q() {
3916         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3917
3918         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3919         index=$($LFS getdirstripe -i $DIR/$tdir)
3920         [ $index -eq 3 ] || error "first stripe index $index != 3"
3921         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3922         [ $index -eq 1 ] || error "second stripe index $index != 1"
3923
3924         # when "-c <stripe_count>" is set, the number of MDTs specified after
3925         # "-i" should equal to the stripe count
3926         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3927 }
3928 run_test 31q "create striped directory on specific MDTs"
3929
3930 #LU-14949
3931 test_31r() {
3932         touch $DIR/$tfile.target
3933         touch $DIR/$tfile.source
3934
3935         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3936         $LCTL set_param fail_loc=0x1419 fail_val=3
3937         cat $DIR/$tfile.target &
3938         CATPID=$!
3939
3940         # Guarantee open is waiting before we get here
3941         sleep 1
3942         mv $DIR/$tfile.source $DIR/$tfile.target
3943
3944         wait $CATPID
3945         RC=$?
3946         if [[ $RC -ne 0 ]]; then
3947                 error "open with cat failed, rc=$RC"
3948         fi
3949 }
3950 run_test 31r "open-rename(replace) race"
3951
3952 cleanup_test32_mount() {
3953         local rc=0
3954         trap 0
3955         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3956         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3957         losetup -d $loopdev || true
3958         rm -rf $DIR/$tdir
3959         return $rc
3960 }
3961
3962 test_32a() {
3963         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3964
3965         echo "== more mountpoints and symlinks ================="
3966         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3967         trap cleanup_test32_mount EXIT
3968         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3969         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3970                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3971         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3972                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3973         cleanup_test32_mount
3974 }
3975 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3976
3977 test_32b() {
3978         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3979
3980         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3981         trap cleanup_test32_mount EXIT
3982         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3983         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3984                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3985         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3986                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3987         cleanup_test32_mount
3988 }
3989 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3990
3991 test_32c() {
3992         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3993
3994         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3995         trap cleanup_test32_mount EXIT
3996         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3997         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3998                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3999         test_mkdir -p $DIR/$tdir/d2/test_dir
4000         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
4001                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
4002         cleanup_test32_mount
4003 }
4004 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
4005
4006 test_32d() {
4007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4008
4009         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4010         trap cleanup_test32_mount EXIT
4011         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4012         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4013                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4014         test_mkdir -p $DIR/$tdir/d2/test_dir
4015         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
4016                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
4017         cleanup_test32_mount
4018 }
4019 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
4020
4021 test_32e() {
4022         rm -fr $DIR/$tdir
4023         test_mkdir -p $DIR/$tdir/tmp
4024         local tmp_dir=$DIR/$tdir/tmp
4025         ln -s $DIR/$tdir $tmp_dir/symlink11
4026         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
4027         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
4028         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
4029 }
4030 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
4031
4032 test_32f() {
4033         rm -fr $DIR/$tdir
4034         test_mkdir -p $DIR/$tdir/tmp
4035         local tmp_dir=$DIR/$tdir/tmp
4036         ln -s $DIR/$tdir $tmp_dir/symlink11
4037         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
4038         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
4039         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
4040 }
4041 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
4042
4043 test_32g() {
4044         local tmp_dir=$DIR/$tdir/tmp
4045         test_mkdir -p $tmp_dir
4046         test_mkdir $DIR/${tdir}2
4047         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
4048         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
4049         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
4050         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
4051         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
4052         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
4053 }
4054 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
4055
4056 test_32h() {
4057         rm -fr $DIR/$tdir $DIR/${tdir}2
4058         tmp_dir=$DIR/$tdir/tmp
4059         test_mkdir -p $tmp_dir
4060         test_mkdir $DIR/${tdir}2
4061         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
4062         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
4063         ls $tmp_dir/symlink12 || error "listing symlink12"
4064         ls $DIR/$tdir/symlink02  || error "listing symlink02"
4065 }
4066 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
4067
4068 test_32i() {
4069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4070
4071         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4072         trap cleanup_test32_mount EXIT
4073         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4074         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4075                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4076         touch $DIR/$tdir/test_file
4077         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
4078                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
4079         cleanup_test32_mount
4080 }
4081 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
4082
4083 test_32j() {
4084         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4085
4086         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4087         trap cleanup_test32_mount EXIT
4088         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4089         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4090                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4091         touch $DIR/$tdir/test_file
4092         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
4093                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
4094         cleanup_test32_mount
4095 }
4096 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
4097
4098 test_32k() {
4099         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4100
4101         rm -fr $DIR/$tdir
4102         trap cleanup_test32_mount EXIT
4103         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4104         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4105                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4106         test_mkdir -p $DIR/$tdir/d2
4107         touch $DIR/$tdir/d2/test_file || error "touch failed"
4108         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4109                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
4110         cleanup_test32_mount
4111 }
4112 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
4113
4114 test_32l() {
4115         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4116
4117         rm -fr $DIR/$tdir
4118         trap cleanup_test32_mount EXIT
4119         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4120         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4121                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4122         test_mkdir -p $DIR/$tdir/d2
4123         touch $DIR/$tdir/d2/test_file || error "touch failed"
4124         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4125                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
4126         cleanup_test32_mount
4127 }
4128 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
4129
4130 test_32m() {
4131         rm -fr $DIR/d32m
4132         test_mkdir -p $DIR/d32m/tmp
4133         TMP_DIR=$DIR/d32m/tmp
4134         ln -s $DIR $TMP_DIR/symlink11
4135         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4136         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
4137                 error "symlink11 not a link"
4138         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
4139                 error "symlink01 not a link"
4140 }
4141 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
4142
4143 test_32n() {
4144         rm -fr $DIR/d32n
4145         test_mkdir -p $DIR/d32n/tmp
4146         TMP_DIR=$DIR/d32n/tmp
4147         ln -s $DIR $TMP_DIR/symlink11
4148         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4149         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4150         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4151 }
4152 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4153
4154 test_32o() {
4155         touch $DIR/$tfile
4156         test_mkdir -p $DIR/d32o/tmp
4157         TMP_DIR=$DIR/d32o/tmp
4158         ln -s $DIR/$tfile $TMP_DIR/symlink12
4159         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4160         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4161                 error "symlink12 not a link"
4162         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4163         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4164                 error "$DIR/d32o/tmp/symlink12 not file type"
4165         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4166                 error "$DIR/d32o/symlink02 not file type"
4167 }
4168 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4169
4170 test_32p() {
4171         log 32p_1
4172         rm -fr $DIR/d32p
4173         log 32p_2
4174         rm -f $DIR/$tfile
4175         log 32p_3
4176         touch $DIR/$tfile
4177         log 32p_4
4178         test_mkdir -p $DIR/d32p/tmp
4179         log 32p_5
4180         TMP_DIR=$DIR/d32p/tmp
4181         log 32p_6
4182         ln -s $DIR/$tfile $TMP_DIR/symlink12
4183         log 32p_7
4184         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4185         log 32p_8
4186         cat $DIR/d32p/tmp/symlink12 ||
4187                 error "Can't open $DIR/d32p/tmp/symlink12"
4188         log 32p_9
4189         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4190         log 32p_10
4191 }
4192 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4193
4194 test_32q() {
4195         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4196
4197         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4198         trap cleanup_test32_mount EXIT
4199         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4200         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4201         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4202                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4203         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4204         cleanup_test32_mount
4205 }
4206 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4207
4208 test_32r() {
4209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4210
4211         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4212         trap cleanup_test32_mount EXIT
4213         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4214         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4215         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4216                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4217         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4218         cleanup_test32_mount
4219 }
4220 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4221
4222 test_33aa() {
4223         rm -f $DIR/$tfile
4224         touch $DIR/$tfile
4225         chmod 444 $DIR/$tfile
4226         chown $RUNAS_ID $DIR/$tfile
4227         log 33_1
4228         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4229         log 33_2
4230 }
4231 run_test 33aa "write file with mode 444 (should return error)"
4232
4233 test_33a() {
4234         rm -fr $DIR/$tdir
4235         test_mkdir $DIR/$tdir
4236         chown $RUNAS_ID $DIR/$tdir
4237         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4238                 error "$RUNAS create $tdir/$tfile failed"
4239         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4240                 error "open RDWR" || true
4241 }
4242 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4243
4244 test_33b() {
4245         rm -fr $DIR/$tdir
4246         test_mkdir $DIR/$tdir
4247         chown $RUNAS_ID $DIR/$tdir
4248         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4249 }
4250 run_test 33b "test open file with malformed flags (No panic)"
4251
4252 test_33c() {
4253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4254         remote_ost_nodsh && skip "remote OST with nodsh"
4255
4256         local ostnum
4257         local ostname
4258         local write_bytes
4259         local all_zeros
4260
4261         all_zeros=true
4262         test_mkdir $DIR/$tdir
4263         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4264
4265         sync
4266         for ostnum in $(seq $OSTCOUNT); do
4267                 # test-framework's OST numbering is one-based, while Lustre's
4268                 # is zero-based
4269                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4270                 # check if at least some write_bytes stats are counted
4271                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4272                               obdfilter.$ostname.stats |
4273                               awk '/^write_bytes/ {print $7}' )
4274                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4275                 if (( ${write_bytes:-0} > 0 )); then
4276                         all_zeros=false
4277                         break
4278                 fi
4279         done
4280
4281         $all_zeros || return 0
4282
4283         # Write four bytes
4284         echo foo > $DIR/$tdir/bar
4285         # Really write them
4286         sync
4287
4288         # Total up write_bytes after writing.  We'd better find non-zeros.
4289         for ostnum in $(seq $OSTCOUNT); do
4290                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4291                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4292                               obdfilter/$ostname/stats |
4293                               awk '/^write_bytes/ {print $7}' )
4294                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4295                 if (( ${write_bytes:-0} > 0 )); then
4296                         all_zeros=false
4297                         break
4298                 fi
4299         done
4300
4301         if $all_zeros; then
4302                 for ostnum in $(seq $OSTCOUNT); do
4303                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4304                         echo "Check write_bytes is in obdfilter.*.stats:"
4305                         do_facet ost$ostnum lctl get_param -n \
4306                                 obdfilter.$ostname.stats
4307                 done
4308                 error "OST not keeping write_bytes stats (b=22312)"
4309         fi
4310 }
4311 run_test 33c "test write_bytes stats"
4312
4313 test_33d() {
4314         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4315         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4316
4317         local MDTIDX=1
4318         local remote_dir=$DIR/$tdir/remote_dir
4319
4320         test_mkdir $DIR/$tdir
4321         $LFS mkdir -i $MDTIDX $remote_dir ||
4322                 error "create remote directory failed"
4323
4324         touch $remote_dir/$tfile
4325         chmod 444 $remote_dir/$tfile
4326         chown $RUNAS_ID $remote_dir/$tfile
4327
4328         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4329
4330         chown $RUNAS_ID $remote_dir
4331         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4332                                         error "create" || true
4333         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4334                                     error "open RDWR" || true
4335         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4336 }
4337 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4338
4339 test_33e() {
4340         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4341
4342         mkdir $DIR/$tdir
4343
4344         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4345         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4346         mkdir $DIR/$tdir/local_dir
4347
4348         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4349         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4350         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4351
4352         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4353                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4354
4355         rmdir $DIR/$tdir/* || error "rmdir failed"
4356
4357         umask 777
4358         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4359         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4360         mkdir $DIR/$tdir/local_dir
4361
4362         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4363         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4364         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4365
4366         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4367                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4368
4369         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4370
4371         umask 000
4372         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4373         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4374         mkdir $DIR/$tdir/local_dir
4375
4376         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4377         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4378         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4379
4380         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4381                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4382 }
4383 run_test 33e "mkdir and striped directory should have same mode"
4384
4385 cleanup_33f() {
4386         trap 0
4387         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4388 }
4389
4390 test_33f() {
4391         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4392         remote_mds_nodsh && skip "remote MDS with nodsh"
4393
4394         mkdir $DIR/$tdir
4395         chmod go+rwx $DIR/$tdir
4396         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4397         trap cleanup_33f EXIT
4398
4399         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4400                 error "cannot create striped directory"
4401
4402         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4403                 error "cannot create files in striped directory"
4404
4405         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4406                 error "cannot remove files in striped directory"
4407
4408         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4409                 error "cannot remove striped directory"
4410
4411         cleanup_33f
4412 }
4413 run_test 33f "nonroot user can create, access, and remove a striped directory"
4414
4415 test_33g() {
4416         mkdir -p $DIR/$tdir/dir2
4417
4418         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4419         echo $err
4420         [[ $err =~ "exists" ]] || error "Not exists error"
4421 }
4422 run_test 33g "nonroot user create already existing root created file"
4423
4424 sub_33h() {
4425         local hash_type=$1
4426         local count=250
4427
4428         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4429                 error "lfs mkdir -H $hash_type $tdir failed"
4430         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4431
4432         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4433         local index2
4434         local fname
4435
4436         for fname in $DIR/$tdir/$tfile.bak \
4437                      $DIR/$tdir/$tfile.SAV \
4438                      $DIR/$tdir/$tfile.orig \
4439                      $DIR/$tdir/$tfile~; do
4440                 touch $fname || error "touch $fname failed"
4441                 index2=$($LFS getstripe -m $fname)
4442                 (( $index == $index2 )) ||
4443                         error "$fname MDT index mismatch $index != $index2"
4444         done
4445
4446         local failed=0
4447         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4448         local pattern
4449
4450         for pattern in ${patterns[*]}; do
4451                 echo "pattern $pattern"
4452                 fname=$DIR/$tdir/$pattern
4453                 for (( i = 0; i < $count; i++ )); do
4454                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4455                                 error "mktemp $DIR/$tdir/$pattern failed"
4456                         index2=$($LFS getstripe -m $fname)
4457                         (( $index == $index2 )) && continue
4458
4459                         failed=$((failed + 1))
4460                         echo "$fname MDT index mismatch $index != $index2"
4461                 done
4462         done
4463
4464         echo "$failed/$count MDT index mismatches, expect ~2-4"
4465         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4466
4467         local same=0
4468         local expect
4469
4470         # verify that "crush" is still broken with all files on same MDT,
4471         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4472         [[ "$hash_type" == "crush" ]] && expect=$count ||
4473                 expect=$((count / MDSCOUNT))
4474
4475         # crush2 doesn't put all-numeric suffixes on the same MDT,
4476         # filename like $tfile.12345678 should *not* be considered temp
4477         for pattern in ${patterns[*]}; do
4478                 local base=${pattern%%X*}
4479                 local suff=${pattern#$base}
4480
4481                 echo "pattern $pattern"
4482                 for (( i = 0; i < $count; i++ )); do
4483                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4484                         touch $fname || error "touch $fname failed"
4485                         index2=$($LFS getstripe -m $fname)
4486                         (( $index != $index2 )) && continue
4487
4488                         same=$((same + 1))
4489                 done
4490         done
4491
4492         # the number of "bad" hashes is random, as it depends on the random
4493         # filenames generated by "mktemp".  Allow some margin in the results.
4494         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4495         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4496            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4497                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4498         same=0
4499
4500         # crush2 doesn't put suffixes with special characters on the same MDT
4501         # filename like $tfile.txt.1234 should *not* be considered temp
4502         for pattern in ${patterns[*]}; do
4503                 local base=${pattern%%X*}
4504                 local suff=${pattern#$base}
4505
4506                 pattern=$base...${suff/XXX}
4507                 echo "pattern=$pattern"
4508                 for (( i = 0; i < $count; i++ )); do
4509                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4510                                 error "touch $fname failed"
4511                         index2=$($LFS getstripe -m $fname)
4512                         (( $index != $index2 )) && continue
4513
4514                         same=$((same + 1))
4515                 done
4516         done
4517
4518         # the number of "bad" hashes is random, as it depends on the random
4519         # filenames generated by "mktemp".  Allow some margin in the results.
4520         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4521         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4522            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4523                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4524 }
4525
4526 test_33h() {
4527         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4528         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4529                 skip "Need MDS version at least 2.13.50"
4530
4531         sub_33h crush
4532 }
4533 run_test 33h "temp file is located on the same MDT as target (crush)"
4534
4535 test_33hh() {
4536         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4537         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4538         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4539                 skip "Need MDS version at least 2.15.0 for crush2"
4540
4541         sub_33h crush2
4542 }
4543 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4544
4545 test_33i()
4546 {
4547         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4548
4549         local FNAME=$(str_repeat 'f' 250)
4550
4551         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4552         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4553
4554         local count
4555         local total
4556
4557         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4558
4559         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4560
4561         lctl --device %$MDC deactivate
4562         stack_trap "lctl --device %$MDC activate"
4563         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4564         total=$(\ls -l $DIR/$tdir | wc -l)
4565         # "ls -l" will list total in the first line
4566         total=$((total - 1))
4567         (( total + count == 1000 )) ||
4568                 error "ls list $total files, $count files on MDT1"
4569 }
4570 run_test 33i "striped directory can be accessed when one MDT is down"
4571
4572 test_33j() {
4573         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4574
4575         mkdir -p $DIR/$tdir/
4576
4577         $LFS setdirstripe -D -i0,1 $DIR/$tdir/striped_dir_a &&
4578                 error "setdirstripe -D -i0,1 incorrectly succeeded"
4579
4580         $LFS setdirstripe -D -i0,1 -c1 $DIR/$tdir/striped_dir_b &&
4581                 error "setdirstripe -D -i0,1 -c1 incorrectly succeeded"
4582
4583         $LFS setdirstripe -D -i0,1 -c3 $DIR/$tdir/striped_dir_c &&
4584                 error "setdirstripe -D -i0,1 -c3 incorrectly succeeded"
4585
4586         $LFS setdirstripe -i0,1 $DIR/$tdir/striped_dir_e ||
4587                 error "-D was not specified, but still failed"
4588 }
4589 run_test 33j "lfs setdirstripe -D -i x,y,x should fail"
4590
4591 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4592 test_34a() {
4593         rm -f $DIR/f34
4594         $MCREATE $DIR/f34 || error "mcreate failed"
4595         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4596                 error "getstripe failed"
4597         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4598         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4599                 error "getstripe failed"
4600         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4601                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4602 }
4603 run_test 34a "truncate file that has not been opened ==========="
4604
4605 test_34b() {
4606         [ ! -f $DIR/f34 ] && test_34a
4607         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4608                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4609         $OPENFILE -f O_RDONLY $DIR/f34
4610         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4611                 error "getstripe failed"
4612         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4613                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4614 }
4615 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4616
4617 test_34c() {
4618         [ ! -f $DIR/f34 ] && test_34a
4619         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4620                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4621         $OPENFILE -f O_RDWR $DIR/f34
4622         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4623                 error "$LFS getstripe failed"
4624         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4625                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4626 }
4627 run_test 34c "O_RDWR opening file-with-size works =============="
4628
4629 test_34d() {
4630         [ ! -f $DIR/f34 ] && test_34a
4631         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4632                 error "dd failed"
4633         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4634                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4635         rm $DIR/f34
4636 }
4637 run_test 34d "write to sparse file ============================="
4638
4639 test_34e() {
4640         rm -f $DIR/f34e
4641         $MCREATE $DIR/f34e || error "mcreate failed"
4642         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4643         $CHECKSTAT -s 1000 $DIR/f34e ||
4644                 error "Size of $DIR/f34e not equal to 1000 bytes"
4645         $OPENFILE -f O_RDWR $DIR/f34e
4646         $CHECKSTAT -s 1000 $DIR/f34e ||
4647                 error "Size of $DIR/f34e not equal to 1000 bytes"
4648 }
4649 run_test 34e "create objects, some with size and some without =="
4650
4651 test_34f() { # bug 6242, 6243
4652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4653
4654         SIZE34F=48000
4655         rm -f $DIR/f34f
4656         $MCREATE $DIR/f34f || error "mcreate failed"
4657         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4658         dd if=$DIR/f34f of=$TMP/f34f
4659         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4660         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4661         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4662         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4663         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4664 }
4665 run_test 34f "read from a file with no objects until EOF ======="
4666
4667 test_34g() {
4668         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4669
4670         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4671                 error "dd failed"
4672         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4673         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4674                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4675         cancel_lru_locks osc
4676         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4677                 error "wrong size after lock cancel"
4678
4679         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4680         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4681                 error "expanding truncate failed"
4682         cancel_lru_locks osc
4683         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4684                 error "wrong expanded size after lock cancel"
4685 }
4686 run_test 34g "truncate long file ==============================="
4687
4688 test_34h() {
4689         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4690
4691         local gid=10
4692         local sz=1000
4693
4694         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4695         sync # Flush the cache so that multiop below does not block on cache
4696              # flush when getting the group lock
4697         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4698         MULTIPID=$!
4699
4700         # Since just timed wait is not good enough, let's do a sync write
4701         # that way we are sure enough time for a roundtrip + processing
4702         # passed + 2 seconds of extra margin.
4703         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4704         rm $DIR/${tfile}-1
4705         sleep 2
4706
4707         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4708                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4709                 kill -9 $MULTIPID
4710         fi
4711         wait $MULTIPID
4712         local nsz=`stat -c %s $DIR/$tfile`
4713         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4714 }
4715 run_test 34h "ftruncate file under grouplock should not block"
4716
4717 test_35a() {
4718         cp /bin/sh $DIR/f35a
4719         chmod 444 $DIR/f35a
4720         chown $RUNAS_ID $DIR/f35a
4721         $RUNAS $DIR/f35a && error || true
4722         rm $DIR/f35a
4723 }
4724 run_test 35a "exec file with mode 444 (should return and not leak)"
4725
4726 test_36a() {
4727         rm -f $DIR/f36
4728         utime $DIR/f36 || error "utime failed for MDS"
4729 }
4730 run_test 36a "MDS utime check (mknod, utime)"
4731
4732 test_36b() {
4733         echo "" > $DIR/f36
4734         utime $DIR/f36 || error "utime failed for OST"
4735 }
4736 run_test 36b "OST utime check (open, utime)"
4737
4738 test_36c() {
4739         rm -f $DIR/d36/f36
4740         test_mkdir $DIR/d36
4741         chown $RUNAS_ID $DIR/d36
4742         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4743 }
4744 run_test 36c "non-root MDS utime check (mknod, utime)"
4745
4746 test_36d() {
4747         [ ! -d $DIR/d36 ] && test_36c
4748         echo "" > $DIR/d36/f36
4749         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4750 }
4751 run_test 36d "non-root OST utime check (open, utime)"
4752
4753 test_36e() {
4754         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4755
4756         test_mkdir $DIR/$tdir
4757         touch $DIR/$tdir/$tfile
4758         $RUNAS utime $DIR/$tdir/$tfile &&
4759                 error "utime worked, expected failure" || true
4760 }
4761 run_test 36e "utime on non-owned file (should return error)"
4762
4763 subr_36fh() {
4764         local fl="$1"
4765         local LANG_SAVE=$LANG
4766         local LC_LANG_SAVE=$LC_LANG
4767         export LANG=C LC_LANG=C # for date language
4768
4769         DATESTR="Dec 20  2000"
4770         test_mkdir $DIR/$tdir
4771         lctl set_param fail_loc=$fl
4772         date; date +%s
4773         cp /etc/hosts $DIR/$tdir/$tfile
4774         sync & # write RPC generated with "current" inode timestamp, but delayed
4775         sleep 1
4776         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4777         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4778         cancel_lru_locks $OSC
4779         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4780         date; date +%s
4781         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4782                 echo "BEFORE: $LS_BEFORE" && \
4783                 echo "AFTER : $LS_AFTER" && \
4784                 echo "WANT  : $DATESTR" && \
4785                 error "$DIR/$tdir/$tfile timestamps changed" || true
4786
4787         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4788 }
4789
4790 test_36f() {
4791         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4792
4793         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4794         subr_36fh "0x80000214"
4795 }
4796 run_test 36f "utime on file racing with OST BRW write =========="
4797
4798 test_36g() {
4799         remote_ost_nodsh && skip "remote OST with nodsh"
4800         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4801         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4802                 skip "Need MDS version at least 2.12.51"
4803
4804         local fmd_max_age
4805         local fmd
4806         local facet="ost1"
4807         local tgt="obdfilter"
4808
4809         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4810
4811         test_mkdir $DIR/$tdir
4812         fmd_max_age=$(do_facet $facet \
4813                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4814                 head -n 1")
4815
4816         echo "FMD max age: ${fmd_max_age}s"
4817         touch $DIR/$tdir/$tfile
4818         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4819                 gawk '{cnt=cnt+$1}  END{print cnt}')
4820         echo "FMD before: $fmd"
4821         [[ $fmd == 0 ]] &&
4822                 error "FMD wasn't create by touch"
4823         sleep $((fmd_max_age + 12))
4824         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4825                 gawk '{cnt=cnt+$1}  END{print cnt}')
4826         echo "FMD after: $fmd"
4827         [[ $fmd == 0 ]] ||
4828                 error "FMD wasn't expired by ping"
4829 }
4830 run_test 36g "FMD cache expiry ====================="
4831
4832 test_36h() {
4833         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4834
4835         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4836         subr_36fh "0x80000227"
4837 }
4838 run_test 36h "utime on file racing with OST BRW write =========="
4839
4840 test_36i() {
4841         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4842
4843         test_mkdir $DIR/$tdir
4844         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4845
4846         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4847         local new_mtime=$((mtime + 200))
4848
4849         #change Modify time of striped dir
4850         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4851                         error "change mtime failed"
4852
4853         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4854
4855         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4856 }
4857 run_test 36i "change mtime on striped directory"
4858
4859 # test_37 - duplicate with tests 32q 32r
4860
4861 test_38() {
4862         local file=$DIR/$tfile
4863         touch $file
4864         openfile -f O_DIRECTORY $file
4865         local RC=$?
4866         local ENOTDIR=20
4867         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4868         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4869 }
4870 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4871
4872 test_39a() { # was test_39
4873         touch $DIR/$tfile
4874         touch $DIR/${tfile}2
4875 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4876 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4877 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4878         sleep 2
4879         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4880         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4881                 echo "mtime"
4882                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4883                 echo "atime"
4884                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4885                 echo "ctime"
4886                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4887                 error "O_TRUNC didn't change timestamps"
4888         fi
4889 }
4890 run_test 39a "mtime changed on create"
4891
4892 test_39b() {
4893         test_mkdir -c1 $DIR/$tdir
4894         cp -p /etc/passwd $DIR/$tdir/fopen
4895         cp -p /etc/passwd $DIR/$tdir/flink
4896         cp -p /etc/passwd $DIR/$tdir/funlink
4897         cp -p /etc/passwd $DIR/$tdir/frename
4898         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4899
4900         sleep 1
4901         echo "aaaaaa" >> $DIR/$tdir/fopen
4902         echo "aaaaaa" >> $DIR/$tdir/flink
4903         echo "aaaaaa" >> $DIR/$tdir/funlink
4904         echo "aaaaaa" >> $DIR/$tdir/frename
4905
4906         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4907         local link_new=`stat -c %Y $DIR/$tdir/flink`
4908         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4909         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4910
4911         cat $DIR/$tdir/fopen > /dev/null
4912         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4913         rm -f $DIR/$tdir/funlink2
4914         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4915
4916         for (( i=0; i < 2; i++ )) ; do
4917                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4918                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4919                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4920                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4921
4922                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4923                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4924                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4925                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4926
4927                 cancel_lru_locks $OSC
4928                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4929         done
4930 }
4931 run_test 39b "mtime change on open, link, unlink, rename  ======"
4932
4933 # this should be set to past
4934 TEST_39_MTIME=`date -d "1 year ago" +%s`
4935
4936 # bug 11063
4937 test_39c() {
4938         touch $DIR1/$tfile
4939         sleep 2
4940         local mtime0=`stat -c %Y $DIR1/$tfile`
4941
4942         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4943         local mtime1=`stat -c %Y $DIR1/$tfile`
4944         [ "$mtime1" = $TEST_39_MTIME ] || \
4945                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4946
4947         local d1=`date +%s`
4948         echo hello >> $DIR1/$tfile
4949         local d2=`date +%s`
4950         local mtime2=`stat -c %Y $DIR1/$tfile`
4951         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4952                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4953
4954         mv $DIR1/$tfile $DIR1/$tfile-1
4955
4956         for (( i=0; i < 2; i++ )) ; do
4957                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4958                 [ "$mtime2" = "$mtime3" ] || \
4959                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4960
4961                 cancel_lru_locks $OSC
4962                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4963         done
4964 }
4965 run_test 39c "mtime change on rename ==========================="
4966
4967 # bug 21114
4968 test_39d() {
4969         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4970
4971         touch $DIR1/$tfile
4972         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4973
4974         for (( i=0; i < 2; i++ )) ; do
4975                 local mtime=`stat -c %Y $DIR1/$tfile`
4976                 [ $mtime = $TEST_39_MTIME ] || \
4977                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4978
4979                 cancel_lru_locks $OSC
4980                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4981         done
4982 }
4983 run_test 39d "create, utime, stat =============================="
4984
4985 # bug 21114
4986 test_39e() {
4987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4988
4989         touch $DIR1/$tfile
4990         local mtime1=`stat -c %Y $DIR1/$tfile`
4991
4992         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4993
4994         for (( i=0; i < 2; i++ )) ; do
4995                 local mtime2=`stat -c %Y $DIR1/$tfile`
4996                 [ $mtime2 = $TEST_39_MTIME ] || \
4997                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4998
4999                 cancel_lru_locks $OSC
5000                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5001         done
5002 }
5003 run_test 39e "create, stat, utime, stat ========================"
5004
5005 # bug 21114
5006 test_39f() {
5007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5008
5009         touch $DIR1/$tfile
5010         mtime1=`stat -c %Y $DIR1/$tfile`
5011
5012         sleep 2
5013         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5014
5015         for (( i=0; i < 2; i++ )) ; do
5016                 local mtime2=`stat -c %Y $DIR1/$tfile`
5017                 [ $mtime2 = $TEST_39_MTIME ] || \
5018                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
5019
5020                 cancel_lru_locks $OSC
5021                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5022         done
5023 }
5024 run_test 39f "create, stat, sleep, utime, stat ================="
5025
5026 # bug 11063
5027 test_39g() {
5028         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5029
5030         echo hello >> $DIR1/$tfile
5031         local mtime1=`stat -c %Y $DIR1/$tfile`
5032
5033         sleep 2
5034         chmod o+r $DIR1/$tfile
5035
5036         for (( i=0; i < 2; i++ )) ; do
5037                 local mtime2=`stat -c %Y $DIR1/$tfile`
5038                 [ "$mtime1" = "$mtime2" ] || \
5039                         error "lost mtime: $mtime2, should be $mtime1"
5040
5041                 cancel_lru_locks $OSC
5042                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5043         done
5044 }
5045 run_test 39g "write, chmod, stat ==============================="
5046
5047 # bug 11063
5048 test_39h() {
5049         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5050
5051         touch $DIR1/$tfile
5052         sleep 1
5053
5054         local d1=`date`
5055         echo hello >> $DIR1/$tfile
5056         local mtime1=`stat -c %Y $DIR1/$tfile`
5057
5058         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5059         local d2=`date`
5060         if [ "$d1" != "$d2" ]; then
5061                 echo "write and touch not within one second"
5062         else
5063                 for (( i=0; i < 2; i++ )) ; do
5064                         local mtime2=`stat -c %Y $DIR1/$tfile`
5065                         [ "$mtime2" = $TEST_39_MTIME ] || \
5066                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
5067
5068                         cancel_lru_locks $OSC
5069                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5070                 done
5071         fi
5072 }
5073 run_test 39h "write, utime within one second, stat ============="
5074
5075 test_39i() {
5076         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5077
5078         touch $DIR1/$tfile
5079         sleep 1
5080
5081         echo hello >> $DIR1/$tfile
5082         local mtime1=`stat -c %Y $DIR1/$tfile`
5083
5084         mv $DIR1/$tfile $DIR1/$tfile-1
5085
5086         for (( i=0; i < 2; i++ )) ; do
5087                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5088
5089                 [ "$mtime1" = "$mtime2" ] || \
5090                         error "lost mtime: $mtime2, should be $mtime1"
5091
5092                 cancel_lru_locks $OSC
5093                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5094         done
5095 }
5096 run_test 39i "write, rename, stat =============================="
5097
5098 test_39j() {
5099         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5100
5101         start_full_debug_logging
5102         touch $DIR1/$tfile
5103         sleep 1
5104
5105         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
5106         lctl set_param fail_loc=0x80000412
5107         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
5108                 error "multiop failed"
5109         local multipid=$!
5110         local mtime1=`stat -c %Y $DIR1/$tfile`
5111
5112         mv $DIR1/$tfile $DIR1/$tfile-1
5113
5114         kill -USR1 $multipid
5115         wait $multipid || error "multiop close failed"
5116
5117         for (( i=0; i < 2; i++ )) ; do
5118                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5119                 [ "$mtime1" = "$mtime2" ] ||
5120                         error "mtime is lost on close: $mtime2, " \
5121                               "should be $mtime1"
5122
5123                 cancel_lru_locks
5124                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5125         done
5126         lctl set_param fail_loc=0
5127         stop_full_debug_logging
5128 }
5129 run_test 39j "write, rename, close, stat ======================="
5130
5131 test_39k() {
5132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5133
5134         touch $DIR1/$tfile
5135         sleep 1
5136
5137         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
5138         local multipid=$!
5139         local mtime1=`stat -c %Y $DIR1/$tfile`
5140
5141         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5142
5143         kill -USR1 $multipid
5144         wait $multipid || error "multiop close failed"
5145
5146         for (( i=0; i < 2; i++ )) ; do
5147                 local mtime2=`stat -c %Y $DIR1/$tfile`
5148
5149                 [ "$mtime2" = $TEST_39_MTIME ] || \
5150                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
5151
5152                 cancel_lru_locks
5153                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5154         done
5155 }
5156 run_test 39k "write, utime, close, stat ========================"
5157
5158 # this should be set to future
5159 TEST_39_ATIME=`date -d "1 year" +%s`
5160
5161 test_39l() {
5162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5163         remote_mds_nodsh && skip "remote MDS with nodsh"
5164
5165         local atime_diff=$(do_facet $SINGLEMDS \
5166                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5167         rm -rf $DIR/$tdir
5168         mkdir_on_mdt0 $DIR/$tdir
5169
5170         # test setting directory atime to future
5171         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5172         local atime=$(stat -c %X $DIR/$tdir)
5173         [ "$atime" = $TEST_39_ATIME ] ||
5174                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5175
5176         # test setting directory atime from future to now
5177         local now=$(date +%s)
5178         touch -a -d @$now $DIR/$tdir
5179
5180         atime=$(stat -c %X $DIR/$tdir)
5181         [ "$atime" -eq "$now"  ] ||
5182                 error "atime is not updated from future: $atime, $now"
5183
5184         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5185         sleep 3
5186
5187         # test setting directory atime when now > dir atime + atime_diff
5188         local d1=$(date +%s)
5189         ls $DIR/$tdir
5190         local d2=$(date +%s)
5191         cancel_lru_locks mdc
5192         atime=$(stat -c %X $DIR/$tdir)
5193         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5194                 error "atime is not updated  : $atime, should be $d2"
5195
5196         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5197         sleep 3
5198
5199         # test not setting directory atime when now < dir atime + atime_diff
5200         ls $DIR/$tdir
5201         cancel_lru_locks mdc
5202         atime=$(stat -c %X $DIR/$tdir)
5203         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5204                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5205
5206         do_facet $SINGLEMDS \
5207                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5208 }
5209 run_test 39l "directory atime update ==========================="
5210
5211 test_39m() {
5212         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5213
5214         touch $DIR1/$tfile
5215         sleep 2
5216         local far_past_mtime=$(date -d "May 29 1953" +%s)
5217         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5218
5219         touch -m -d @$far_past_mtime $DIR1/$tfile
5220         touch -a -d @$far_past_atime $DIR1/$tfile
5221
5222         for (( i=0; i < 2; i++ )) ; do
5223                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5224                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5225                         error "atime or mtime set incorrectly"
5226
5227                 cancel_lru_locks $OSC
5228                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5229         done
5230 }
5231 run_test 39m "test atime and mtime before 1970"
5232
5233 test_39n() { # LU-3832
5234         remote_mds_nodsh && skip "remote MDS with nodsh"
5235
5236         local atime_diff=$(do_facet $SINGLEMDS \
5237                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5238         local atime0
5239         local atime1
5240         local atime2
5241
5242         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5243
5244         rm -rf $DIR/$tfile
5245         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5246         atime0=$(stat -c %X $DIR/$tfile)
5247
5248         sleep 5
5249         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5250         atime1=$(stat -c %X $DIR/$tfile)
5251
5252         sleep 5
5253         cancel_lru_locks mdc
5254         cancel_lru_locks osc
5255         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5256         atime2=$(stat -c %X $DIR/$tfile)
5257
5258         do_facet $SINGLEMDS \
5259                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5260
5261         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5262         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5263 }
5264 run_test 39n "check that O_NOATIME is honored"
5265
5266 test_39o() {
5267         TESTDIR=$DIR/$tdir/$tfile
5268         [ -e $TESTDIR ] && rm -rf $TESTDIR
5269         mkdir -p $TESTDIR
5270         cd $TESTDIR
5271         links1=2
5272         ls
5273         mkdir a b
5274         ls
5275         links2=$(stat -c %h .)
5276         [ $(($links1 + 2)) != $links2 ] &&
5277                 error "wrong links count $(($links1 + 2)) != $links2"
5278         rmdir b
5279         links3=$(stat -c %h .)
5280         [ $(($links1 + 1)) != $links3 ] &&
5281                 error "wrong links count $links1 != $links3"
5282         return 0
5283 }
5284 run_test 39o "directory cached attributes updated after create"
5285
5286 test_39p() {
5287         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5288
5289         local MDTIDX=1
5290         TESTDIR=$DIR/$tdir/$tdir
5291         [ -e $TESTDIR ] && rm -rf $TESTDIR
5292         test_mkdir -p $TESTDIR
5293         cd $TESTDIR
5294         links1=2
5295         ls
5296         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5297         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5298         ls
5299         links2=$(stat -c %h .)
5300         [ $(($links1 + 2)) != $links2 ] &&
5301                 error "wrong links count $(($links1 + 2)) != $links2"
5302         rmdir remote_dir2
5303         links3=$(stat -c %h .)
5304         [ $(($links1 + 1)) != $links3 ] &&
5305                 error "wrong links count $links1 != $links3"
5306         return 0
5307 }
5308 run_test 39p "remote directory cached attributes updated after create ========"
5309
5310 test_39r() {
5311         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5312                 skip "no atime update on old OST"
5313         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5314                 skip_env "ldiskfs only test"
5315         fi
5316
5317         local saved_adiff
5318         local ahost=$(facet_active_host ost1)
5319         saved_adiff=$(do_facet ost1 \
5320                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5321         stack_trap "do_facet ost1 \
5322                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5323
5324         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5325
5326         $LFS setstripe -i 0 $DIR/$tfile
5327         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5328                 error "can't write initial file"
5329         cancel_lru_locks osc
5330
5331         # exceed atime_diff and access file
5332         sleep 10
5333         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5334                 error "can't udpate atime"
5335
5336         # atime_cli value is in decimal
5337         local atime_cli=$(stat -c %X $DIR/$tfile)
5338         echo "client atime: $atime_cli"
5339
5340         local ostdev=$(ostdevname 1)
5341         local fid=($($LFS getstripe $DIR/$tfile | grep 0x))
5342         local seq=${fid[3]#0x}
5343         local oid=${fid[1]}
5344         local oid_hex
5345
5346         if [ $seq == 0 ]; then
5347                 oid_hex=${fid[1]}
5348         else
5349                 oid_hex=${fid[2]#0x}
5350         fi
5351         local objpath="O/$seq/d$(($oid % 32))/$oid_hex"
5352         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5353
5354         # allow atime update to be written to device
5355         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync=1"
5356         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5357
5358         # Give enough time for server to get updated. Until then
5359         # the value read is defaulted to "0x00000000:00000000"
5360         # Wait until atime read via debugfs is not equal to zero.
5361         # Max limit to wait is 30 seconds.
5362         wait_update_cond $ahost                                         \
5363                 "$cmd |& awk -F'[: ]' '/atime:/ { print \\\$4 }'"       \
5364                 "-gt" "0" 30 || error "atime on ost is still 0 after 30 seconds"
5365         # atime_ost value is in hex
5366         local atime_ost=$(do_facet ost1 "$cmd" |&
5367                           awk -F'[: ]' '/atime:/ { print $4 }')
5368         # debugfs returns atime in 0xNNNNNNNN:00000000 format
5369         # convert Hex to decimal before comparing
5370         local atime_ost_dec=$((atime_ost))
5371
5372         # The test pass criteria is that the client time and server should
5373         # be same (2s gap accepted). This gap could arise due to VFS updating
5374         # the atime after the read(dd), stat and the updated time from the
5375         # inode
5376         (( $((atime_cli - atime_ost_dec)) <= 2 )) ||
5377                 error "atime on client $atime_cli != ost $atime_ost_dec"
5378 }
5379 run_test 39r "lazy atime update on OST"
5380
5381 test_39q() { # LU-8041
5382         local testdir=$DIR/$tdir
5383         mkdir -p $testdir
5384         multiop_bg_pause $testdir D_c || error "multiop failed"
5385         local multipid=$!
5386         cancel_lru_locks mdc
5387         kill -USR1 $multipid
5388         local atime=$(stat -c %X $testdir)
5389         [ "$atime" -ne 0 ] || error "atime is zero"
5390 }
5391 run_test 39q "close won't zero out atime"
5392
5393 test_39s() {
5394         local atime0
5395         local atime1
5396         local atime2
5397         local atime3
5398         local atime4
5399
5400         umount_client $MOUNT
5401         mount_client $MOUNT relatime
5402
5403         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer conv=fsync
5404         atime0=$(stat -c %X $DIR/$tfile)
5405
5406         # First read updates atime
5407         sleep 1
5408         cat $DIR/$tfile >/dev/null
5409         atime1=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5410
5411         # Next reads do not update atime
5412         sleep 1
5413         cat $DIR/$tfile >/dev/null
5414         atime2=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5415
5416         # If mtime is greater than atime, atime is updated
5417         sleep 1
5418         touch -m $DIR/$tfile # (mtime = now)
5419         sleep 1
5420         cat $DIR/$tfile >/dev/null # (atime is updated because atime < mtime)
5421         atime3=$(stat -c %X $DIR/$tfile) # (atime = mtime = atime0 + 3)
5422
5423         # Next reads do not update atime
5424         sleep 1
5425         cat $DIR/$tfile >/dev/null
5426         atime4=$(stat -c %X $DIR/$tfile)
5427
5428         # Remount the client to clear 'relatime' option
5429         remount_client $MOUNT
5430
5431         (( atime0 < atime1 )) ||
5432                 error "atime $atime0 should be smaller than $atime1"
5433         (( atime1 == atime2 )) ||
5434                 error "atime $atime1 was updated to $atime2"
5435         (( atime1 < atime3 )) || error "atime1 $atime1 != atime3 $atime3"
5436         (( atime3 == atime4 )) || error "atime3 $atime3 != atime4 $atime4"
5437 }
5438 run_test 39s "relatime is supported"
5439
5440 test_40() {
5441         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5442         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5443                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5444         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5445                 error "$tfile is not 4096 bytes in size"
5446 }
5447 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5448
5449 test_41() {
5450         # bug 1553
5451         small_write $DIR/f41 18
5452 }
5453 run_test 41 "test small file write + fstat ====================="
5454
5455 count_ost_writes() {
5456         lctl get_param -n ${OSC}.*.stats |
5457                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5458                         END { printf("%0.0f", writes) }'
5459 }
5460
5461 # decent default
5462 WRITEBACK_SAVE=500
5463 DIRTY_RATIO_SAVE=40
5464 MAX_DIRTY_RATIO=50
5465 BG_DIRTY_RATIO_SAVE=10
5466 MAX_BG_DIRTY_RATIO=25
5467
5468 start_writeback() {
5469         trap 0
5470         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5471         # dirty_ratio, dirty_background_ratio
5472         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5473                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5474                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5475                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5476         else
5477                 # if file not here, we are a 2.4 kernel
5478                 kill -CONT `pidof kupdated`
5479         fi
5480 }
5481
5482 stop_writeback() {
5483         # setup the trap first, so someone cannot exit the test at the
5484         # exact wrong time and mess up a machine
5485         trap start_writeback EXIT
5486         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5487         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5488                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5489                 sysctl -w vm.dirty_writeback_centisecs=0
5490                 sysctl -w vm.dirty_writeback_centisecs=0
5491                 # save and increase /proc/sys/vm/dirty_ratio
5492                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5493                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5494                 # save and increase /proc/sys/vm/dirty_background_ratio
5495                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5496                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5497         else
5498                 # if file not here, we are a 2.4 kernel
5499                 kill -STOP `pidof kupdated`
5500         fi
5501 }
5502
5503 # ensure that all stripes have some grant before we test client-side cache
5504 setup_test42() {
5505         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5506                 dd if=/dev/zero of=$i bs=4k count=1
5507                 rm $i
5508         done
5509 }
5510
5511 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5512 # file truncation, and file removal.
5513 test_42a() {
5514         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5515
5516         setup_test42
5517         cancel_lru_locks $OSC
5518         stop_writeback
5519         sync; sleep 1; sync # just to be safe
5520         BEFOREWRITES=`count_ost_writes`
5521         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5522         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5523         AFTERWRITES=`count_ost_writes`
5524         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5525                 error "$BEFOREWRITES < $AFTERWRITES"
5526         start_writeback
5527 }
5528 run_test 42a "ensure that we don't flush on close"
5529
5530 test_42b() {
5531         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5532
5533         setup_test42
5534         cancel_lru_locks $OSC
5535         stop_writeback
5536         sync
5537         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5538         BEFOREWRITES=$(count_ost_writes)
5539         unlink $DIR/f42b || error "unlink $DIR/f42b: $?"
5540         AFTERWRITES=$(count_ost_writes)
5541         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5542                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5543         fi
5544         BEFOREWRITES=$(count_ost_writes)
5545         sync || error "sync: $?"
5546         AFTERWRITES=$(count_ost_writes)
5547         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5548                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5549         fi
5550         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5551         start_writeback
5552         return 0
5553 }
5554 run_test 42b "test destroy of file with cached dirty data ======"
5555
5556 # if these tests just want to test the effect of truncation,
5557 # they have to be very careful.  consider:
5558 # - the first open gets a {0,EOF}PR lock
5559 # - the first write conflicts and gets a {0, count-1}PW
5560 # - the rest of the writes are under {count,EOF}PW
5561 # - the open for truncate tries to match a {0,EOF}PR
5562 #   for the filesize and cancels the PWs.
5563 # any number of fixes (don't get {0,EOF} on open, match
5564 # composite locks, do smarter file size management) fix
5565 # this, but for now we want these tests to verify that
5566 # the cancellation with truncate intent works, so we
5567 # start the file with a full-file pw lock to match against
5568 # until the truncate.
5569 trunc_test() {
5570         test=$1
5571         file=$DIR/$test
5572         offset=$2
5573         cancel_lru_locks $OSC
5574         stop_writeback
5575         # prime the file with 0,EOF PW to match
5576         touch $file
5577         $TRUNCATE $file 0
5578         sync; sync
5579         # now the real test..
5580         dd if=/dev/zero of=$file bs=1024 count=100
5581         BEFOREWRITES=`count_ost_writes`
5582         $TRUNCATE $file $offset
5583         cancel_lru_locks $OSC
5584         AFTERWRITES=`count_ost_writes`
5585         start_writeback
5586 }
5587
5588 test_42c() {
5589         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5590
5591         trunc_test 42c 1024
5592         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5593                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5594         rm $file
5595 }
5596 run_test 42c "test partial truncate of file with cached dirty data"
5597
5598 test_42d() {
5599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5600
5601         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5602         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5603         $LCTL set_param debug=+cache
5604
5605         trunc_test 42d 0
5606         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5607                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5608         rm $file
5609 }
5610 run_test 42d "test complete truncate of file with cached dirty data"
5611
5612 test_42e() { # bug22074
5613         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5614
5615         local TDIR=$DIR/${tdir}e
5616         local pages=16 # hardcoded 16 pages, don't change it.
5617         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5618         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5619         local max_dirty_mb
5620         local warmup_files
5621
5622         test_mkdir $DIR/${tdir}e
5623         $LFS setstripe -c 1 $TDIR
5624         createmany -o $TDIR/f $files
5625
5626         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5627
5628         # we assume that with $OSTCOUNT files, at least one of them will
5629         # be allocated on OST0.
5630         warmup_files=$((OSTCOUNT * max_dirty_mb))
5631         createmany -o $TDIR/w $warmup_files
5632
5633         # write a large amount of data into one file and sync, to get good
5634         # avail_grant number from OST.
5635         for ((i=0; i<$warmup_files; i++)); do
5636                 idx=$($LFS getstripe -i $TDIR/w$i)
5637                 [ $idx -ne 0 ] && continue
5638                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5639                 break
5640         done
5641         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5642         sync
5643         $LCTL get_param $proc_osc0/cur_dirty_bytes
5644         $LCTL get_param $proc_osc0/cur_grant_bytes
5645
5646         # create as much dirty pages as we can while not to trigger the actual
5647         # RPCs directly. but depends on the env, VFS may trigger flush during this
5648         # period, hopefully we are good.
5649         for ((i=0; i<$warmup_files; i++)); do
5650                 idx=$($LFS getstripe -i $TDIR/w$i)
5651                 [ $idx -ne 0 ] && continue
5652                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5653         done
5654         $LCTL get_param $proc_osc0/cur_dirty_bytes
5655         $LCTL get_param $proc_osc0/cur_grant_bytes
5656
5657         # perform the real test
5658         $LCTL set_param $proc_osc0/rpc_stats 0
5659         for ((;i<$files; i++)); do
5660                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5661                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5662         done
5663         sync
5664         $LCTL get_param $proc_osc0/rpc_stats
5665
5666         local percent=0
5667         local have_ppr=false
5668         $LCTL get_param $proc_osc0/rpc_stats |
5669                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5670                         # skip lines until we are at the RPC histogram data
5671                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5672                         $have_ppr || continue
5673
5674                         # we only want the percent stat for < 16 pages
5675                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5676
5677                         percent=$((percent + WPCT))
5678                         if [[ $percent -gt 15 ]]; then
5679                                 error "less than 16-pages write RPCs" \
5680                                       "$percent% > 15%"
5681                                 break
5682                         fi
5683                 done
5684         rm -rf $TDIR
5685 }
5686 run_test 42e "verify sub-RPC writes are not done synchronously"
5687
5688 test_43A() { # was test_43
5689         test_mkdir $DIR/$tdir
5690         cp -p /bin/ls $DIR/$tdir/$tfile
5691         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5692         pid=$!
5693         # give multiop a chance to open
5694         sleep 1
5695
5696         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5697         kill -USR1 $pid
5698         # Wait for multiop to exit
5699         wait $pid
5700 }
5701 run_test 43A "execution of file opened for write should return -ETXTBSY"
5702
5703 test_43a() {
5704         test_mkdir $DIR/$tdir
5705         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5706         $DIR/$tdir/sleep 60 &
5707         SLEEP_PID=$!
5708         # Make sure exec of $tdir/sleep wins race with truncate
5709         sleep 1
5710         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5711         kill $SLEEP_PID
5712 }
5713 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5714
5715 test_43b() {
5716         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5717
5718         test_mkdir $DIR/$tdir
5719         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5720         $DIR/$tdir/sleep 60 &
5721         SLEEP_PID=$!
5722         # Make sure exec of $tdir/sleep wins race with truncate
5723         sleep 1
5724         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5725         kill $SLEEP_PID
5726 }
5727 run_test 43b "truncate of file being executed should return -ETXTBSY"
5728
5729 test_43c() {
5730         local testdir="$DIR/$tdir"
5731         test_mkdir $testdir
5732         cp $SHELL $testdir/
5733         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5734                 ( cd $testdir && md5sum -c )
5735 }
5736 run_test 43c "md5sum of copy into lustre"
5737
5738 test_44A() { # was test_44
5739         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5740
5741         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5742         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5743 }
5744 run_test 44A "zero length read from a sparse stripe"
5745
5746 test_44a() {
5747         local nstripe=$($LFS getstripe -c -d $DIR)
5748         [ -z "$nstripe" ] && skip "can't get stripe info"
5749         [[ $nstripe -gt $OSTCOUNT ]] &&
5750                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5751
5752         local stride=$($LFS getstripe -S -d $DIR)
5753         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5754                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5755         fi
5756
5757         OFFSETS="0 $((stride/2)) $((stride-1))"
5758         for offset in $OFFSETS; do
5759                 for i in $(seq 0 $((nstripe-1))); do
5760                         local GLOBALOFFSETS=""
5761                         # size in Bytes
5762                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5763                         local myfn=$DIR/d44a-$size
5764                         echo "--------writing $myfn at $size"
5765                         ll_sparseness_write $myfn $size ||
5766                                 error "ll_sparseness_write"
5767                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5768                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5769                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5770
5771                         for j in $(seq 0 $((nstripe-1))); do
5772                                 # size in Bytes
5773                                 size=$((((j + $nstripe )*$stride + $offset)))
5774                                 ll_sparseness_write $myfn $size ||
5775                                         error "ll_sparseness_write"
5776                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5777                         done
5778                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5779                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5780                         rm -f $myfn
5781                 done
5782         done
5783 }
5784 run_test 44a "test sparse pwrite ==============================="
5785
5786 dirty_osc_total() {
5787         tot=0
5788         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5789                 tot=$(($tot + $d))
5790         done
5791         echo $tot
5792 }
5793 do_dirty_record() {
5794         before=`dirty_osc_total`
5795         echo executing "\"$*\""
5796         eval $*
5797         after=`dirty_osc_total`
5798         echo before $before, after $after
5799 }
5800 test_45() {
5801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5802
5803         f="$DIR/f45"
5804         # Obtain grants from OST if it supports it
5805         echo blah > ${f}_grant
5806         stop_writeback
5807         sync
5808         do_dirty_record "echo blah > $f"
5809         [[ $before -eq $after ]] && error "write wasn't cached"
5810         do_dirty_record "> $f"
5811         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5812         do_dirty_record "echo blah > $f"
5813         [[ $before -eq $after ]] && error "write wasn't cached"
5814         do_dirty_record "sync"
5815         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5816         do_dirty_record "echo blah > $f"
5817         [[ $before -eq $after ]] && error "write wasn't cached"
5818         do_dirty_record "cancel_lru_locks osc"
5819         [[ $before -gt $after ]] ||
5820                 error "lock cancellation didn't lower dirty count"
5821         start_writeback
5822 }
5823 run_test 45 "osc io page accounting ============================"
5824
5825 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5826 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5827 # objects offset and an assert hit when an rpc was built with 1023's mapped
5828 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5829 test_46() {
5830         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5831
5832         f="$DIR/f46"
5833         stop_writeback
5834         sync
5835         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5836         sync
5837         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5838         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5839         sync
5840         start_writeback
5841 }
5842 run_test 46 "dirtying a previously written page ================"
5843
5844 # test_47 is removed "Device nodes check" is moved to test_28
5845
5846 test_48a() { # bug 2399
5847         [ "$mds1_FSTYPE" = "zfs" ] &&
5848         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5849                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5850
5851         test_mkdir $DIR/$tdir
5852         cd $DIR/$tdir
5853         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5854         test_mkdir $DIR/$tdir
5855         touch foo || error "'touch foo' failed after recreating cwd"
5856         test_mkdir bar
5857         touch .foo || error "'touch .foo' failed after recreating cwd"
5858         test_mkdir .bar
5859         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5860         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5861         cd . || error "'cd .' failed after recreating cwd"
5862         mkdir . && error "'mkdir .' worked after recreating cwd"
5863         rmdir . && error "'rmdir .' worked after recreating cwd"
5864         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5865         cd .. || error "'cd ..' failed after recreating cwd"
5866 }
5867 run_test 48a "Access renamed working dir (should return errors)="
5868
5869 test_48b() { # bug 2399
5870         rm -rf $DIR/$tdir
5871         test_mkdir $DIR/$tdir
5872         cd $DIR/$tdir
5873         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5874         touch foo && error "'touch foo' worked after removing cwd"
5875         mkdir foo && error "'mkdir foo' worked after removing cwd"
5876         touch .foo && error "'touch .foo' worked after removing cwd"
5877         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5878         ls . > /dev/null && error "'ls .' worked after removing cwd"
5879         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5880         mkdir . && error "'mkdir .' worked after removing cwd"
5881         rmdir . && error "'rmdir .' worked after removing cwd"
5882         ln -s . foo && error "'ln -s .' worked after removing cwd"
5883         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5884 }
5885 run_test 48b "Access removed working dir (should return errors)="
5886
5887 test_48c() { # bug 2350
5888         #lctl set_param debug=-1
5889         #set -vx
5890         rm -rf $DIR/$tdir
5891         test_mkdir -p $DIR/$tdir/dir
5892         cd $DIR/$tdir/dir
5893         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5894         $TRACE touch foo && error "touch foo worked after removing cwd"
5895         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5896         touch .foo && error "touch .foo worked after removing cwd"
5897         mkdir .foo && error "mkdir .foo worked after removing cwd"
5898         $TRACE ls . && error "'ls .' worked after removing cwd"
5899         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5900         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5901         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5902         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5903         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5904 }
5905 run_test 48c "Access removed working subdir (should return errors)"
5906
5907 test_48d() { # bug 2350
5908         #lctl set_param debug=-1
5909         #set -vx
5910         rm -rf $DIR/$tdir
5911         test_mkdir -p $DIR/$tdir/dir
5912         cd $DIR/$tdir/dir
5913         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5914         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5915         $TRACE touch foo && error "'touch foo' worked after removing parent"
5916         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5917         touch .foo && error "'touch .foo' worked after removing parent"
5918         mkdir .foo && error "mkdir .foo worked after removing parent"
5919         $TRACE ls . && error "'ls .' worked after removing parent"
5920         $TRACE ls .. && error "'ls ..' worked after removing parent"
5921         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5922         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5923         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5924         true
5925 }
5926 run_test 48d "Access removed parent subdir (should return errors)"
5927
5928 test_48e() { # bug 4134
5929         #lctl set_param debug=-1
5930         #set -vx
5931         rm -rf $DIR/$tdir
5932         test_mkdir -p $DIR/$tdir/dir
5933         cd $DIR/$tdir/dir
5934         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5935         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5936         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5937         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5938         # On a buggy kernel addition of "touch foo" after cd .. will
5939         # produce kernel oops in lookup_hash_it
5940         touch ../foo && error "'cd ..' worked after recreate parent"
5941         cd $DIR
5942         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5943 }
5944 run_test 48e "Access to recreated parent subdir (should return errors)"
5945
5946 test_48f() {
5947         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5948                 skip "need MDS >= 2.13.55"
5949         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5950         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5951                 skip "needs different host for mdt1 mdt2"
5952         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5953
5954         $LFS mkdir -i0 $DIR/$tdir
5955         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5956
5957         for d in sub1 sub2 sub3; do
5958                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5959                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5960                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5961         done
5962
5963         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5964 }
5965 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5966
5967 test_49() { # LU-1030
5968         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5969         remote_ost_nodsh && skip "remote OST with nodsh"
5970
5971         # get ost1 size - $FSNAME-OST0000
5972         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5973                 awk '{ print $4 }')
5974         # write 800M at maximum
5975         [[ $ost1_size -lt 2 ]] && ost1_size=2
5976         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5977
5978         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5979         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5980         local dd_pid=$!
5981
5982         # change max_pages_per_rpc while writing the file
5983         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5984         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5985         # loop until dd process exits
5986         while ps ax -opid | grep -wq $dd_pid; do
5987                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5988                 sleep $((RANDOM % 5 + 1))
5989         done
5990         # restore original max_pages_per_rpc
5991         $LCTL set_param $osc1_mppc=$orig_mppc
5992         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5993 }
5994 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5995
5996 test_50() {
5997         # bug 1485
5998         test_mkdir $DIR/$tdir
5999         cd $DIR/$tdir
6000         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
6001 }
6002 run_test 50 "special situations: /proc symlinks  ==============="
6003
6004 test_51a() {    # was test_51
6005         # bug 1516 - create an empty entry right after ".." then split dir
6006         test_mkdir -c1 $DIR/$tdir
6007         touch $DIR/$tdir/foo
6008         $MCREATE $DIR/$tdir/bar
6009         rm $DIR/$tdir/foo
6010         createmany -m $DIR/$tdir/longfile 201
6011         FNUM=202
6012         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
6013                 $MCREATE $DIR/$tdir/longfile$FNUM
6014                 FNUM=$(($FNUM + 1))
6015                 echo -n "+"
6016         done
6017         echo
6018         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
6019 }
6020 run_test 51a "special situations: split htree with empty entry =="
6021
6022 cleanup_print_lfs_df () {
6023         trap 0
6024         $LFS df
6025         $LFS df -i
6026 }
6027
6028 test_51b() {
6029         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6030
6031         local dir=$DIR/$tdir
6032         local nrdirs=$((65536 + 100))
6033
6034         # cleanup the directory
6035         rm -fr $dir
6036
6037         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
6038
6039         $LFS df
6040         $LFS df -i
6041         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
6042         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
6043         [[ $numfree -lt $nrdirs ]] &&
6044                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
6045
6046         # need to check free space for the directories as well
6047         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
6048         numfree=$(( blkfree / $(fs_inode_ksize) ))
6049         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
6050
6051         trap cleanup_print_lfs_df EXIT
6052
6053         # create files
6054         createmany -d $dir/d $nrdirs || {
6055                 unlinkmany $dir/d $nrdirs
6056                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
6057         }
6058
6059         # really created :
6060         nrdirs=$(ls -U $dir | wc -l)
6061
6062         # unlink all but 100 subdirectories, then check it still works
6063         local left=100
6064         local delete=$((nrdirs - left))
6065
6066         $LFS df
6067         $LFS df -i
6068
6069         # for ldiskfs the nlink count should be 1, but this is OSD specific
6070         # and so this is listed for informational purposes only
6071         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
6072         unlinkmany -d $dir/d $delete ||
6073                 error "unlink of first $delete subdirs failed"
6074
6075         echo "nlink between: $(stat -c %h $dir)"
6076         local found=$(ls -U $dir | wc -l)
6077         [ $found -ne $left ] &&
6078                 error "can't find subdirs: found only $found, expected $left"
6079
6080         unlinkmany -d $dir/d $delete $left ||
6081                 error "unlink of second $left subdirs failed"
6082         # regardless of whether the backing filesystem tracks nlink accurately
6083         # or not, the nlink count shouldn't be more than "." and ".." here
6084         local after=$(stat -c %h $dir)
6085         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
6086                 echo "nlink after: $after"
6087
6088         cleanup_print_lfs_df
6089 }
6090 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
6091
6092 test_51d_sub() {
6093         local stripecount=$1
6094         local nfiles=$2
6095
6096         log "create files with stripecount=$stripecount"
6097         $LFS setstripe -C $stripecount $DIR/$tdir
6098         createmany -o $DIR/$tdir/t- $nfiles
6099         $LFS getstripe $DIR/$tdir > $TMP/$tfile
6100         for ((n = 0; n < $OSTCOUNT; n++)); do
6101                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
6102                            END { printf("%0.0f", objs) }' $TMP/$tfile)
6103                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
6104                             '($1 == '$n') { objs += 1 } \
6105                             END { printf("%0.0f", objs) }')
6106                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
6107         done
6108         unlinkmany $DIR/$tdir/t- $nfiles
6109         rm  -f $TMP/$tfile
6110
6111         local nlast
6112         local min=4
6113         local max=6 # allow variance of (1 - $min/$max) = 33% by default
6114
6115         # For some combinations of stripecount and OSTCOUNT current code
6116         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
6117         # than others. Rather than skipping this test entirely, check that
6118         # and keep testing to ensure imbalance does not get worse. LU-15282
6119         (( (OSTCOUNT == 6 && stripecount == 4) ||
6120            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
6121            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
6122         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
6123                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
6124                         { $LFS df && $LFS df -i &&
6125                         error "stripecount=$stripecount: " \
6126                               "OST $n has fewer objects vs. OST $nlast " \
6127                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
6128                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
6129                         { $LFS df && $LFS df -i &&
6130                         error "stripecount=$stripecount: " \
6131                               "OST $n has more objects vs. OST $nlast " \
6132                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
6133
6134                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
6135                         { $LFS df && $LFS df -i &&
6136                         error "stripecount=$stripecount: " \
6137                               "OST $n has fewer #0 objects vs. OST $nlast " \
6138                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
6139                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
6140                         { $LFS df && $LFS df -i &&
6141                         error "stripecount=$stripecount: " \
6142                               "OST $n has more #0 objects vs. OST $nlast " \
6143                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
6144         done
6145 }
6146
6147 test_51d() {
6148         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6149         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
6150
6151         local stripecount
6152         local per_ost=100
6153         local nfiles=$((per_ost * OSTCOUNT))
6154         local mdts=$(comma_list $(mdts_nodes))
6155         local param="osp.*.create_count"
6156         local qos_old=$(do_facet mds1 \
6157                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
6158
6159         do_nodes $mdts \
6160                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
6161         stack_trap "do_nodes $mdts \
6162                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
6163
6164         test_mkdir $DIR/$tdir
6165         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
6166         (( dirstripes > 0 )) || dirstripes=1
6167
6168         # Ensure enough OST objects precreated for tests to pass without
6169         # running out of objects.  This is an LOV r-r OST algorithm test,
6170         # not an OST object precreation test.
6171         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
6172         (( old >= nfiles )) ||
6173         {
6174                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
6175
6176                 do_nodes $mdts "$LCTL set_param $param=$create_count"
6177                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
6178
6179                 # trigger precreation from all MDTs for all OSTs
6180                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
6181                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
6182                 done
6183         }
6184
6185         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
6186                 sleep 8  # allow object precreation to catch up
6187                 test_51d_sub $stripecount $nfiles
6188         done
6189 }
6190 run_test 51d "check LOV round-robin OST object distribution"
6191
6192 test_51e() {
6193         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6194                 skip_env "ldiskfs only test"
6195         fi
6196
6197         test_mkdir -c1 $DIR/$tdir
6198         test_mkdir -c1 $DIR/$tdir/d0
6199
6200         touch $DIR/$tdir/d0/foo
6201         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
6202                 error "file exceed 65000 nlink limit!"
6203         unlinkmany $DIR/$tdir/d0/f- 65001
6204         return 0
6205 }
6206 run_test 51e "check file nlink limit"
6207
6208 test_51f() {
6209         test_mkdir $DIR/$tdir
6210
6211         local max=100000
6212         local ulimit_old=$(ulimit -n)
6213         local spare=20 # number of spare fd's for scripts/libraries, etc.
6214         local mdt=$($LFS getstripe -m $DIR/$tdir)
6215         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
6216
6217         echo "MDT$mdt numfree=$numfree, max=$max"
6218         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
6219         if [ $((numfree + spare)) -gt $ulimit_old ]; then
6220                 while ! ulimit -n $((numfree + spare)); do
6221                         numfree=$((numfree * 3 / 4))
6222                 done
6223                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
6224         else
6225                 echo "left ulimit at $ulimit_old"
6226         fi
6227
6228         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
6229                 unlinkmany $DIR/$tdir/f $numfree
6230                 error "create+open $numfree files in $DIR/$tdir failed"
6231         }
6232         ulimit -n $ulimit_old
6233
6234         # if createmany exits at 120s there will be fewer than $numfree files
6235         unlinkmany $DIR/$tdir/f $numfree || true
6236 }
6237 run_test 51f "check many open files limit"
6238
6239 test_52a() {
6240         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
6241         test_mkdir $DIR/$tdir
6242         touch $DIR/$tdir/foo
6243         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6244         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6245         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6246         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6247         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6248                                         error "link worked"
6249         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6250         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6251         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6252                                                      error "lsattr"
6253         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6254         cp -r $DIR/$tdir $TMP/
6255         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6256 }
6257 run_test 52a "append-only flag test (should return errors)"
6258
6259 test_52b() {
6260         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6261         test_mkdir $DIR/$tdir
6262         touch $DIR/$tdir/foo
6263         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6264         cat test > $DIR/$tdir/foo && error "cat test worked"
6265         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6266         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6267         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6268                                         error "link worked"
6269         echo foo >> $DIR/$tdir/foo && error "echo worked"
6270         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6271         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6272         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6273         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6274                                                         error "lsattr"
6275         chattr -i $DIR/$tdir/foo || error "chattr failed"
6276
6277         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6278 }
6279 run_test 52b "immutable flag test (should return errors) ======="
6280
6281 test_53() {
6282         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6283         remote_mds_nodsh && skip "remote MDS with nodsh"
6284         remote_ost_nodsh && skip "remote OST with nodsh"
6285
6286         local param
6287         local param_seq
6288         local ostname
6289         local mds_last
6290         local mds_last_seq
6291         local ost_last
6292         local ost_last_seq
6293         local ost_last_id
6294         local ostnum
6295         local node
6296         local found=false
6297         local support_last_seq=true
6298
6299         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6300                 support_last_seq=false
6301
6302         # only test MDT0000
6303         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6304         local value
6305         for value in $(do_facet $SINGLEMDS \
6306                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6307                 param=$(echo ${value[0]} | cut -d "=" -f1)
6308                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6309
6310                 if $support_last_seq; then
6311                         param_seq=$(echo $param |
6312                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6313                         mds_last_seq=$(do_facet $SINGLEMDS \
6314                                        $LCTL get_param -n $param_seq)
6315                 fi
6316                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6317
6318                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6319                 node=$(facet_active_host ost$((ostnum+1)))
6320                 param="obdfilter.$ostname.last_id"
6321                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6322                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6323                         ost_last_id=$ost_last
6324
6325                         if $support_last_seq; then
6326                                 ost_last_id=$(echo $ost_last |
6327                                               awk -F':' '{print $2}' |
6328                                               sed -e "s/^0x//g")
6329                                 ost_last_seq=$(echo $ost_last |
6330                                                awk -F':' '{print $1}')
6331                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6332                         fi
6333
6334                         if [[ $ost_last_id != $mds_last ]]; then
6335                                 error "$ost_last_id != $mds_last"
6336                         else
6337                                 found=true
6338                                 break
6339                         fi
6340                 done
6341         done
6342         $found || error "can not match last_seq/last_id for $mdtosc"
6343         return 0
6344 }
6345 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6346
6347 test_54a() {
6348         $SOCKETSERVER $DIR/socket ||
6349                 error "$SOCKETSERVER $DIR/socket failed: $?"
6350         $SOCKETCLIENT $DIR/socket ||
6351                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6352         unlink $DIR/socket || error "unlink $DIR/socket failed: $?"
6353 }
6354 run_test 54a "unix domain socket test"
6355
6356 test_54b() {
6357         f="$DIR/f54b"
6358         mknod $f c 1 3
6359         chmod 0666 $f
6360         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6361 }
6362 run_test 54b "char device works in lustre ======================"
6363
6364 find_loop_dev() {
6365         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6366         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6367         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6368
6369         for i in $(seq 3 7); do
6370                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6371                 LOOPDEV=$LOOPBASE$i
6372                 LOOPNUM=$i
6373                 break
6374         done
6375 }
6376
6377 cleanup_54c() {
6378         local rc=0
6379         loopdev="$DIR/loop54c"
6380
6381         trap 0
6382         $UMOUNT $DIR/$tdir || rc=$?
6383         losetup -d $loopdev || true
6384         losetup -d $LOOPDEV || true
6385         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6386         return $rc
6387 }
6388
6389 test_54c() {
6390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6391
6392         loopdev="$DIR/loop54c"
6393
6394         find_loop_dev
6395         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6396         trap cleanup_54c EXIT
6397         mknod $loopdev b 7 $LOOPNUM
6398         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6399         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6400         losetup $loopdev $DIR/$tfile ||
6401                 error "can't set up $loopdev for $DIR/$tfile"
6402         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6403         test_mkdir $DIR/$tdir
6404         mount -t ext2 $loopdev $DIR/$tdir ||
6405                 error "error mounting $loopdev on $DIR/$tdir"
6406         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6407                 error "dd write"
6408         df $DIR/$tdir
6409         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6410                 error "dd read"
6411         cleanup_54c
6412 }
6413 run_test 54c "block device works in lustre ====================="
6414
6415 test_54d() {
6416         local pipe="$DIR/$tfile.pipe"
6417         local string="aaaaaa"
6418
6419         mknod $pipe p
6420         echo -n "$string" > $pipe &
6421         local result=$(cat $pipe)
6422         [[ "$result" == "$string" ]] || error "$result != $string"
6423 }
6424 run_test 54d "fifo device works in lustre ======================"
6425
6426 test_54e() {
6427         f="$DIR/f54e"
6428         string="aaaaaa"
6429         cp -aL /dev/console $f
6430         echo $string > $f || error "echo $string to $f failed"
6431 }
6432 run_test 54e "console/tty device works in lustre ======================"
6433
6434 test_55a() {
6435         local dev_path="/sys/kernel/debug/lustre/devices"
6436
6437         load_module kunit/obd_test verbose=2 || error "load_module failed"
6438
6439         # This must be run in iteractive mode, since attach and setup
6440         # are stateful
6441         eval "$LCTL <<-EOF || error 'OBD device creation failed'
6442                 attach obd_test obd_name obd_uuid
6443                 setup obd_test
6444         EOF"
6445
6446         echo "Devices:"
6447         cat "$dev_path" | tail -n 10
6448
6449         $LCTL --device "obd_name" cleanup
6450         $LCTL --device "obd_name" detach
6451
6452         dmesg | tail -n 25 | grep "Lustre: OBD:.*FAIL" &&
6453                 error "OBD unit test failed"
6454
6455         rmmod -v obd_test ||
6456                 error "rmmod failed (may trigger a failure in a later test)"
6457 }
6458 run_test 55a "OBD device life cycle unit tests"
6459
6460 test_55b() {
6461         local dev_path="/sys/kernel/debug/lustre/devices"
6462         local dev_count="$(wc -l $dev_path | awk '{print $1}')"
6463
6464         # Set up a large number of devices, using the number
6465         # that can be set up in about a minute (based on prior
6466         # testing). We don't want to run this test forever.
6467         local num_dev_to_create="$(( 24000 - $dev_count))"
6468
6469         load_module kunit/obd_test || error "load_module failed"
6470
6471         local start=$SECONDS
6472
6473         # This must be run in iteractive mode, since attach and setup
6474         # are stateful
6475         for ((i = 1; i <= num_dev_to_create; i++)); do
6476                 echo "attach obd_test obd_name_$i obd_uuid_$i"
6477                 echo "setup obd_test_$i"
6478         done | $LCTL || error "OBD device creation failed"
6479
6480         echo "Load time: $((SECONDS - start))"
6481         echo "Devices:"
6482         cat "$dev_path" | tail -n 10
6483
6484         for ((i = 1; i <= num_dev_to_create; i++)); do
6485                 echo "--device obd_name_$i cleanup"
6486                 echo "--device obd_name_$i detach"
6487         done | $LCTL || error "OBD device cleanup failed"
6488
6489         echo "Unload time: $((SECONDS - start))"
6490
6491         rmmod -v obd_test ||
6492                 error "rmmod failed (may trigger a failure in a later test)"
6493 }
6494 run_test 55b "Load and unload max OBD devices"
6495
6496 test_56a() {
6497         local numfiles=3
6498         local numdirs=2
6499         local dir=$DIR/$tdir
6500
6501         rm -rf $dir
6502         test_mkdir -p $dir/dir
6503         for i in $(seq $numfiles); do
6504                 touch $dir/file$i
6505                 touch $dir/dir/file$i
6506         done
6507
6508         local numcomp=$($LFS getstripe --component-count $dir)
6509
6510         [[ $numcomp == 0 ]] && numcomp=1
6511
6512         # test lfs getstripe with --recursive
6513         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6514
6515         [[ $filenum -eq $((numfiles * 2)) ]] ||
6516                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6517         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6518         [[ $filenum -eq $numfiles ]] ||
6519                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6520         echo "$LFS getstripe showed obdidx or l_ost_idx"
6521
6522         # test lfs getstripe with file instead of dir
6523         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6524         [[ $filenum -eq 1 ]] ||
6525                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6526         echo "$LFS getstripe file1 passed"
6527
6528         #test lfs getstripe with --verbose
6529         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6530         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6531                 error "$LFS getstripe --verbose $dir: "\
6532                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6533         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6534                 error "$LFS getstripe $dir: showed lmm_magic"
6535
6536         #test lfs getstripe with -v prints lmm_fid
6537         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6538         local countfids=$(((numdirs + numfiles) * numcomp))
6539         [[ $filenum -eq $countfids ]] ||
6540                 error "$LFS getstripe -v $dir: "\
6541                       "got $filenum want $countfids lmm_fid"
6542         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6543                 error "$LFS getstripe $dir: showed lmm_fid by default"
6544         echo "$LFS getstripe --verbose passed"
6545
6546         #check for FID information
6547         local fid1=$($LFS getstripe --fid $dir/file1)
6548         local fid2=$($LFS getstripe --verbose $dir/file1 |
6549                      awk '/lmm_fid: / { print $2; exit; }')
6550         local fid3=$($LFS path2fid $dir/file1)
6551
6552         [ "$fid1" != "$fid2" ] &&
6553                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6554         [ "$fid1" != "$fid3" ] &&
6555                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6556         echo "$LFS getstripe --fid passed"
6557
6558         #test lfs getstripe with --obd
6559         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6560                 error "$LFS getstripe --obd wrong_uuid: should return error"
6561
6562         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6563
6564         local ostidx=1
6565         local obduuid=$(ostuuid_from_index $ostidx)
6566         local found=$($LFS getstripe -r --obd $obduuid $dir |
6567                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6568
6569         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6570         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6571                 ((filenum--))
6572         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6573                 ((filenum--))
6574
6575         [[ $found -eq $filenum ]] ||
6576                 error "$LFS getstripe --obd: found $found expect $filenum"
6577         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6578                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6579                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6580                 error "$LFS getstripe --obd: should not show file on other obd"
6581         echo "$LFS getstripe --obd passed"
6582 }
6583 run_test 56a "check $LFS getstripe"
6584
6585 test_56b() {
6586         local dir=$DIR/$tdir
6587         local numdirs=3
6588
6589         test_mkdir $dir
6590         for i in $(seq $numdirs); do
6591                 test_mkdir $dir/dir$i
6592         done
6593
6594         # test lfs getdirstripe default mode is non-recursion, which is
6595         # different from lfs getstripe
6596         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6597
6598         [[ $dircnt -eq 1 ]] ||
6599                 error "$LFS getdirstripe: found $dircnt, not 1"
6600         dircnt=$($LFS getdirstripe --recursive $dir |
6601                 grep -c lmv_stripe_count)
6602         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6603                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6604 }
6605 run_test 56b "check $LFS getdirstripe"
6606
6607 test_56bb() {
6608         verify_yaml_available || skip_env "YAML verification not installed"
6609         local output_file=$DIR/$tfile.out
6610
6611         $LFS getdirstripe -v -D -y $DIR 1> $output_file
6612
6613         cat $output_file
6614         cat $output_file | verify_yaml || error "layout is not valid YAML"
6615 }
6616 run_test 56bb "check $LFS getdirstripe layout is YAML"
6617
6618 test_56c() {
6619         remote_ost_nodsh && skip "remote OST with nodsh"
6620
6621         local ost_idx=0
6622         local ost_name=$(ostname_from_index $ost_idx)
6623         local old_status=$(ost_dev_status $ost_idx)
6624         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6625
6626         [[ -z "$old_status" ]] ||
6627                 skip_env "OST $ost_name is in $old_status status"
6628
6629         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6630         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6631                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6632         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6633                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6634                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6635         fi
6636
6637         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6638                 error "$LFS df -v showing inactive devices"
6639         sleep_maxage
6640
6641         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6642
6643         [[ "$new_status" =~ "D" ]] ||
6644                 error "$ost_name status is '$new_status', missing 'D'"
6645         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6646                 [[ "$new_status" =~ "N" ]] ||
6647                         error "$ost_name status is '$new_status', missing 'N'"
6648         fi
6649         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6650                 [[ "$new_status" =~ "f" ]] ||
6651                         error "$ost_name status is '$new_status', missing 'f'"
6652         fi
6653
6654         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6655         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6656                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6657         [[ -z "$p" ]] && restore_lustre_params < $p || true
6658         sleep_maxage
6659
6660         new_status=$(ost_dev_status $ost_idx)
6661         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6662                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6663         # can't check 'f' as devices may actually be on flash
6664 }
6665 run_test 56c "check 'lfs df' showing device status"
6666
6667 test_56d() {
6668         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6669         local osts=$($LFS df -v $MOUNT | grep -c OST)
6670
6671         $LFS df $MOUNT
6672
6673         (( mdts == MDSCOUNT )) ||
6674                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6675         (( osts == OSTCOUNT )) ||
6676                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6677 }
6678 run_test 56d "'lfs df -v' prints only configured devices"
6679
6680 test_56e() {
6681         err_enoent=2 # No such file or directory
6682         err_eopnotsupp=95 # Operation not supported
6683
6684         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6685         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6686
6687         # Check for handling of path not exists
6688         output=$($LFS df $enoent_mnt 2>&1)
6689         ret=$?
6690
6691         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6692         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6693                 error "expect failure $err_enoent, not $ret"
6694
6695         # Check for handling of non-Lustre FS
6696         output=$($LFS df $notsup_mnt)
6697         ret=$?
6698
6699         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6700         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6701                 error "expect success $err_eopnotsupp, not $ret"
6702
6703         # Check for multiple LustreFS argument
6704         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6705         ret=$?
6706
6707         [[ $output -eq 3 && $ret -eq 0 ]] ||
6708                 error "expect success 3, not $output, rc = $ret"
6709
6710         # Check for correct non-Lustre FS handling among multiple
6711         # LustreFS argument
6712         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6713                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6714         ret=$?
6715
6716         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6717                 error "expect success 2, not $output, rc = $ret"
6718 }
6719 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6720
6721 NUMFILES=3
6722 NUMDIRS=3
6723 setup_56() {
6724         local local_tdir="$1"
6725         local local_numfiles="$2"
6726         local local_numdirs="$3"
6727         local dir_params="$4"
6728         local dir_stripe_params="$5"
6729
6730         if [ ! -d "$local_tdir" ] ; then
6731                 test_mkdir -p $dir_stripe_params $local_tdir
6732                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6733                 for i in $(seq $local_numfiles) ; do
6734                         touch $local_tdir/file$i
6735                 done
6736                 for i in $(seq $local_numdirs) ; do
6737                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6738                         for j in $(seq $local_numfiles) ; do
6739                                 touch $local_tdir/dir$i/file$j
6740                         done
6741                 done
6742         fi
6743 }
6744
6745 setup_56_special() {
6746         local local_tdir=$1
6747         local local_numfiles=$2
6748         local local_numdirs=$3
6749
6750         setup_56 $local_tdir $local_numfiles $local_numdirs
6751
6752         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6753                 for i in $(seq $local_numfiles) ; do
6754                         mknod $local_tdir/loop${i}b b 7 $i
6755                         mknod $local_tdir/null${i}c c 1 3
6756                         ln -s $local_tdir/file1 $local_tdir/link${i}
6757                 done
6758                 for i in $(seq $local_numdirs) ; do
6759                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6760                         mknod $local_tdir/dir$i/null${i}c c 1 3
6761                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6762                 done
6763         fi
6764 }
6765
6766 test_56g() {
6767         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6768         local expected=$(($NUMDIRS + 2))
6769
6770         setup_56 $dir $NUMFILES $NUMDIRS
6771
6772         # test lfs find with -name
6773         for i in $(seq $NUMFILES) ; do
6774                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6775
6776                 [ $nums -eq $expected ] ||
6777                         error "lfs find -name '*$i' $dir wrong: "\
6778                               "found $nums, expected $expected"
6779         done
6780 }
6781 run_test 56g "check lfs find -name"
6782
6783 test_56h() {
6784         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6785         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6786
6787         setup_56 $dir $NUMFILES $NUMDIRS
6788
6789         # test lfs find with ! -name
6790         for i in $(seq $NUMFILES) ; do
6791                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6792
6793                 [ $nums -eq $expected ] ||
6794                         error "lfs find ! -name '*$i' $dir wrong: "\
6795                               "found $nums, expected $expected"
6796         done
6797 }
6798 run_test 56h "check lfs find ! -name"
6799
6800 test_56i() {
6801         local dir=$DIR/$tdir
6802
6803         test_mkdir $dir
6804
6805         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6806         local out=$($cmd)
6807
6808         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6809 }
6810 run_test 56i "check 'lfs find -ost UUID' skips directories"
6811
6812 test_56j() {
6813         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6814
6815         setup_56_special $dir $NUMFILES $NUMDIRS
6816
6817         local expected=$((NUMDIRS + 1))
6818         local cmd="$LFS find -type d $dir"
6819         local nums=$($cmd | wc -l)
6820
6821         [ $nums -eq $expected ] ||
6822                 error "'$cmd' wrong: found $nums, expected $expected"
6823 }
6824 run_test 56j "check lfs find -type d"
6825
6826 test_56k() {
6827         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6828
6829         setup_56_special $dir $NUMFILES $NUMDIRS
6830
6831         local expected=$(((NUMDIRS + 1) * NUMFILES))
6832         local cmd="$LFS find -type f $dir"
6833         local nums=$($cmd | wc -l)
6834
6835         [ $nums -eq $expected ] ||
6836                 error "'$cmd' wrong: found $nums, expected $expected"
6837 }
6838 run_test 56k "check lfs find -type f"
6839
6840 test_56l() {
6841         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6842
6843         setup_56_special $dir $NUMFILES $NUMDIRS
6844
6845         local expected=$((NUMDIRS + NUMFILES))
6846         local cmd="$LFS find -type b $dir"
6847         local nums=$($cmd | wc -l)
6848
6849         [ $nums -eq $expected ] ||
6850                 error "'$cmd' wrong: found $nums, expected $expected"
6851 }
6852 run_test 56l "check lfs find -type b"
6853
6854 test_56m() {
6855         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6856
6857         setup_56_special $dir $NUMFILES $NUMDIRS
6858
6859         local expected=$((NUMDIRS + NUMFILES))
6860         local cmd="$LFS find -type c $dir"
6861         local nums=$($cmd | wc -l)
6862         [ $nums -eq $expected ] ||
6863                 error "'$cmd' wrong: found $nums, expected $expected"
6864 }
6865 run_test 56m "check lfs find -type c"
6866
6867 test_56n() {
6868         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6869         setup_56_special $dir $NUMFILES $NUMDIRS
6870
6871         local expected=$((NUMDIRS + NUMFILES))
6872         local cmd="$LFS find -type l $dir"
6873         local nums=$($cmd | wc -l)
6874
6875         [ $nums -eq $expected ] ||
6876                 error "'$cmd' wrong: found $nums, expected $expected"
6877 }
6878 run_test 56n "check lfs find -type l"
6879
6880 test_56o() {
6881         local dir=$DIR/$tdir
6882
6883         setup_56 $dir $NUMFILES $NUMDIRS
6884         utime $dir/file1 > /dev/null || error "utime (1)"
6885         utime $dir/file2 > /dev/null || error "utime (2)"
6886         utime $dir/dir1 > /dev/null || error "utime (3)"
6887         utime $dir/dir2 > /dev/null || error "utime (4)"
6888         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6889         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6890
6891         local expected=4
6892         local nums=$($LFS find -mtime +0 $dir | wc -l)
6893
6894         [ $nums -eq $expected ] ||
6895                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6896
6897         expected=12
6898         cmd="$LFS find -mtime 0 $dir"
6899         nums=$($cmd | wc -l)
6900         [ $nums -eq $expected ] ||
6901                 error "'$cmd' wrong: found $nums, expected $expected"
6902 }
6903 run_test 56o "check lfs find -mtime for old files"
6904
6905 test_56ob() {
6906         local dir=$DIR/$tdir
6907         local expected=1
6908         local count=0
6909
6910         # just to make sure there is something that won't be found
6911         test_mkdir $dir
6912         touch $dir/$tfile.now
6913
6914         for age in year week day hour min; do
6915                 count=$((count + 1))
6916
6917                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6918                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6919                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6920
6921                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6922                 local nums=$($cmd | wc -l)
6923                 [ $nums -eq $expected ] ||
6924                         error "'$cmd' wrong: found $nums, expected $expected"
6925
6926                 cmd="$LFS find $dir -atime $count${age:0:1}"
6927                 nums=$($cmd | wc -l)
6928                 [ $nums -eq $expected ] ||
6929                         error "'$cmd' wrong: found $nums, expected $expected"
6930         done
6931
6932         sleep 2
6933         cmd="$LFS find $dir -ctime +1s -type f"
6934         nums=$($cmd | wc -l)
6935         (( $nums == $count * 2 + 1)) ||
6936                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6937 }
6938 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6939
6940 test_newerXY_base() {
6941         local x=$1
6942         local y=$2
6943         local dir=$DIR/$tdir
6944         local ref
6945         local negref
6946
6947         if [ $y == "t" ]; then
6948                 if [ $x == "b" ]; then
6949                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6950                 else
6951                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6952                 fi
6953         else
6954                 ref=$DIR/$tfile.newer.$x$y
6955                 touch $ref || error "touch $ref failed"
6956         fi
6957
6958         echo "before = $ref"
6959         sleep 2
6960         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6961         sleep 2
6962         if [ $y == "t" ]; then
6963                 if [ $x == "b" ]; then
6964                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6965                 else
6966                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6967                 fi
6968         else
6969                 negref=$DIR/$tfile.negnewer.$x$y
6970                 touch $negref || error "touch $negref failed"
6971         fi
6972
6973         echo "after = $negref"
6974         local cmd="$LFS find $dir -newer$x$y $ref"
6975         local nums=$(eval $cmd | wc -l)
6976         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6977
6978         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6979                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6980
6981         cmd="$LFS find $dir ! -newer$x$y $negref"
6982         nums=$(eval $cmd | wc -l)
6983         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6984                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6985
6986         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6987         nums=$(eval $cmd | wc -l)
6988         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6989                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6990
6991         rm -rf $DIR/*
6992 }
6993
6994 test_56oc() {
6995         test_newerXY_base "a" "a"
6996         test_newerXY_base "a" "m"
6997         test_newerXY_base "a" "c"
6998         test_newerXY_base "m" "a"
6999         test_newerXY_base "m" "m"
7000         test_newerXY_base "m" "c"
7001         test_newerXY_base "c" "a"
7002         test_newerXY_base "c" "m"
7003         test_newerXY_base "c" "c"
7004
7005         test_newerXY_base "a" "t"
7006         test_newerXY_base "m" "t"
7007         test_newerXY_base "c" "t"
7008
7009         (( $MDS1_VERSION >= $(version_code v2_13_53-145-g186b97e68a) &&
7010            $CLIENT_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
7011                 { echo "btime needs v2_13_53-145-g186b97e68a"; return 0; }
7012
7013         test_newerXY_base "b" "b"
7014         test_newerXY_base "b" "t"
7015 }
7016 run_test 56oc "check lfs find -newerXY work"
7017
7018 test_56od() {
7019         (( $MDS1_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
7020                 skip "btime unsupported on MDS < v2_13_53-145-g186b97e68a"
7021
7022         (( $CLIENT_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
7023                 skip "btime unsupported on clients < v2_13_53-145-g186b97e68a"
7024
7025         local dir=$DIR/$tdir
7026         local ref=$DIR/$tfile.ref
7027         local negref=$DIR/$tfile.negref
7028
7029         mkdir $dir || error "mkdir $dir failed"
7030         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
7031         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
7032         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
7033         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
7034         touch $ref || error "touch $ref failed"
7035         # sleep 3 seconds at least
7036         sleep 3
7037
7038         local before=$(do_facet mds1 date +%s)
7039         local skew=$(($(date +%s) - before + 1))
7040
7041         if (( skew < 0 && skew > -5 )); then
7042                 sleep $((0 - skew + 1))
7043                 skew=0
7044         fi
7045
7046         # Set the dir stripe params to limit files all on MDT0,
7047         # otherwise we need to calc the max clock skew between
7048         # the client and MDTs.
7049         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
7050         sleep 2
7051         touch $negref || error "touch $negref failed"
7052
7053         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
7054         local nums=$($cmd | wc -l)
7055         local expected=$(((NUMFILES + 1) * NUMDIRS))
7056
7057         [ $nums -eq $expected ] ||
7058                 error "'$cmd' wrong: found $nums, expected $expected"
7059
7060         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
7061         nums=$($cmd | wc -l)
7062         expected=$((NUMFILES + 1))
7063         [ $nums -eq $expected ] ||
7064                 error "'$cmd' wrong: found $nums, expected $expected"
7065
7066         [ $skew -lt 0 ] && return
7067
7068         local after=$(do_facet mds1 date +%s)
7069         local age=$((after - before + 1 + skew))
7070
7071         cmd="$LFS find $dir -btime -${age}s -type f"
7072         nums=$($cmd | wc -l)
7073         expected=$(((NUMFILES + 1) * NUMDIRS))
7074
7075         echo "Clock skew between client and server: $skew, age:$age"
7076         [ $nums -eq $expected ] ||
7077                 error "'$cmd' wrong: found $nums, expected $expected"
7078
7079         expected=$(($NUMDIRS + 1))
7080         cmd="$LFS find $dir -btime -${age}s -type d"
7081         nums=$($cmd | wc -l)
7082         [ $nums -eq $expected ] ||
7083                 error "'$cmd' wrong: found $nums, expected $expected"
7084         rm -f $ref $negref || error "Failed to remove $ref $negref"
7085 }
7086 run_test 56od "check lfs find -btime with units"
7087
7088 test_56p() {
7089         [ $RUNAS_ID -eq $UID ] &&
7090                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7091
7092         local dir=$DIR/$tdir
7093
7094         setup_56 $dir $NUMFILES $NUMDIRS
7095         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
7096
7097         local expected=$NUMFILES
7098         local cmd="$LFS find -uid $RUNAS_ID $dir"
7099         local nums=$($cmd | wc -l)
7100
7101         [ $nums -eq $expected ] ||
7102                 error "'$cmd' wrong: found $nums, expected $expected"
7103
7104         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
7105         cmd="$LFS find ! -uid $RUNAS_ID $dir"
7106         nums=$($cmd | wc -l)
7107         [ $nums -eq $expected ] ||
7108                 error "'$cmd' wrong: found $nums, expected $expected"
7109 }
7110 run_test 56p "check lfs find -uid and ! -uid"
7111
7112 test_56q() {
7113         [ $RUNAS_ID -eq $UID ] &&
7114                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7115
7116         local dir=$DIR/$tdir
7117
7118         setup_56 $dir $NUMFILES $NUMDIRS
7119         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
7120
7121         local expected=$NUMFILES
7122         local cmd="$LFS find -gid $RUNAS_GID $dir"
7123         local nums=$($cmd | wc -l)
7124
7125         [ $nums -eq $expected ] ||
7126                 error "'$cmd' wrong: found $nums, expected $expected"
7127
7128         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
7129         cmd="$LFS find ! -gid $RUNAS_GID $dir"
7130         nums=$($cmd | wc -l)
7131         [ $nums -eq $expected ] ||
7132                 error "'$cmd' wrong: found $nums, expected $expected"
7133 }
7134 run_test 56q "check lfs find -gid and ! -gid"
7135
7136 test_56r() {
7137         local dir=$DIR/$tdir
7138
7139         setup_56 $dir $NUMFILES $NUMDIRS
7140
7141         local expected=12
7142         local cmd="$LFS find -size 0 -type f -lazy $dir"
7143         local nums=$($cmd | wc -l)
7144
7145         [ $nums -eq $expected ] ||
7146                 error "'$cmd' wrong: found $nums, expected $expected"
7147         cmd="$LFS find -size 0 -type f $dir"
7148         nums=$($cmd | wc -l)
7149         [ $nums -eq $expected ] ||
7150                 error "'$cmd' wrong: found $nums, expected $expected"
7151
7152         expected=0
7153         cmd="$LFS find ! -size 0 -type f -lazy $dir"
7154         nums=$($cmd | wc -l)
7155         [ $nums -eq $expected ] ||
7156                 error "'$cmd' wrong: found $nums, expected $expected"
7157         cmd="$LFS find ! -size 0 -type f $dir"
7158         nums=$($cmd | wc -l)
7159         [ $nums -eq $expected ] ||
7160                 error "'$cmd' wrong: found $nums, expected $expected"
7161
7162         echo "test" > $dir/$tfile
7163         echo "test2" > $dir/$tfile.2 && sync
7164         expected=1
7165         cmd="$LFS find -size 5c -type f -lazy $dir"
7166         nums=$($cmd | wc -l)
7167         [ $nums -eq $expected ] ||
7168                 error "'$cmd' wrong: found $nums, expected $expected"
7169         cmd="$LFS find -size 5c -type f $dir"
7170         nums=$($cmd | wc -l)
7171         [ $nums -eq $expected ] ||
7172                 error "'$cmd' wrong: found $nums, expected $expected"
7173
7174         expected=1
7175         cmd="$LFS find -size +5c -type f -lazy $dir"
7176         nums=$($cmd | wc -l)
7177         [ $nums -eq $expected ] ||
7178                 error "'$cmd' wrong: found $nums, expected $expected"
7179         cmd="$LFS find -size +5c -type f $dir"
7180         nums=$($cmd | wc -l)
7181         [ $nums -eq $expected ] ||
7182                 error "'$cmd' wrong: found $nums, expected $expected"
7183
7184         expected=2
7185         cmd="$LFS find -size +0 -type f -lazy $dir"
7186         nums=$($cmd | wc -l)
7187         [ $nums -eq $expected ] ||
7188                 error "'$cmd' wrong: found $nums, expected $expected"
7189         cmd="$LFS find -size +0 -type f $dir"
7190         nums=$($cmd | wc -l)
7191         [ $nums -eq $expected ] ||
7192                 error "'$cmd' wrong: found $nums, expected $expected"
7193
7194         expected=2
7195         cmd="$LFS find ! -size -5c -type f -lazy $dir"
7196         nums=$($cmd | wc -l)
7197         [ $nums -eq $expected ] ||
7198                 error "'$cmd' wrong: found $nums, expected $expected"
7199         cmd="$LFS find ! -size -5c -type f $dir"
7200         nums=$($cmd | wc -l)
7201         [ $nums -eq $expected ] ||
7202                 error "'$cmd' wrong: found $nums, expected $expected"
7203
7204         expected=12
7205         cmd="$LFS find -size -5c -type f -lazy $dir"
7206         nums=$($cmd | wc -l)
7207         [ $nums -eq $expected ] ||
7208                 error "'$cmd' wrong: found $nums, expected $expected"
7209         cmd="$LFS find -size -5c -type f $dir"
7210         nums=$($cmd | wc -l)
7211         [ $nums -eq $expected ] ||
7212                 error "'$cmd' wrong: found $nums, expected $expected"
7213 }
7214 run_test 56r "check lfs find -size works"
7215
7216 test_56ra_sub() {
7217         local expected=$1
7218         local glimpses=$2
7219         local cmd="$3"
7220
7221         cancel_lru_locks $OSC
7222
7223         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7224         local nums=$($cmd | wc -l)
7225
7226         [ $nums -eq $expected ] ||
7227                 error "'$cmd' wrong: found $nums, expected $expected"
7228
7229         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7230
7231         if (( rpcs_before + glimpses != rpcs_after )); then
7232                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
7233                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
7234
7235                 if [[ $glimpses == 0 ]]; then
7236                         error "'$cmd' should not send glimpse RPCs to OST"
7237                 else
7238                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
7239                 fi
7240         fi
7241 }
7242
7243 test_56ra() {
7244         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
7245                 skip "MDS < 2.12.58 doesn't return LSOM data"
7246         local dir=$DIR/$tdir
7247         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
7248
7249         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
7250
7251         # statahead_agl may cause extra glimpse which confuses results. LU-13017
7252         $LCTL set_param -n llite.*.statahead_agl=0
7253         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
7254
7255         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7256         # open and close all files to ensure LSOM is updated
7257         cancel_lru_locks $OSC
7258         find $dir -type f | xargs cat > /dev/null
7259
7260         #   expect_found  glimpse_rpcs  command_to_run
7261         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
7262         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
7263         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
7264         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
7265
7266         echo "test" > $dir/$tfile
7267         echo "test2" > $dir/$tfile.2 && sync
7268         cancel_lru_locks $OSC
7269         cat $dir/$tfile $dir/$tfile.2 > /dev/null
7270
7271         test_56ra_sub  1  0 "$LFS find -size 5c -type f -lazy $dir"
7272         test_56ra_sub  1 14 "$LFS find -size 5c -type f $dir"
7273         test_56ra_sub  1  0 "$LFS find -size +5c -type f -lazy $dir"
7274         test_56ra_sub  1 14 "$LFS find -size +5c -type f $dir"
7275
7276         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
7277         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
7278         test_56ra_sub  2  0 "$LFS find ! -size -5c -type f -lazy $dir"
7279         test_56ra_sub  2 14 "$LFS find ! -size -5c -type f $dir"
7280         test_56ra_sub 12  0 "$LFS find -size -5c -type f -lazy $dir"
7281         test_56ra_sub 12 14 "$LFS find -size -5c -type f $dir"
7282 }
7283 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
7284
7285 test_56rb() {
7286         local dir=$DIR/$tdir
7287         local tmp=$TMP/$tfile.log
7288         local mdt_idx;
7289
7290         test_mkdir -p $dir || error "failed to mkdir $dir"
7291         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
7292                 error "failed to setstripe $dir/$tfile"
7293         mdt_idx=$($LFS getdirstripe -i $dir)
7294         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
7295
7296         stack_trap "rm -f $tmp" EXIT
7297         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7298         ! grep -q obd_uuid $tmp ||
7299                 error "failed to find --size +100K --ost 0 $dir"
7300         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7301         ! grep -q obd_uuid $tmp ||
7302                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7303 }
7304 run_test 56rb "check lfs find --size --ost/--mdt works"
7305
7306 test_56rc() {
7307         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7308         local dir=$DIR/$tdir
7309         local found
7310
7311         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7312         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7313         (( $MDSCOUNT > 2 )) &&
7314                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7315         mkdir $dir/$tdir-{1..10}
7316         touch $dir/$tfile-{1..10}
7317
7318         found=$($LFS find $dir --mdt-count 2 | wc -l)
7319         expect=11
7320         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7321
7322         found=$($LFS find $dir -T +1 | wc -l)
7323         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7324         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7325
7326         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7327         expect=11
7328         (( $found == $expect )) || error "found $found all_char, expect $expect"
7329
7330         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7331         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7332         (( $found == $expect )) || error "found $found all_char, expect $expect"
7333 }
7334 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7335
7336 test_56rd() {
7337         local dir=$DIR/$tdir
7338
7339         test_mkdir $dir
7340         rm -f $dir/*
7341
7342         mkfifo $dir/fifo || error "failed to create fifo file"
7343         $LFS find $dir -t p --printf "%p %y %LP\n" ||
7344                 error "should not fail even cannot get projid from pipe file"
7345         found=$($LFS find $dir -t p --printf "%y")
7346         [[ "p" == $found ]] || error "found $found, expect p"
7347
7348         mknod $dir/chardev c 1 5 ||
7349                 error "failed to create character device file"
7350         $LFS find $dir -t c --printf "%p %y %LP\n" ||
7351                 error "should not fail even cannot get projid from chardev file"
7352         found=$($LFS find $dir -t c --printf "%y")
7353         [[ "c" == $found ]] || error "found $found, expect c"
7354
7355         found=$($LFS find $dir ! -type d --printf "%p %y %LP\n" | wc -l)
7356         (( found == 2 )) || error "unable to list all files"
7357 }
7358 run_test 56rd "check lfs find --printf special files"
7359
7360 test_56s() { # LU-611 #LU-9369
7361         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7362
7363         local dir=$DIR/$tdir
7364         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7365
7366         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7367         for i in $(seq $NUMDIRS); do
7368                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7369         done
7370
7371         local expected=$NUMDIRS
7372         local cmd="$LFS find -c $OSTCOUNT $dir"
7373         local nums=$($cmd | wc -l)
7374
7375         [ $nums -eq $expected ] || {
7376                 $LFS getstripe -R $dir
7377                 error "'$cmd' wrong: found $nums, expected $expected"
7378         }
7379
7380         expected=$((NUMDIRS + onestripe))
7381         cmd="$LFS find -stripe-count +0 -type f $dir"
7382         nums=$($cmd | wc -l)
7383         [ $nums -eq $expected ] || {
7384                 $LFS getstripe -R $dir
7385                 error "'$cmd' wrong: found $nums, expected $expected"
7386         }
7387
7388         expected=$onestripe
7389         cmd="$LFS find -stripe-count 1 -type f $dir"
7390         nums=$($cmd | wc -l)
7391         [ $nums -eq $expected ] || {
7392                 $LFS getstripe -R $dir
7393                 error "'$cmd' wrong: found $nums, expected $expected"
7394         }
7395
7396         cmd="$LFS find -stripe-count -2 -type f $dir"
7397         nums=$($cmd | wc -l)
7398         [ $nums -eq $expected ] || {
7399                 $LFS getstripe -R $dir
7400                 error "'$cmd' wrong: found $nums, expected $expected"
7401         }
7402
7403         expected=0
7404         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7405         nums=$($cmd | wc -l)
7406         [ $nums -eq $expected ] || {
7407                 $LFS getstripe -R $dir
7408                 error "'$cmd' wrong: found $nums, expected $expected"
7409         }
7410 }
7411 run_test 56s "check lfs find -stripe-count works"
7412
7413 test_56t() { # LU-611 #LU-9369
7414         local dir=$DIR/$tdir
7415
7416         setup_56 $dir 0 $NUMDIRS
7417         for i in $(seq $NUMDIRS); do
7418                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7419         done
7420
7421         local expected=$NUMDIRS
7422         local cmd="$LFS find -S 8M $dir"
7423         local nums=$($cmd | wc -l)
7424
7425         [ $nums -eq $expected ] || {
7426                 $LFS getstripe -R $dir
7427                 error "'$cmd' wrong: found $nums, expected $expected"
7428         }
7429         rm -rf $dir
7430
7431         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7432
7433         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7434
7435         expected=$(((NUMDIRS + 1) * NUMFILES))
7436         cmd="$LFS find -stripe-size 512k -type f $dir"
7437         nums=$($cmd | wc -l)
7438         [ $nums -eq $expected ] ||
7439                 error "'$cmd' wrong: found $nums, expected $expected"
7440
7441         cmd="$LFS find -stripe-size +320k -type f $dir"
7442         nums=$($cmd | wc -l)
7443         [ $nums -eq $expected ] ||
7444                 error "'$cmd' wrong: found $nums, expected $expected"
7445
7446         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7447         cmd="$LFS find -stripe-size +200k -type f $dir"
7448         nums=$($cmd | wc -l)
7449         [ $nums -eq $expected ] ||
7450                 error "'$cmd' wrong: found $nums, expected $expected"
7451
7452         cmd="$LFS find -stripe-size -640k -type f $dir"
7453         nums=$($cmd | wc -l)
7454         [ $nums -eq $expected ] ||
7455                 error "'$cmd' wrong: found $nums, expected $expected"
7456
7457         expected=4
7458         cmd="$LFS find -stripe-size 256k -type f $dir"
7459         nums=$($cmd | wc -l)
7460         [ $nums -eq $expected ] ||
7461                 error "'$cmd' wrong: found $nums, expected $expected"
7462
7463         cmd="$LFS find -stripe-size -320k -type f $dir"
7464         nums=$($cmd | wc -l)
7465         [ $nums -eq $expected ] ||
7466                 error "'$cmd' wrong: found $nums, expected $expected"
7467
7468         expected=0
7469         cmd="$LFS find -stripe-size 1024k -type f $dir"
7470         nums=$($cmd | wc -l)
7471         [ $nums -eq $expected ] ||
7472                 error "'$cmd' wrong: found $nums, expected $expected"
7473 }
7474 run_test 56t "check lfs find -stripe-size works"
7475
7476 test_56u() { # LU-611
7477         local dir=$DIR/$tdir
7478
7479         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7480
7481         if [[ $OSTCOUNT -gt 1 ]]; then
7482                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7483                 onestripe=4
7484         else
7485                 onestripe=0
7486         fi
7487
7488         local expected=$(((NUMDIRS + 1) * NUMFILES))
7489         local cmd="$LFS find -stripe-index 0 -type f $dir"
7490         local nums=$($cmd | wc -l)
7491
7492         [ $nums -eq $expected ] ||
7493                 error "'$cmd' wrong: found $nums, expected $expected"
7494
7495         expected=$onestripe
7496         cmd="$LFS find -stripe-index 1 -type f $dir"
7497         nums=$($cmd | wc -l)
7498         [ $nums -eq $expected ] ||
7499                 error "'$cmd' wrong: found $nums, expected $expected"
7500
7501         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7502         nums=$($cmd | wc -l)
7503         [ $nums -eq $expected ] ||
7504                 error "'$cmd' wrong: found $nums, expected $expected"
7505
7506         expected=0
7507         # This should produce an error and not return any files
7508         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7509         nums=$($cmd 2>/dev/null | wc -l)
7510         [ $nums -eq $expected ] ||
7511                 error "'$cmd' wrong: found $nums, expected $expected"
7512
7513         if [[ $OSTCOUNT -gt 1 ]]; then
7514                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7515                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7516                 nums=$($cmd | wc -l)
7517                 [ $nums -eq $expected ] ||
7518                         error "'$cmd' wrong: found $nums, expected $expected"
7519         fi
7520 }
7521 run_test 56u "check lfs find -stripe-index works"
7522
7523 test_56v() {
7524         local mdt_idx=0
7525         local dir=$DIR/$tdir
7526
7527         setup_56 $dir $NUMFILES $NUMDIRS
7528
7529         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7530         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7531
7532         for file in $($LFS find -m $UUID $dir); do
7533                 file_midx=$($LFS getstripe -m $file)
7534                 [ $file_midx -eq $mdt_idx ] ||
7535                         error "lfs find -m $UUID != getstripe -m $file_midx"
7536         done
7537 }
7538 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7539
7540 test_56wa() {
7541         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7542         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7543
7544         local dir=$DIR/$tdir
7545
7546         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7547         stack_trap "rm -rf $dir"
7548
7549         local stripe_size=$($LFS getstripe -S -d $dir) ||
7550                 error "$LFS getstripe -S -d $dir failed"
7551         stripe_size=${stripe_size%% *}
7552
7553         local file_size=$((stripe_size * OSTCOUNT))
7554         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7555         local required_space=$((file_num * file_size))
7556         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7557                            head -n1)
7558         (( free_space >= required_space / 1024 )) ||
7559                 skip_env "need $required_space, have $free_space kbytes"
7560
7561         local dd_bs=65536
7562         local dd_count=$((file_size / dd_bs))
7563
7564         # write data into the files
7565         local i
7566         local j
7567         local file
7568
7569         for ((i = 1; i <= NUMFILES; i++ )); do
7570                 file=$dir/file$i
7571                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7572                         error "write data into $file failed"
7573         done
7574         for ((i = 1; i <= NUMDIRS; i++ )); do
7575                 for ((j = 1; j <= NUMFILES; j++ )); do
7576                         file=$dir/dir$i/file$j
7577                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7578                                 error "write data into $file failed"
7579                 done
7580         done
7581
7582         # $LFS_MIGRATE will fail if hard link migration is unsupported
7583         if (( MDS1_VERSION > $(version_code 2.5.55) )); then
7584                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7585                         error "creating links to $dir/dir1/file1 failed"
7586         fi
7587
7588         local expected=-1
7589
7590         (( OSTCOUNT <= 1 )) || expected=$((OSTCOUNT - 1))
7591
7592         # lfs_migrate file
7593         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7594
7595         echo "$cmd"
7596         eval $cmd || error "$cmd failed"
7597
7598         check_stripe_count $dir/file1 $expected
7599
7600         if (( $MDS1_VERSION >= $(version_code 2.6.90) )); then
7601                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7602                 # OST 1 if it is on OST 0. This file is small enough to
7603                 # be on only one stripe.
7604                 file=$dir/migr_1_ost
7605                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7606                         error "write data into $file failed"
7607                 local obdidx=$($LFS getstripe -i $file)
7608                 local oldmd5=$(md5sum $file)
7609                 local newobdidx=0
7610
7611                 (( obdidx != 0 )) || newobdidx=1
7612                 cmd="$LFS migrate -i $newobdidx $file"
7613                 echo $cmd
7614                 eval $cmd || error "$cmd failed"
7615
7616                 local realobdix=$($LFS getstripe -i $file)
7617                 local newmd5=$(md5sum $file)
7618
7619                 (( $newobdidx == $realobdix )) ||
7620                         error "new OST is different (was=$obdidx, wanted=$newobdidx, got=$realobdix)"
7621                 [[ "$oldmd5" == "$newmd5" ]] ||
7622                         error "md5sum differ: $oldmd5, $newmd5"
7623         fi
7624
7625         # lfs_migrate dir
7626         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7627         echo "$cmd"
7628         eval $cmd || error "$cmd failed"
7629
7630         for (( j = 1; j <= NUMFILES; j++ )); do
7631                 check_stripe_count $dir/dir1/file$j $expected
7632         done
7633
7634         # lfs_migrate works with lfs find
7635         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7636              $LFS_MIGRATE -y -c $expected"
7637         echo "$cmd"
7638         eval $cmd || error "$cmd failed"
7639
7640         for (( i = 2; i <= NUMFILES; i++ )); do
7641                 check_stripe_count $dir/file$i $expected
7642         done
7643         for (( i = 2; i <= NUMDIRS; i++ )); do
7644                 for (( j = 1; j <= NUMFILES; j++ )); do
7645                         check_stripe_count $dir/dir$i/file$j $expected
7646                 done
7647         done
7648 }
7649 run_test 56wa "check lfs_migrate -c stripe_count works"
7650
7651 test_56wb() {
7652         local file1=$DIR/$tdir/file1
7653         local create_pool=false
7654         local initial_pool=$($LFS getstripe -p $DIR)
7655         local pool_list=()
7656         local pool=""
7657
7658         echo -n "Creating test dir..."
7659         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7660         echo "done."
7661
7662         echo -n "Creating test file..."
7663         touch $file1 || error "cannot create file"
7664         echo "done."
7665
7666         echo -n "Detecting existing pools..."
7667         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7668
7669         if [ ${#pool_list[@]} -gt 0 ]; then
7670                 echo "${pool_list[@]}"
7671                 for thispool in "${pool_list[@]}"; do
7672                         if [[ -z "$initial_pool" ||
7673                               "$initial_pool" != "$thispool" ]]; then
7674                                 pool="$thispool"
7675                                 echo "Using existing pool '$pool'"
7676                                 break
7677                         fi
7678                 done
7679         else
7680                 echo "none detected."
7681         fi
7682         if [ -z "$pool" ]; then
7683                 pool=${POOL:-testpool}
7684                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7685                 echo -n "Creating pool '$pool'..."
7686                 create_pool=true
7687                 pool_add $pool &> /dev/null ||
7688                         error "pool_add failed"
7689                 echo "done."
7690
7691                 echo -n "Adding target to pool..."
7692                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7693                         error "pool_add_targets failed"
7694                 echo "done."
7695         fi
7696
7697         echo -n "Setting pool using -p option..."
7698         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7699                 error "migrate failed rc = $?"
7700         echo "done."
7701
7702         echo -n "Verifying test file is in pool after migrating..."
7703         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7704                 error "file was not migrated to pool $pool"
7705         echo "done."
7706
7707         echo -n "Removing test file from pool '$pool'..."
7708         # "lfs migrate $file" won't remove the file from the pool
7709         # until some striping information is changed.
7710         $LFS migrate -c 1 $file1 &> /dev/null ||
7711                 error "cannot remove from pool"
7712         [ "$($LFS getstripe -p $file1)" ] &&
7713                 error "pool still set"
7714         echo "done."
7715
7716         echo -n "Setting pool using --pool option..."
7717         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7718                 error "migrate failed rc = $?"
7719         echo "done."
7720
7721         # Clean up
7722         rm -f $file1
7723         if $create_pool; then
7724                 destroy_test_pools 2> /dev/null ||
7725                         error "destroy test pools failed"
7726         fi
7727 }
7728 run_test 56wb "check lfs_migrate pool support"
7729
7730 test_56wc() {
7731         local file1="$DIR/$tdir/$tfile"
7732         local md5
7733         local parent_ssize
7734         local parent_scount
7735         local cur_ssize
7736         local cur_scount
7737         local orig_ssize
7738         local new_scount
7739         local cur_comp
7740
7741         echo -n "Creating test dir..."
7742         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7743         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7744                 error "cannot set stripe by '-S 1M -c 1'"
7745         echo "done"
7746
7747         echo -n "Setting initial stripe for test file..."
7748         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7749                 error "cannot set stripe"
7750         cur_ssize=$($LFS getstripe -S "$file1")
7751         (( cur_ssize == 524288 )) || error "setstripe -S $cur_ssize != 524288"
7752         echo "done."
7753
7754         dd if=/dev/urandom of=$file1 bs=1M count=12 || error "dd $file1 failed"
7755         stack_trap "rm -f $file1"
7756         md5="$(md5sum $file1)"
7757
7758         # File currently set to -S 512K -c 1
7759
7760         # Ensure -c and -S options are rejected when -R is set
7761         echo -n "Verifying incompatible options are detected..."
7762         $LFS_MIGRATE -R -c 1 "$file1" &&
7763                 error "incompatible -R and -c options not detected"
7764         $LFS_MIGRATE -R -S 1M "$file1" &&
7765                 error "incompatible -R and -S options not detected"
7766         $LFS_MIGRATE -R -p pool "$file1" &&
7767                 error "incompatible -R and -p options not detected"
7768         $LFS_MIGRATE -R -E eof -c 1 "$file1" &&
7769                 error "incompatible -R and -E options not detected"
7770         $LFS_MIGRATE -R -A "$file1" &&
7771                 error "incompatible -R and -A options not detected"
7772         $LFS_MIGRATE -A -c 1 "$file1" &&
7773                 error "incompatible -A and -c options not detected"
7774         $LFS_MIGRATE -A -S 1M "$file1" &&
7775                 error "incompatible -A and -S options not detected"
7776         $LFS_MIGRATE -A -p pool "$file1" &&
7777                 error "incompatible -A and -p options not detected"
7778         $LFS_MIGRATE -A -E eof -c 1 "$file1" &&
7779                 error "incompatible -A and -E options not detected"
7780         echo "done."
7781
7782         # Ensure unrecognized options are passed through to 'lfs migrate'
7783         echo -n "Verifying -S option is passed through to lfs migrate..."
7784         $LFS_MIGRATE -y -S 1M "$file1" || error "migration failed"
7785         cur_ssize=$($LFS getstripe -S "$file1")
7786         (( cur_ssize == 1048576 )) || error "migrate -S $cur_ssize != 1048576"
7787         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (1)"
7788         echo "done."
7789
7790         # File currently set to -S 1M -c 1
7791
7792         # Ensure long options are supported
7793         echo -n "Verifying long options supported..."
7794         $LFS_MIGRATE --non-block "$file1" ||
7795                 error "long option without argument not supported"
7796         $LFS_MIGRATE --stripe-size 512K "$file1" ||
7797                 error "long option with argument not supported"
7798         cur_ssize=$($LFS getstripe -S "$file1")
7799         (( cur_ssize == 524288 )) ||
7800                 error "migrate --stripe-size $cur_ssize != 524288"
7801         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (2)"
7802         echo "done."
7803
7804         # File currently set to -S 512K -c 1
7805
7806         if (( OSTCOUNT > 1 )); then
7807                 echo -n "Verifying explicit stripe count can be set..."
7808                 $LFS_MIGRATE -c 2 "$file1" || error "migrate failed"
7809                 cur_scount=$($LFS getstripe -c "$file1")
7810                 (( cur_scount == 2 )) || error "migrate -c $cur_scount != 2"
7811                 [[ "$(md5sum $file1)" == "$md5" ]] ||
7812                         error "file data has changed (3)"
7813                 echo "done."
7814         fi
7815
7816         # File currently set to -S 512K -c 1 or -S 512K -c 2
7817
7818         # Ensure parent striping is used if -R is set, and no stripe
7819         # count or size is specified
7820         echo -n "Setting stripe for parent directory..."
7821         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7822                 error "cannot set stripe '-S 2M -c 1'"
7823         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (4)"
7824         echo "done."
7825
7826         echo -n "Verifying restripe option uses parent stripe settings..."
7827         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7828         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7829         $LFS_MIGRATE -R "$file1" || error "migrate failed"
7830         cur_ssize=$($LFS getstripe -S "$file1")
7831         (( cur_ssize == parent_ssize )) ||
7832                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7833         cur_scount=$($LFS getstripe -c "$file1")
7834         (( cur_scount == parent_scount )) ||
7835                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7836         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (5)"
7837         echo "done."
7838
7839         # File currently set to -S 1M -c 1
7840
7841         # Ensure striping is preserved if -R is not set, and no stripe
7842         # count or size is specified
7843         echo -n "Verifying striping size preserved when not specified..."
7844         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7845         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7846                 error "cannot set stripe on parent directory"
7847         $LFS_MIGRATE "$file1" || error "migrate failed"
7848         cur_ssize=$($LFS getstripe -S "$file1")
7849         (( cur_ssize == orig_ssize )) ||
7850                 error "migrate by default $cur_ssize != $orig_ssize"
7851         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (6)"
7852         echo "done."
7853
7854         # Ensure file name properly detected when final option has no argument
7855         echo -n "Verifying file name properly detected..."
7856         $LFS_MIGRATE "$file1" ||
7857                 error "file name interpreted as option argument"
7858         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (7)"
7859         echo "done."
7860
7861         # Ensure PFL arguments are passed through properly
7862         echo -n "Verifying PFL options passed through..."
7863         new_scount=$(((OSTCOUNT + 1) / 2))
7864         $LFS_MIGRATE -E 1M -c 1 -E 16M -c $new_scount -E eof -c -1 "$file1" ||
7865                 error "migrate PFL arguments failed"
7866         cur_comp=$($LFS getstripe --comp-count $file1)
7867         (( cur_comp == 3 )) || error "component count '$cur_comp' != 3"
7868         cur_scount=$($LFS getstripe --stripe-count $file1)
7869         (( cur_scount == new_scount)) ||
7870                 error "PFL stripe count $cur_scount != $new_scount"
7871         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (8)"
7872         echo "done."
7873 }
7874 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7875
7876 test_56wd() {
7877         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7878
7879         local file1=$DIR/$tdir/$tfile
7880
7881         echo -n "Creating test dir..."
7882         test_mkdir $DIR/$tdir || error "cannot create dir"
7883         echo "done."
7884
7885         echo -n "Creating test file..."
7886         echo "$tfile" > $file1
7887         echo "done."
7888
7889         # Ensure 'lfs migrate' will fail by using a non-existent option,
7890         # and make sure rsync is not called to recover
7891         echo -n "Make sure --no-rsync option works..."
7892         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7893                 grep -q 'refusing to fall back to rsync' ||
7894                 error "rsync was called with --no-rsync set"
7895         echo "done."
7896
7897         # Ensure rsync is called without trying 'lfs migrate' first
7898         echo -n "Make sure --rsync option works..."
7899         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7900                 grep -q 'falling back to rsync' &&
7901                 error "lfs migrate was called with --rsync set"
7902         echo "done."
7903 }
7904 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7905
7906 test_56we() {
7907         local td=$DIR/$tdir
7908         local tf=$td/$tfile
7909
7910         test_mkdir $td || error "cannot create $td"
7911         touch $tf || error "cannot touch $tf"
7912
7913         echo -n "Make sure --non-direct|-D works..."
7914         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7915                 grep -q "lfs migrate --non-direct" ||
7916                 error "--non-direct option cannot work correctly"
7917         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7918                 grep -q "lfs migrate -D" ||
7919                 error "-D option cannot work correctly"
7920         echo "done."
7921 }
7922 run_test 56we "check lfs_migrate --non-direct|-D support"
7923
7924 test_56x() {
7925         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7926         check_swap_layouts_support
7927
7928         local dir=$DIR/$tdir
7929         local ref1=/etc/passwd
7930         local file1=$dir/file1
7931
7932         test_mkdir $dir || error "creating dir $dir"
7933         $LFS setstripe -c 2 $file1
7934         cp $ref1 $file1
7935         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7936         stripe=$($LFS getstripe -c $file1)
7937         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7938         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7939
7940         # clean up
7941         rm -f $file1
7942 }
7943 run_test 56x "lfs migration support"
7944
7945 test_56xa() {
7946         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7947         check_swap_layouts_support
7948
7949         local dir=$DIR/$tdir/$testnum
7950
7951         test_mkdir -p $dir
7952
7953         local ref1=/etc/passwd
7954         local file1=$dir/file1
7955
7956         $LFS setstripe -c 2 $file1
7957         cp $ref1 $file1
7958         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7959
7960         local stripe=$($LFS getstripe -c $file1)
7961
7962         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7963         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7964
7965         # clean up
7966         rm -f $file1
7967 }
7968 run_test 56xa "lfs migration --block support"
7969
7970 check_migrate_links() {
7971         [[ "$1" == "--rsync" ]] && local opts="--rsync -y" && shift
7972         local dir="$1"
7973         local file1="$dir/file1"
7974         local begin="$2"
7975         local count="$3"
7976         local runas="$4"
7977         local total_count=$(($begin + $count - 1))
7978         local symlink_count=10
7979         local uniq_count=10
7980
7981         if [ ! -f "$file1" ]; then
7982                 echo -n "creating initial file..."
7983                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7984                         error "cannot setstripe initial file"
7985                 echo "done"
7986
7987                 echo -n "creating symlinks..."
7988                 for s in $(seq 1 $symlink_count); do
7989                         ln -s "$file1" "$dir/slink$s" ||
7990                                 error "cannot create symlinks"
7991                 done
7992                 echo "done"
7993
7994                 echo -n "creating nonlinked files..."
7995                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7996                         error "cannot create nonlinked files"
7997                 echo "done"
7998         fi
7999
8000         # create hard links
8001         if [ ! -f "$dir/file$total_count" ]; then
8002                 echo -n "creating hard links $begin:$total_count..."
8003                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
8004                         /dev/null || error "cannot create hard links"
8005                 echo "done"
8006         fi
8007
8008         echo -n "checking number of hard links listed in xattrs..."
8009         local fid=$($LFS getstripe -F "$file1")
8010         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
8011
8012         echo "${#paths[*]}"
8013         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
8014                         skip "hard link list has unexpected size, skipping test"
8015         fi
8016         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
8017                         error "link names should exceed xattrs size"
8018         fi
8019
8020         echo -n "migrating files..."
8021         local migrate_out=$($runas $LFS_MIGRATE $opts -S '1m' $dir)
8022         local rc=$?
8023         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
8024         echo "done"
8025
8026         # make sure all links have been properly migrated
8027         echo -n "verifying files..."
8028         fid=$($LFS getstripe -F "$file1") ||
8029                 error "cannot get fid for file $file1"
8030         for i in $(seq 2 $total_count); do
8031                 local fid2=$($LFS getstripe -F $dir/file$i)
8032
8033                 [ "$fid2" == "$fid" ] ||
8034                         error "migrated hard link has mismatched FID"
8035         done
8036
8037         # make sure hard links were properly detected, and migration was
8038         # performed only once for the entire link set; nonlinked files should
8039         # also be migrated
8040         local actual=$(grep -c 'done' <<< "$migrate_out")
8041         local expected=$(($uniq_count + 1))
8042
8043         [ "$actual" -eq  "$expected" ] ||
8044                 error "hard links individually migrated ($actual != $expected)"
8045
8046         # make sure the correct number of hard links are present
8047         local hardlinks=$(stat -c '%h' "$file1")
8048
8049         [ $hardlinks -eq $total_count ] ||
8050                 error "num hard links $hardlinks != $total_count"
8051         echo "done"
8052
8053         return 0
8054 }
8055
8056 test_56xb() {
8057         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
8058                 skip "Need MDS version at least 2.10.55"
8059
8060         local dir="$DIR/$tdir"
8061
8062         test_mkdir "$dir" || error "cannot create dir $dir"
8063
8064         echo "testing lfs migrate mode when all links fit within xattrs"
8065         check_migrate_links "$dir" 2 99
8066
8067         echo "testing rsync mode when all links fit within xattrs"
8068         check_migrate_links --rsync "$dir" 2 99
8069
8070         echo "testing lfs migrate mode when all links do not fit within xattrs"
8071         check_migrate_links "$dir" 101 100
8072
8073         echo "testing rsync mode when all links do not fit within xattrs"
8074         check_migrate_links --rsync "$dir" 101 100
8075
8076         chown -R $RUNAS_ID $dir
8077         echo "testing non-root lfs migrate mode when not all links are in xattr"
8078         check_migrate_links "$dir" 101 100 "$RUNAS"
8079
8080         # clean up
8081         rm -rf $dir
8082 }
8083 run_test 56xb "lfs migration hard link support"
8084
8085 test_56xc() {
8086         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8087
8088         local dir="$DIR/$tdir"
8089
8090         test_mkdir "$dir" || error "cannot create dir $dir"
8091
8092         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
8093         echo -n "Setting initial stripe for 20MB test file..."
8094         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
8095                 error "cannot setstripe 20MB file"
8096         echo "done"
8097         echo -n "Sizing 20MB test file..."
8098         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
8099         echo "done"
8100         echo -n "Verifying small file autostripe count is 1..."
8101         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
8102                 error "cannot migrate 20MB file"
8103         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
8104                 error "cannot get stripe for $dir/20mb"
8105         [ $stripe_count -eq 1 ] ||
8106                 error "unexpected stripe count $stripe_count for 20MB file"
8107         rm -f "$dir/20mb"
8108         echo "done"
8109
8110         # Test 2: File is small enough to fit within the available space on
8111         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
8112         # have at least an additional 1KB for each desired stripe for test 3
8113         echo -n "Setting stripe for 1GB test file..."
8114         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
8115         echo "done"
8116         echo -n "Sizing 1GB test file..."
8117         # File size is 1GB + 3KB
8118         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
8119         echo "done"
8120
8121         # need at least 512MB per OST for 1GB file to fit in 2 stripes
8122         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
8123         if (( avail > 524288 * OSTCOUNT )); then
8124                 echo -n "Migrating 1GB file..."
8125                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
8126                         error "cannot migrate 1GB file"
8127                 echo "done"
8128                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
8129                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
8130                         error "cannot getstripe for 1GB file"
8131                 [ $stripe_count -eq 2 ] ||
8132                         error "unexpected stripe count $stripe_count != 2"
8133                 echo "done"
8134         fi
8135
8136         # Test 3: File is too large to fit within the available space on
8137         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
8138         if [ $OSTCOUNT -ge 3 ]; then
8139                 # The required available space is calculated as
8140                 # file size (1GB + 3KB) / OST count (3).
8141                 local kb_per_ost=349526
8142
8143                 echo -n "Migrating 1GB file with limit..."
8144                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
8145                         error "cannot migrate 1GB file with limit"
8146                 echo "done"
8147
8148                 stripe_count=$($LFS getstripe -c "$dir/1gb")
8149                 echo -n "Verifying 1GB autostripe count with limited space..."
8150                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
8151                         error "unexpected stripe count $stripe_count (min 3)"
8152                 echo "done"
8153         fi
8154
8155         # clean up
8156         rm -rf $dir
8157 }
8158 run_test 56xc "lfs migration autostripe"
8159
8160 test_56xd() {
8161         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8162
8163         local dir=$DIR/$tdir
8164         local f_mgrt=$dir/$tfile.mgrt
8165         local f_yaml=$dir/$tfile.yaml
8166         local f_copy=$dir/$tfile.copy
8167         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8168         local layout_copy="-c 2 -S 2M -i 1"
8169         local yamlfile=$dir/yamlfile
8170         local layout_before;
8171         local layout_after;
8172
8173         test_mkdir "$dir" || error "cannot create dir $dir"
8174         stack_trap "rm -rf $dir"
8175         $LFS setstripe $layout_yaml $f_yaml ||
8176                 error "cannot setstripe $f_yaml with layout $layout_yaml"
8177         $LFS getstripe --yaml $f_yaml > $yamlfile
8178         $LFS setstripe $layout_copy $f_copy ||
8179                 error "cannot setstripe $f_copy with layout $layout_copy"
8180         touch $f_mgrt
8181         dd if=/dev/zero of=$f_mgrt bs=1M count=4
8182
8183         # 1. test option --yaml
8184         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
8185                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
8186         layout_before=$(get_layout_param $f_yaml)
8187         layout_after=$(get_layout_param $f_mgrt)
8188         [ "$layout_after" == "$layout_before" ] ||
8189                 error "lfs_migrate --yaml: $layout_after != $layout_before"
8190
8191         # 2. test option --copy
8192         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
8193                 error "cannot migrate $f_mgrt with --copy $f_copy"
8194         layout_before=$(SKIP_INDEX=yes get_layout_param $f_copy)
8195         layout_after=$(SKIP_INDEX=yes get_layout_param $f_mgrt)
8196         [ "$layout_after" == "$layout_before" ] ||
8197                 error "lfs_migrate --copy: $layout_after != $layout_before"
8198 }
8199 run_test 56xd "check lfs_migrate --yaml and --copy support"
8200
8201 test_56xe() {
8202         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8203
8204         local dir=$DIR/$tdir
8205         local f_comp=$dir/$tfile
8206         local layout="-E 1M -S 512K -E 2M -c 2 -E 3M -c 2 -E eof -c $OSTCOUNT"
8207         local layout_before=""
8208         local layout_after=""
8209
8210         test_mkdir "$dir" || error "cannot create dir $dir"
8211         stack_trap "rm -rf $dir"
8212         $LFS setstripe $layout $f_comp ||
8213                 error "cannot setstripe $f_comp with layout $layout"
8214         layout_before=$(SKIP_INDEX=yes get_layout_param $f_comp)
8215         dd if=/dev/zero of=$f_comp bs=1M count=4
8216
8217         # 1. migrate a comp layout file by lfs_migrate
8218         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
8219         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8220         idx_before=$($LFS getstripe $f_comp | awk '$2 == "0:" { print $5 }' |
8221                      tr '\n' ' ')
8222         [ "$layout_before" == "$layout_after" ] ||
8223                 error "lfs_migrate: $layout_before != $layout_after"
8224
8225         # 2. migrate a comp layout file by lfs migrate
8226         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8227         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8228         idx_after=$($LFS getstripe $f_comp | awk '$2 == "0:" { print $5 }' |
8229                      tr '\n' ' ')
8230         [ "$layout_before" == "$layout_after" ] ||
8231                 error "lfs migrate: $layout_before != $layout_after"
8232
8233         # this may not fail every time with a broken lfs migrate, but will fail
8234         # often enough to notice, and will not have false positives very often
8235         [ "$idx_before" != "$idx_after" ] ||
8236                 error "lfs migrate: $idx_before == $idx_after"
8237 }
8238 run_test 56xe "migrate a composite layout file"
8239
8240 test_56xf() {
8241         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8242
8243         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
8244                 skip "Need server version at least 2.13.53"
8245
8246         local dir=$DIR/$tdir
8247         local f_comp=$dir/$tfile
8248         local layout="-E 1M -c1 -E -1 -c2"
8249         local fid_before=""
8250         local fid_after=""
8251
8252         test_mkdir "$dir" || error "cannot create dir $dir"
8253         stack_trap "rm -rf $dir"
8254         $LFS setstripe $layout $f_comp ||
8255                 error "cannot setstripe $f_comp with layout $layout"
8256         fid_before=$($LFS getstripe --fid $f_comp)
8257         dd if=/dev/zero of=$f_comp bs=1M count=4
8258
8259         # 1. migrate a comp layout file to a comp layout
8260         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8261         fid_after=$($LFS getstripe --fid $f_comp)
8262         [ "$fid_before" == "$fid_after" ] ||
8263                 error "comp-to-comp migrate: $fid_before != $fid_after"
8264
8265         # 2. migrate a comp layout file to a plain layout
8266         $LFS migrate -c2 $f_comp ||
8267                 error "cannot migrate $f_comp by lfs migrate"
8268         fid_after=$($LFS getstripe --fid $f_comp)
8269         [ "$fid_before" == "$fid_after" ] ||
8270                 error "comp-to-plain migrate: $fid_before != $fid_after"
8271
8272         # 3. migrate a plain layout file to a comp layout
8273         $LFS migrate $layout $f_comp ||
8274                 error "cannot migrate $f_comp by lfs migrate"
8275         fid_after=$($LFS getstripe --fid $f_comp)
8276         [ "$fid_before" == "$fid_after" ] ||
8277                 error "plain-to-comp migrate: $fid_before != $fid_after"
8278 }
8279 run_test 56xf "FID is not lost during migration of a composite layout file"
8280
8281 check_file_ost_range() {
8282         local file="$1"
8283         shift
8284         local range="$*"
8285         local -a file_range
8286         local idx
8287
8288         file_range=($($LFS getstripe -y "$file" |
8289                 awk '/l_ost_idx:/ { print $NF }'))
8290
8291         if [[ "${#file_range[@]}" = 0 ]]; then
8292                 echo "No osts found for $file"
8293                 return 1
8294         fi
8295
8296         for idx in "${file_range[@]}"; do
8297                 [[ " $range " =~ " $idx " ]] ||
8298                         return 1
8299         done
8300
8301         return 0
8302 }
8303
8304 sub_test_56xg() {
8305         local stripe_opt="$1"
8306         local pool="$2"
8307         shift 2
8308         local pool_ostidx="$(seq $* | tr '\n' ' ')"
8309
8310         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
8311                 error "Fail to migrate $tfile on $pool"
8312         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
8313                 error "$tfile is not in pool $pool"
8314         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
8315                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
8316 }
8317
8318 test_56xg() {
8319         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8320         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
8321         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
8322                 skip "Need MDS version newer than 2.14.52"
8323
8324         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
8325         local -a pool_ranges=("0 0" "1 1" "0 1")
8326
8327         # init pools
8328         for i in "${!pool_names[@]}"; do
8329                 pool_add ${pool_names[$i]} ||
8330                         error "pool_add failed (pool: ${pool_names[$i]})"
8331                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
8332                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
8333         done
8334
8335         # init the file to migrate
8336         $LFS setstripe -c1 -i1 $DIR/$tfile ||
8337                 error "Unable to create $tfile on OST1"
8338         stack_trap "rm -f $DIR/$tfile"
8339         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
8340                 error "Unable to write on $tfile"
8341
8342         echo "1. migrate $tfile on pool ${pool_names[0]}"
8343         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
8344
8345         echo "2. migrate $tfile on pool ${pool_names[2]}"
8346         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
8347
8348         echo "3. migrate $tfile on pool ${pool_names[1]}"
8349         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
8350
8351         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
8352         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
8353         echo
8354
8355         # Clean pools
8356         destroy_test_pools ||
8357                 error "pool_destroy failed"
8358 }
8359 run_test 56xg "lfs migrate pool support"
8360
8361 test_56xh() {
8362         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8363
8364         local size_mb=25
8365         local file1=$DIR/$tfile
8366         local tmp1=$TMP/$tfile.tmp
8367
8368         $LFS setstripe -c 2 $file1
8369
8370         stack_trap "rm -f $file1 $tmp1"
8371         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8372                         error "error creating $tmp1"
8373         ls -lsh $tmp1
8374         cp $tmp1 $file1
8375
8376         local start=$SECONDS
8377
8378         $LFS migrate --stats --stats-interval=1 -W 1M -c 1 $file1 ||
8379                 error "migrate failed rc = $?"
8380
8381         local elapsed=$((SECONDS - start))
8382
8383         # with 1MB/s, elapsed should equal size_mb
8384         (( elapsed >= size_mb * 95 / 100 )) ||
8385                 error "'lfs migrate -W' too fast ($elapsed < 0.95 * $size_mb)?"
8386
8387         (( elapsed <= size_mb * 120 / 100 )) ||
8388                 error_not_in_vm "'lfs migrate -W' slow ($elapsed > 1.2 * $size_mb)"
8389
8390         (( elapsed <= size_mb * 350 / 100 )) ||
8391                 error "'lfs migrate -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8392
8393         stripe=$($LFS getstripe -c $file1)
8394         (( $stripe == 1 )) || error "stripe of $file1 is $stripe != 1"
8395         cmp $file1 $tmp1 || error "content mismatch $file1 differs from $tmp1"
8396
8397         # Clean up file (since it is multiple MB)
8398         rm -f $file1 $tmp1
8399 }
8400 run_test 56xh "lfs migrate bandwidth limitation support"
8401
8402 test_56xi() {
8403         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8404         verify_yaml_available || skip_env "YAML verification not installed"
8405
8406         local size_mb=5
8407         local file1=$DIR/$tfile.1
8408         local file2=$DIR/$tfile.2
8409         local file3=$DIR/$tfile.3
8410         local output_file=$DIR/$tfile.out
8411         local tmp1=$TMP/$tfile.tmp
8412
8413         $LFS setstripe -c 2 $file1
8414         $LFS setstripe -c 2 $file2
8415         $LFS setstripe -c 2 $file3
8416
8417         stack_trap "rm -f $file1 $file2 $file3 $tmp1 $output_file"
8418         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8419                         error "error creating $tmp1"
8420         ls -lsh $tmp1
8421         cp $tmp1 $file1
8422         cp $tmp1 $file2
8423         cp $tmp1 $file3
8424
8425         $LFS migrate --stats --stats-interval=1 \
8426                 -c 1 $file1 $file2 $file3 1> $output_file ||
8427                 error "migrate failed rc = $?"
8428
8429         cat $output_file
8430         cat $output_file | verify_yaml || error "rename_stats is not valid YAML"
8431
8432         # Clean up file (since it is multiple MB)
8433         rm -f $file1 $file2 $file3 $tmp1 $output_file
8434 }
8435 run_test 56xi "lfs migrate stats support"
8436
8437 test_56xj() { # LU-16571 "lfs migrate -b" can cause thread starvation on OSS
8438         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8439
8440         local file=$DIR/$tfile
8441         local linkdir=$DIR/$tdir
8442
8443         test_mkdir $linkdir || error "fail to create $linkdir"
8444         $LFS setstripe -i 0 -c 1 -S1M $file
8445         stack_trap "rm -rf $file $linkdir"
8446         dd if=/dev/urandom of=$file bs=1M count=10 ||
8447                 error "fail to create $file"
8448
8449         # Create file links
8450         local cpts
8451         local threads_max
8452         local nlinks
8453
8454         thread_max=$(do_facet ost1 "$LCTL get_param -n ost.OSS.ost.threads_max")
8455         cpts=$(do_facet ost1 "$LCTL get_param -n cpu_partition_table | wc -l")
8456         (( nlinks = thread_max * 3 / 2 / cpts))
8457
8458         echo "create $nlinks hard links of $file"
8459         createmany -l $file $linkdir/link $nlinks
8460
8461         # Parallel migrates (should not block)
8462         local i
8463         for ((i = 0; i < nlinks; i++)); do
8464                 echo $linkdir/link$i
8465         done | xargs -n1 -P $nlinks $LFS migrate -c2
8466
8467         local stripe_count
8468         stripe_count=$($LFS getstripe -c $file) ||
8469                 error "fail to get stripe count on $file"
8470
8471         ((stripe_count == 2)) ||
8472                 error "fail to migrate $file (stripe_count = $stripe_count)"
8473 }
8474 run_test 56xj "lfs migrate -b should not cause starvation of threads on OSS"
8475
8476 test_56xk() {
8477         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8478
8479         local size_mb=5
8480         local file1=$DIR/$tfile
8481
8482         stack_trap "rm -f $file1"
8483         $LFS setstripe -c 1 $file1
8484         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8485                 error "error creating $file1"
8486         $LFS mirror extend -N $file1 || error "can't mirror"
8487         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8488                 error "can't dd"
8489         $LFS getstripe $file1 | grep stale ||
8490                 error "one component must be stale"
8491
8492         local start=$SECONDS
8493         $LFS mirror resync --stats --stats-interval=1 -W 1M $file1 ||
8494                 error "migrate failed rc = $?"
8495         local elapsed=$((SECONDS - start))
8496         $LFS getstripe $file1 | grep stale &&
8497                 error "all components must be sync"
8498
8499         # with 1MB/s, elapsed should equal size_mb
8500         (( elapsed >= size_mb * 95 / 100 )) ||
8501                 error "'lfs mirror resync -W' too fast ($elapsed < 0.95 * $size_mb)?"
8502
8503         (( elapsed <= size_mb * 120 / 100 )) ||
8504                 error_not_in_vm "'lfs mirror resync -W' slow ($elapsed > 1.2 * $size_mb)"
8505
8506         (( elapsed <= size_mb * 350 / 100 )) ||
8507                 error "'lfs mirror resync -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8508 }
8509 run_test 56xk "lfs mirror resync bandwidth limitation support"
8510
8511 test_56xl() {
8512         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8513         verify_yaml_available || skip_env "YAML verification not installed"
8514
8515         local size_mb=5
8516         local file1=$DIR/$tfile.1
8517         local output_file=$DIR/$tfile.out
8518
8519         stack_trap "rm -f $file1"
8520         $LFS setstripe -c 1 $file1
8521         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8522                 error "error creating $file1"
8523         $LFS mirror extend -N $file1 || error "can't mirror"
8524         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8525                 error "can't dd"
8526         $LFS getstripe $file1 | grep stale ||
8527                 error "one component must be stale"
8528         $LFS getstripe $file1
8529
8530         $LFS mirror resync --stats --stats-interval=1 $file1 >$output_file ||
8531                 error "resync failed rc = $?"
8532         $LFS getstripe $file1 | grep stale &&
8533                 error "all components must be sync"
8534
8535         cat $output_file
8536         cat $output_file | verify_yaml || error "stats is not valid YAML"
8537 }
8538 run_test 56xl "lfs mirror resync stats support"
8539
8540 test_56y() {
8541         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8542                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8543
8544         local res=""
8545         local dir=$DIR/$tdir
8546         local f1=$dir/file1
8547         local f2=$dir/file2
8548
8549         test_mkdir -p $dir || error "creating dir $dir"
8550         touch $f1 || error "creating std file $f1"
8551         $MULTIOP $f2 H2c || error "creating released file $f2"
8552
8553         # a directory can be raid0, so ask only for files
8554         res=$($LFS find $dir -L raid0 -type f | wc -l)
8555         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8556
8557         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8558         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8559
8560         # only files can be released, so no need to force file search
8561         res=$($LFS find $dir -L released)
8562         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8563
8564         res=$($LFS find $dir -type f \! -L released)
8565         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8566 }
8567 run_test 56y "lfs find -L raid0|released"
8568
8569 test_56z() { # LU-4824
8570         # This checks to make sure 'lfs find' continues after errors
8571         # There are two classes of errors that should be caught:
8572         # - If multiple paths are provided, all should be searched even if one
8573         #   errors out
8574         # - If errors are encountered during the search, it should not terminate
8575         #   early
8576         local dir=$DIR/$tdir
8577         local i
8578
8579         test_mkdir $dir
8580         for i in d{0..9}; do
8581                 test_mkdir $dir/$i
8582                 touch $dir/$i/$tfile
8583         done
8584         $LFS find $DIR/non_existent_dir $dir &&
8585                 error "$LFS find did not return an error"
8586         # Make a directory unsearchable. This should NOT be the last entry in
8587         # directory order.  Arbitrarily pick the 6th entry
8588         chmod 700 $($LFS find $dir -type d | sed '6!d')
8589
8590         $RUNAS $LFS find $DIR/non_existent $dir
8591         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8592
8593         # The user should be able to see 10 directories and 9 files
8594         (( count == 19 )) ||
8595                 error "$LFS find found $count != 19 entries after error"
8596 }
8597 run_test 56z "lfs find should continue after an error"
8598
8599 test_56aa() { # LU-5937
8600         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8601
8602         local dir=$DIR/$tdir
8603
8604         mkdir $dir
8605         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8606
8607         createmany -o $dir/striped_dir/${tfile}- 1024
8608         local dirs=$($LFS find --size +8k $dir/)
8609
8610         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8611 }
8612 run_test 56aa "lfs find --size under striped dir"
8613
8614 test_56ab() { # LU-10705
8615         test_mkdir $DIR/$tdir
8616         dd if=/dev/urandom of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8617         dd if=/dev/urandom of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8618         dd if=/dev/urandom of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8619         # Flush writes to ensure valid blocks.  Need to be more thorough for
8620         # ZFS, since blocks are not allocated/returned to client immediately.
8621         sync_all_data
8622         wait_zfs_commit ost1 2
8623         cancel_lru_locks osc
8624         ls -ls $DIR/$tdir
8625
8626         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8627
8628         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8629
8630         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8631         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8632
8633         rm -f $DIR/$tdir/$tfile.[123]
8634 }
8635 run_test 56ab "lfs find --blocks"
8636
8637 # LU-11188
8638 test_56aca() {
8639         local dir="$DIR/$tdir"
8640         local perms=(001 002 003 004 005 006 007
8641                      010 020 030 040 050 060 070
8642                      100 200 300 400 500 600 700
8643                      111 222 333 444 555 666 777)
8644         local perm_minus=(8 8 4 8 4 4 2
8645                           8 8 4 8 4 4 2
8646                           8 8 4 8 4 4 2
8647                           4 4 2 4 2 2 1)
8648         local perm_slash=(8  8 12  8 12 12 14
8649                           8  8 12  8 12 12 14
8650                           8  8 12  8 12 12 14
8651                          16 16 24 16 24 24 28)
8652
8653         test_mkdir "$dir"
8654         for perm in ${perms[*]}; do
8655                 touch "$dir/$tfile.$perm"
8656                 chmod $perm "$dir/$tfile.$perm"
8657         done
8658
8659         for ((i = 0; i < ${#perms[*]}; i++)); do
8660                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8661                 (( $num == 1 )) ||
8662                         error "lfs find -perm ${perms[i]}:"\
8663                               "$num != 1"
8664
8665                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8666                 (( $num == ${perm_minus[i]} )) ||
8667                         error "lfs find -perm -${perms[i]}:"\
8668                               "$num != ${perm_minus[i]}"
8669
8670                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8671                 (( $num == ${perm_slash[i]} )) ||
8672                         error "lfs find -perm /${perms[i]}:"\
8673                               "$num != ${perm_slash[i]}"
8674         done
8675 }
8676 run_test 56aca "check lfs find -perm with octal representation"
8677
8678 test_56acb() {
8679         local dir=$DIR/$tdir
8680         # p is the permission of write and execute for user, group and other
8681         # without the umask. It is used to test +wx.
8682         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8683         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8684         local symbolic=(+t  a+t u+t g+t o+t
8685                         g+s u+s o+s +s o+sr
8686                         o=r,ug+o,u+w
8687                         u+ g+ o+ a+ ugo+
8688                         u- g- o- a- ugo-
8689                         u= g= o= a= ugo=
8690                         o=r,ug+o,u+w u=r,a+u,u+w
8691                         g=r,ugo=g,u+w u+x,+X +X
8692                         u+x,u+X u+X u+x,g+X o+r,+X
8693                         u+x,go+X +wx +rwx)
8694
8695         test_mkdir $dir
8696         for perm in ${perms[*]}; do
8697                 touch "$dir/$tfile.$perm"
8698                 chmod $perm "$dir/$tfile.$perm"
8699         done
8700
8701         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8702                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8703
8704                 (( $num == 1 )) ||
8705                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8706         done
8707 }
8708 run_test 56acb "check lfs find -perm with symbolic representation"
8709
8710 test_56acc() {
8711         local dir=$DIR/$tdir
8712         local tests="17777 787 789 abcd
8713                 ug=uu ug=a ug=gu uo=ou urw
8714                 u+xg+x a=r,u+x,"
8715
8716         test_mkdir $dir
8717         for err in $tests; do
8718                 if $LFS find $dir -perm $err 2>/dev/null; then
8719                         error "lfs find -perm $err: parsing should have failed"
8720                 fi
8721         done
8722 }
8723 run_test 56acc "check parsing error for lfs find -perm"
8724
8725 test_56ba() {
8726         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8727                 skip "Need MDS version at least 2.10.50"
8728
8729         # Create composite files with one component
8730         local dir=$DIR/$tdir
8731
8732         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8733         # Create composite files with three components
8734         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8735         # LU-16904 Create plain layout files
8736         lfs setstripe -c 1 $dir/$tfile-{1..10}
8737
8738         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8739
8740         [[ $nfiles == 10 ]] ||
8741                 error "lfs find -E 1M found $nfiles != 10 files"
8742
8743         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8744         [[ $nfiles == 25 ]] ||
8745                 error "lfs find ! -E 1M found $nfiles != 25 files"
8746
8747         # All files have a component that starts at 0
8748         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8749         [[ $nfiles == 35 ]] ||
8750                 error "lfs find --component-start 0 - $nfiles != 35 files"
8751
8752         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8753         [[ $nfiles == 15 ]] ||
8754                 error "lfs find --component-start 2M - $nfiles != 15 files"
8755
8756         # All files created here have a componenet that does not starts at 2M
8757         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8758         [[ $nfiles == 35 ]] ||
8759                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8760
8761         # Find files with a specified number of components
8762         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8763         [[ $nfiles == 15 ]] ||
8764                 error "lfs find --component-count 3 - $nfiles != 15 files"
8765
8766         # Remember non-composite files have a component count of zero
8767         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8768         [[ $nfiles == 10 ]] ||
8769                 error "lfs find --component-count 0 - $nfiles != 10 files"
8770
8771         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8772         [[ $nfiles == 20 ]] ||
8773                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8774
8775         # All files have a flag called "init"
8776         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8777         [[ $nfiles == 35 ]] ||
8778                 error "lfs find --component-flags init - $nfiles != 35 files"
8779
8780         # Multi-component files will have a component not initialized
8781         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8782         [[ $nfiles == 15 ]] ||
8783                 error "lfs find !--component-flags init - $nfiles != 15 files"
8784
8785         rm -rf $dir
8786
8787 }
8788 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8789
8790 test_56ca() {
8791         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8792                 skip "Need MDS version at least 2.10.57"
8793
8794         local td=$DIR/$tdir
8795         local tf=$td/$tfile
8796         local dir
8797         local nfiles
8798         local cmd
8799         local i
8800         local j
8801
8802         # create mirrored directories and mirrored files
8803         mkdir $td || error "mkdir $td failed"
8804         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8805         createmany -o $tf- 10 || error "create $tf- failed"
8806
8807         for i in $(seq 2); do
8808                 dir=$td/dir$i
8809                 mkdir $dir || error "mkdir $dir failed"
8810                 $LFS mirror create -N$((3 + i)) $dir ||
8811                         error "create mirrored dir $dir failed"
8812                 createmany -o $dir/$tfile- 10 ||
8813                         error "create $dir/$tfile- failed"
8814         done
8815
8816         # change the states of some mirrored files
8817         echo foo > $tf-6
8818         for i in $(seq 2); do
8819                 dir=$td/dir$i
8820                 for j in $(seq 4 9); do
8821                         echo foo > $dir/$tfile-$j
8822                 done
8823         done
8824
8825         # find mirrored files with specific mirror count
8826         cmd="$LFS find --mirror-count 3 --type f $td"
8827         nfiles=$($cmd | wc -l)
8828         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8829
8830         cmd="$LFS find ! --mirror-count 3 --type f $td"
8831         nfiles=$($cmd | wc -l)
8832         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8833
8834         cmd="$LFS find --mirror-count +2 --type f $td"
8835         nfiles=$($cmd | wc -l)
8836         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8837
8838         cmd="$LFS find --mirror-count -6 --type f $td"
8839         nfiles=$($cmd | wc -l)
8840         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8841
8842         # find mirrored files with specific file state
8843         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8844         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8845
8846         cmd="$LFS find --mirror-state=ro --type f $td"
8847         nfiles=$($cmd | wc -l)
8848         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8849
8850         cmd="$LFS find ! --mirror-state=ro --type f $td"
8851         nfiles=$($cmd | wc -l)
8852         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8853
8854         cmd="$LFS find --mirror-state=wp --type f $td"
8855         nfiles=$($cmd | wc -l)
8856         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8857
8858         cmd="$LFS find ! --mirror-state=sp --type f $td"
8859         nfiles=$($cmd | wc -l)
8860         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8861 }
8862 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8863
8864 test_56da() { # LU-14179
8865         local path=$DIR/$tdir
8866
8867         test_mkdir $path
8868         cd $path
8869
8870         local longdir=$(str_repeat 'a' 255)
8871
8872         for i in {1..15}; do
8873                 path=$path/$longdir
8874                 test_mkdir $longdir
8875                 cd $longdir
8876         done
8877
8878         local len=${#path}
8879         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8880
8881         test_mkdir $lastdir
8882         cd $lastdir
8883         # PATH_MAX-1
8884         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8885
8886         # NAME_MAX
8887         touch $(str_repeat 'f' 255)
8888
8889         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8890                 error "lfs find reported an error"
8891
8892         rm -rf $DIR/$tdir
8893 }
8894 run_test 56da "test lfs find with long paths"
8895
8896 test_56ea() { #LU-10378
8897         local path=$DIR/$tdir
8898         local pool=$TESTNAME
8899
8900         # Create ost pool
8901         pool_add $pool || error "pool_add $pool failed"
8902         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8903                 error "adding targets to $pool failed"
8904
8905         # Set default pool on directory before creating file
8906         mkdir $path || error "mkdir $path failed"
8907         $LFS setstripe -p $pool $path ||
8908                 error "set OST pool on $pool failed"
8909         touch $path/$tfile || error "touch $path/$tfile failed"
8910
8911         # Compare basic file attributes from -printf and stat
8912         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G %n")
8913         local attr_stat=$(stat -c "%X %Y %Z %u %g %h" $path/$tfile)
8914
8915         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8916                 error "Attrs from lfs find and stat don't match"
8917
8918         # Compare Lustre attributes from lfs find and lfs getstripe
8919         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8920         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8921         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8922         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8923         local fpool=$($LFS getstripe --pool $path/$tfile)
8924         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8925
8926         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8927                 error "Attrs from lfs find and lfs getstripe don't match"
8928
8929         # Verify behavior for unknown escape/format sequences
8930         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8931
8932         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8933                 error "Escape/format codes don't match"
8934 }
8935 run_test 56ea "test lfs find -printf option"
8936
8937 test_56eb() {
8938         local dir=$DIR/$tdir
8939         local subdir_1=$dir/subdir_1
8940
8941         test_mkdir -p $subdir_1
8942         ln -s subdir_1 $dir/link_1
8943
8944         $LFS getstripe $dir | grep "^$dir/link_1$" -A1 ||
8945                 error "symlink is not followed"
8946
8947         $LFS getstripe --no-follow $dir |
8948                 grep "^$dir/link_1 has no stripe info$" ||
8949                 error "symlink should not have stripe info"
8950
8951         touch $dir/testfile
8952         ln -s testfile $dir/file_link_2
8953
8954         $LFS getstripe $dir | grep "^$dir/file_link_2$" -A1 ||
8955                 error "symlink is not followed"
8956
8957         $LFS getstripe --no-follow $dir |
8958                 grep "^$dir/file_link_2 has no stripe info$" ||
8959                 error "symlink should not have stripe info"
8960 }
8961 run_test 56eb "check lfs getstripe on symlink"
8962
8963 test_56ec() {
8964         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8965         local dir=$DIR/$tdir
8966         local srcfile=$dir/srcfile
8967         local srcyaml=$dir/srcyaml
8968         local destfile=$dir/destfile
8969
8970         test_mkdir -p $dir
8971
8972         $LFS setstripe -i 1 $srcfile
8973         $LFS getstripe --hex-idx --yaml $srcfile > $srcyaml
8974         # if the setstripe yaml parsing fails for any reason, the command can
8975         # randomly assign the correct OST index, leading to an erroneous
8976         # success. but the chance of false success is low enough that a
8977         # regression should still be quickly caught.
8978         $LFS setstripe --yaml=$srcyaml $destfile
8979
8980         local srcindex=$($LFS getstripe -i $srcfile)
8981         local destindex=$($LFS getstripe -i $destfile)
8982
8983         if [[ ! $srcindex -eq $destindex ]]; then
8984                 error "setstripe did not set OST index correctly"
8985         fi
8986 }
8987 run_test 56ec "check lfs getstripe,setstripe --hex --yaml"
8988
8989 test_56eda() {
8990         local dir=$DIR/$tdir
8991         local subdir=$dir/subdir
8992         local file1=$dir/$tfile
8993         local file2=$dir/$tfile\2
8994         local link=$dir/$tfile-link
8995         local nfiles
8996
8997         test_mkdir -p $dir
8998         $LFS setdirstripe -c1 $subdir
8999         touch $file1
9000         touch $file2
9001         ln $file2 $link
9002
9003         nfiles=$($LFS find --links 1 $dir | wc -l)
9004         (( $nfiles == 1 )) ||
9005                 error "lfs find --links expected 1 file, got $nfiles"
9006
9007         nfiles=$($LFS find --type f --links 2 $dir | wc -l)
9008         (( $nfiles == 2 )) ||
9009                 error "lfs find --links expected 2 files, got $nfiles"
9010
9011         nfiles=$($LFS find --type d --links 2 $dir | wc -l)
9012         (( $nfiles == 1 )) ||
9013                 error "lfs find --links expected 1 directory, got $nfiles"
9014 }
9015 run_test 56eda "check lfs find --links"
9016
9017 test_56edb() {
9018         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
9019
9020         local dir=$DIR/$tdir
9021         local stripedir=$dir/stripedir
9022         local nfiles
9023
9024         test_mkdir -p $dir
9025
9026         $LFS setdirstripe -c2 $stripedir
9027
9028         $LFS getdirstripe $stripedir
9029
9030         nfiles=$($LFS find --type d --links 2 $stripedir | wc -l)
9031         (( $nfiles == 1 )) ||
9032                 error "lfs find --links expected 1 directory, got $nfiles"
9033 }
9034 run_test 56edb "check lfs find --links for directory striped on multiple MDTs"
9035
9036 test_56ef() {
9037         local dir=$DIR/$tdir
9038         local dir1=$dir/d1
9039         local dir2=$dir/d2
9040         local nfiles
9041         local err_msg
9042
9043         test_mkdir -p $dir
9044
9045         mkdir $dir1
9046         mkdir $dir2
9047
9048         touch $dir1/f
9049         touch $dir2/f
9050
9051         nfiles=$($LFS find $dir1 $dir2 ! -type d | wc -l)
9052         (( $nfiles == 2 )) ||
9053                 error "(1) lfs find expected 2 files, got $nfiles"
9054
9055         nfiles=$($LFS find $dir1 $dir2 -type f | wc -l)
9056         (( $nfiles == 2 )) ||
9057                 error "(2) lfs find expected 2 files, got $nfiles"
9058
9059         nfiles=$($LFS find -type f $dir1 $dir2 | wc -l)
9060         (( $nfiles == 2 )) ||
9061                 error "(3) lfs find expected 2 files, got $nfiles"
9062
9063         err_msg=$($LFS find $dir1/typo $dir1/f 2>&1 > /dev/null)
9064         [[ $err_msg =~ "No such file or directory" ]] ||
9065                 error "expected standard error message, got: '$err_msg'"
9066 }
9067 run_test 56ef "lfs find with multiple paths"
9068
9069 test_56eg() {
9070         local dir=$DIR/$tdir
9071         local found
9072
9073         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9074
9075         test_mkdir -p $dir
9076
9077         touch $dir/$tfile
9078         ln -s $dir/$tfile $dir/$tfile.symlink
9079         setfattr -n "trusted.test" -v "test_target" $dir/$tfile
9080         setfattr --no-dereference -n "trusted.test" -v "test_link" \
9081                 $dir/$tfile.symlink
9082         setfattr --no-dereference -n "trusted.common" \
9083                 $dir/{$tfile,$tfile.symlink}
9084
9085         found=$($LFS find -xattr "trusted.*=test_target" \
9086                 -xattr "trusted.common" $dir)
9087         [[ "$found" == "$dir/$tfile" ]] || {
9088                 getfattr -d -m trusted.* $dir/$tfile
9089                 error "should have found '$tfile' with xattr 'trusted.test=test_target', got '$found'"
9090         }
9091
9092         found=$($LFS find -xattr "trusted.*=test_link" \
9093                 -xattr "trusted.common" $dir)
9094         [[ "$found" == "$dir/$tfile.symlink" ]] || {
9095                 getfattr --no-dereference -d -m trusted.* $dir/$tfile.symlink
9096                 error "should have found '$tfile.symlink' with xattr 'trusted.test=test_link', got '$found'"
9097         }
9098
9099         rm -f $dir/*
9100
9101         touch $dir/$tfile.1
9102         touch $dir/$tfile.2
9103         setfattr -n "user.test" -v "1" $dir/$tfile.1
9104         setfattr -n "user.test" -v "2" $dir/$tfile.2
9105         setfattr -n "user.test2" -v "common" $dir/$tfile.{1,2}
9106
9107         found=$($LFS find -xattr "user.*=common" -xattr "user.test=1" $dir)
9108         [[ "$found" == "$dir/$tfile.1" ]] || {
9109                 getfattr -d $dir/$tfile.1
9110                 error "should have found '$tfile.1' with xattr user.test=1', got '$found'"
9111         }
9112
9113         found=$($LFS find -xattr "user.*=common" ! -xattr "user.test=1" $dir)
9114         [[ "$found" == "$dir/$tfile.2" ]] || {
9115                 getfattr -d $dir/$tfile.2
9116                 error "should have found '$tfile.2' without xattr 'user.test=1', got '$found'"
9117         }
9118
9119         setfattr -n "user.empty" $dir/$tfile.1
9120         found=$($LFS find -xattr "user.empty" $dir)
9121         [[ "$found" == "$dir/$tfile.1" ]] || {
9122                 getfattr -d $dir/$tfile.1
9123                 error "should have found '$tfile.1' with xattr 'user.empty=', got '$found'"
9124         }
9125
9126         # setfattr command normally does not store terminating null byte
9127         # when writing a string as an xattr value.
9128         #
9129         # In order to test matching a value string that includes a terminating
9130         # null, explicitly encode the string "test\0" with the null terminator.
9131         setfattr -n "user.test" -v "0x7465737400" $dir/$tfile.1
9132         found=$($LFS find -xattr "user.test=test" $dir)
9133         [[ "$found" == "$dir/$tfile.1" ]] || {
9134                 getfattr -d --encoding=hex $dir/$tfile.1
9135                 error "should have found '$tfile.1' with xattr 'user.test=0x7465737400', got '$found'"
9136         }
9137 }
9138 run_test 56eg "lfs find -xattr"
9139
9140 test_57a() {
9141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9142         # note test will not do anything if MDS is not local
9143         if [ "$mds1_FSTYPE" != ldiskfs ]; then
9144                 skip_env "ldiskfs only test"
9145         fi
9146         remote_mds_nodsh && skip "remote MDS with nodsh"
9147
9148         local MNTDEV="osd*.*MDT*.mntdev"
9149         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
9150         [ -z "$DEV" ] && error "can't access $MNTDEV"
9151         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
9152                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
9153                         error "can't access $DEV"
9154                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
9155                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
9156                 rm $TMP/t57a.dump
9157         done
9158 }
9159 run_test 57a "verify MDS filesystem created with large inodes =="
9160
9161 test_57b() {
9162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9163         if [ "$mds1_FSTYPE" != ldiskfs ]; then
9164                 skip_env "ldiskfs only test"
9165         fi
9166         remote_mds_nodsh && skip "remote MDS with nodsh"
9167
9168         local dir=$DIR/$tdir
9169         local filecount=100
9170         local file1=$dir/f1
9171         local fileN=$dir/f$filecount
9172
9173         rm -rf $dir || error "removing $dir"
9174         test_mkdir -c1 $dir
9175         local mdtidx=$($LFS getstripe -m $dir)
9176         local mdtname=MDT$(printf %04x $mdtidx)
9177         local facet=mds$((mdtidx + 1))
9178
9179         echo "mcreating $filecount files"
9180         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
9181
9182         # verify that files do not have EAs yet
9183         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
9184                 error "$file1 has an EA"
9185         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
9186                 error "$fileN has an EA"
9187
9188         sync
9189         sleep 1
9190         df $dir  #make sure we get new statfs data
9191         local mdsfree=$(do_facet $facet \
9192                         lctl get_param -n osd*.*$mdtname.kbytesfree)
9193         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
9194         local file
9195
9196         echo "opening files to create objects/EAs"
9197         for file in $(seq -f $dir/f%g 1 $filecount); do
9198                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
9199                         error "opening $file"
9200         done
9201
9202         # verify that files have EAs now
9203         $LFS getstripe -y $file1 | grep -q "l_ost_idx" ||
9204                 error "$file1 missing EA"
9205         $LFS getstripe -y $fileN | grep -q "l_ost_idx" ||
9206                 error "$fileN missing EA"
9207
9208         sleep 1  #make sure we get new statfs data
9209         df $dir
9210         local mdsfree2=$(do_facet $facet \
9211                          lctl get_param -n osd*.*$mdtname.kbytesfree)
9212         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
9213
9214         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
9215                 if [ "$mdsfree" != "$mdsfree2" ]; then
9216                         error "MDC before $mdcfree != after $mdcfree2"
9217                 else
9218                         echo "MDC before $mdcfree != after $mdcfree2"
9219                         echo "unable to confirm if MDS has large inodes"
9220                 fi
9221         fi
9222         rm -rf $dir
9223 }
9224 run_test 57b "default LOV EAs are stored inside large inodes ==="
9225
9226 test_58() {
9227         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9228         [ -z "$(which wiretest 2>/dev/null)" ] &&
9229                         skip_env "could not find wiretest"
9230
9231         wiretest
9232 }
9233 run_test 58 "verify cross-platform wire constants =============="
9234
9235 test_59() {
9236         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9237
9238         echo "touch 130 files"
9239         createmany -o $DIR/f59- 130
9240         echo "rm 130 files"
9241         unlinkmany $DIR/f59- 130
9242         sync
9243         # wait for commitment of removal
9244         wait_delete_completed
9245 }
9246 run_test 59 "verify cancellation of llog records async ========="
9247
9248 TEST60_HEAD="test_60 run $RANDOM"
9249 test_60a() {
9250         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9251         remote_mgs_nodsh && skip "remote MGS with nodsh"
9252         do_facet mgs "! which run-llog.sh &> /dev/null" &&
9253                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
9254                         skip_env "missing subtest run-llog.sh"
9255
9256         log "$TEST60_HEAD - from kernel mode"
9257         do_facet mgs "$LCTL dk > /dev/null"
9258         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
9259         do_facet mgs $LCTL dk > $TMP/$tfile
9260
9261         # LU-6388: test llog_reader
9262         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
9263         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
9264         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
9265                         skip_env "missing llog_reader"
9266         local fstype=$(facet_fstype mgs)
9267         [ $fstype != ldiskfs -a $fstype != zfs ] &&
9268                 skip_env "Only for ldiskfs or zfs type mgs"
9269
9270         local mntpt=$(facet_mntpt mgs)
9271         local mgsdev=$(mgsdevname 1)
9272         local fid_list
9273         local fid
9274         local rec_list
9275         local rec
9276         local rec_type
9277         local obj_file
9278         local path
9279         local seq
9280         local oid
9281         local pass=true
9282
9283         #get fid and record list
9284         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
9285                 tail -n 4))
9286         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
9287                 tail -n 4))
9288         #remount mgs as ldiskfs or zfs type
9289         stop mgs || error "stop mgs failed"
9290         mount_fstype mgs || error "remount mgs failed"
9291         for ((i = 0; i < ${#fid_list[@]}; i++)); do
9292                 fid=${fid_list[i]}
9293                 rec=${rec_list[i]}
9294                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
9295                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
9296                 oid=$((16#$oid))
9297
9298                 case $fstype in
9299                         ldiskfs )
9300                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
9301                         zfs )
9302                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
9303                 esac
9304                 echo "obj_file is $obj_file"
9305                 do_facet mgs $llog_reader $obj_file
9306
9307                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
9308                         awk '{ print $3 }' | sed -e "s/^type=//g")
9309                 if [ $rec_type != $rec ]; then
9310                         echo "FAILED test_60a wrong record type $rec_type," \
9311                               "should be $rec"
9312                         pass=false
9313                         break
9314                 fi
9315
9316                 #check obj path if record type is LLOG_LOGID_MAGIC
9317                 if [ "$rec" == "1064553b" ]; then
9318                         path=$(do_facet mgs $llog_reader $obj_file |
9319                                 grep "path=" | awk '{ print $NF }' |
9320                                 sed -e "s/^path=//g")
9321                         if [ $obj_file != $mntpt/$path ]; then
9322                                 echo "FAILED test_60a wrong obj path" \
9323                                       "$montpt/$path, should be $obj_file"
9324                                 pass=false
9325                                 break
9326                         fi
9327                 fi
9328         done
9329         rm -f $TMP/$tfile
9330         #restart mgs before "error", otherwise it will block the next test
9331         stop mgs || error "stop mgs failed"
9332         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
9333         $pass || error "test failed, see FAILED test_60a messages for specifics"
9334 }
9335 run_test 60a "llog_test run from kernel module and test llog_reader"
9336
9337 test_60b() { # bug 6411
9338         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9339
9340         dmesg > $DIR/$tfile
9341         LLOG_COUNT=$(do_facet mgs dmesg |
9342                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
9343                           /llog_[a-z]*.c:[0-9]/ {
9344                                 if (marker)
9345                                         from_marker++
9346                                 from_begin++
9347                           }
9348                           END {
9349                                 if (marker)
9350                                         print from_marker
9351                                 else
9352                                         print from_begin
9353                           }")
9354
9355         [[ $LLOG_COUNT -gt 120 ]] &&
9356                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
9357 }
9358 run_test 60b "limit repeated messages from CERROR/CWARN"
9359
9360 test_60c() {
9361         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9362
9363         echo "create 5000 files"
9364         createmany -o $DIR/f60c- 5000
9365 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
9366         lctl set_param fail_loc=0x80000137
9367         unlinkmany $DIR/f60c- 5000
9368         lctl set_param fail_loc=0
9369 }
9370 run_test 60c "unlink file when mds full"
9371
9372 test_60d() {
9373         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9374
9375         SAVEPRINTK=$(lctl get_param -n printk)
9376         # verify "lctl mark" is even working"
9377         MESSAGE="test message ID $RANDOM $$"
9378         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9379         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
9380
9381         lctl set_param printk=0 || error "set lnet.printk failed"
9382         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
9383         MESSAGE="new test message ID $RANDOM $$"
9384         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
9385         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9386         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
9387
9388         lctl set_param -n printk="$SAVEPRINTK"
9389 }
9390 run_test 60d "test printk console message masking"
9391
9392 test_60e() {
9393         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9394         remote_mds_nodsh && skip "remote MDS with nodsh"
9395
9396         touch $DIR/$tfile
9397 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
9398         do_facet mds1 lctl set_param fail_loc=0x15b
9399         rm $DIR/$tfile
9400 }
9401 run_test 60e "no space while new llog is being created"
9402
9403 test_60f() {
9404         local old_path=$($LCTL get_param -n debug_path)
9405
9406         stack_trap "$LCTL set_param debug_path=$old_path"
9407         stack_trap "rm -f $TMP/$tfile*"
9408         rm -f $TMP/$tfile* 2> /dev/null
9409         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
9410         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
9411         test_mkdir $DIR/$tdir
9412         # retry in case the open is cached and not released
9413         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
9414                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
9415                 sleep 0.1
9416         done
9417         ls $TMP/$tfile*
9418         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
9419 }
9420 run_test 60f "change debug_path works"
9421
9422 test_60g() {
9423         local pid
9424         local i
9425
9426         test_mkdir -c $MDSCOUNT $DIR/$tdir
9427
9428         (
9429                 local index=0
9430                 while true; do
9431                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
9432                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
9433                                 2>/dev/null
9434                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
9435                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
9436                         index=$((index + 1))
9437                 done
9438         ) &
9439
9440         pid=$!
9441
9442         for i in {0..100}; do
9443                 # define OBD_FAIL_OSD_TXN_START    0x19a
9444                 local index=$((i % MDSCOUNT + 1))
9445
9446                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
9447                         > /dev/null
9448                 sleep 0.01
9449         done
9450
9451         kill -9 $pid
9452
9453         for i in $(seq $MDSCOUNT); do
9454                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
9455         done
9456
9457         mkdir $DIR/$tdir/new || error "mkdir failed"
9458         rmdir $DIR/$tdir/new || error "rmdir failed"
9459
9460         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
9461                 -t namespace
9462         for i in $(seq $MDSCOUNT); do
9463                 wait_update_facet mds$i "$LCTL get_param -n \
9464                         mdd.$(facet_svc mds$i).lfsck_namespace |
9465                         awk '/^status/ { print \\\$2 }'" "completed"
9466         done
9467
9468         ls -R $DIR/$tdir
9469         rm -rf $DIR/$tdir || error "rmdir failed"
9470 }
9471 run_test 60g "transaction abort won't cause MDT hung"
9472
9473 test_60h() {
9474         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
9475                 skip "Need MDS version at least 2.12.52"
9476         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
9477
9478         local f
9479
9480         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
9481         #define OBD_FAIL_MDS_STRIPE_FID          0x189
9482         for fail_loc in 0x80000188 0x80000189; do
9483                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
9484                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
9485                         error "mkdir $dir-$fail_loc failed"
9486                 for i in {0..10}; do
9487                         # create may fail on missing stripe
9488                         echo $i > $DIR/$tdir-$fail_loc/$i
9489                 done
9490                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9491                         error "getdirstripe $tdir-$fail_loc failed"
9492                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
9493                         error "migrate $tdir-$fail_loc failed"
9494                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9495                         error "getdirstripe $tdir-$fail_loc failed"
9496                 pushd $DIR/$tdir-$fail_loc
9497                 for f in *; do
9498                         echo $f | cmp $f - || error "$f data mismatch"
9499                 done
9500                 popd
9501                 rm -rf $DIR/$tdir-$fail_loc
9502         done
9503 }
9504 run_test 60h "striped directory with missing stripes can be accessed"
9505
9506 function t60i_load() {
9507         mkdir $DIR/$tdir
9508         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
9509         $LCTL set_param fail_loc=0x131c fail_val=1
9510         for ((i=0; i<5000; i++)); do
9511                 touch $DIR/$tdir/f$i
9512         done
9513 }
9514
9515 test_60i() {
9516         changelog_register || error "changelog_register failed"
9517         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
9518         changelog_users $SINGLEMDS | grep -q $cl_user ||
9519                 error "User $cl_user not found in changelog_users"
9520         changelog_chmask "ALL"
9521         t60i_load &
9522         local PID=$!
9523         for((i=0; i<100; i++)); do
9524                 changelog_dump >/dev/null ||
9525                         error "can't read changelog"
9526         done
9527         kill $PID
9528         wait $PID
9529         changelog_deregister || error "changelog_deregister failed"
9530         $LCTL set_param fail_loc=0
9531 }
9532 run_test 60i "llog: new record vs reader race"
9533
9534 test_60j() {
9535         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
9536                 skip "need MDS version at least 2.15.50"
9537         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9538         remote_mds_nodsh && skip "remote MDS with nodsh"
9539         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
9540
9541         changelog_users $SINGLEMDS | grep "^cl" &&
9542                 skip "active changelog user"
9543
9544         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
9545
9546         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
9547                 skip_env "missing llog_reader"
9548
9549         mkdir_on_mdt0 $DIR/$tdir
9550
9551         local f=$DIR/$tdir/$tfile
9552         local mdt_dev
9553         local tmpfile
9554         local plain
9555
9556         changelog_register || error "cannot register changelog user"
9557
9558         # set changelog_mask to ALL
9559         changelog_chmask "ALL"
9560         changelog_clear
9561
9562         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
9563         unlinkmany ${f}- 100 || error "unlinkmany failed"
9564
9565         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
9566         mdt_dev=$(facet_device $SINGLEMDS)
9567
9568         do_facet $SINGLEMDS sync
9569         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
9570                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
9571                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
9572
9573         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
9574
9575         # if $tmpfile is not on EXT3 filesystem for some reason
9576         [[ ${plain:0:1} == 'O' ]] ||
9577                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
9578
9579         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
9580                 $mdt_dev; stat -c %s $tmpfile")
9581         echo "Truncate llog from $size to $((size - size % 8192))"
9582         size=$((size - size % 8192))
9583         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
9584         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9585                 grep -c 'in bitmap only')
9586         (( $errs > 0 )) || error "llog_reader didn't find lost records"
9587
9588         size=$((size - 9000))
9589         echo "Corrupt llog in the middle at $size"
9590         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
9591                 count=333 conv=notrunc
9592         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9593                 grep -c 'next chunk')
9594         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
9595 }
9596 run_test 60j "llog_reader reports corruptions"
9597
9598 test_61a() {
9599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9600
9601         f="$DIR/f61"
9602         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
9603         cancel_lru_locks osc
9604         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
9605         sync
9606 }
9607 run_test 61a "mmap() writes don't make sync hang ================"
9608
9609 test_61b() {
9610         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
9611 }
9612 run_test 61b "mmap() of unstriped file is successful"
9613
9614 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
9615 # Though this test is irrelevant anymore, it helped to reveal some
9616 # other grant bugs (LU-4482), let's keep it.
9617 test_63a() {   # was test_63
9618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9619
9620         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
9621
9622         for i in `seq 10` ; do
9623                 dd if=/dev/zero of=$DIR/f63 bs=8k &
9624                 sleep 5
9625                 kill $!
9626                 sleep 1
9627         done
9628
9629         rm -f $DIR/f63 || true
9630 }
9631 run_test 63a "Verify oig_wait interruption does not crash ======="
9632
9633 # bug 2248 - async write errors didn't return to application on sync
9634 # bug 3677 - async write errors left page locked
9635 test_63b() {
9636         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9637
9638         debugsave
9639         lctl set_param debug=-1
9640
9641         # ensure we have a grant to do async writes
9642         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
9643         rm $DIR/$tfile
9644
9645         sync    # sync lest earlier test intercept the fail_loc
9646
9647         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9648         lctl set_param fail_loc=0x80000406
9649         $MULTIOP $DIR/$tfile Owy && \
9650                 error "sync didn't return ENOMEM"
9651         sync; sleep 2; sync     # do a real sync this time to flush page
9652         lctl get_param -n llite.*.dump_page_cache | grep locked && \
9653                 error "locked page left in cache after async error" || true
9654         debugrestore
9655 }
9656 run_test 63b "async write errors should be returned to fsync ==="
9657
9658 test_64a () {
9659         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9660
9661         lfs df $DIR
9662         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
9663 }
9664 run_test 64a "verify filter grant calculations (in kernel) ====="
9665
9666 test_64b () {
9667         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9668
9669         bash oos.sh $MOUNT || error "oos.sh failed: $?"
9670 }
9671 run_test 64b "check out-of-space detection on client"
9672
9673 test_64c() {
9674         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
9675 }
9676 run_test 64c "verify grant shrink"
9677
9678 import_param() {
9679         local tgt=$1
9680         local param=$2
9681
9682         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
9683 }
9684
9685 # this does exactly what osc_request.c:osc_announce_cached() does in
9686 # order to calculate max amount of grants to ask from server
9687 want_grant() {
9688         local tgt=$1
9689
9690         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
9691         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
9692
9693         ((rpc_in_flight++));
9694         nrpages=$((nrpages * rpc_in_flight))
9695
9696         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
9697
9698         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
9699
9700         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
9701         local undirty=$((nrpages * PAGE_SIZE))
9702
9703         local max_extent_pages
9704         max_extent_pages=$(import_param $tgt grant_max_extent_size)
9705         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
9706         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
9707         local grant_extent_tax
9708         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9709
9710         undirty=$((undirty + nrextents * grant_extent_tax))
9711
9712         echo $undirty
9713 }
9714
9715 # this is size of unit for grant allocation. It should be equal to
9716 # what tgt_grant.c:tgt_grant_chunk() calculates
9717 grant_chunk() {
9718         local tgt=$1
9719         local max_brw_size
9720         local grant_extent_tax
9721
9722         max_brw_size=$(import_param $tgt max_brw_size)
9723
9724         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9725
9726         echo $(((max_brw_size + grant_extent_tax) * 2))
9727 }
9728
9729 test_64d() {
9730         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
9731                 skip "OST < 2.10.55 doesn't limit grants enough"
9732
9733         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9734
9735         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9736                 skip "no grant_param connect flag"
9737
9738         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9739
9740         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9741         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9742
9743
9744         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9745         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9746
9747         $LFS setstripe $DIR/$tfile -i 0 -c 1
9748         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9749         ddpid=$!
9750
9751         while kill -0 $ddpid; do
9752                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9753
9754                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9755                         kill $ddpid
9756                         error "cur_grant $cur_grant > $max_cur_granted"
9757                 fi
9758
9759                 sleep 1
9760         done
9761 }
9762 run_test 64d "check grant limit exceed"
9763
9764 check_grants() {
9765         local tgt=$1
9766         local expected=$2
9767         local msg=$3
9768         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9769
9770         ((cur_grants == expected)) ||
9771                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9772 }
9773
9774 round_up_p2() {
9775         echo $((($1 + $2 - 1) & ~($2 - 1)))
9776 }
9777
9778 test_64e() {
9779         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9780         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9781                 skip "Need OSS version at least 2.11.56"
9782
9783         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9784         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9785         $LCTL set_param debug=+cache
9786
9787         # Remount client to reset grant
9788         remount_client $MOUNT || error "failed to remount client"
9789         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9790
9791         local init_grants=$(import_param $osc_tgt initial_grant)
9792
9793         check_grants $osc_tgt $init_grants "init grants"
9794
9795         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9796         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9797         local gbs=$(import_param $osc_tgt grant_block_size)
9798
9799         # write random number of bytes from max_brw_size / 4 to max_brw_size
9800         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9801         # align for direct io
9802         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9803         # round to grant consumption unit
9804         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9805
9806         local grants=$((wb_round_up + extent_tax))
9807
9808         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9809         stack_trap "rm -f $DIR/$tfile"
9810
9811         # define OBD_FAIL_TGT_NO_GRANT 0x725
9812         # make the server not grant more back
9813         do_facet ost1 $LCTL set_param fail_loc=0x725
9814         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9815
9816         do_facet ost1 $LCTL set_param fail_loc=0
9817
9818         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9819
9820         rm -f $DIR/$tfile || error "rm failed"
9821
9822         # Remount client to reset grant
9823         remount_client $MOUNT || error "failed to remount client"
9824         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9825
9826         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9827
9828         # define OBD_FAIL_TGT_NO_GRANT 0x725
9829         # make the server not grant more back
9830         do_facet ost1 $LCTL set_param fail_loc=0x725
9831         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9832         do_facet ost1 $LCTL set_param fail_loc=0
9833
9834         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9835 }
9836 run_test 64e "check grant consumption (no grant allocation)"
9837
9838 test_64f() {
9839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9840
9841         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9842         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9843         $LCTL set_param debug=+cache
9844
9845         # Remount client to reset grant
9846         remount_client $MOUNT || error "failed to remount client"
9847         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9848
9849         local init_grants=$(import_param $osc_tgt initial_grant)
9850         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9851         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9852         local gbs=$(import_param $osc_tgt grant_block_size)
9853         local chunk=$(grant_chunk $osc_tgt)
9854
9855         # write random number of bytes from max_brw_size / 4 to max_brw_size
9856         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9857         # align for direct io
9858         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9859         # round to grant consumption unit
9860         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9861
9862         local grants=$((wb_round_up + extent_tax))
9863
9864         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9865         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9866                 error "error writing to $DIR/$tfile"
9867
9868         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9869                 "direct io with grant allocation"
9870
9871         rm -f $DIR/$tfile || error "rm failed"
9872
9873         # Remount client to reset grant
9874         remount_client $MOUNT || error "failed to remount client"
9875         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9876
9877         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9878
9879         # Testing that buffered IO consumes grant on the client
9880
9881         # Delay the RPC on the server so it's guaranteed to not complete even
9882         # if the RPC is sent from the client
9883         #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
9884         $LCTL set_param fail_loc=0x50a fail_val=3
9885         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 conv=notrunc ||
9886                 error "error writing to $DIR/$tfile with buffered IO"
9887
9888         check_grants $osc_tgt $((init_grants - grants)) \
9889                 "buffered io, not write rpc"
9890
9891         # Clear the fail loc and do a sync on the client
9892         $LCTL set_param fail_loc=0 fail_val=0
9893         sync
9894
9895         # RPC is now known to have sent
9896         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9897                 "buffered io, one RPC"
9898 }
9899 run_test 64f "check grant consumption (with grant allocation)"
9900
9901 test_64g() {
9902         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9903                 skip "Need MDS version at least 2.14.56"
9904
9905         local mdts=$(comma_list $(mdts_nodes))
9906
9907         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9908                         tr '\n' ' ')
9909         stack_trap "$LCTL set_param $old"
9910
9911         # generate dirty pages and increase dirty granted on MDT
9912         stack_trap "rm -f $DIR/$tfile-*"
9913         for (( i = 0; i < 10; i++)); do
9914                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9915                         error "can't set stripe"
9916                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9917                         error "can't dd"
9918                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9919                         $LFS getstripe $DIR/$tfile-$i
9920                         error "not DoM file"
9921                 }
9922         done
9923
9924         # flush dirty pages
9925         sync
9926
9927         # wait until grant shrink reset grant dirty on MDTs
9928         for ((i = 0; i < 120; i++)); do
9929                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9930                         awk '{sum=sum+$1} END {print sum}')
9931                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9932                 echo "$grant_dirty grants, $vm_dirty pages"
9933                 (( grant_dirty + vm_dirty == 0 )) && break
9934                 (( i == 3 )) && sync &&
9935                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9936                 sleep 1
9937         done
9938
9939         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9940                 awk '{sum=sum+$1} END {print sum}')
9941         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9942 }
9943 run_test 64g "grant shrink on MDT"
9944
9945 test_64h() {
9946         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9947                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9948
9949         local instance=$($LFS getname -i $DIR)
9950         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9951         local num_exps=$(do_facet ost1 \
9952             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9953         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9954         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9955         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9956
9957         # 10MiB is for file to be written, max_brw_size * 16 *
9958         # num_exps is space reserve so that tgt_grant_shrink() decided
9959         # to not shrink
9960         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9961         (( avail * 1024 < expect )) &&
9962                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9963
9964         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9965         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9966         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9967         $LCTL set_param osc.*OST0000*.grant_shrink=1
9968         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9969
9970         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9971         stack_trap "rm -f $DIR/$tfile"
9972         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9973
9974         # drop cache so that coming read would do rpc
9975         cancel_lru_locks osc
9976
9977         # shrink interval is set to 10, pause for 7 seconds so that
9978         # grant thread did not wake up yet but coming read entered
9979         # shrink mode for rpc (osc_should_shrink_grant())
9980         sleep 7
9981
9982         declare -a cur_grant_bytes
9983         declare -a tot_granted
9984         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9985         tot_granted[0]=$(do_facet ost1 \
9986             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9987
9988         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9989
9990         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9991         tot_granted[1]=$(do_facet ost1 \
9992             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9993
9994         # grant change should be equal on both sides
9995         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9996                 tot_granted[0] - tot_granted[1])) ||
9997                 error "grant change mismatch, "                                \
9998                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9999                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
10000 }
10001 run_test 64h "grant shrink on read"
10002
10003 test_64i() {
10004         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
10005                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
10006
10007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10008         remote_ost_nodsh && skip "remote OSTs with nodsh"
10009
10010         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10011         stack_trap "rm -f $DIR/$tfile"
10012
10013         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
10014
10015         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
10016         local instance=$($LFS getname -i $DIR)
10017
10018         local osc_tgt="$FSNAME-OST0000-osc-$instance"
10019         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
10020
10021         # shrink grants and simulate rpc loss
10022         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
10023         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
10024         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
10025
10026         fail ost1
10027
10028         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
10029
10030         local testid=$(echo $TESTNAME | tr '_' ' ')
10031
10032         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
10033                 grep "GRANT, real grant" &&
10034                 error "client has more grants then it owns" || true
10035 }
10036 run_test 64i "shrink on reconnect"
10037
10038 # bug 1414 - set/get directories' stripe info
10039 test_65a() {
10040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10041
10042         # LU-16904 check if the root is set as PFL layout
10043         local numcomp=$($LFS getstripe --component-count $MOUNT)
10044         [ $numcomp -eq 0 ] || skip "Skip test_65a for PFL layout"
10045
10046         test_mkdir $DIR/$tdir
10047         touch $DIR/$tdir/f1
10048         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
10049 }
10050 run_test 65a "directory with no stripe info"
10051
10052 test_65b() {
10053         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10054
10055         test_mkdir $DIR/$tdir
10056         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10057
10058         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
10059                                                 error "setstripe"
10060         touch $DIR/$tdir/f2
10061         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
10062 }
10063 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
10064
10065 test_65c() {
10066         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10067         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
10068
10069         test_mkdir $DIR/$tdir
10070         local stripesize=$($LFS getstripe -S $DIR/$tdir)
10071
10072         $LFS setstripe -S $((stripesize * 4)) -i 1 \
10073                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
10074         touch $DIR/$tdir/f3
10075         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
10076 }
10077 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
10078
10079 test_65d() {
10080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10081
10082         test_mkdir $DIR/$tdir
10083         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
10084         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10085
10086         if [[ $STRIPECOUNT -le 0 ]]; then
10087                 sc=1
10088         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
10089                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
10090                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
10091         else
10092                 sc=$(($STRIPECOUNT - 1))
10093         fi
10094         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
10095         touch $DIR/$tdir/f4 $DIR/$tdir/f5
10096         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
10097                 error "lverify failed"
10098 }
10099 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
10100
10101 test_65e() {
10102         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10103
10104         # LU-16904 delete layout when root is set as PFL layout
10105         save_layout_restore_at_exit $MOUNT
10106         $LFS setstripe -d $MOUNT || error "setstripe failed"
10107
10108         test_mkdir $DIR/$tdir
10109
10110         $LFS setstripe $DIR/$tdir || error "setstripe"
10111         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
10112                                         error "no stripe info failed"
10113         touch $DIR/$tdir/f6
10114         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
10115 }
10116 run_test 65e "directory setstripe defaults"
10117
10118 test_65f() {
10119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10120
10121         test_mkdir $DIR/${tdir}f
10122         $RUNAS $LFS setstripe $DIR/${tdir}f &&
10123                 error "setstripe succeeded" || true
10124 }
10125 run_test 65f "dir setstripe permission (should return error) ==="
10126
10127 test_65g() {
10128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10129
10130         # LU-16904 delete layout when root is set as PFL layout
10131         save_layout_restore_at_exit $MOUNT
10132         $LFS setstripe -d $MOUNT || error "setstripe failed"
10133
10134         test_mkdir $DIR/$tdir
10135         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10136
10137         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
10138                 error "setstripe -S failed"
10139         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
10140         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
10141                 error "delete default stripe failed"
10142 }
10143 run_test 65g "directory setstripe -d"
10144
10145 test_65h() {
10146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10147
10148         test_mkdir $DIR/$tdir
10149         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10150
10151         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
10152                 error "setstripe -S failed"
10153         test_mkdir $DIR/$tdir/dd1
10154         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
10155                 error "stripe info inherit failed"
10156 }
10157 run_test 65h "directory stripe info inherit ===================="
10158
10159 test_65i() {
10160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10161
10162         save_layout_restore_at_exit $MOUNT
10163
10164         # bug6367: set non-default striping on root directory
10165         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
10166
10167         # bug12836: getstripe on -1 default directory striping
10168         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
10169
10170         # bug12836: getstripe -v on -1 default directory striping
10171         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
10172
10173         # bug12836: new find on -1 default directory striping
10174         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
10175 }
10176 run_test 65i "various tests to set root directory striping"
10177
10178 test_65j() { # bug6367
10179         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10180
10181         sync; sleep 1
10182
10183         # if we aren't already remounting for each test, do so for this test
10184         if [ "$I_MOUNTED" = "yes" ]; then
10185                 cleanup || error "failed to unmount"
10186                 setup
10187         fi
10188
10189         save_layout_restore_at_exit $MOUNT
10190
10191         $LFS setstripe -d $MOUNT || error "setstripe failed"
10192 }
10193 run_test 65j "set default striping on root directory (bug 6367)="
10194
10195 cleanup_65k() {
10196         rm -rf $DIR/$tdir
10197         wait_delete_completed
10198         do_facet $SINGLEMDS "lctl set_param -n \
10199                 osp.$ost*MDT0000.max_create_count=$max_count"
10200         do_facet $SINGLEMDS "lctl set_param -n \
10201                 osp.$ost*MDT0000.create_count=$count"
10202         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10203         echo $INACTIVE_OSC "is Activate"
10204
10205         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10206 }
10207
10208 test_65k() { # bug11679
10209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10210         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10211         remote_mds_nodsh && skip "remote MDS with nodsh"
10212
10213         local disable_precreate=true
10214         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
10215                 disable_precreate=false
10216
10217         echo "Check OST status: "
10218         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
10219                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
10220
10221         for OSC in $MDS_OSCS; do
10222                 echo $OSC "is active"
10223                 do_facet $SINGLEMDS lctl --device %$OSC activate
10224         done
10225
10226         for INACTIVE_OSC in $MDS_OSCS; do
10227                 local ost=$(osc_to_ost $INACTIVE_OSC)
10228                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
10229                                lov.*md*.target_obd |
10230                                awk -F: /$ost/'{ print $1 }' | head -n 1)
10231
10232                 mkdir -p $DIR/$tdir
10233                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
10234                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
10235
10236                 echo "Deactivate: " $INACTIVE_OSC
10237                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
10238
10239                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
10240                               osp.$ost*MDT0000.create_count")
10241                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
10242                                   osp.$ost*MDT0000.max_create_count")
10243                 $disable_precreate &&
10244                         do_facet $SINGLEMDS "lctl set_param -n \
10245                                 osp.$ost*MDT0000.max_create_count=0"
10246
10247                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
10248                         [ -f $DIR/$tdir/$idx ] && continue
10249                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
10250                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
10251                                 { cleanup_65k;
10252                                   error "setstripe $idx should succeed"; }
10253                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
10254                 done
10255                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
10256                 rmdir $DIR/$tdir
10257
10258                 do_facet $SINGLEMDS "lctl set_param -n \
10259                         osp.$ost*MDT0000.max_create_count=$max_count"
10260                 do_facet $SINGLEMDS "lctl set_param -n \
10261                         osp.$ost*MDT0000.create_count=$count"
10262                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10263                 echo $INACTIVE_OSC "is Activate"
10264
10265                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10266         done
10267 }
10268 run_test 65k "validate manual striping works properly with deactivated OSCs"
10269
10270 test_65l() { # bug 12836
10271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10272
10273         test_mkdir -p $DIR/$tdir/test_dir
10274         $LFS setstripe -c -1 $DIR/$tdir/test_dir
10275         $LFS find -mtime -1 $DIR/$tdir >/dev/null
10276 }
10277 run_test 65l "lfs find on -1 stripe dir ========================"
10278
10279 test_65m() {
10280         local layout=$(save_layout $MOUNT)
10281         $RUNAS $LFS setstripe -c 2 $MOUNT && {
10282                 restore_layout $MOUNT $layout
10283                 error "setstripe should fail by non-root users"
10284         }
10285         true
10286 }
10287 run_test 65m "normal user can't set filesystem default stripe"
10288
10289 test_65n() {
10290         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
10291         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
10292                 skip "Need MDS version at least 2.12.50"
10293         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
10294
10295         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
10296         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
10297         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
10298
10299         save_layout_restore_at_exit $MOUNT
10300
10301         # new subdirectory under root directory should not inherit
10302         # the default layout from root
10303         # LU-16904 check if the root is set as PFL layout
10304         local numcomp=$($LFS getstripe --component-count $MOUNT)
10305
10306         if [[ $numcomp -eq 0 ]]; then
10307                 local dir1=$MOUNT/$tdir-1
10308                 mkdir $dir1 || error "mkdir $dir1 failed"
10309                 ! getfattr -n trusted.lov $dir1 &> /dev/null ||
10310                         error "$dir1 shouldn't have LOV EA"
10311         fi
10312
10313         # delete the default layout on root directory
10314         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
10315
10316         local dir2=$MOUNT/$tdir-2
10317         mkdir $dir2 || error "mkdir $dir2 failed"
10318         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
10319                 error "$dir2 shouldn't have LOV EA"
10320
10321         # set a new striping pattern on root directory
10322         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10323         local new_def_stripe_size=$((def_stripe_size * 2))
10324         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
10325                 error "set stripe size on $MOUNT failed"
10326
10327         # new file created in $dir2 should inherit the new stripe size from
10328         # the filesystem default
10329         local file2=$dir2/$tfile-2
10330         touch $file2 || error "touch $file2 failed"
10331
10332         local file2_stripe_size=$($LFS getstripe -S $file2)
10333         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
10334         {
10335                 echo "file2_stripe_size: '$file2_stripe_size'"
10336                 echo "new_def_stripe_size: '$new_def_stripe_size'"
10337                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
10338         }
10339
10340         local dir3=$MOUNT/$tdir-3
10341         mkdir $dir3 || error "mkdir $dir3 failed"
10342         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
10343         # the root layout, which is the actual default layout that will be used
10344         # when new files are created in $dir3.
10345         local dir3_layout=$(get_layout_param $dir3)
10346         local root_dir_layout=$(get_layout_param $MOUNT)
10347         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
10348         {
10349                 echo "dir3_layout: '$dir3_layout'"
10350                 echo "root_dir_layout: '$root_dir_layout'"
10351                 error "$dir3 should show the default layout from $MOUNT"
10352         }
10353
10354         # set OST pool on root directory
10355         local pool=$TESTNAME
10356         pool_add $pool || error "add $pool failed"
10357         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10358                 error "add targets to $pool failed"
10359
10360         $LFS setstripe -p $pool $MOUNT ||
10361                 error "set OST pool on $MOUNT failed"
10362
10363         # new file created in $dir3 should inherit the pool from
10364         # the filesystem default
10365         local file3=$dir3/$tfile-3
10366         touch $file3 || error "touch $file3 failed"
10367
10368         local file3_pool=$($LFS getstripe -p $file3)
10369         [[ "$file3_pool" = "$pool" ]] ||
10370                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
10371
10372         local dir4=$MOUNT/$tdir-4
10373         mkdir $dir4 || error "mkdir $dir4 failed"
10374         local dir4_layout=$(get_layout_param $dir4)
10375         root_dir_layout=$(get_layout_param $MOUNT)
10376         echo "$LFS getstripe -d $dir4"
10377         $LFS getstripe -d $dir4
10378         echo "$LFS getstripe -d $MOUNT"
10379         $LFS getstripe -d $MOUNT
10380         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
10381         {
10382                 echo "dir4_layout: '$dir4_layout'"
10383                 echo "root_dir_layout: '$root_dir_layout'"
10384                 error "$dir4 should show the default layout from $MOUNT"
10385         }
10386
10387         # new file created in $dir4 should inherit the pool from
10388         # the filesystem default
10389         local file4=$dir4/$tfile-4
10390         touch $file4 || error "touch $file4 failed"
10391
10392         local file4_pool=$($LFS getstripe -p $file4)
10393         [[ "$file4_pool" = "$pool" ]] ||
10394                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
10395
10396         # new subdirectory under non-root directory should inherit
10397         # the default layout from its parent directory
10398         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
10399                 error "set directory layout on $dir4 failed"
10400
10401         local dir5=$dir4/$tdir-5
10402         mkdir $dir5 || error "mkdir $dir5 failed"
10403
10404         dir4_layout=$(get_layout_param $dir4)
10405         local dir5_layout=$(get_layout_param $dir5)
10406         [[ "$dir4_layout" = "$dir5_layout" ]] ||
10407         {
10408                 echo "dir4_layout: '$dir4_layout'"
10409                 echo "dir5_layout: '$dir5_layout'"
10410                 error "$dir5 should inherit the default layout from $dir4"
10411         }
10412
10413         # though subdir under ROOT doesn't inherit default layout, but
10414         # its sub dir/file should be created with default layout.
10415         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
10416         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
10417                 skip "Need MDS version at least 2.12.59"
10418
10419         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
10420         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
10421         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
10422
10423         if [ $default_lmv_hash == "none" ]; then
10424                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
10425         else
10426                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
10427                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
10428         fi
10429
10430         $LFS setdirstripe -D -c 2 $MOUNT ||
10431                 error "setdirstripe -D -c 2 failed"
10432         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
10433         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
10434         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
10435
10436         # $dir4 layout includes pool
10437         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
10438         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10439                 error "pool lost on setstripe"
10440         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
10441         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10442                 error "pool lost on compound layout setstripe"
10443 }
10444 run_test 65n "don't inherit default layout from root for new subdirectories"
10445
10446 test_65o() {
10447         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
10448                 skip "need MDS version at least 2.14.57"
10449
10450         # set OST pool on root directory
10451         local pool=$TESTNAME
10452
10453         pool_add $pool || error "add $pool failed"
10454         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10455                 error "add targets to $pool failed"
10456
10457         local dir1=$MOUNT/$tdir
10458
10459         mkdir $dir1 || error "mkdir $dir1 failed"
10460
10461         # set a new striping pattern on root directory
10462         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10463
10464         $LFS setstripe -p $pool $dir1 ||
10465                 error "set directory layout on $dir1 failed"
10466
10467         # $dir1 layout includes pool
10468         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
10469         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10470                 error "pool lost on setstripe"
10471         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
10472         $LFS getstripe $dir1
10473         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10474                 error "pool lost on compound layout setstripe"
10475
10476         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
10477                 error "setdirstripe failed on sub-dir with inherited pool"
10478         $LFS getstripe $dir1/dir2
10479         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
10480                 error "pool lost on compound layout setdirstripe"
10481
10482         $LFS setstripe -E -1 -c 1 $dir1
10483         $LFS getstripe -d $dir1
10484         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10485                 error "pool lost on setstripe"
10486 }
10487 run_test 65o "pool inheritance for mdt component"
10488
10489 test_65p () { # LU-16152
10490         local src_dir=$DIR/$tdir/src_dir
10491         local dst_dir=$DIR/$tdir/dst_dir
10492         local yaml_file=$DIR/$tdir/layout.yaml
10493         local border
10494
10495         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10496                 skip "Need at least version 2.15.51"
10497
10498         test_mkdir -p $src_dir
10499         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
10500                 error "failed to setstripe"
10501         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
10502                 error "failed to getstripe"
10503
10504         test_mkdir -p $dst_dir
10505         $LFS setstripe --yaml $yaml_file $dst_dir ||
10506                 error "failed to setstripe with yaml file"
10507         border=$($LFS getstripe -d $dst_dir |
10508                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
10509                 error "failed to getstripe"
10510
10511         # 2048M is 0x80000000, or 2147483648
10512         (( $border == 2147483648 )) ||
10513                 error "failed to handle huge number in yaml layout"
10514 }
10515 run_test 65p "setstripe with yaml file and huge number"
10516
10517 test_65q () { # LU-16194
10518         local src_dir=$DIR/$tdir/src_dir
10519
10520         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) &&
10521         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
10522                 skip "Need at least version 2.15.51"
10523
10524         test_mkdir -p $src_dir
10525         # 8E is 0x8000 0000 0000 0000, which is negative as s64
10526         $LFS setstripe -E 8E -c 4 -E EOF -c 8 $src_dir &&
10527                 error "should fail if extent start/end >=8E"
10528
10529         # EOF should work as before
10530         $LFS setstripe -E 8M -c 4 -E EOF -c 8 $src_dir ||
10531                 error "failed to setstripe normally"
10532 }
10533 run_test 65q "setstripe with >=8E offset should fail"
10534
10535 # bug 2543 - update blocks count on client
10536 test_66() {
10537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10538
10539         local COUNT=${COUNT:-8}
10540         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
10541         sync; sync_all_data; sync; sync_all_data
10542         cancel_lru_locks osc
10543         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
10544         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
10545 }
10546 run_test 66 "update inode blocks count on client ==============="
10547
10548 meminfo() {
10549         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
10550 }
10551
10552 swap_used() {
10553         swapon -s | awk '($1 == "'$1'") { print $4 }'
10554 }
10555
10556 # bug5265, obdfilter oa2dentry return -ENOENT
10557 # #define OBD_FAIL_SRV_ENOENT 0x217
10558 test_69() {
10559         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10560         remote_ost_nodsh && skip "remote OST with nodsh"
10561
10562         f="$DIR/$tfile"
10563         $LFS setstripe -c 1 -i 0 $f
10564         stack_trap "rm -f $f ${f}.2"
10565
10566         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
10567
10568         do_facet ost1 lctl set_param fail_loc=0x217
10569         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
10570         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
10571
10572         do_facet ost1 lctl set_param fail_loc=0
10573         $DIRECTIO write $f 0 2 || error "write error"
10574
10575         cancel_lru_locks osc
10576         $DIRECTIO read $f 0 1 || error "read error"
10577
10578         do_facet ost1 lctl set_param fail_loc=0x217
10579         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
10580
10581         do_facet ost1 lctl set_param fail_loc=0
10582 }
10583 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
10584
10585 test_70a() {
10586         # Perform a really simple test of health write and health check
10587         (( $OST1_VERSION >= $(version_code 2.15.59) )) ||
10588                 skip "OSTs < 2.15.59 doesn't have enable_health_write"
10589
10590         local orig_value="$(do_facet ost1 $LCTL get_param -n enable_health_write)"
10591
10592         stack_trap "do_facet ost1 $LCTL set_param enable_health_write $orig_value"
10593
10594         # Test with health write off
10595         do_facet ost1 $LCTL set_param enable_health_write off ||
10596                 error "can't set enable_health_write off"
10597         do_facet ost1 $LCTL get_param enable_health_write ||
10598                 error "can't get enable_health_write"
10599
10600         [[ "$(do_facet ost1 $LCTL get_param health_check)" =~ "healthy" ]] ||
10601                 error "not healthy (1)"
10602
10603         # Test with health write on
10604         do_facet ost1 $LCTL set_param enable_health_write on ||
10605                 error "can't set enable_health_write on"
10606         do_facet ost1 $LCTL get_param enable_health_write ||
10607                 error "can't get enable_health_write"
10608
10609         [[ "$(do_facet ost1 $LCTL get_param health_check)" =~ "healthy" ]] ||
10610                 error "not healthy (2)"
10611 }
10612 run_test 70a "verify health_check, health_write don't explode (on OST)"
10613
10614 test_71() {
10615         test_mkdir $DIR/$tdir
10616         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
10617         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
10618 }
10619 run_test 71 "Running dbench on lustre (don't segment fault) ===="
10620
10621 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
10622         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10623         [ "$RUNAS_ID" = "$UID" ] &&
10624                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10625         # Check that testing environment is properly set up. Skip if not
10626         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
10627                 skip_env "User $RUNAS_ID does not exist - skipping"
10628
10629         touch $DIR/$tfile
10630         chmod 777 $DIR/$tfile
10631         chmod ug+s $DIR/$tfile
10632         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
10633                 error "$RUNAS dd $DIR/$tfile failed"
10634         # See if we are still setuid/sgid
10635         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10636                 error "S/gid is not dropped on write"
10637         # Now test that MDS is updated too
10638         cancel_lru_locks mdc
10639         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10640                 error "S/gid is not dropped on MDS"
10641         rm -f $DIR/$tfile
10642 }
10643 run_test 72a "Test that remove suid works properly (bug5695) ===="
10644
10645 test_72b() { # bug 24226 -- keep mode setting when size is not changing
10646         local perm
10647
10648         [ "$RUNAS_ID" = "$UID" ] &&
10649                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10650         [ "$RUNAS_ID" -eq 0 ] &&
10651                 skip_env "RUNAS_ID = 0 -- skipping"
10652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10653         # Check that testing environment is properly set up. Skip if not
10654         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
10655                 skip_env "User $RUNAS_ID does not exist - skipping"
10656
10657         touch $DIR/${tfile}-f{g,u}
10658         test_mkdir $DIR/${tfile}-dg
10659         test_mkdir $DIR/${tfile}-du
10660         chmod 770 $DIR/${tfile}-{f,d}{g,u}
10661         chmod g+s $DIR/${tfile}-{f,d}g
10662         chmod u+s $DIR/${tfile}-{f,d}u
10663         for perm in 777 2777 4777; do
10664                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
10665                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
10666                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
10667                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
10668         done
10669         true
10670 }
10671 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
10672
10673 # bug 3462 - multiple simultaneous MDC requests
10674 test_73() {
10675         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10676
10677         test_mkdir $DIR/d73-1
10678         test_mkdir $DIR/d73-2
10679         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
10680         pid1=$!
10681
10682         lctl set_param fail_loc=0x80000129
10683         $MULTIOP $DIR/d73-1/f73-2 Oc &
10684         sleep 1
10685         lctl set_param fail_loc=0
10686
10687         $MULTIOP $DIR/d73-2/f73-3 Oc &
10688         pid3=$!
10689
10690         kill -USR1 $pid1
10691         wait $pid1 || return 1
10692
10693         sleep 25
10694
10695         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
10696         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
10697         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
10698
10699         rm -rf $DIR/d73-*
10700 }
10701 run_test 73 "multiple MDC requests (should not deadlock)"
10702
10703 test_74a() { # bug 6149, 6184
10704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10705
10706         touch $DIR/f74a
10707         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10708         #
10709         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10710         # will spin in a tight reconnection loop
10711         $LCTL set_param fail_loc=0x8000030e
10712         # get any lock that won't be difficult - lookup works.
10713         ls $DIR/f74a
10714         $LCTL set_param fail_loc=0
10715         rm -f $DIR/f74a
10716         true
10717 }
10718 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
10719
10720 test_74b() { # bug 13310
10721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10722
10723         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10724         #
10725         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10726         # will spin in a tight reconnection loop
10727         $LCTL set_param fail_loc=0x8000030e
10728         # get a "difficult" lock
10729         touch $DIR/f74b
10730         $LCTL set_param fail_loc=0
10731         rm -f $DIR/f74b
10732         true
10733 }
10734 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
10735
10736 test_74c() {
10737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10738
10739         #define OBD_FAIL_LDLM_NEW_LOCK
10740         $LCTL set_param fail_loc=0x319
10741         touch $DIR/$tfile && error "touch successful"
10742         $LCTL set_param fail_loc=0
10743         true
10744 }
10745 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
10746
10747 slab_lic=/sys/kernel/slab/lustre_inode_cache
10748 num_objects() {
10749         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
10750         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
10751                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
10752 }
10753
10754 test_76a() { # Now for b=20433, added originally in b=1443
10755         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10756
10757         cancel_lru_locks osc
10758         # there may be some slab objects cached per core
10759         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10760         local before=$(num_objects)
10761         local count=$((512 * cpus))
10762         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10763         local margin=$((count / 10))
10764         if [[ -f $slab_lic/aliases ]]; then
10765                 local aliases=$(cat $slab_lic/aliases)
10766                 (( aliases > 0 )) && margin=$((margin * aliases))
10767         fi
10768
10769         echo "before slab objects: $before"
10770         for i in $(seq $count); do
10771                 touch $DIR/$tfile
10772                 rm -f $DIR/$tfile
10773         done
10774         cancel_lru_locks osc
10775         local after=$(num_objects)
10776         echo "created: $count, after slab objects: $after"
10777         # shared slab counts are not very accurate, allow significant margin
10778         # the main goal is that the cache growth is not permanently > $count
10779         while (( after > before + margin )); do
10780                 sleep 1
10781                 after=$(num_objects)
10782                 wait=$((wait + 1))
10783                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10784                 if (( wait > 60 )); then
10785                         error "inode slab grew from $before+$margin to $after"
10786                 fi
10787         done
10788 }
10789 run_test 76a "confirm clients recycle inodes properly ===="
10790
10791 test_76b() {
10792         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10793         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10794
10795         local count=512
10796         local before=$(num_objects)
10797
10798         for i in $(seq $count); do
10799                 mkdir $DIR/$tdir
10800                 rmdir $DIR/$tdir
10801         done
10802
10803         local after=$(num_objects)
10804         local wait=0
10805
10806         while (( after > before )); do
10807                 sleep 1
10808                 after=$(num_objects)
10809                 wait=$((wait + 1))
10810                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10811                 if (( wait > 60 )); then
10812                         error "inode slab grew from $before to $after"
10813                 fi
10814         done
10815
10816         echo "slab objects before: $before, after: $after"
10817 }
10818 run_test 76b "confirm clients recycle directory inodes properly ===="
10819
10820 export ORIG_CSUM=""
10821 set_checksums()
10822 {
10823         # Note: in sptlrpc modes which enable its own bulk checksum, the
10824         # original crc32_le bulk checksum will be automatically disabled,
10825         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10826         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10827         # In this case set_checksums() will not be no-op, because sptlrpc
10828         # bulk checksum will be enabled all through the test.
10829
10830         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10831         lctl set_param -n osc.*.checksums $1
10832         return 0
10833 }
10834
10835 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10836                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10837 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10838                              tr -d [] | head -n1)}
10839 set_checksum_type()
10840 {
10841         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10842         rc=$?
10843         log "set checksum type to $1, rc = $rc"
10844         return $rc
10845 }
10846
10847 get_osc_checksum_type()
10848 {
10849         # arugment 1: OST name, like OST0000
10850         ost=$1
10851         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10852                         sed 's/.*\[\(.*\)\].*/\1/g')
10853         rc=$?
10854         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10855         echo $checksum_type
10856 }
10857
10858 F77_TMP=$TMP/f77-temp
10859 F77SZ=8
10860 setup_f77() {
10861         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10862                 error "error writing to $F77_TMP"
10863 }
10864
10865 test_77a() { # bug 10889
10866         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10867         $GSS && skip_env "could not run with gss"
10868
10869         [ ! -f $F77_TMP ] && setup_f77
10870         set_checksums 1
10871         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10872         set_checksums 0
10873         rm -f $DIR/$tfile
10874 }
10875 run_test 77a "normal checksum read/write operation"
10876
10877 test_77b() { # bug 10889
10878         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10879         $GSS && skip_env "could not run with gss"
10880
10881         [ ! -f $F77_TMP ] && setup_f77
10882         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10883         $LCTL set_param fail_loc=0x80000409
10884         set_checksums 1
10885
10886         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10887                 error "dd error: $?"
10888         $LCTL set_param fail_loc=0
10889
10890         for algo in $CKSUM_TYPES; do
10891                 cancel_lru_locks osc
10892                 set_checksum_type $algo
10893                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10894                 $LCTL set_param fail_loc=0x80000408
10895                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10896                 $LCTL set_param fail_loc=0
10897         done
10898         set_checksums 0
10899         set_checksum_type $ORIG_CSUM_TYPE
10900         rm -f $DIR/$tfile
10901 }
10902 run_test 77b "checksum error on client write, read"
10903
10904 cleanup_77c() {
10905         trap 0
10906         set_checksums 0
10907         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10908         $check_ost &&
10909                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10910         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10911         $check_ost && [ -n "$ost_file_prefix" ] &&
10912                 do_facet ost1 rm -f ${ost_file_prefix}\*
10913 }
10914
10915 test_77c() {
10916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10917         $GSS && skip_env "could not run with gss"
10918         remote_ost_nodsh && skip "remote OST with nodsh"
10919
10920         local bad1
10921         local osc_file_prefix
10922         local osc_file
10923         local check_ost=false
10924         local ost_file_prefix
10925         local ost_file
10926         local orig_cksum
10927         local dump_cksum
10928         local fid
10929
10930         # ensure corruption will occur on first OSS/OST
10931         $LFS setstripe -i 0 $DIR/$tfile
10932
10933         [ ! -f $F77_TMP ] && setup_f77
10934         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10935                 error "dd write error: $?"
10936         fid=$($LFS path2fid $DIR/$tfile)
10937
10938         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10939         then
10940                 check_ost=true
10941                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10942                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10943         else
10944                 echo "OSS do not support bulk pages dump upon error"
10945         fi
10946
10947         osc_file_prefix=$($LCTL get_param -n debug_path)
10948         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10949
10950         trap cleanup_77c EXIT
10951
10952         set_checksums 1
10953         # enable bulk pages dump upon error on Client
10954         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10955         # enable bulk pages dump upon error on OSS
10956         $check_ost &&
10957                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10958
10959         # flush Client cache to allow next read to reach OSS
10960         cancel_lru_locks osc
10961
10962         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10963         $LCTL set_param fail_loc=0x80000408
10964         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10965         $LCTL set_param fail_loc=0
10966
10967         rm -f $DIR/$tfile
10968
10969         # check cksum dump on Client
10970         osc_file=$(ls ${osc_file_prefix}*)
10971         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10972         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10973         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10974         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10975         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10976                      cksum)
10977         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10978         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10979                 error "dump content does not match on Client"
10980
10981         $check_ost || skip "No need to check cksum dump on OSS"
10982
10983         # check cksum dump on OSS
10984         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10985         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10986         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10987         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10988         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10989                 error "dump content does not match on OSS"
10990
10991         cleanup_77c
10992 }
10993 run_test 77c "checksum error on client read with debug"
10994
10995 test_77d() { # bug 10889
10996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10997         $GSS && skip_env "could not run with gss"
10998
10999         stack_trap "rm -f $DIR/$tfile"
11000         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
11001         $LCTL set_param fail_loc=0x80000409
11002         set_checksums 1
11003         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
11004                 error "direct write: rc=$?"
11005         $LCTL set_param fail_loc=0
11006         set_checksums 0
11007
11008         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
11009         $LCTL set_param fail_loc=0x80000408
11010         set_checksums 1
11011         cancel_lru_locks osc
11012         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
11013                 error "direct read: rc=$?"
11014         $LCTL set_param fail_loc=0
11015         set_checksums 0
11016 }
11017 run_test 77d "checksum error on OST direct write, read"
11018
11019 test_77f() { # bug 10889
11020         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11021         $GSS && skip_env "could not run with gss"
11022
11023         set_checksums 1
11024         stack_trap "rm -f $DIR/$tfile"
11025         for algo in $CKSUM_TYPES; do
11026                 cancel_lru_locks osc
11027                 set_checksum_type $algo
11028                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
11029                 $LCTL set_param fail_loc=0x409
11030                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
11031                         error "direct write succeeded"
11032                 $LCTL set_param fail_loc=0
11033         done
11034         set_checksum_type $ORIG_CSUM_TYPE
11035         set_checksums 0
11036 }
11037 run_test 77f "repeat checksum error on write (expect error)"
11038
11039 test_77g() { # bug 10889
11040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11041         $GSS && skip_env "could not run with gss"
11042         remote_ost_nodsh && skip "remote OST with nodsh"
11043
11044         [ ! -f $F77_TMP ] && setup_f77
11045
11046         local file=$DIR/$tfile
11047         stack_trap "rm -f $file" EXIT
11048
11049         $LFS setstripe -c 1 -i 0 $file
11050         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
11051         do_facet ost1 lctl set_param fail_loc=0x8000021a
11052         set_checksums 1
11053         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
11054                 error "write error: rc=$?"
11055         do_facet ost1 lctl set_param fail_loc=0
11056         set_checksums 0
11057
11058         cancel_lru_locks osc
11059         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
11060         do_facet ost1 lctl set_param fail_loc=0x8000021b
11061         set_checksums 1
11062         cmp $F77_TMP $file || error "file compare failed"
11063         do_facet ost1 lctl set_param fail_loc=0
11064         set_checksums 0
11065 }
11066 run_test 77g "checksum error on OST write, read"
11067
11068 test_77k() { # LU-10906
11069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11070         $GSS && skip_env "could not run with gss"
11071
11072         local cksum_param="osc.$FSNAME*.checksums"
11073         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
11074         local checksum
11075         local i
11076
11077         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
11078         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
11079         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
11080
11081         for i in 0 1; do
11082                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
11083                         error "failed to set checksum=$i on MGS"
11084                 wait_update $HOSTNAME "$get_checksum" $i
11085                 #remount
11086                 echo "remount client, checksum should be $i"
11087                 remount_client $MOUNT || error "failed to remount client"
11088                 checksum=$(eval $get_checksum)
11089                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
11090         done
11091         # remove persistent param to avoid races with checksum mountopt below
11092         do_facet mgs $LCTL set_param -P -d $cksum_param ||
11093                 error "failed to delete checksum on MGS"
11094
11095         for opt in "checksum" "nochecksum"; do
11096                 #remount with mount option
11097                 echo "remount client with option $opt, checksum should be $i"
11098                 umount_client $MOUNT || error "failed to umount client"
11099                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
11100                         error "failed to mount client with option '$opt'"
11101                 checksum=$(eval $get_checksum)
11102                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
11103                 i=$((i - 1))
11104         done
11105
11106         remount_client $MOUNT || error "failed to remount client"
11107 }
11108 run_test 77k "enable/disable checksum correctly"
11109
11110 test_77l() {
11111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11112         $GSS && skip_env "could not run with gss"
11113
11114         set_checksums 1
11115         stack_trap "set_checksums $ORIG_CSUM" EXIT
11116         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
11117         local old
11118
11119         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
11120         $LCTL set_param osc.*.idle_timeout=10
11121         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
11122
11123         set_checksum_type invalid && error "unexpected success of invalid checksum type"
11124
11125         $LFS setstripe -c 1 -i 0 $DIR/$tfile
11126         for algo in $CKSUM_TYPES; do
11127                 set_checksum_type $algo || error "fail to set checksum type $algo"
11128                 osc_algo=$(get_osc_checksum_type OST0000)
11129                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
11130
11131                 # no locks, no reqs to let the connection idle
11132                 cancel_lru_locks osc
11133                 lru_resize_disable osc
11134                 wait_osc_import_state client ost1 IDLE
11135
11136                 # ensure ost1 is connected
11137                 stat $DIR/$tfile >/dev/null || error "can't stat"
11138                 wait_osc_import_state client ost1 FULL
11139
11140                 osc_algo=$(get_osc_checksum_type OST0000)
11141                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
11142         done
11143         return 0
11144 }
11145 run_test 77l "preferred checksum type is remembered after reconnected"
11146
11147 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
11148 rm -f $F77_TMP
11149 unset F77_TMP
11150
11151 test_77m() {
11152         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
11153                 skip "Need at least version 2.14.52"
11154         local param=checksum_speed
11155
11156         $LCTL get_param $param || error "reading $param failed"
11157
11158         csum_speeds=$($LCTL get_param -n $param)
11159
11160         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
11161                 error "known checksum types are missing"
11162 }
11163 run_test 77m "Verify checksum_speed is correctly read"
11164
11165 check_filefrag_77n() {
11166         local nr_ext=0
11167         local starts=()
11168         local ends=()
11169
11170         while read extidx a b start end rest; do
11171                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
11172                         nr_ext=$(( $nr_ext + 1 ))
11173                         starts+=( ${start%..} )
11174                         ends+=( ${end%:} )
11175                 fi
11176         done < <( filefrag -sv $1 )
11177
11178         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
11179         return 1
11180 }
11181
11182 test_77n() {
11183         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
11184
11185         touch $DIR/$tfile
11186         $TRUNCATE $DIR/$tfile 0
11187         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
11188         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
11189         check_filefrag_77n $DIR/$tfile ||
11190                 skip "$tfile blocks not contiguous around hole"
11191
11192         set_checksums 1
11193         stack_trap "set_checksums $ORIG_CSUM" EXIT
11194         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
11195         stack_trap "rm -f $DIR/$tfile"
11196
11197         for algo in $CKSUM_TYPES; do
11198                 if [[ "$algo" =~ ^t10 ]]; then
11199                         set_checksum_type $algo ||
11200                                 error "fail to set checksum type $algo"
11201                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
11202                                 error "fail to read $tfile with $algo"
11203                 fi
11204         done
11205         rm -f $DIR/$tfile
11206         return 0
11207 }
11208 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
11209
11210 test_77o() {
11211         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
11212                 skip "Need MDS version at least 2.14.55"
11213         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
11214                 skip "Need OST version at least 2.14.55"
11215         local ofd=obdfilter
11216         local mdt=mdt
11217
11218         # print OST checksum_type
11219         echo "$ofd.$FSNAME-*.checksum_type:"
11220         do_nodes $(comma_list $(osts_nodes)) \
11221                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
11222
11223         # print MDT checksum_type
11224         echo "$mdt.$FSNAME-*.checksum_type:"
11225         do_nodes $(comma_list $(mdts_nodes)) \
11226                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
11227
11228         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
11229                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
11230
11231         (( $o_count == $OSTCOUNT )) ||
11232                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
11233
11234         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
11235                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
11236
11237         (( $m_count == $MDSCOUNT )) ||
11238                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
11239 }
11240 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
11241
11242 cleanup_test_78() {
11243         trap 0
11244         rm -f $DIR/$tfile
11245 }
11246
11247 test_78() { # bug 10901
11248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11249         remote_ost || skip_env "local OST"
11250
11251         NSEQ=5
11252         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
11253         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
11254         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
11255         echo "MemTotal: $MEMTOTAL"
11256
11257         # reserve 256MB of memory for the kernel and other running processes,
11258         # and then take 1/2 of the remaining memory for the read/write buffers.
11259         if [ $MEMTOTAL -gt 512 ] ;then
11260                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
11261         else
11262                 # for those poor memory-starved high-end clusters...
11263                 MEMTOTAL=$((MEMTOTAL / 2))
11264         fi
11265         echo "Mem to use for directio: $MEMTOTAL"
11266
11267         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
11268         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
11269         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
11270         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
11271                 head -n1)
11272         echo "Smallest OST: $SMALLESTOST"
11273         [[ $SMALLESTOST -lt 10240 ]] &&
11274                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
11275
11276         trap cleanup_test_78 EXIT
11277
11278         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
11279                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
11280
11281         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
11282         echo "File size: $F78SIZE"
11283         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
11284         for i in $(seq 1 $NSEQ); do
11285                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
11286                 echo directIO rdwr round $i of $NSEQ
11287                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
11288         done
11289
11290         cleanup_test_78
11291 }
11292 run_test 78 "handle large O_DIRECT writes correctly ============"
11293
11294 test_79() { # bug 12743
11295         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11296
11297         wait_delete_completed
11298
11299         BKTOTAL=$(calc_osc_kbytes kbytestotal)
11300         BKFREE=$(calc_osc_kbytes kbytesfree)
11301         BKAVAIL=$(calc_osc_kbytes kbytesavail)
11302
11303         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
11304         DFTOTAL=`echo $STRING | cut -d, -f1`
11305         DFUSED=`echo $STRING  | cut -d, -f2`
11306         DFAVAIL=`echo $STRING | cut -d, -f3`
11307         DFFREE=$(($DFTOTAL - $DFUSED))
11308
11309         ALLOWANCE=$((64 * $OSTCOUNT))
11310
11311         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
11312            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
11313                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
11314         fi
11315         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
11316            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
11317                 error "df free($DFFREE) mismatch OST free($BKFREE)"
11318         fi
11319         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
11320            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
11321                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
11322         fi
11323 }
11324 run_test 79 "df report consistency check ======================="
11325
11326 test_80() { # bug 10718
11327         remote_ost_nodsh && skip "remote OST with nodsh"
11328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11329
11330         # relax strong synchronous semantics for slow backends like ZFS
11331         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
11332                 local soc="obdfilter.*.sync_lock_cancel"
11333                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11334
11335                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
11336                 if [ -z "$save" ]; then
11337                         soc="obdfilter.*.sync_on_lock_cancel"
11338                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11339                 fi
11340
11341                 if [ "$save" != "never" ]; then
11342                         local hosts=$(comma_list $(osts_nodes))
11343
11344                         do_nodes $hosts $LCTL set_param $soc=never
11345                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
11346                 fi
11347         fi
11348
11349         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
11350         sync; sleep 1; sync
11351         local before=$(date +%s)
11352         cancel_lru_locks osc
11353         local after=$(date +%s)
11354         local diff=$((after - before))
11355         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
11356
11357         rm -f $DIR/$tfile
11358 }
11359 run_test 80 "Page eviction is equally fast at high offsets too"
11360
11361 test_81a() { # LU-456
11362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11363         remote_ost_nodsh && skip "remote OST with nodsh"
11364
11365         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11366         # MUST OR with the CFS_FAIL_ONCE (0x80000000)
11367         do_facet ost1 lctl set_param fail_loc=0x80000228
11368
11369         # write should trigger a retry and success
11370         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11371         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11372         RC=$?
11373         if [ $RC -ne 0 ] ; then
11374                 error "write should success, but failed for $RC"
11375         fi
11376 }
11377 run_test 81a "OST should retry write when get -ENOSPC ==============="
11378
11379 test_81b() { # LU-456
11380         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11381         remote_ost_nodsh && skip "remote OST with nodsh"
11382
11383         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11384         # Don't OR with the CFS_FAIL_ONCE (0x80000000)
11385         do_facet ost1 lctl set_param fail_loc=0x228
11386
11387         # write should retry several times and return -ENOSPC finally
11388         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11389         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11390         RC=$?
11391         ENOSPC=28
11392         if [ $RC -ne $ENOSPC ] ; then
11393                 error "dd should fail for -ENOSPC, but succeed."
11394         fi
11395 }
11396 run_test 81b "OST should return -ENOSPC when retry still fails ======="
11397
11398 test_99() {
11399         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
11400
11401         test_mkdir $DIR/$tdir.cvsroot
11402         chown $RUNAS_ID $DIR/$tdir.cvsroot
11403
11404         cd $TMP
11405         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
11406
11407         cd /etc/init.d
11408         # some versions of cvs import exit(1) when asked to import links or
11409         # files they can't read.  ignore those files.
11410         local toignore=$(find . -type l -printf '-I %f\n' -o \
11411                          ! -perm /4 -printf '-I %f\n')
11412         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
11413                 $tdir.reposname vtag rtag
11414
11415         cd $DIR
11416         test_mkdir $DIR/$tdir.reposname
11417         chown $RUNAS_ID $DIR/$tdir.reposname
11418         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
11419
11420         cd $DIR/$tdir.reposname
11421         $RUNAS touch foo99
11422         $RUNAS cvs add -m 'addmsg' foo99
11423         $RUNAS cvs update
11424         $RUNAS cvs commit -m 'nomsg' foo99
11425         rm -fr $DIR/$tdir.cvsroot
11426 }
11427 run_test 99 "cvs strange file/directory operations"
11428
11429 test_100() {
11430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11431         [[ "$NETTYPE" =~ tcp ]] ||
11432                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
11433         [[ -n "$(type -p ss)" ]] || skip_env "ss not available"
11434         remote_ost_nodsh && skip "remote OST with nodsh"
11435         remote_mds_nodsh && skip "remote MDS with nodsh"
11436         remote_servers || skip "useless for local single node setup"
11437
11438         ss -tna | ( rc=1; while read STATE SND RCV LOCAL REMOTE STAT; do
11439                 [[ "${REMOTE/*:/}" == "$ACCEPTOR_PORT" ]] || continue
11440
11441                 rc=0
11442                 if (( ${LOCAL/*:/} >= 1024 )); then
11443                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
11444                         ss -tna
11445                         error "local: ${LOCAL/*:/} > 1024 remote: ${REMOTE/*:/}"
11446                 fi
11447         done
11448         (( $rc == 0 )) || error "privileged port not found" )
11449 }
11450 run_test 100 "check local port using privileged port"
11451
11452 function get_named_value()
11453 {
11454     local tag=$1
11455
11456     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
11457 }
11458
11459 test_101a() {
11460         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11461
11462         local s
11463         local discard
11464         local nreads=10000
11465         local cache_limit=32
11466
11467         $LCTL set_param -n osc.*-osc*.rpc_stats=0
11468         $LCTL set_param -n llite.*.read_ahead_stats=0
11469         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
11470                               awk '/^max_cached_mb/ { print $2 }')
11471         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
11472         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
11473
11474         #
11475         # randomly read 10000 of 64K chunks from file 3x 32MB in size
11476         #
11477         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
11478         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
11479
11480         discard=0
11481         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
11482                    get_named_value 'read.but.discarded'); do
11483                         discard=$(($discard + $s))
11484         done
11485
11486         $LCTL get_param osc.*-osc*.rpc_stats
11487         $LCTL get_param llite.*.read_ahead_stats
11488
11489         # Discard is generally zero, but sometimes a few random reads line up
11490         # and trigger larger readahead, which is wasted & leads to discards.
11491         if [[ $(($discard)) -gt $nreads ]]; then
11492                 error "too many ($discard) discarded pages"
11493         fi
11494         rm -f $DIR/$tfile || true
11495 }
11496 run_test 101a "check read-ahead for random reads"
11497
11498 setup_test101bc() {
11499         test_mkdir $DIR/$tdir
11500         local ssize=$1
11501         local FILE_LENGTH=$2
11502         STRIPE_OFFSET=0
11503
11504         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
11505
11506         local list=$(comma_list $(osts_nodes))
11507         set_osd_param $list '' read_cache_enable 0
11508         set_osd_param $list '' writethrough_cache_enable 0
11509
11510         trap cleanup_test101bc EXIT
11511         # prepare the read-ahead file
11512         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
11513
11514         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
11515                                 count=$FILE_SIZE_MB 2> /dev/null
11516
11517 }
11518
11519 cleanup_test101bc() {
11520         trap 0
11521         rm -rf $DIR/$tdir
11522         rm -f $DIR/$tfile
11523
11524         local list=$(comma_list $(osts_nodes))
11525         set_osd_param $list '' read_cache_enable 1
11526         set_osd_param $list '' writethrough_cache_enable 1
11527 }
11528
11529 ra_check_101() {
11530         local read_size=$1
11531         local stripe_size=$2
11532         local stride_length=$((stripe_size / read_size))
11533         local stride_width=$((stride_length * OSTCOUNT))
11534         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
11535                                 (stride_width - stride_length) ))
11536         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
11537                   get_named_value 'read.but.discarded' | calc_sum)
11538
11539         if [[ $discard -gt $discard_limit ]]; then
11540                 $LCTL get_param llite.*.read_ahead_stats
11541                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
11542         else
11543                 echo "Read-ahead success for size ${read_size}"
11544         fi
11545 }
11546
11547 test_101b() {
11548         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11549         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11550
11551         local STRIPE_SIZE=1048576
11552         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
11553
11554         if [ $SLOW == "yes" ]; then
11555                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
11556         else
11557                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
11558         fi
11559
11560         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
11561
11562         # prepare the read-ahead file
11563         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11564         cancel_lru_locks osc
11565         for BIDX in 2 4 8 16 32 64 128 256
11566         do
11567                 local BSIZE=$((BIDX*4096))
11568                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
11569                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
11570                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
11571                 $LCTL set_param -n llite.*.read_ahead_stats=0
11572                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
11573                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
11574                 cancel_lru_locks osc
11575                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
11576         done
11577         cleanup_test101bc
11578         true
11579 }
11580 run_test 101b "check stride-io mode read-ahead ================="
11581
11582 test_101c() {
11583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11584
11585         local STRIPE_SIZE=1048576
11586         local FILE_LENGTH=$((STRIPE_SIZE*100))
11587         local nreads=10000
11588         local rsize=65536
11589         local osc_rpc_stats
11590
11591         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11592
11593         cancel_lru_locks osc
11594         $LCTL set_param osc.*.rpc_stats=0
11595         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
11596         $LCTL get_param osc.*.rpc_stats
11597         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
11598                 local stats=$($LCTL get_param -n $osc_rpc_stats)
11599                 local lines=$(echo "$stats" | awk 'END {print NR;}')
11600                 local size
11601
11602                 if [ $lines -le 20 ]; then
11603                         echo "continue debug"
11604                         continue
11605                 fi
11606                 for size in 1 2 4 8; do
11607                         local rpc=$(echo "$stats" |
11608                                     awk '($1 == "'$size':") {print $2; exit; }')
11609                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
11610                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
11611                 done
11612                 echo "$osc_rpc_stats check passed!"
11613         done
11614         cleanup_test101bc
11615         true
11616 }
11617 run_test 101c "check stripe_size aligned read-ahead"
11618
11619 test_101d() {
11620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11621
11622         local file=$DIR/$tfile
11623         local sz_MB=${FILESIZE_101d:-80}
11624         local ra_MB=${READAHEAD_MB:-40}
11625
11626         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
11627         [ $free_MB -lt $sz_MB ] &&
11628                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
11629
11630         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
11631         $LFS setstripe -c -1 $file || error "setstripe failed"
11632
11633         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
11634         echo Cancel LRU locks on lustre client to flush the client cache
11635         cancel_lru_locks osc
11636
11637         echo Disable read-ahead
11638         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11639         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11640         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
11641         $LCTL get_param -n llite.*.max_read_ahead_mb
11642
11643         echo "Reading the test file $file with read-ahead disabled"
11644         local sz_KB=$((sz_MB * 1024 / 4))
11645         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
11646         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
11647         # 83886080 bytes (84 MB, 80 MiB) copied, 16 s, 5.2 MB/s
11648         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11649                       sed -e '/records/d' -e 's/.* \([0-9][0-9\.]*\) *s.*/\1/')
11650
11651         echo "Cancel LRU locks on lustre client to flush the client cache"
11652         cancel_lru_locks osc
11653         echo Enable read-ahead with ${ra_MB}MB
11654         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
11655
11656         echo "Reading the test file $file with read-ahead enabled"
11657         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11658                       sed -e '/records/d' -e 's/.* \([0-9][0-9\.]*\) *s.*/\1/')
11659
11660         echo "read-ahead disabled time read '$raOFF'"
11661         echo "read-ahead enabled time read '$raON'"
11662
11663         rm -f $file
11664         wait_delete_completed
11665
11666         # use awk for this check instead of bash because it handles decimals
11667         awk "{ exit !($raOFF < 0.5 || $raOFF > $raON) }" <<<"ignore_me" ||
11668                 error "readahead ${raON}s > no-readahead ${raOFF}s (${sz_MB}M)"
11669 }
11670 run_test 101d "file read with and without read-ahead enabled"
11671
11672 test_101e() {
11673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11674
11675         local file=$DIR/$tfile
11676         local size_KB=500  #KB
11677         local count=100
11678         local bsize=1024
11679
11680         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
11681         local need_KB=$((count * size_KB))
11682         [[ $free_KB -le $need_KB ]] &&
11683                 skip_env "Need free space $need_KB, have $free_KB"
11684
11685         echo "Creating $count ${size_KB}K test files"
11686         for ((i = 0; i < $count; i++)); do
11687                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
11688         done
11689
11690         echo "Cancel LRU locks on lustre client to flush the client cache"
11691         cancel_lru_locks $OSC
11692
11693         echo "Reset readahead stats"
11694         $LCTL set_param -n llite.*.read_ahead_stats=0
11695
11696         for ((i = 0; i < $count; i++)); do
11697                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
11698         done
11699
11700         $LCTL get_param llite.*.max_cached_mb
11701         $LCTL get_param llite.*.read_ahead_stats
11702         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11703                      get_named_value 'misses' | calc_sum)
11704
11705         for ((i = 0; i < $count; i++)); do
11706                 rm -rf $file.$i 2>/dev/null
11707         done
11708
11709         #10000 means 20% reads are missing in readahead
11710         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
11711 }
11712 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
11713
11714 test_101f() {
11715         which iozone || skip_env "no iozone installed"
11716
11717         local old_debug=$($LCTL get_param debug)
11718         old_debug=${old_debug#*=}
11719         $LCTL set_param debug="reada mmap"
11720
11721         # create a test file
11722         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
11723
11724         echo Cancel LRU locks on lustre client to flush the client cache
11725         cancel_lru_locks osc
11726
11727         echo Reset readahead stats
11728         $LCTL set_param -n llite.*.read_ahead_stats=0
11729
11730         echo mmap read the file with small block size
11731         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
11732                 > /dev/null 2>&1
11733
11734         echo checking missing pages
11735         $LCTL get_param llite.*.read_ahead_stats
11736         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11737                         get_named_value 'misses' | calc_sum)
11738
11739         $LCTL set_param debug="$old_debug"
11740         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
11741         rm -f $DIR/$tfile
11742 }
11743 run_test 101f "check mmap read performance"
11744
11745 test_101g_brw_size_test() {
11746         local mb=$1
11747         local pages=$((mb * 1048576 / PAGE_SIZE))
11748         local file=$DIR/$tfile
11749
11750         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11751                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11752         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11753                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11754                         return 2
11755         done
11756
11757         stack_trap "rm -f $file" EXIT
11758         $LCTL set_param -n osc.*.rpc_stats=0
11759
11760         # 10 RPCs should be enough for the test
11761         local count=10
11762         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11763                 { error "dd write ${mb} MB blocks failed"; return 3; }
11764         cancel_lru_locks osc
11765         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11766                 { error "dd write ${mb} MB blocks failed"; return 4; }
11767
11768         # calculate number of full-sized read and write RPCs
11769         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11770                 sed -n '/pages per rpc/,/^$/p' |
11771                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11772                 END { print reads,writes }'))
11773         # allow one extra full-sized read RPC for async readahead
11774         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11775                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11776         [[ ${rpcs[1]} == $count ]] ||
11777                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11778 }
11779
11780 test_101g() {
11781         remote_ost_nodsh && skip "remote OST with nodsh"
11782
11783         local rpcs
11784         local osts=$(get_facets OST)
11785         local list=$(comma_list $(osts_nodes))
11786         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11787         local brw_size="obdfilter.*.brw_size"
11788
11789         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11790
11791         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11792
11793         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11794                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11795                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11796            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11797                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11798                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11799
11800                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11801                         suffix="M"
11802
11803                 if [[ $orig_mb -lt 16 ]]; then
11804                         save_lustre_params $osts "$brw_size" > $p
11805                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11806                                 error "set 16MB RPC size failed"
11807
11808                         echo "remount client to enable new RPC size"
11809                         remount_client $MOUNT || error "remount_client failed"
11810                 fi
11811
11812                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11813                 # should be able to set brw_size=12, but no rpc_stats for that
11814                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11815         fi
11816
11817         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11818
11819         if [[ $orig_mb -lt 16 ]]; then
11820                 restore_lustre_params < $p
11821                 remount_client $MOUNT || error "remount_client restore failed"
11822         fi
11823
11824         rm -f $p $DIR/$tfile
11825 }
11826 run_test 101g "Big bulk(4/16 MiB) readahead"
11827
11828 test_101h() {
11829         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11830
11831         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11832                 error "dd 70M file failed"
11833         echo Cancel LRU locks on lustre client to flush the client cache
11834         cancel_lru_locks osc
11835
11836         echo "Reset readahead stats"
11837         $LCTL set_param -n llite.*.read_ahead_stats 0
11838
11839         echo "Read 10M of data but cross 64M bundary"
11840         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11841         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11842                      get_named_value 'misses' | calc_sum)
11843         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11844         rm -f $p $DIR/$tfile
11845 }
11846 run_test 101h "Readahead should cover current read window"
11847
11848 test_101i() {
11849         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11850                 error "dd 10M file failed"
11851
11852         local max_per_file_mb=$($LCTL get_param -n \
11853                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11854         cancel_lru_locks osc
11855         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11856         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11857                 error "set max_read_ahead_per_file_mb to 1 failed"
11858
11859         echo "Reset readahead stats"
11860         $LCTL set_param llite.*.read_ahead_stats=0
11861
11862         dd if=$DIR/$tfile of=/dev/null bs=2M
11863
11864         $LCTL get_param llite.*.read_ahead_stats
11865         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11866                      awk '/misses/ { print $2 }')
11867         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11868         rm -f $DIR/$tfile
11869 }
11870 run_test 101i "allow current readahead to exceed reservation"
11871
11872 test_101j() {
11873         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11874                 error "setstripe $DIR/$tfile failed"
11875         local file_size=$((1048576 * 16))
11876         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11877         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11878
11879         echo Disable read-ahead
11880         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11881
11882         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11883         for blk in $PAGE_SIZE 1048576 $file_size; do
11884                 cancel_lru_locks osc
11885                 echo "Reset readahead stats"
11886                 $LCTL set_param -n llite.*.read_ahead_stats=0
11887                 local count=$(($file_size / $blk))
11888                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11889                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11890                              get_named_value 'failed.to.fast.read' | calc_sum)
11891                 $LCTL get_param -n llite.*.read_ahead_stats
11892                 [ $miss -eq $count ] || error "expected $count got $miss"
11893         done
11894
11895         rm -f $p $DIR/$tfile
11896 }
11897 run_test 101j "A complete read block should be submitted when no RA"
11898
11899 test_readahead_base() {
11900         local file=$DIR/$tfile
11901         local size=$1
11902         local iosz
11903         local ramax
11904         local ranum
11905
11906         $LCTL set_param -n llite.*.read_ahead_stats=0
11907         # The first page is not accounted into readahead
11908         ramax=$(((size + PAGE_SIZE - 1) / PAGE_SIZE - 1))
11909         iosz=$(((size + 1048575) / 1048576 * 1048576))
11910         echo "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11911
11912         $LCTL mark  "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11913         fallocate -l $size $file || error "failed to fallocate $file"
11914         cancel_lru_locks osc
11915         $MULTIOP $file or${iosz}c || error "failed to read $file"
11916         $LCTL get_param -n llite.*.read_ahead_stats
11917         ranum=$($LCTL get_param -n llite.*.read_ahead_stats |
11918                 awk '/readahead.pages/ { print $7 }' | calc_sum)
11919         (( $ranum <= $ramax )) ||
11920                 error "read-ahead pages is $ranum more than $ramax"
11921         rm -rf $file || error "failed to remove $file"
11922 }
11923
11924 test_101m()
11925 {
11926         local file=$DIR/$tfile
11927         local ramax
11928         local ranum
11929         local size
11930         local iosz
11931
11932         check_set_fallocate_or_skip
11933         stack_trap "rm -f $file" EXIT
11934
11935         test_readahead_base 4096
11936
11937         # file size: 16K = 16384
11938         test_readahead_base 16384
11939         test_readahead_base 16385
11940         test_readahead_base 16383
11941
11942         # file size: 1M + 1 = 1048576 + 1
11943         test_readahead_base 1048577
11944         # file size: 1M + 16K
11945         test_readahead_base $((1048576 + 16384))
11946
11947         # file size: stripe_size * (stripe_count - 1) + 16K
11948         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11949         test_readahead_base $((1048576 * (OSTCOUNT - 1) + 16384))
11950         # file size: stripe_size * stripe_count + 16K
11951         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11952         test_readahead_base $((1048576 * OSTCOUNT + 16384))
11953         # file size: 2 * stripe_size * stripe_count + 16K
11954         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11955         test_readahead_base $((2 * 1048576 * OSTCOUNT + 16384))
11956 }
11957 run_test 101m "read ahead for small file and last stripe of the file"
11958
11959 setup_test102() {
11960         test_mkdir $DIR/$tdir
11961         chown $RUNAS_ID $DIR/$tdir
11962         STRIPE_SIZE=65536
11963         STRIPE_OFFSET=1
11964         STRIPE_COUNT=$OSTCOUNT
11965         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11966
11967         trap cleanup_test102 EXIT
11968         cd $DIR
11969         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11970         cd $DIR/$tdir
11971         for num in 1 2 3 4; do
11972                 for count in $(seq 1 $STRIPE_COUNT); do
11973                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11974                                 local size=`expr $STRIPE_SIZE \* $num`
11975                                 local file=file"$num-$idx-$count"
11976                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11977                         done
11978                 done
11979         done
11980
11981         cd $DIR
11982         $1 tar cf $TMP/f102.tar $tdir --xattrs
11983 }
11984
11985 cleanup_test102() {
11986         trap 0
11987         rm -f $TMP/f102.tar
11988         rm -rf $DIR/d0.sanity/d102
11989 }
11990
11991 test_102a() {
11992         [ "$UID" != 0 ] && skip "must run as root"
11993         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11994                 skip_env "must have user_xattr"
11995
11996         [ -z "$(which setfattr 2>/dev/null)" ] &&
11997                 skip_env "could not find setfattr"
11998
11999         local testfile=$DIR/$tfile
12000
12001         touch $testfile
12002         echo "set/get xattr..."
12003         setfattr -n trusted.name1 -v value1 $testfile ||
12004                 error "setfattr -n trusted.name1=value1 $testfile failed"
12005         getfattr -n trusted.name1 $testfile 2> /dev/null |
12006           grep "trusted.name1=.value1" ||
12007                 error "$testfile missing trusted.name1=value1"
12008
12009         setfattr -n user.author1 -v author1 $testfile ||
12010                 error "setfattr -n user.author1=author1 $testfile failed"
12011         getfattr -n user.author1 $testfile 2> /dev/null |
12012           grep "user.author1=.author1" ||
12013                 error "$testfile missing trusted.author1=author1"
12014
12015         echo "listxattr..."
12016         setfattr -n trusted.name2 -v value2 $testfile ||
12017                 error "$testfile unable to set trusted.name2"
12018         setfattr -n trusted.name3 -v value3 $testfile ||
12019                 error "$testfile unable to set trusted.name3"
12020         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
12021             grep "trusted.name" | wc -l) -eq 3 ] ||
12022                 error "$testfile missing 3 trusted.name xattrs"
12023
12024         setfattr -n user.author2 -v author2 $testfile ||
12025                 error "$testfile unable to set user.author2"
12026         setfattr -n user.author3 -v author3 $testfile ||
12027                 error "$testfile unable to set user.author3"
12028         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
12029             grep "user.author" | wc -l) -eq 3 ] ||
12030                 error "$testfile missing 3 user.author xattrs"
12031
12032         echo "remove xattr..."
12033         setfattr -x trusted.name1 $testfile ||
12034                 error "$testfile error deleting trusted.name1"
12035         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
12036                 error "$testfile did not delete trusted.name1 xattr"
12037
12038         setfattr -x user.author1 $testfile ||
12039                 error "$testfile error deleting user.author1"
12040         echo "set lustre special xattr ..."
12041         $LFS setstripe -c1 $testfile
12042         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
12043                 awk -F "=" '/trusted.lov/ { print $2 }' )
12044         setfattr -n "trusted.lov" -v $lovea $testfile ||
12045                 error "$testfile doesn't ignore setting trusted.lov again"
12046         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
12047                 error "$testfile allow setting invalid trusted.lov"
12048         rm -f $testfile
12049 }
12050 run_test 102a "user xattr test =================================="
12051
12052 check_102b_layout() {
12053         local layout="$*"
12054         local testfile=$DIR/$tfile
12055
12056         echo "test layout '$layout'"
12057         $LFS setstripe $layout $testfile || error "setstripe failed"
12058         $LFS getstripe -y $testfile
12059
12060         echo "get/set/list trusted.lov xattr ..." # b=10930
12061         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
12062         [[ "$value" =~ "trusted.lov" ]] ||
12063                 error "can't get trusted.lov from $testfile"
12064         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
12065                 error "getstripe failed"
12066
12067         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
12068
12069         value=$(cut -d= -f2 <<<$value)
12070         # LU-13168: truncated xattr should fail if short lov_user_md header
12071         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
12072                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
12073         for len in $lens; do
12074                 echo "setfattr $len $testfile.2"
12075                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
12076                         [ $len -lt 66 ] && error "short xattr len=$len worked"
12077         done
12078         local stripe_size=$($LFS getstripe -S $testfile.2)
12079         local stripe_count=$($LFS getstripe -c $testfile.2)
12080         [[ $stripe_size -eq 65536 ]] ||
12081                 error "stripe size $stripe_size != 65536"
12082         [[ $stripe_count -eq $stripe_count_orig ]] ||
12083                 error "stripe count $stripe_count != $stripe_count_orig"
12084         rm $testfile $testfile.2
12085 }
12086
12087 test_102b() {
12088         [ -z "$(which setfattr 2>/dev/null)" ] &&
12089                 skip_env "could not find setfattr"
12090         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12091
12092         # check plain layout
12093         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
12094
12095         # and also check composite layout
12096         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
12097
12098 }
12099 run_test 102b "getfattr/setfattr for trusted.lov EAs"
12100
12101 test_102c() {
12102         [ -z "$(which setfattr 2>/dev/null)" ] &&
12103                 skip_env "could not find setfattr"
12104         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12105
12106         # b10930: get/set/list lustre.lov xattr
12107         echo "get/set/list lustre.lov xattr ..."
12108         test_mkdir $DIR/$tdir
12109         chown $RUNAS_ID $DIR/$tdir
12110         local testfile=$DIR/$tdir/$tfile
12111         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
12112                 error "setstripe failed"
12113         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
12114                 error "getstripe failed"
12115         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
12116         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
12117
12118         local testfile2=${testfile}2
12119         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
12120                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
12121
12122         $RUNAS $MCREATE $testfile2
12123         $RUNAS setfattr -n lustre.lov -v $value $testfile2
12124         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
12125         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
12126         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
12127         [ $stripe_count -eq $STRIPECOUNT ] ||
12128                 error "stripe count $stripe_count != $STRIPECOUNT"
12129 }
12130 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
12131
12132 compare_stripe_info1() {
12133         local stripe_index_all_zero=true
12134
12135         for num in 1 2 3 4; do
12136                 for count in $(seq 1 $STRIPE_COUNT); do
12137                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
12138                                 local size=$((STRIPE_SIZE * num))
12139                                 local file=file"$num-$offset-$count"
12140                                 stripe_size=$($LFS getstripe -S $PWD/$file)
12141                                 [[ $stripe_size -ne $size ]] &&
12142                                     error "$file: size $stripe_size != $size"
12143                                 stripe_count=$($LFS getstripe -c $PWD/$file)
12144                                 # allow fewer stripes to be created, ORI-601
12145                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
12146                                     error "$file: count $stripe_count != $count"
12147                                 stripe_index=$($LFS getstripe -i $PWD/$file)
12148                                 [[ $stripe_index -ne 0 ]] &&
12149                                         stripe_index_all_zero=false
12150                         done
12151                 done
12152         done
12153         $stripe_index_all_zero &&
12154                 error "all files are being extracted starting from OST index 0"
12155         return 0
12156 }
12157
12158 have_xattrs_include() {
12159         tar --help | grep -q xattrs-include &&
12160                 echo --xattrs-include="lustre.*"
12161 }
12162
12163 test_102d() {
12164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12165         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12166
12167         XINC=$(have_xattrs_include)
12168         setup_test102
12169         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
12170         cd $DIR/$tdir/$tdir
12171         compare_stripe_info1
12172 }
12173 run_test 102d "tar restore stripe info from tarfile,not keep osts"
12174
12175 test_102f() {
12176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12177         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12178
12179         XINC=$(have_xattrs_include)
12180         setup_test102
12181         test_mkdir $DIR/$tdir.restore
12182         cd $DIR
12183         tar cf - --xattrs $tdir | tar xf - \
12184                 -C $DIR/$tdir.restore --xattrs $XINC
12185         cd $DIR/$tdir.restore/$tdir
12186         compare_stripe_info1
12187 }
12188 run_test 102f "tar copy files, not keep osts"
12189
12190 grow_xattr() {
12191         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
12192                 skip "must have user_xattr"
12193         [ -z "$(which setfattr 2>/dev/null)" ] &&
12194                 skip_env "could not find setfattr"
12195         [ -z "$(which getfattr 2>/dev/null)" ] &&
12196                 skip_env "could not find getfattr"
12197
12198         local xsize=${1:-1024}  # in bytes
12199         local file=$DIR/$tfile
12200         local value="$(generate_string $xsize)"
12201         local xbig=trusted.big
12202         local toobig=$2
12203
12204         touch $file
12205         log "save $xbig on $file"
12206         if [ -z "$toobig" ]
12207         then
12208                 setfattr -n $xbig -v $value $file ||
12209                         error "saving $xbig on $file failed"
12210         else
12211                 setfattr -n $xbig -v $value $file &&
12212                         error "saving $xbig on $file succeeded"
12213                 return 0
12214         fi
12215
12216         local orig=$(get_xattr_value $xbig $file)
12217         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
12218
12219         local xsml=trusted.sml
12220         log "save $xsml on $file"
12221         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
12222
12223         local new=$(get_xattr_value $xbig $file)
12224         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
12225
12226         log "grow $xsml on $file"
12227         setfattr -n $xsml -v "$value" $file ||
12228                 error "growing $xsml on $file failed"
12229
12230         new=$(get_xattr_value $xbig $file)
12231         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
12232         log "$xbig still valid after growing $xsml"
12233
12234         rm -f $file
12235 }
12236
12237 test_102h() { # bug 15777
12238         grow_xattr 1024
12239 }
12240 run_test 102h "grow xattr from inside inode to external block"
12241
12242 test_102ha() {
12243         large_xattr_enabled || skip_env "ea_inode feature disabled"
12244
12245         echo "setting xattr of max xattr size: $(max_xattr_size)"
12246         grow_xattr $(max_xattr_size)
12247
12248         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
12249         echo "This should fail:"
12250         grow_xattr $(($(max_xattr_size) + 10)) 1
12251 }
12252 run_test 102ha "grow xattr from inside inode to external inode"
12253
12254 test_102i() { # bug 17038
12255         [ -z "$(which getfattr 2>/dev/null)" ] &&
12256                 skip "could not find getfattr"
12257
12258         touch $DIR/$tfile
12259         ln -s $DIR/$tfile $DIR/${tfile}link
12260         getfattr -n trusted.lov $DIR/$tfile ||
12261                 error "lgetxattr on $DIR/$tfile failed"
12262         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
12263                 grep -i "no such attr" ||
12264                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
12265         rm -f $DIR/$tfile $DIR/${tfile}link
12266 }
12267 run_test 102i "lgetxattr test on symbolic link ============"
12268
12269 test_102j() {
12270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12271         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12272
12273         XINC=$(have_xattrs_include)
12274         setup_test102 "$RUNAS"
12275         chown $RUNAS_ID $DIR/$tdir
12276         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
12277         cd $DIR/$tdir/$tdir
12278         compare_stripe_info1 "$RUNAS"
12279 }
12280 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
12281
12282 test_102k() {
12283         [ -z "$(which setfattr 2>/dev/null)" ] &&
12284                 skip "could not find setfattr"
12285
12286         touch $DIR/$tfile
12287         # b22187 just check that does not crash for regular file.
12288         setfattr -n trusted.lov $DIR/$tfile
12289         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
12290         local test_kdir=$DIR/$tdir
12291         test_mkdir $test_kdir
12292         local default_size=$($LFS getstripe -S $test_kdir)
12293         local default_count=$($LFS getstripe -c $test_kdir)
12294         local default_offset=$($LFS getstripe -i $test_kdir)
12295         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
12296                 error 'dir setstripe failed'
12297         setfattr -n trusted.lov $test_kdir
12298         local stripe_size=$($LFS getstripe -S $test_kdir)
12299         local stripe_count=$($LFS getstripe -c $test_kdir)
12300         local stripe_offset=$($LFS getstripe -i $test_kdir)
12301         [ $stripe_size -eq $default_size ] ||
12302                 error "stripe size $stripe_size != $default_size"
12303         [ $stripe_count -eq $default_count ] ||
12304                 error "stripe count $stripe_count != $default_count"
12305         [ $stripe_offset -eq $default_offset ] ||
12306                 error "stripe offset $stripe_offset != $default_offset"
12307         rm -rf $DIR/$tfile $test_kdir
12308 }
12309 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
12310
12311 test_102l() {
12312         [ -z "$(which getfattr 2>/dev/null)" ] &&
12313                 skip "could not find getfattr"
12314
12315         # LU-532 trusted. xattr is invisible to non-root
12316         local testfile=$DIR/$tfile
12317
12318         touch $testfile
12319
12320         echo "listxattr as user..."
12321         chown $RUNAS_ID $testfile
12322         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
12323             grep -q "trusted" &&
12324                 error "$testfile trusted xattrs are user visible"
12325
12326         return 0;
12327 }
12328 run_test 102l "listxattr size test =================================="
12329
12330 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
12331         local path=$DIR/$tfile
12332         touch $path
12333
12334         listxattr_size_check $path || error "listattr_size_check $path failed"
12335 }
12336 run_test 102m "Ensure listxattr fails on small bufffer ========"
12337
12338 cleanup_test102
12339
12340 getxattr() { # getxattr path name
12341         # Return the base64 encoding of the value of xattr name on path.
12342         local path=$1
12343         local name=$2
12344
12345         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
12346         # file: $path
12347         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12348         #
12349         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12350
12351         getfattr --absolute-names --encoding=base64 --name=$name $path |
12352                 awk -F= -v name=$name '$1 == name {
12353                         print substr($0, index($0, "=") + 1);
12354         }'
12355 }
12356
12357 test_102n() { # LU-4101 mdt: protect internal xattrs
12358         [ -z "$(which setfattr 2>/dev/null)" ] &&
12359                 skip "could not find setfattr"
12360         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
12361         then
12362                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
12363         fi
12364
12365         local file0=$DIR/$tfile.0
12366         local file1=$DIR/$tfile.1
12367         local xattr0=$TMP/$tfile.0
12368         local xattr1=$TMP/$tfile.1
12369         local namelist="lov lma lmv link fid version som hsm"
12370         local name
12371         local value
12372
12373         rm -rf $file0 $file1 $xattr0 $xattr1
12374         touch $file0 $file1
12375
12376         # Get 'before' xattrs of $file1.
12377         getfattr --absolute-names --dump --match=- $file1 > $xattr0
12378
12379         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
12380                 namelist+=" lfsck_namespace"
12381         for name in $namelist; do
12382                 # Try to copy xattr from $file0 to $file1.
12383                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12384
12385                 setfattr --name=trusted.$name --value="$value" $file1 ||
12386                         error "setxattr 'trusted.$name' failed"
12387
12388                 # Try to set a garbage xattr.
12389                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12390
12391                 if [[ x$name == "xlov" ]]; then
12392                         setfattr --name=trusted.lov --value="$value" $file1 &&
12393                         error "setxattr invalid 'trusted.lov' success"
12394                 else
12395                         setfattr --name=trusted.$name --value="$value" $file1 ||
12396                                 error "setxattr invalid 'trusted.$name' failed"
12397                 fi
12398
12399                 # Try to remove the xattr from $file1. We don't care if this
12400                 # appears to succeed or fail, we just don't want there to be
12401                 # any changes or crashes.
12402                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12403         done
12404
12405         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
12406         then
12407                 name="lfsck_ns"
12408                 # Try to copy xattr from $file0 to $file1.
12409                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12410
12411                 setfattr --name=trusted.$name --value="$value" $file1 ||
12412                         error "setxattr 'trusted.$name' failed"
12413
12414                 # Try to set a garbage xattr.
12415                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12416
12417                 setfattr --name=trusted.$name --value="$value" $file1 ||
12418                         error "setxattr 'trusted.$name' failed"
12419
12420                 # Try to remove the xattr from $file1. We don't care if this
12421                 # appears to succeed or fail, we just don't want there to be
12422                 # any changes or crashes.
12423                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12424         fi
12425
12426         # Get 'after' xattrs of file1.
12427         getfattr --absolute-names --dump --match=- $file1 > $xattr1
12428
12429         if ! diff $xattr0 $xattr1; then
12430                 error "before and after xattrs of '$file1' differ"
12431         fi
12432
12433         rm -rf $file0 $file1 $xattr0 $xattr1
12434
12435         return 0
12436 }
12437 run_test 102n "silently ignore setxattr on internal trusted xattrs"
12438
12439 test_102p() { # LU-4703 setxattr did not check ownership
12440         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
12441                 skip "MDS needs to be at least 2.5.56"
12442
12443         local testfile=$DIR/$tfile
12444
12445         touch $testfile
12446
12447         echo "setfacl as user..."
12448         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
12449         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
12450
12451         echo "setfattr as user..."
12452         setfacl -m "u:$RUNAS_ID:---" $testfile
12453         $RUNAS setfattr -x system.posix_acl_access $testfile
12454         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
12455 }
12456 run_test 102p "check setxattr(2) correctly fails without permission"
12457
12458 test_102q() {
12459         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
12460                 skip "MDS needs to be at least 2.6.92"
12461
12462         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
12463 }
12464 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
12465
12466 test_102r() {
12467         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
12468                 skip "MDS needs to be at least 2.6.93"
12469
12470         touch $DIR/$tfile || error "touch"
12471         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
12472         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
12473         rm $DIR/$tfile || error "rm"
12474
12475         #normal directory
12476         mkdir -p $DIR/$tdir || error "mkdir"
12477         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12478         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12479         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12480                 error "$testfile error deleting user.author1"
12481         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12482                 grep "user.$(basename $tdir)" &&
12483                 error "$tdir did not delete user.$(basename $tdir)"
12484         rmdir $DIR/$tdir || error "rmdir"
12485
12486         #striped directory
12487         test_mkdir $DIR/$tdir
12488         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12489         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12490         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12491                 error "$testfile error deleting user.author1"
12492         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12493                 grep "user.$(basename $tdir)" &&
12494                 error "$tdir did not delete user.$(basename $tdir)"
12495         rmdir $DIR/$tdir || error "rm striped dir"
12496 }
12497 run_test 102r "set EAs with empty values"
12498
12499 test_102s() {
12500         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12501                 skip "MDS needs to be at least 2.11.52"
12502
12503         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12504
12505         save_lustre_params client "llite.*.xattr_cache" > $save
12506
12507         for cache in 0 1; do
12508                 lctl set_param llite.*.xattr_cache=$cache
12509
12510                 rm -f $DIR/$tfile
12511                 touch $DIR/$tfile || error "touch"
12512                 for prefix in lustre security system trusted user; do
12513                         # Note getxattr() may fail with 'Operation not
12514                         # supported' or 'No such attribute' depending
12515                         # on prefix and cache.
12516                         getfattr -n $prefix.n102s $DIR/$tfile &&
12517                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
12518                 done
12519         done
12520
12521         restore_lustre_params < $save
12522 }
12523 run_test 102s "getting nonexistent xattrs should fail"
12524
12525 test_102t() {
12526         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12527                 skip "MDS needs to be at least 2.11.52"
12528
12529         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12530
12531         save_lustre_params client "llite.*.xattr_cache" > $save
12532
12533         for cache in 0 1; do
12534                 lctl set_param llite.*.xattr_cache=$cache
12535
12536                 for buf_size in 0 256; do
12537                         rm -f $DIR/$tfile
12538                         touch $DIR/$tfile || error "touch"
12539                         setfattr -n user.multiop $DIR/$tfile
12540                         $MULTIOP $DIR/$tfile oa$buf_size ||
12541                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
12542                 done
12543         done
12544
12545         restore_lustre_params < $save
12546 }
12547 run_test 102t "zero length xattr values handled correctly"
12548
12549 run_acl_subtest()
12550 {
12551         local test=$LUSTRE/tests/acl/$1.test
12552         local tmp=$(mktemp -t $1-XXXXXX).test
12553         local bin=$2
12554         local dmn=$3
12555         local grp=$4
12556         local nbd=$5
12557         export LANG=C
12558
12559
12560         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
12561         local sedgroups="-e s/:users/:$grp/g"
12562         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
12563
12564         sed $sedusers $sedgroups < $test > $tmp
12565         stack_trap "rm -f $tmp"
12566         [[ -s $tmp ]] || error "sed failed to create test script"
12567
12568         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
12569         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
12570 }
12571
12572 test_103a() {
12573         [ "$UID" != 0 ] && skip "must run as root"
12574         $GSS && skip_env "could not run under gss"
12575         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
12576                 skip_env "must have acl enabled"
12577         which setfacl || skip_env "could not find setfacl"
12578         remote_mds_nodsh && skip "remote MDS with nodsh"
12579
12580         local mdts=$(comma_list $(mdts_nodes))
12581         local saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
12582
12583         [[ -z "$saved" ]] || do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE
12584         stack_trap "[[ -z \"$saved\" ]] || \
12585                     do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$saved" EXIT
12586
12587         ACLBIN=${ACLBIN:-"bin"}
12588         ACLDMN=${ACLDMN:-"daemon"}
12589         ACLGRP=${ACLGRP:-"users"}
12590         ACLNBD=${ACLNBD:-"nobody"}
12591
12592         if ! id $ACLBIN ||
12593            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
12594                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
12595                 ACLBIN=$USER0
12596                 if ! id $ACLBIN ; then
12597                         cat /etc/passwd
12598                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
12599                 fi
12600         fi
12601         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
12602            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
12603                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
12604                 ACLDMN=$USER1
12605                 if ! id $ACLDMN ; then
12606                         cat /etc/passwd
12607                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
12608                 fi
12609         fi
12610         if ! getent group $ACLGRP; then
12611                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
12612                 ACLGRP="$TSTUSR"
12613                 if ! getent group $ACLGRP; then
12614                         echo "cannot find group '$ACLGRP', adding it"
12615                         cat /etc/group
12616                         add_group 60000 $ACLGRP
12617                 fi
12618         fi
12619
12620         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
12621         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
12622         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12623
12624         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12625                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
12626                 ACLGRP="$TSTUSR"
12627                 if ! getent group $ACLGRP; then
12628                         echo "cannot find group '$ACLGRP', adding it"
12629                         cat /etc/group
12630                         add_group 60000 $ACLGRP
12631                 fi
12632                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12633                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12634                         cat /etc/group
12635                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
12636                 fi
12637         fi
12638
12639         gpasswd -a $ACLDMN $ACLBIN ||
12640                 error "setting client group failed"             # LU-5641
12641         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
12642                 error "setting MDS group failed"                # LU-5641
12643
12644         declare -a identity_old
12645
12646         for ((num = 1; num <= $MDSCOUNT; num++)); do
12647                 switch_identity $num true || identity_old[$num]=$?
12648         done
12649
12650         SAVE_UMASK=$(umask)
12651         umask 0022
12652         mkdir -p $DIR/$tdir
12653         cd $DIR/$tdir
12654
12655         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
12656         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
12657         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
12658         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
12659         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
12660         # CentOS7- uses nobody=99, while newer distros use nobody=65534
12661         if ! id -u $ACLNBD ||
12662            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
12663                 ACLNBD="nfsnobody"
12664                 if ! id -u $ACLNBD; then
12665                         ACLNBD=""
12666                 fi
12667         fi
12668         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
12669                 add_group $(id -u $ACLNBD) $ACLNBD
12670                 if ! getent group $ACLNBD; then
12671                         ACLNBD=""
12672                 fi
12673         fi
12674         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
12675            [[ -n "$ACLNBD" ]] && which setfattr; then
12676                 run_acl_subtest permissions_xattr \
12677                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
12678         elif [[ -z "$ACLNBD" ]]; then
12679                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
12680         else
12681                 echo "skip 'permission_xattr' test - missing setfattr command"
12682         fi
12683         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
12684
12685         # inheritance test got from HP
12686         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
12687         chmod +x make-tree || error "chmod +x failed"
12688         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
12689         rm -f make-tree
12690
12691         echo "LU-974 ignore umask when acl is enabled..."
12692         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
12693         if [ $MDSCOUNT -ge 2 ]; then
12694                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
12695         fi
12696
12697         echo "LU-2561 newly created file is same size as directory..."
12698         if [ "$mds1_FSTYPE" != "zfs" ]; then
12699                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
12700         else
12701                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
12702         fi
12703
12704         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
12705
12706         cd $SAVE_PWD
12707         umask $SAVE_UMASK
12708
12709         for ((num = 1; num <= $MDSCOUNT; num++)); do
12710                 if [[ "${identity_old[$num]}" == 1 ]]; then
12711                         switch_identity $num false || identity_old[$num]=$?
12712                 fi
12713         done
12714 }
12715 run_test 103a "acl test"
12716
12717 test_103b() {
12718         declare -a pids
12719         local U
12720
12721         stack_trap "rm -f $DIR/$tfile.*"
12722         for U in {0..511}; do
12723                 {
12724                 local O=$(printf "%04o" $U)
12725
12726                 umask $(printf "%04o" $((511 ^ $O)))
12727                 $LFS setstripe -c 1 $DIR/$tfile.s$O
12728                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
12729
12730                 (( $S == ($O & 0666) )) ||
12731                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
12732
12733                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
12734                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
12735                 (( $S == ($O & 0666) )) ||
12736                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
12737
12738                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
12739                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
12740                 (( $S == ($O & 0666) )) ||
12741                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
12742                 rm -f $DIR/$tfile.[smp]$0
12743                 } &
12744                 local pid=$!
12745
12746                 # limit the concurrently running threads to 64. LU-11878
12747                 local idx=$((U % 64))
12748                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
12749                 pids[idx]=$pid
12750         done
12751         wait
12752 }
12753 run_test 103b "umask lfs setstripe"
12754
12755 test_103c() {
12756         mkdir -p $DIR/$tdir
12757         cp -rp $DIR/$tdir $DIR/$tdir.bak
12758
12759         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
12760                 error "$DIR/$tdir shouldn't contain default ACL"
12761         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
12762                 error "$DIR/$tdir.bak shouldn't contain default ACL"
12763         true
12764 }
12765 run_test 103c "'cp -rp' won't set empty acl"
12766
12767 test_103e() {
12768         local numacl
12769         local fileacl
12770         local saved_debug=$($LCTL get_param -n debug)
12771
12772         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
12773                 skip "MDS needs to be at least 2.14.52"
12774
12775         large_xattr_enabled || skip_env "ea_inode feature disabled"
12776
12777         mkdir -p $DIR/$tdir
12778         # add big LOV EA to cause reply buffer overflow earlier
12779         $LFS setstripe -C 1000 $DIR/$tdir
12780         lctl set_param mdc.*-mdc*.stats=clear
12781
12782         $LCTL set_param debug=0
12783         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
12784         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
12785
12786         # add a large number of default ACLs (expect 8000+ for 2.13+)
12787         for U in {2..7000}; do
12788                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
12789                         error "Able to add just $U default ACLs"
12790         done
12791         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
12792         echo "$numacl default ACLs created"
12793
12794         stat $DIR/$tdir || error "Cannot stat directory"
12795         # check file creation
12796         touch $DIR/$tdir/$tfile ||
12797                 error "failed to create $tfile with $numacl default ACLs"
12798         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
12799         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12800         echo "$fileacl ACLs were inherited"
12801         (( $fileacl == $numacl )) ||
12802                 error "Not all default ACLs were inherited: $numacl != $fileacl"
12803         # check that new ACLs creation adds new ACLs to inherited ACLs
12804         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
12805                 error "Cannot set new ACL"
12806         numacl=$((numacl + 1))
12807         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12808         (( $fileacl == $numacl )) ||
12809                 error "failed to add new ACL: $fileacl != $numacl as expected"
12810         # adds more ACLs to a file to reach their maximum at 8000+
12811         numacl=0
12812         for U in {20000..25000}; do
12813                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12814                 numacl=$((numacl + 1))
12815         done
12816         echo "Added $numacl more ACLs to the file"
12817         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12818         echo "Total $fileacl ACLs in file"
12819         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12820         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12821         rmdir $DIR/$tdir || error "Cannot remove directory"
12822 }
12823 run_test 103e "inheritance of big amount of default ACLs"
12824
12825 test_103f() {
12826         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12827                 skip "MDS needs to be at least 2.14.51"
12828
12829         large_xattr_enabled || skip_env "ea_inode feature disabled"
12830
12831         # enable changelog to consume more internal MDD buffers
12832         changelog_register
12833
12834         mkdir -p $DIR/$tdir
12835         # add big LOV EA
12836         $LFS setstripe -C 1000 $DIR/$tdir
12837         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12838         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12839         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12840         rmdir $DIR/$tdir || error "Cannot remove directory"
12841 }
12842 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12843
12844 test_104a() {
12845         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12846
12847         touch $DIR/$tfile
12848         lfs df || error "lfs df failed"
12849         lfs df -ih || error "lfs df -ih failed"
12850         lfs df -h $DIR || error "lfs df -h $DIR failed"
12851         lfs df -i $DIR || error "lfs df -i $DIR failed"
12852         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12853         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12854
12855         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12856         lctl --device %$OSC deactivate
12857         lfs df || error "lfs df with deactivated OSC failed"
12858         lctl --device %$OSC activate
12859         # wait the osc back to normal
12860         wait_osc_import_ready client ost
12861
12862         lfs df || error "lfs df with reactivated OSC failed"
12863         rm -f $DIR/$tfile
12864 }
12865 run_test 104a "lfs df [-ih] [path] test ========================="
12866
12867 test_104b() {
12868         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12869         [ $RUNAS_ID -eq $UID ] &&
12870                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12871
12872         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12873                         grep "Permission denied" | wc -l)))
12874         if [ $denied_cnt -ne 0 ]; then
12875                 error "lfs check servers test failed"
12876         fi
12877 }
12878 run_test 104b "$RUNAS lfs check servers test ===================="
12879
12880 #
12881 # Verify $1 is within range of $2.
12882 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12883 # $1 is <= 2% of $2. Else Fail.
12884 #
12885 value_in_range() {
12886         # Strip all units (M, G, T)
12887         actual=$(echo $1 | tr -d A-Z)
12888         expect=$(echo $2 | tr -d A-Z)
12889
12890         expect_lo=$(($expect * 98 / 100)) # 2% below
12891         expect_hi=$(($expect * 102 / 100)) # 2% above
12892
12893         # permit 2% drift above and below
12894         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12895 }
12896
12897 test_104c() {
12898         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12899         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12900
12901         local ost_param="osd-zfs.$FSNAME-OST0000."
12902         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12903         local ofacets=$(get_facets OST)
12904         local mfacets=$(get_facets MDS)
12905         local saved_ost_blocks=
12906         local saved_mdt_blocks=
12907
12908         echo "Before recordsize change"
12909         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12910         df=($(df -h | grep "$MOUNT"$))
12911
12912         # For checking.
12913         echo "lfs output : ${lfs_df[*]}"
12914         echo "df  output : ${df[*]}"
12915
12916         for facet in ${ofacets//,/ }; do
12917                 if [ -z $saved_ost_blocks ]; then
12918                         saved_ost_blocks=$(do_facet $facet \
12919                                 lctl get_param -n $ost_param.blocksize)
12920                         echo "OST Blocksize: $saved_ost_blocks"
12921                 fi
12922                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12923                 do_facet $facet zfs set recordsize=32768 $ost
12924         done
12925
12926         # BS too small. Sufficient for functional testing.
12927         for facet in ${mfacets//,/ }; do
12928                 if [ -z $saved_mdt_blocks ]; then
12929                         saved_mdt_blocks=$(do_facet $facet \
12930                                 lctl get_param -n $mdt_param.blocksize)
12931                         echo "MDT Blocksize: $saved_mdt_blocks"
12932                 fi
12933                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12934                 do_facet $facet zfs set recordsize=32768 $mdt
12935         done
12936
12937         # Give new values chance to reflect change
12938         sleep 2
12939
12940         echo "After recordsize change"
12941         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12942         df_after=($(df -h | grep "$MOUNT"$))
12943
12944         # For checking.
12945         echo "lfs output : ${lfs_df_after[*]}"
12946         echo "df  output : ${df_after[*]}"
12947
12948         # Verify lfs df
12949         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12950                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12951         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12952                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12953         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12954                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12955
12956         # Verify df
12957         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12958                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12959         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12960                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12961         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12962                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12963
12964         # Restore MDT recordize back to original
12965         for facet in ${mfacets//,/ }; do
12966                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12967                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12968         done
12969
12970         # Restore OST recordize back to original
12971         for facet in ${ofacets//,/ }; do
12972                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12973                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12974         done
12975
12976         return 0
12977 }
12978 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12979
12980 test_104d() {
12981         (( $RUNAS_ID != $UID )) ||
12982                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12983
12984         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12985                 skip "lustre version doesn't support lctl dl with non-root"
12986
12987         # debugfs only allows root users to access files, so the
12988         # previous move of the "devices" file to debugfs broke
12989         # "lctl dl" for non-root users. The LU-9680 Netlink
12990         # interface again allows non-root users to list devices.
12991         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12992                 error "lctl dl doesn't work for non root"
12993
12994         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12995         [ "$ost_count" -eq $OSTCOUNT ]  ||
12996                 error "lctl dl reports wrong number of OST devices"
12997
12998         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12999         [ "$mdt_count" -eq $MDSCOUNT ]  ||
13000                 error "lctl dl reports wrong number of MDT devices"
13001 }
13002 run_test 104d "$RUNAS lctl dl test"
13003
13004 test_105a() {
13005         # doesn't work on 2.4 kernels
13006         touch $DIR/$tfile
13007         if $(flock_is_enabled); then
13008                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
13009         else
13010                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
13011         fi
13012         rm -f $DIR/$tfile
13013 }
13014 run_test 105a "flock when mounted without -o flock test ========"
13015
13016 test_105b() {
13017         touch $DIR/$tfile
13018         if $(flock_is_enabled); then
13019                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
13020         else
13021                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
13022         fi
13023         rm -f $DIR/$tfile
13024 }
13025 run_test 105b "fcntl when mounted without -o flock test ========"
13026
13027 test_105c() {
13028         touch $DIR/$tfile
13029         if $(flock_is_enabled); then
13030                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
13031         else
13032                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
13033         fi
13034         rm -f $DIR/$tfile
13035 }
13036 run_test 105c "lockf when mounted without -o flock test"
13037
13038 test_105d() { # bug 15924
13039         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13040
13041         test_mkdir $DIR/$tdir
13042         flock_is_enabled || skip_env "mount w/o flock enabled"
13043         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
13044         $LCTL set_param fail_loc=0x80000315
13045         flocks_test 2 $DIR/$tdir
13046 }
13047 run_test 105d "flock race (should not freeze) ========"
13048
13049 test_105e() { # bug 22660 && 22040
13050         flock_is_enabled || skip_env "mount w/o flock enabled"
13051
13052         touch $DIR/$tfile
13053         flocks_test 3 $DIR/$tfile
13054 }
13055 run_test 105e "Two conflicting flocks from same process"
13056
13057 wait_end() {
13058         echo $*
13059         while :; do
13060                 [ -f $TMP/${tfile}_sTOP ] && return
13061                 sleep 1
13062         done
13063 }
13064
13065 test_105f() {
13066         flock_is_enabled || skip_env "mount w/o flock enabled"
13067
13068         local pmax=$(ulimit -u)
13069         local i=0
13070         touch $DIR/$tfile
13071         [ $pmax -gt 20 ] && pmax=20
13072         for((i=0; i <= $pmax; i++)) {
13073                 wait_end "R4000, 5000" | flocks_test 6 $DIR/$tfile &
13074         }
13075         for((i=0; i <= 10; i++)) {
13076                 local locks=$(do_facet $SINGLEMDS $LCTL get_param -n \
13077                         ldlm.namespaces.mdt-${FSNAME}-MDT0000*.lock_count)
13078                 [ $locks -ge $pmax ] && break
13079                 [ $i -eq 10 ] && error "The locks cannot be added after 10 secs"
13080                 sleep 1
13081         }
13082         touch $TMP/${tfile}_sTOP
13083         wait
13084         rm -r $DIR/$tfile $TMP/${tfile}_sTOP
13085 }
13086 run_test 105f "Enqueue same range flocks"
13087
13088 test_106() { #bug 10921
13089         test_mkdir $DIR/$tdir
13090         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
13091         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
13092 }
13093 run_test 106 "attempt exec of dir followed by chown of that dir"
13094
13095 test_107() {
13096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13097
13098         CDIR=`pwd`
13099         local file=core
13100
13101         cd $DIR
13102         rm -f $file
13103
13104         local save_pattern=$(sysctl -n kernel.core_pattern)
13105         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
13106         sysctl -w kernel.core_pattern=$file
13107         sysctl -w kernel.core_uses_pid=0
13108
13109         ulimit -c unlimited
13110         sleep 60 &
13111         SLEEPPID=$!
13112
13113         sleep 1
13114
13115         kill -s 11 $SLEEPPID
13116         wait $SLEEPPID
13117         if [ -e $file ]; then
13118                 size=`stat -c%s $file`
13119                 [ $size -eq 0 ] && error "Fail to create core file $file"
13120         else
13121                 error "Fail to create core file $file"
13122         fi
13123         rm -f $file
13124         sysctl -w kernel.core_pattern=$save_pattern
13125         sysctl -w kernel.core_uses_pid=$save_uses_pid
13126         cd $CDIR
13127 }
13128 run_test 107 "Coredump on SIG"
13129
13130 test_110() {
13131         test_mkdir $DIR/$tdir
13132         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
13133         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
13134                 error "mkdir with 256 char should fail, but did not"
13135         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
13136                 error "create with 255 char failed"
13137         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
13138                 error "create with 256 char should fail, but did not"
13139
13140         ls -l $DIR/$tdir
13141         rm -rf $DIR/$tdir
13142 }
13143 run_test 110 "filename length checking"
13144
13145 test_116a() { # was previously test_116()
13146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13147         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13148         remote_mds_nodsh && skip "remote MDS with nodsh"
13149
13150         echo -n "Free space priority "
13151         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
13152                 head -n1
13153         declare -a AVAIL
13154         free_min_max
13155
13156         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
13157         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
13158         stack_trap simple_cleanup_common
13159
13160         # Check if we need to generate uneven OSTs
13161         test_mkdir -p $DIR/$tdir/OST${MINI}
13162         local FILL=$((MINV / 4))
13163         local DIFF=$((MAXV - MINV))
13164         local DIFF2=$((DIFF * 100 / MINV))
13165
13166         local threshold=$(do_facet $SINGLEMDS \
13167                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
13168         threshold=${threshold%%%}
13169         echo -n "Check for uneven OSTs: "
13170         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
13171
13172         if [[ $DIFF2 -gt $threshold ]]; then
13173                 echo "ok"
13174                 echo "Don't need to fill OST$MINI"
13175         else
13176                 # generate uneven OSTs. Write 2% over the QOS threshold value
13177                 echo "no"
13178                 DIFF=$((threshold - DIFF2 + 2))
13179                 DIFF2=$((MINV * DIFF / 100))
13180                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
13181                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
13182                         error "setstripe failed"
13183                 DIFF=$((DIFF2 / 2048))
13184                 i=0
13185                 while [ $i -lt $DIFF ]; do
13186                         i=$((i + 1))
13187                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
13188                                 bs=2M count=1 2>/dev/null
13189                         echo -n .
13190                 done
13191                 echo .
13192                 sync
13193                 sleep_maxage
13194                 free_min_max
13195         fi
13196
13197         DIFF=$((MAXV - MINV))
13198         DIFF2=$((DIFF * 100 / MINV))
13199         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
13200         if [ $DIFF2 -gt $threshold ]; then
13201                 echo "ok"
13202         else
13203                 skip "QOS imbalance criteria not met"
13204         fi
13205
13206         MINI1=$MINI
13207         MINV1=$MINV
13208         MAXI1=$MAXI
13209         MAXV1=$MAXV
13210
13211         # now fill using QOS
13212         $LFS setstripe -c 1 $DIR/$tdir
13213         FILL=$((FILL / 200))
13214         if [ $FILL -gt 600 ]; then
13215                 FILL=600
13216         fi
13217         echo "writing $FILL files to QOS-assigned OSTs"
13218         i=0
13219         while [ $i -lt $FILL ]; do
13220                 i=$((i + 1))
13221                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
13222                         count=1 2>/dev/null
13223                 echo -n .
13224         done
13225         echo "wrote $i 200k files"
13226         sync
13227         sleep_maxage
13228
13229         echo "Note: free space may not be updated, so measurements might be off"
13230         free_min_max
13231         DIFF2=$((MAXV - MINV))
13232         echo "free space delta: orig $DIFF final $DIFF2"
13233         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
13234         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
13235         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
13236         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
13237         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
13238         if [[ $DIFF -gt 0 ]]; then
13239                 FILL=$((DIFF2 * 100 / DIFF - 100))
13240                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
13241         fi
13242
13243         # Figure out which files were written where
13244         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
13245                awk '/'$MINI1': / {print $2; exit}')
13246         echo $UUID
13247         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
13248         echo "$MINC files created on smaller OST $MINI1"
13249         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
13250                awk '/'$MAXI1': / {print $2; exit}')
13251         echo $UUID
13252         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
13253         echo "$MAXC files created on larger OST $MAXI1"
13254         if [[ $MINC -gt 0 ]]; then
13255                 FILL=$((MAXC * 100 / MINC - 100))
13256                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
13257         fi
13258         [[ $MAXC -gt $MINC ]] ||
13259                 error_ignore LU-9 "stripe QOS didn't balance free space"
13260 }
13261 run_test 116a "stripe QOS: free space balance ==================="
13262
13263 test_116b() { # LU-2093
13264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13265         remote_mds_nodsh && skip "remote MDS with nodsh"
13266
13267 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
13268         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
13269                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
13270         [ -z "$old_rr" ] && skip "no QOS"
13271         do_facet $SINGLEMDS lctl set_param \
13272                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
13273         mkdir -p $DIR/$tdir
13274         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
13275         createmany -o $DIR/$tdir/f- 20 || error "can't create"
13276         do_facet $SINGLEMDS lctl set_param fail_loc=0
13277         rm -rf $DIR/$tdir
13278         do_facet $SINGLEMDS lctl set_param \
13279                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
13280 }
13281 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
13282
13283 test_117() # bug 10891
13284 {
13285         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13286
13287         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
13288         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
13289         lctl set_param fail_loc=0x21e
13290         > $DIR/$tfile || error "truncate failed"
13291         lctl set_param fail_loc=0
13292         echo "Truncate succeeded."
13293         rm -f $DIR/$tfile
13294 }
13295 run_test 117 "verify osd extend =========="
13296
13297 NO_SLOW_RESENDCOUNT=4
13298 export OLD_RESENDCOUNT=""
13299 set_resend_count () {
13300         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
13301         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
13302         lctl set_param -n $PROC_RESENDCOUNT $1
13303         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
13304 }
13305
13306 # for reduce test_118* time (b=14842)
13307 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13308
13309 # Reset async IO behavior after error case
13310 reset_async() {
13311         FILE=$DIR/reset_async
13312
13313         # Ensure all OSCs are cleared
13314         $LFS setstripe -c -1 $FILE
13315         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
13316         sync
13317         rm $FILE
13318 }
13319
13320 test_118a() #bug 11710
13321 {
13322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13323
13324         reset_async
13325
13326         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13327         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13328         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13329
13330         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13331                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13332                 return 1;
13333         fi
13334         rm -f $DIR/$tfile
13335 }
13336 run_test 118a "verify O_SYNC works =========="
13337
13338 test_118b()
13339 {
13340         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13341         remote_ost_nodsh && skip "remote OST with nodsh"
13342
13343         reset_async
13344
13345         #define OBD_FAIL_SRV_ENOENT 0x217
13346         set_nodes_failloc "$(osts_nodes)" 0x217
13347         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13348         RC=$?
13349         set_nodes_failloc "$(osts_nodes)" 0
13350         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13351         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13352                     grep -c writeback)
13353
13354         if [[ $RC -eq 0 ]]; then
13355                 error "Must return error due to dropped pages, rc=$RC"
13356                 return 1;
13357         fi
13358
13359         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13360                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13361                 return 1;
13362         fi
13363
13364         echo "Dirty pages not leaked on ENOENT"
13365
13366         # Due to the above error the OSC will issue all RPCs syncronously
13367         # until a subsequent RPC completes successfully without error.
13368         $MULTIOP $DIR/$tfile Ow4096yc
13369         rm -f $DIR/$tfile
13370
13371         return 0
13372 }
13373 run_test 118b "Reclaim dirty pages on fatal error =========="
13374
13375 test_118c()
13376 {
13377         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13378
13379         # for 118c, restore the original resend count, LU-1940
13380         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
13381                                 set_resend_count $OLD_RESENDCOUNT
13382         remote_ost_nodsh && skip "remote OST with nodsh"
13383
13384         reset_async
13385
13386         #define OBD_FAIL_OST_EROFS               0x216
13387         set_nodes_failloc "$(osts_nodes)" 0x216
13388
13389         # multiop should block due to fsync until pages are written
13390         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13391         MULTIPID=$!
13392         sleep 1
13393
13394         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13395                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13396         fi
13397
13398         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13399                     grep -c writeback)
13400         if [[ $WRITEBACK -eq 0 ]]; then
13401                 error "No page in writeback, writeback=$WRITEBACK"
13402         fi
13403
13404         set_nodes_failloc "$(osts_nodes)" 0
13405         wait $MULTIPID
13406         RC=$?
13407         if [[ $RC -ne 0 ]]; then
13408                 error "Multiop fsync failed, rc=$RC"
13409         fi
13410
13411         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13412         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13413                     grep -c writeback)
13414         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13415                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13416         fi
13417
13418         rm -f $DIR/$tfile
13419         echo "Dirty pages flushed via fsync on EROFS"
13420         return 0
13421 }
13422 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
13423
13424 # continue to use small resend count to reduce test_118* time (b=14842)
13425 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13426
13427 test_118d()
13428 {
13429         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13430         remote_ost_nodsh && skip "remote OST with nodsh"
13431
13432         reset_async
13433
13434         #define OBD_FAIL_OST_BRW_PAUSE_BULK
13435         set_nodes_failloc "$(osts_nodes)" 0x214
13436         # multiop should block due to fsync until pages are written
13437         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13438         MULTIPID=$!
13439         sleep 1
13440
13441         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13442                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13443         fi
13444
13445         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13446                     grep -c writeback)
13447         if [[ $WRITEBACK -eq 0 ]]; then
13448                 error "No page in writeback, writeback=$WRITEBACK"
13449         fi
13450
13451         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
13452         set_nodes_failloc "$(osts_nodes)" 0
13453
13454         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13455         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13456                     grep -c writeback)
13457         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13458                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13459         fi
13460
13461         rm -f $DIR/$tfile
13462         echo "Dirty pages gaurenteed flushed via fsync"
13463         return 0
13464 }
13465 run_test 118d "Fsync validation inject a delay of the bulk =========="
13466
13467 test_118f() {
13468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13469
13470         reset_async
13471
13472         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
13473         lctl set_param fail_loc=0x8000040a
13474
13475         # Should simulate EINVAL error which is fatal
13476         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13477         RC=$?
13478         if [[ $RC -eq 0 ]]; then
13479                 error "Must return error due to dropped pages, rc=$RC"
13480         fi
13481
13482         lctl set_param fail_loc=0x0
13483
13484         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13485         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13486         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13487                     grep -c writeback)
13488         if [[ $LOCKED -ne 0 ]]; then
13489                 error "Locked pages remain in cache, locked=$LOCKED"
13490         fi
13491
13492         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13493                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13494         fi
13495
13496         rm -f $DIR/$tfile
13497         echo "No pages locked after fsync"
13498
13499         reset_async
13500         return 0
13501 }
13502 run_test 118f "Simulate unrecoverable OSC side error =========="
13503
13504 test_118g() {
13505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13506
13507         reset_async
13508
13509         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
13510         lctl set_param fail_loc=0x406
13511
13512         # simulate local -ENOMEM
13513         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13514         RC=$?
13515
13516         lctl set_param fail_loc=0
13517         if [[ $RC -eq 0 ]]; then
13518                 error "Must return error due to dropped pages, rc=$RC"
13519         fi
13520
13521         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13522         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13523         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13524                         grep -c writeback)
13525         if [[ $LOCKED -ne 0 ]]; then
13526                 error "Locked pages remain in cache, locked=$LOCKED"
13527         fi
13528
13529         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13530                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13531         fi
13532
13533         rm -f $DIR/$tfile
13534         echo "No pages locked after fsync"
13535
13536         reset_async
13537         return 0
13538 }
13539 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
13540
13541 test_118h() {
13542         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13543         remote_ost_nodsh && skip "remote OST with nodsh"
13544
13545         reset_async
13546
13547         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13548         set_nodes_failloc "$(osts_nodes)" 0x20e
13549         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13550         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13551         RC=$?
13552
13553         set_nodes_failloc "$(osts_nodes)" 0
13554         if [[ $RC -eq 0 ]]; then
13555                 error "Must return error due to dropped pages, rc=$RC"
13556         fi
13557
13558         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13559         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13560         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13561                     grep -c writeback)
13562         if [[ $LOCKED -ne 0 ]]; then
13563                 error "Locked pages remain in cache, locked=$LOCKED"
13564         fi
13565
13566         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13567                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13568         fi
13569
13570         rm -f $DIR/$tfile
13571         echo "No pages locked after fsync"
13572
13573         return 0
13574 }
13575 run_test 118h "Verify timeout in handling recoverables errors  =========="
13576
13577 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13578
13579 test_118i() {
13580         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13581         remote_ost_nodsh && skip "remote OST with nodsh"
13582
13583         reset_async
13584
13585         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13586         set_nodes_failloc "$(osts_nodes)" 0x20e
13587
13588         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13589         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13590         PID=$!
13591         sleep 5
13592         set_nodes_failloc "$(osts_nodes)" 0
13593
13594         wait $PID
13595         RC=$?
13596         if [[ $RC -ne 0 ]]; then
13597                 error "got error, but should be not, rc=$RC"
13598         fi
13599
13600         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13601         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13602         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13603         if [[ $LOCKED -ne 0 ]]; then
13604                 error "Locked pages remain in cache, locked=$LOCKED"
13605         fi
13606
13607         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13608                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13609         fi
13610
13611         rm -f $DIR/$tfile
13612         echo "No pages locked after fsync"
13613
13614         return 0
13615 }
13616 run_test 118i "Fix error before timeout in recoverable error  =========="
13617
13618 [ "$SLOW" = "no" ] && set_resend_count 4
13619
13620 test_118j() {
13621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13622         remote_ost_nodsh && skip "remote OST with nodsh"
13623
13624         reset_async
13625
13626         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
13627         set_nodes_failloc "$(osts_nodes)" 0x220
13628
13629         # return -EIO from OST
13630         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13631         RC=$?
13632         set_nodes_failloc "$(osts_nodes)" 0x0
13633         if [[ $RC -eq 0 ]]; then
13634                 error "Must return error due to dropped pages, rc=$RC"
13635         fi
13636
13637         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13638         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13639         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13640         if [[ $LOCKED -ne 0 ]]; then
13641                 error "Locked pages remain in cache, locked=$LOCKED"
13642         fi
13643
13644         # in recoverable error on OST we want resend and stay until it finished
13645         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13646                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13647         fi
13648
13649         rm -f $DIR/$tfile
13650         echo "No pages locked after fsync"
13651
13652         return 0
13653 }
13654 run_test 118j "Simulate unrecoverable OST side error =========="
13655
13656 test_118k()
13657 {
13658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13659         remote_ost_nodsh && skip "remote OSTs with nodsh"
13660
13661         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13662         set_nodes_failloc "$(osts_nodes)" 0x20e
13663         test_mkdir $DIR/$tdir
13664
13665         for ((i=0;i<10;i++)); do
13666                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
13667                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
13668                 SLEEPPID=$!
13669                 sleep 0.500s
13670                 kill $SLEEPPID
13671                 wait $SLEEPPID
13672         done
13673
13674         set_nodes_failloc "$(osts_nodes)" 0
13675         rm -rf $DIR/$tdir
13676 }
13677 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
13678
13679 test_118l() # LU-646
13680 {
13681         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13682
13683         test_mkdir $DIR/$tdir
13684         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
13685         rm -rf $DIR/$tdir
13686 }
13687 run_test 118l "fsync dir"
13688
13689 test_118m() # LU-3066
13690 {
13691         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13692
13693         test_mkdir $DIR/$tdir
13694         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
13695         rm -rf $DIR/$tdir
13696 }
13697 run_test 118m "fdatasync dir ========="
13698
13699 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13700
13701 test_118n()
13702 {
13703         local begin
13704         local end
13705
13706         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13707         remote_ost_nodsh && skip "remote OSTs with nodsh"
13708
13709         # Sleep to avoid a cached response.
13710         #define OBD_STATFS_CACHE_SECONDS 1
13711         sleep 2
13712
13713         # Inject a 10 second delay in the OST_STATFS handler.
13714         #define OBD_FAIL_OST_STATFS_DELAY 0x242
13715         set_nodes_failloc "$(osts_nodes)" 0x242
13716
13717         begin=$SECONDS
13718         stat --file-system $MOUNT > /dev/null
13719         end=$SECONDS
13720
13721         set_nodes_failloc "$(osts_nodes)" 0
13722
13723         if ((end - begin > 20)); then
13724             error "statfs took $((end - begin)) seconds, expected 10"
13725         fi
13726 }
13727 run_test 118n "statfs() sends OST_STATFS requests in parallel"
13728
13729 test_119a() # bug 11737
13730 {
13731         BSIZE=$((512 * 1024))
13732         directio write $DIR/$tfile 0 1 $BSIZE
13733         # We ask to read two blocks, which is more than a file size.
13734         # directio will indicate an error when requested and actual
13735         # sizes aren't equeal (a normal situation in this case) and
13736         # print actual read amount.
13737         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
13738         if [ "$NOB" != "$BSIZE" ]; then
13739                 error "read $NOB bytes instead of $BSIZE"
13740         fi
13741         rm -f $DIR/$tfile
13742 }
13743 run_test 119a "Short directIO read must return actual read amount"
13744
13745 test_119b() # bug 11737
13746 {
13747         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13748
13749         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
13750         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
13751         sync
13752         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
13753                 error "direct read failed"
13754         rm -f $DIR/$tfile
13755 }
13756 run_test 119b "Sparse directIO read must return actual read amount"
13757
13758 test_119c() # bug 13099
13759 {
13760         BSIZE=1048576
13761         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
13762         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
13763         rm -f $DIR/$tfile
13764 }
13765 run_test 119c "Testing for direct read hitting hole"
13766
13767 # Note: test 119d was removed, skipping 119d for new tests to avoid polluting
13768 # Maloo test history
13769
13770 test_119e()
13771 {
13772         (( $MDS1_VERSION >= $(version_code 2.15.58) )) ||
13773                 skip "Need server version at least 2.15.58"
13774         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13775
13776         local stripe_size=$((1024 * 1024)) #1 MiB
13777         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13778         local file_size=$((25 * stripe_size))
13779         local bsizes
13780
13781         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13782         stack_trap "rm -f $DIR/$tfile*"
13783
13784         # Just a bit bigger than the largest size in the test set below
13785         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13786                 error "buffered i/o to create file failed"
13787
13788         # trivial test of unaligned DIO
13789         dd if=$DIR/$tfile.1 bs=4095 of=$DIR/$tfile.2 count=4 \
13790                 iflag=direct oflag=direct ||
13791                 error "trivial unaligned dio failed"
13792
13793         # Test of disabling unaligned DIO support
13794         $LCTL set_param llite.*.unaligned_dio=0
13795         stack_trap "$LCTL set_param llite.*.unaligned_dio=1"
13796         echo "testing disabling unaligned DIO - 'invalid argument' expected:"
13797         dd if=$DIR/$tfile.1 bs=1024 of=$DIR/$tfile.2 count=4 \
13798                 iflag=direct oflag=direct &&
13799                 error "unaligned dio succeeded when disabled"
13800         $LCTL set_param llite.*.unaligned_dio=1
13801
13802         # Clean up before next part of test
13803         rm -f $DIR/$tfile.2
13804
13805         if zfs_or_rotational; then
13806                 # DIO on ZFS can take up to 2 seconds per IO
13807                 # rotational is better, but still slow.
13808                 # Limit testing on those media to larger sizes
13809                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13810                         $((stripe_size + 1024))"
13811         else
13812                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13813                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13814                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13815                         $((stripe_size - 1)) $stripe_size \
13816                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13817                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13818         fi
13819
13820         for bs in $bsizes; do
13821                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13822                 echo "Read/write with DIO at size $bs"
13823                 # Read and write with DIO from source to dest
13824                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 \
13825                         iflag=direct oflag=direct ||
13826                         error "dio failed"
13827
13828                 ls -la $DIR/$tfile.1 $DIR/$tfile.2
13829                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13830                         error "size incorrect, file copy read/write bsize: $bs"
13831                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13832                         error "files differ, bsize $bs"
13833                 rm -f $DIR/$tfile.2
13834         done
13835 }
13836 run_test 119e "Basic tests of dio read and write at various sizes"
13837
13838 test_119f()
13839 {
13840         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13841
13842         local stripe_size=$((1024 * 1024)) #1 MiB
13843         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13844         local file_size=$((25 * stripe_size))
13845         local bsizes
13846
13847         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13848         stack_trap "rm -f $DIR/$tfile*"
13849
13850         # Just a bit bigger than the largest size in the test set below
13851         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13852                 error "buffered i/o to create file failed"
13853
13854         if zfs_or_rotational; then
13855                 # DIO on ZFS can take up to 2 seconds per IO
13856                 # rotational is better, but still slow.
13857                 # Limit testing on those media to larger sizes
13858                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13859                         $((stripe_size + 1024))"
13860         else
13861                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13862                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13863                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13864                         $((stripe_size - 1)) $stripe_size \
13865                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13866                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13867         fi
13868
13869         for bs in $bsizes; do
13870                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13871                 # Read and write with DIO from source to dest in two
13872                 # threads - should give correct copy of file
13873
13874                 echo "bs: $bs"
13875                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13876                         oflag=direct conv=notrunc &
13877                 pid_dio1=$!
13878                 # Note block size is different here for a more interesting race
13879                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
13880                         iflag=direct oflag=direct conv=notrunc &
13881                 pid_dio2=$!
13882                 wait $pid_dio1
13883                 rc1=$?
13884                 wait $pid_dio2
13885                 rc2=$?
13886                 if (( rc1 != 0 )); then
13887                         error "dio copy 1 w/bsize $bs failed: $rc1"
13888                 fi
13889                 if (( rc2 != 0 )); then
13890                         error "dio copy 2 w/bsize $bs failed: $rc2"
13891                 fi
13892
13893
13894                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13895                         error "size incorrect, file copy read/write bsize: $bs"
13896                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13897                         error "files differ, bsize $bs"
13898                 rm -f $DIR/$tfile.2
13899         done
13900 }
13901 run_test 119f "dio vs dio race"
13902
13903 test_119g()
13904 {
13905         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13906
13907         local stripe_size=$((1024 * 1024)) #1 MiB
13908         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13909         local file_size=$((25 * stripe_size))
13910         local bsizes
13911
13912         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13913         stack_trap "rm -f $DIR/$tfile*"
13914
13915         # Just a bit bigger than the largest size in the test set below
13916         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13917                 error "buffered i/o to create file failed"
13918
13919         if zfs_or_rotational; then
13920                 # DIO on ZFS can take up to 2 seconds per IO
13921                 # rotational is better, but still slow.
13922                 # Limit testing on those media to larger sizes
13923                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13924                         $((stripe_size + 1024))"
13925         else
13926                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13927                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13928                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13929                         $((stripe_size - 1)) $stripe_size \
13930                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13931                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13932         fi
13933
13934         for bs in $bsizes; do
13935                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13936                 echo "bs: $bs"
13937                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13938                         oflag=direct conv=notrunc &
13939                 pid_dio1=$!
13940                 # Buffered I/O with similar but not the same block size
13941                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 &
13942                 pid_bio2=$!
13943                 wait $pid_dio1
13944                 rc1=$?
13945                 wait $pid_bio2
13946                 rc2=$?
13947                 if (( rc1 != 0 )); then
13948                         error "dio copy 1 w/bsize $bs failed: $rc1"
13949                 fi
13950                 if (( rc2 != 0 )); then
13951                         error "buffered copy 2 w/bsize $bs failed: $rc2"
13952                 fi
13953
13954                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13955                         error "size incorrect"
13956                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13957                         error "files differ, bsize $bs"
13958                 rm -f $DIR/$tfile.2
13959         done
13960 }
13961 run_test 119g "dio vs buffered I/O race"
13962
13963 test_119h()
13964 {
13965         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13966
13967         local stripe_size=$((1024 * 1024)) #1 MiB
13968         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13969         local file_size=$((25 * stripe_size))
13970         local bsizes
13971
13972         stack_trap "rm -f $DIR/$tfile.*"
13973
13974         if zfs_or_rotational; then
13975                 # DIO on ZFS can take up to 2 seconds per IO
13976                 # rotational is better, but still slow.
13977                 # Limit testing on those media to larger sizes
13978                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13979                         $((stripe_size + 1024))"
13980         else
13981                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13982                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13983                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13984                         $((stripe_size - 1)) $stripe_size \
13985                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13986                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13987         fi
13988
13989         for bs in $bsizes; do
13990                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13991                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13992                 echo "unaligned writes of blocksize: $bs"
13993                 # Write a file with unaligned DIO and regular DIO, and compare
13994                 # them
13995                 # with 'u', multiop randomly unaligns the io from the buffer
13996                 $MULTIOP $DIR/$tfile.1 \
13997                 oO_CREAT:O_RDWR:O_DIRECT:wu${bs}wu${bs}wu${bs}wu${bs}wu${bs} ||
13998                         error "multiop memory unaligned write failed, $bs"
13999                 $MULTIOP $DIR/$tfile.2 \
14000                 oO_CREAT:O_RDWR:O_DIRECT:w${bs}w${bs}w${bs}w${bs}w${bs} ||
14001                         error "multiop memory aligned write failed, $bs"
14002
14003                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
14004                         error "files differ, bsize $bs"
14005                 rm -f $DIR/$tfile.*
14006         done
14007
14008         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
14009         dd if=/dev/zero bs=$((stripe_size * 5)) of=$DIR/$tfile.1 count=5 ||
14010                 error "dd to create source file for read failed"
14011
14012         # Just a few quick tests to make sure unaligned DIO reads don't crash
14013         for bs in $bsizes; do
14014
14015                 echo "unaligned reads of blocksize: $bs"
14016                 # with 'u', multiop randomly unaligns the io from the buffer
14017                 $MULTIOP $DIR/$tfile.1 \
14018                 oO_CREAT:O_RDWR:O_DIRECT:ru${bs}ru${bs}ru${bs}ru${bs}ru${bs} ||
14019                         error "multiop memory unaligned read failed, $bs"
14020
14021         done
14022         rm -f $DIR/$tfile*
14023 }
14024 run_test 119h "basic tests of memory unaligned dio"
14025
14026 # aiocp with the '-a' option makes testing memory unaligned aio trivial
14027 test_119i()
14028 {
14029         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14030         which aiocp || skip_env "no aiocp installed"
14031
14032         local stripe_size=$((1024 * 1024)) #1 MiB
14033         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
14034         local file_size=$((25 * stripe_size))
14035         local bsizes
14036
14037         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
14038         stack_trap "rm -f $DIR/$tfile.*"
14039
14040         # Just a bit bigger than the largest size in the test set below
14041         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
14042                 error "buffered i/o to create file failed"
14043
14044         if zfs_or_rotational; then
14045                 # DIO on ZFS can take up to 2 seconds per IO
14046                 # rotational is better, but still slow.
14047                 # Limit testing on those media to larger sizes
14048                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
14049                         $((stripe_size + 1024))"
14050         else
14051                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
14052                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
14053                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
14054                         $((stripe_size - 1)) $stripe_size \
14055                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
14056                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
14057         fi
14058
14059         # Do page aligned and NOT page aligned AIO
14060         for align in 8 512 $((PAGE_SIZE)); do
14061         # Deliberately includes a few aligned sizes
14062         for bs in $bsizes; do
14063                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
14064
14065                 echo "bs: $bs, align: $align, file_size $file_size"
14066                 aiocp -a $align -b $bs -s $file_size -f O_DIRECT \
14067                         $DIR/$tfile.1 $DIR/$tfile.2 ||
14068                         error "unaligned aio failed, bs: $bs, align: $align"
14069
14070                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
14071                         error "size incorrect"
14072                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
14073                         error "files differ"
14074                 rm -f $DIR/$tfile.2
14075         done
14076         done
14077 }
14078 run_test 119i "test unaligned aio at varying sizes"
14079
14080 test_119j()
14081 {
14082         (( $LINUX_VERSION_CODE > $(version_code 4.5.0) )) ||
14083                 skip "needs kernel > 4.5.0 for ki_flags support"
14084
14085         local rpcs
14086         dd if=/dev/urandom of=$DIR/$tfile bs=8 count=1 || error "(0) dd failed"
14087         sync
14088         $LCTL set_param -n osc.*.rpc_stats=0
14089         # Read from page cache, does not generate an rpc
14090         dd if=$DIR/$tfile of=/dev/null bs=8 count=1 || error "(1) dd failed"
14091         $LCTL get_param osc.*.rpc_stats
14092         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
14093                 sed -n '/pages per rpc/,/^$/p' |
14094                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
14095                 END { print reads,writes }'))
14096         [[ ${rpcs[0]} == 0 ]] ||
14097                 error "(3) ${rpcs[0]} != 0 read RPCs"
14098
14099         # Test hybrid IO read
14100         # Force next BIO as DIO
14101         # This forces an RPC to the server
14102         #define OBD_FAIL_LLITE_FORCE_BIO_AS_DIO 0x1429
14103         $LCTL set_param fail_loc=0x1429
14104         dd if=$DIR/$tfile of=/dev/null bs=8 count=1 || error "(4) dd failed"
14105         $LCTL get_param osc.*.rpc_stats
14106         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
14107                 sed -n '/pages per rpc/,/^$/p' |
14108                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
14109                 END { print reads,writes }'))
14110         [[ ${rpcs[0]} == 1 ]] ||
14111                 error "(5) ${rpcs[0]} != 1 read RPCs"
14112
14113         # Test hybrid IO write
14114         #define OBD_FAIL_LLITE_FORCE_BIO_AS_DIO 0x1429
14115         $LCTL set_param fail_loc=0x1429
14116         #NB: We do not check for 0 write RPCs in the BIO case because that
14117         # would make the test racey vs cache flushing
14118         # but the DIO case is guaranteed to generate 1 write RPC
14119         dd if=/dev/zero of=$DIR/$tfile bs=8 count=1 || error "(6) dd failed"
14120         $LCTL get_param osc.*.rpc_stats
14121         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
14122                 sed -n '/pages per rpc/,/^$/p' |
14123                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
14124                 END { print reads,writes }'))
14125         [[ ${rpcs[1]} == 1 ]] ||
14126                 error "(7) ${rpcs[0]} != 1 read RPCs"
14127 }
14128 run_test 119j "basic tests of hybrid IO switching"
14129
14130 test_120a() {
14131         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14132         remote_mds_nodsh && skip "remote MDS with nodsh"
14133         test_mkdir -i0 -c1 $DIR/$tdir
14134         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14135                 skip_env "no early lock cancel on server"
14136
14137         lru_resize_disable mdc
14138         lru_resize_disable osc
14139         cancel_lru_locks mdc
14140         # asynchronous object destroy at MDT could cause bl ast to client
14141         cancel_lru_locks osc
14142
14143         stat $DIR/$tdir > /dev/null
14144         can1=$(do_facet mds1 \
14145                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14146                awk '/ldlm_cancel/ {print $2}')
14147         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14148                awk '/ldlm_bl_callback/ {print $2}')
14149         test_mkdir -i0 -c1 $DIR/$tdir/d1
14150         can2=$(do_facet mds1 \
14151                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14152                awk '/ldlm_cancel/ {print $2}')
14153         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14154                awk '/ldlm_bl_callback/ {print $2}')
14155         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14156         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14157         lru_resize_enable mdc
14158         lru_resize_enable osc
14159 }
14160 run_test 120a "Early Lock Cancel: mkdir test"
14161
14162 test_120b() {
14163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14164         remote_mds_nodsh && skip "remote MDS with nodsh"
14165         test_mkdir $DIR/$tdir
14166         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14167                 skip_env "no early lock cancel on server"
14168
14169         lru_resize_disable mdc
14170         lru_resize_disable osc
14171         cancel_lru_locks mdc
14172         stat $DIR/$tdir > /dev/null
14173         can1=$(do_facet $SINGLEMDS \
14174                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14175                awk '/ldlm_cancel/ {print $2}')
14176         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14177                awk '/ldlm_bl_callback/ {print $2}')
14178         touch $DIR/$tdir/f1
14179         can2=$(do_facet $SINGLEMDS \
14180                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14181                awk '/ldlm_cancel/ {print $2}')
14182         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14183                awk '/ldlm_bl_callback/ {print $2}')
14184         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14185         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14186         lru_resize_enable mdc
14187         lru_resize_enable osc
14188 }
14189 run_test 120b "Early Lock Cancel: create test"
14190
14191 test_120c() {
14192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14193         remote_mds_nodsh && skip "remote MDS with nodsh"
14194         test_mkdir -i0 -c1 $DIR/$tdir
14195         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14196                 skip "no early lock cancel on server"
14197
14198         lru_resize_disable mdc
14199         lru_resize_disable osc
14200         test_mkdir -i0 -c1 $DIR/$tdir/d1
14201         test_mkdir -i0 -c1 $DIR/$tdir/d2
14202         touch $DIR/$tdir/d1/f1
14203         cancel_lru_locks mdc
14204         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
14205         can1=$(do_facet mds1 \
14206                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14207                awk '/ldlm_cancel/ {print $2}')
14208         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14209                awk '/ldlm_bl_callback/ {print $2}')
14210         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
14211         can2=$(do_facet mds1 \
14212                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14213                awk '/ldlm_cancel/ {print $2}')
14214         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14215                awk '/ldlm_bl_callback/ {print $2}')
14216         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14217         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14218         lru_resize_enable mdc
14219         lru_resize_enable osc
14220 }
14221 run_test 120c "Early Lock Cancel: link test"
14222
14223 test_120d() {
14224         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14225         remote_mds_nodsh && skip "remote MDS with nodsh"
14226         test_mkdir -i0 -c1 $DIR/$tdir
14227         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14228                 skip_env "no early lock cancel on server"
14229
14230         lru_resize_disable mdc
14231         lru_resize_disable osc
14232         touch $DIR/$tdir
14233         cancel_lru_locks mdc
14234         stat $DIR/$tdir > /dev/null
14235         can1=$(do_facet mds1 \
14236                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14237                awk '/ldlm_cancel/ {print $2}')
14238         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14239                awk '/ldlm_bl_callback/ {print $2}')
14240         chmod a+x $DIR/$tdir
14241         can2=$(do_facet mds1 \
14242                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14243                awk '/ldlm_cancel/ {print $2}')
14244         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14245                awk '/ldlm_bl_callback/ {print $2}')
14246         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14247         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14248         lru_resize_enable mdc
14249         lru_resize_enable osc
14250 }
14251 run_test 120d "Early Lock Cancel: setattr test"
14252
14253 test_120e() {
14254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14255         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14256                 skip_env "no early lock cancel on server"
14257         remote_mds_nodsh && skip "remote MDS with nodsh"
14258
14259         local dlmtrace_set=false
14260
14261         test_mkdir -i0 -c1 $DIR/$tdir
14262         lru_resize_disable mdc
14263         lru_resize_disable osc
14264         ! $LCTL get_param debug | grep -q dlmtrace &&
14265                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
14266         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
14267         cancel_lru_locks mdc
14268         cancel_lru_locks osc
14269         dd if=$DIR/$tdir/f1 of=/dev/null
14270         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
14271         # XXX client can not do early lock cancel of OST lock
14272         # during unlink (LU-4206), so cancel osc lock now.
14273         sleep 2
14274         cancel_lru_locks osc
14275         can1=$(do_facet mds1 \
14276                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14277                awk '/ldlm_cancel/ {print $2}')
14278         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14279                awk '/ldlm_bl_callback/ {print $2}')
14280         unlink $DIR/$tdir/f1
14281         sleep 5
14282         can2=$(do_facet mds1 \
14283                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14284                awk '/ldlm_cancel/ {print $2}')
14285         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14286                awk '/ldlm_bl_callback/ {print $2}')
14287         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
14288                 $LCTL dk $TMP/cancel.debug.txt
14289         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
14290                 $LCTL dk $TMP/blocking.debug.txt
14291         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
14292         lru_resize_enable mdc
14293         lru_resize_enable osc
14294 }
14295 run_test 120e "Early Lock Cancel: unlink test"
14296
14297 test_120f() {
14298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14299         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14300                 skip_env "no early lock cancel on server"
14301         remote_mds_nodsh && skip "remote MDS with nodsh"
14302
14303         test_mkdir -i0 -c1 $DIR/$tdir
14304         lru_resize_disable mdc
14305         lru_resize_disable osc
14306         test_mkdir -i0 -c1 $DIR/$tdir/d1
14307         test_mkdir -i0 -c1 $DIR/$tdir/d2
14308         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
14309         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
14310         cancel_lru_locks mdc
14311         cancel_lru_locks osc
14312         dd if=$DIR/$tdir/d1/f1 of=/dev/null
14313         dd if=$DIR/$tdir/d2/f2 of=/dev/null
14314         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
14315         # XXX client can not do early lock cancel of OST lock
14316         # during rename (LU-4206), so cancel osc lock now.
14317         sleep 2
14318         cancel_lru_locks osc
14319         can1=$(do_facet mds1 \
14320                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14321                awk '/ldlm_cancel/ {print $2}')
14322         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14323                awk '/ldlm_bl_callback/ {print $2}')
14324         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
14325         sleep 5
14326         can2=$(do_facet mds1 \
14327                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14328                awk '/ldlm_cancel/ {print $2}')
14329         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14330                awk '/ldlm_bl_callback/ {print $2}')
14331         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14332         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14333         lru_resize_enable mdc
14334         lru_resize_enable osc
14335 }
14336 run_test 120f "Early Lock Cancel: rename test"
14337
14338 test_120g() {
14339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14340         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14341                 skip_env "no early lock cancel on server"
14342         remote_mds_nodsh && skip "remote MDS with nodsh"
14343
14344         lru_resize_disable mdc
14345         lru_resize_disable osc
14346         count=10000
14347         echo create $count files
14348         test_mkdir $DIR/$tdir
14349         cancel_lru_locks mdc
14350         cancel_lru_locks osc
14351         t0=$(date +%s)
14352
14353         can0=$(do_facet $SINGLEMDS \
14354                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14355                awk '/ldlm_cancel/ {print $2}')
14356         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14357                awk '/ldlm_bl_callback/ {print $2}')
14358         createmany -o $DIR/$tdir/f $count
14359         sync
14360         can1=$(do_facet $SINGLEMDS \
14361                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14362                awk '/ldlm_cancel/ {print $2}')
14363         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14364                awk '/ldlm_bl_callback/ {print $2}')
14365         t1=$(date +%s)
14366         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
14367         echo rm $count files
14368         rm -r $DIR/$tdir
14369         sync
14370         can2=$(do_facet $SINGLEMDS \
14371                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14372                awk '/ldlm_cancel/ {print $2}')
14373         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14374                awk '/ldlm_bl_callback/ {print $2}')
14375         t2=$(date +%s)
14376         echo total: $count removes in $((t2-t1))
14377         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
14378         sleep 2
14379         # wait for commitment of removal
14380         lru_resize_enable mdc
14381         lru_resize_enable osc
14382 }
14383 run_test 120g "Early Lock Cancel: performance test"
14384
14385 test_121() { #bug #10589
14386         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14387
14388         rm -rf $DIR/$tfile
14389         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
14390 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
14391         lctl set_param fail_loc=0x310
14392         cancel_lru_locks osc > /dev/null
14393         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
14394         lctl set_param fail_loc=0
14395         [[ $reads -eq $writes ]] ||
14396                 error "read $reads blocks, must be $writes blocks"
14397 }
14398 run_test 121 "read cancel race ========="
14399
14400 test_123a_base() { # was test 123, statahead(bug 11401)
14401         local lsx="$1"
14402
14403         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
14404
14405         SLOWOK=0
14406         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
14407                 log "testing UP system. Performance may be lower than expected."
14408                 SLOWOK=1
14409         fi
14410         running_in_vm && SLOWOK=1
14411
14412         $LCTL set_param mdc.*.batch_stats=0
14413
14414         rm -rf $DIR/$tdir
14415         test_mkdir $DIR/$tdir
14416         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
14417         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
14418         MULT=10
14419         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
14420                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
14421
14422                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
14423                 lctl set_param -n llite.*.statahead_max 0
14424                 lctl get_param llite.*.statahead_max
14425                 cancel_lru_locks mdc
14426                 cancel_lru_locks osc
14427                 stime=$(date +%s)
14428                 time $lsx $DIR/$tdir | wc -l
14429                 etime=$(date +%s)
14430                 delta=$((etime - stime))
14431                 log "$lsx $i files without statahead: $delta sec"
14432                 lctl set_param llite.*.statahead_max=$max
14433
14434                 swrong=$(lctl get_param -n llite.*.statahead_stats |
14435                          awk '/statahead.wrong:/ { print $NF }')
14436                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
14437                 cancel_lru_locks mdc
14438                 cancel_lru_locks osc
14439                 stime=$(date +%s)
14440                 time $lsx $DIR/$tdir | wc -l
14441                 etime=$(date +%s)
14442                 delta_sa=$((etime - stime))
14443                 log "$lsx $i files with statahead: $delta_sa sec"
14444                 lctl get_param -n llite.*.statahead_stats
14445                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
14446                          awk '/statahead.wrong:/ { print $NF }')
14447
14448                 [[ $swrong -lt $ewrong ]] &&
14449                         log "statahead was stopped, maybe too many locks held!"
14450                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
14451
14452                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
14453                         max=$(lctl get_param -n llite.*.statahead_max |
14454                                 head -n 1)
14455                         lctl set_param -n llite.*.statahead_max 0
14456                         lctl get_param llite.*.statahead_max
14457                         cancel_lru_locks mdc
14458                         cancel_lru_locks osc
14459                         stime=$(date +%s)
14460                         time $lsx $DIR/$tdir | wc -l
14461                         etime=$(date +%s)
14462                         delta=$((etime - stime))
14463                         log "$lsx $i files again without statahead: $delta sec"
14464                         lctl set_param llite.*.statahead_max=$max
14465                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
14466                                 if [ $SLOWOK -eq 0 ]; then
14467                                         error "$lsx $i files is slower with statahead!"
14468                                 else
14469                                         log "$lsx $i files is slower with statahead!"
14470                                 fi
14471                                 break
14472                         fi
14473                 fi
14474
14475                 [ $delta -gt 20 ] && break
14476                 [ $delta -gt 8 ] && MULT=$((50 / delta))
14477                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
14478         done
14479         log "$lsx done"
14480
14481         stime=$(date +%s)
14482         rm -r $DIR/$tdir
14483         sync
14484         etime=$(date +%s)
14485         delta=$((etime - stime))
14486         log "rm -r $DIR/$tdir/: $delta seconds"
14487         log "rm done"
14488         lctl get_param -n llite.*.statahead_stats
14489         $LCTL get_param mdc.*.batch_stats
14490 }
14491
14492 test_123aa() {
14493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14494
14495         test_123a_base "ls -l"
14496 }
14497 run_test 123aa "verify statahead work"
14498
14499 test_123ab() {
14500         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14501
14502         statx_supported || skip_env "Test must be statx() syscall supported"
14503
14504         test_123a_base "$STATX -l"
14505 }
14506 run_test 123ab "verify statahead work by using statx"
14507
14508 test_123ac() {
14509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14510
14511         statx_supported || skip_env "Test must be statx() syscall supported"
14512
14513         local rpcs_before
14514         local rpcs_after
14515         local agl_before
14516         local agl_after
14517
14518         cancel_lru_locks $OSC
14519         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14520         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
14521                      awk '/agl.total:/ { print $NF }')
14522         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
14523         test_123a_base "$STATX --cached=always -D"
14524         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
14525                     awk '/agl.total:/ { print $NF }')
14526         [ $agl_before -eq $agl_after ] ||
14527                 error "Should not trigger AGL thread - $agl_before:$agl_after"
14528         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14529         [ $rpcs_after -eq $rpcs_before ] ||
14530                 error "$STATX should not send glimpse RPCs to $OSC"
14531 }
14532 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
14533
14534 test_batch_statahead() {
14535         local max=$1
14536         local batch_max=$2
14537         local num=10000
14538         local batch_rpcs
14539         local unbatch_rpcs
14540         local hit_total
14541
14542         echo -e "\nbatching: statahead_max=$max statahead_batch_max=$batch_max"
14543         $LCTL set_param mdc.*.batch_stats=0
14544         $LCTL set_param llite.*.statahead_max=$max
14545         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14546         # Verify that batched statahead is faster than one without statahead
14547         test_123a_base "ls -l"
14548
14549         stack_trap "rm -rf $DIR/$tdir" EXIT
14550         mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
14551         createmany -o $DIR/$tdir/$tfile $num || error "failed to create files"
14552
14553         # unbatched statahead
14554         $LCTL set_param llite.*.statahead_batch_max=0
14555         $LCTL set_param llite.*.statahead_stats=clear
14556         $LCTL set_param mdc.*.stats=clear
14557         cancel_lru_locks mdc
14558         cancel_lru_locks osc
14559         time ls -l $DIR/$tdir | wc -l
14560         unbatch_rpcs=$(calc_stats mdc.*.stats ldlm_ibits_enqueue)
14561         wait_update_facet client "pgrep ll_sa" "" 35 ||
14562                 error "ll_sa thread is still running"
14563         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14564                     awk '/hit.total:/ { print $NF }')
14565         # hit ratio should be larger than 75% (7500).
14566         (( $hit_total > 7500 )) ||
14567                 error "unbatched statahead hit count ($hit_total) is too low"
14568
14569         # batched statahead
14570         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14571         $LCTL set_param llite.*.statahead_stats=clear
14572         $LCTL set_param mdc.*.batch_stats=clear
14573         $LCTL set_param mdc.*.stats=clear
14574         cancel_lru_locks mdc
14575         cancel_lru_locks osc
14576         time ls -l $DIR/$tdir | wc -l
14577         batch_rpcs=$(calc_stats mdc.*.stats mds_batch)
14578         # wait for statahead thread to quit and update statahead stats
14579         wait_update_facet client "pgrep ll_sa" "" 35 ||
14580                 error "ll_sa thread is still running"
14581         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14582                     awk '/hit.total:/ { print $NF }')
14583         # hit ratio should be larger than 75% (7500).
14584         (( $hit_total > 7500 )) ||
14585                 error "batched statahead hit count ($hit_total) is too low"
14586
14587         echo "unbatched RPCs: $unbatch_rpcs, batched RPCs: $batch_rpcs"
14588         (( $unbatch_rpcs > $batch_rpcs )) ||
14589                 error "batched statahead does not reduce RPC count"
14590         $LCTL get_param mdc.*.batch_stats
14591 }
14592
14593 test_123ad() {
14594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14595
14596         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
14597                 skip "Need server version at least 2.15.53"
14598
14599         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14600                 skip "Server does not support batch RPC"
14601
14602         local max
14603         local batch_max
14604
14605         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14606         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14607
14608         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14609         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14610
14611         test_batch_statahead 32 32
14612         test_batch_statahead 2048 256
14613 }
14614 run_test 123ad "Verify batching statahead works correctly"
14615
14616 test_123b () { # statahead(bug 15027)
14617         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14618
14619         test_mkdir $DIR/$tdir
14620         createmany -o $DIR/$tdir/$tfile-%d 1000
14621
14622         cancel_lru_locks mdc
14623         cancel_lru_locks osc
14624
14625 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
14626         lctl set_param fail_loc=0x80000803
14627         ls -lR $DIR/$tdir > /dev/null
14628         log "ls done"
14629         lctl set_param fail_loc=0x0
14630         lctl get_param -n llite.*.statahead_stats
14631         rm -r $DIR/$tdir
14632         sync
14633
14634 }
14635 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
14636
14637 test_123c() {
14638         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
14639
14640         test_mkdir -i 0 -c 1 $DIR/$tdir.0
14641         test_mkdir -i 1 -c 1 $DIR/$tdir.1
14642         touch $DIR/$tdir.1/{1..3}
14643         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
14644
14645         remount_client $MOUNT
14646
14647         $MULTIOP $DIR/$tdir.0 Q
14648
14649         # let statahead to complete
14650         ls -l $DIR/$tdir.0 > /dev/null
14651
14652         testid=$(echo $TESTNAME | tr '_' ' ')
14653         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
14654                 error "statahead warning" || true
14655 }
14656 run_test 123c "Can not initialize inode warning on DNE statahead"
14657
14658 test_123d() {
14659         local num=100
14660         local swrong
14661         local ewrong
14662
14663         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
14664         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
14665                 error "setdirstripe $DIR/$tdir failed"
14666         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
14667         remount_client $MOUNT
14668         $LCTL get_param llite.*.statahead_max
14669         $LCTL set_param llite.*.statahead_stats=0 ||
14670                 error "clear statahead_stats failed"
14671         swrong=$(lctl get_param -n llite.*.statahead_stats |
14672                  awk '/statahead.wrong:/ { print $NF }')
14673         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
14674         # wait for statahead thread finished to update hit/miss stats.
14675         sleep 1
14676         $LCTL get_param -n llite.*.statahead_stats
14677         ewrong=$(lctl get_param -n llite.*.statahead_stats |
14678                  awk '/statahead.wrong:/ { print $NF }')
14679         (( $swrong == $ewrong )) ||
14680                 log "statahead was stopped, maybe too many locks held!"
14681 }
14682 run_test 123d "Statahead on striped directories works correctly"
14683
14684 test_123e() {
14685         local max
14686         local batch_max
14687         local dir=$DIR/$tdir
14688
14689         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14690                 skip "Server does not support batch RPC"
14691
14692         mkdir $dir || error "mkdir $dir failed"
14693         $LFS setstripe -C 32 $dir || error "setstripe $dir failed"
14694         stack_trap "rm -rf $dir"
14695
14696         touch $dir/$tfile.{0..1000} || error "touch 1000 files failed"
14697
14698         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14699         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14700         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14701         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14702
14703         $LCTL set_param llite.*.statahead_max=2048
14704         $LCTL set_param llite.*.statahead_batch_max=1024
14705
14706         ls -l $dir
14707         $LCTL get_param mdc.*.batch_stats
14708         $LCTL get_param llite.*.statahead_*
14709 }
14710 run_test 123e "statahead with large wide striping"
14711
14712 test_123f() {
14713         local max
14714         local batch_max
14715         local dir=$DIR/$tdir
14716
14717         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14718                 skip "Server does not support batch RPC"
14719
14720         mkdir $dir || error "mkdir $dir failed"
14721         $LFS setstripe -C 1000 $dir || error "setstripe $dir failed"
14722         stack_trap "rm -rf $dir"
14723
14724         touch $dir/$tfile.{0..200} || error "touch 200 files failed"
14725
14726         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14727         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14728
14729         $LCTL set_param llite.*.statahead_max=64
14730         $LCTL set_param llite.*.statahead_batch_max=64
14731
14732         ls -l $dir
14733         lctl get_param mdc.*.batch_stats
14734         lctl get_param llite.*.statahead_*
14735
14736         $LCTL set_param llite.*.statahead_max=$max
14737         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14738 }
14739 run_test 123f "Retry mechanism with large wide striping files"
14740
14741 test_123g() {
14742         local dir=$DIR/$tdir
14743         local num=1000
14744
14745         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14746                 skip "Server does not support batch RPC"
14747
14748         mkdir $dir || error "failed to mkdir $dir"
14749         createmany -o $dir/$tfile $num || error "failed creatmany files"
14750         cancel_lru_locks mdc
14751         cancel_lru_locks osc
14752
14753         $LCTL set_param llite.*.statahead_stats=clear
14754         $LCTL set_param mdc.*.batch_stats=clear
14755         aheadmany -c stat -s 0 -e $num -b $tfile -d $dir ||
14756                 error "aheadmany $dir with $tfile failed"
14757         wait_update_facet client "pgrep ll_sa" "" 35 ||
14758                 error "ll_sa thread is still running"
14759         $LCTL get_param -n llite.*.statahead_stats
14760         $LCTL get_param -n mdc.*.batch_stats
14761
14762         local count
14763
14764         count=$($LCTL get_param -n llite.*.statahead_stats |
14765                 awk '/hit.total:/ {print $2}')
14766         echo "Hit total: $count"
14767         # Hit ratio should be >= 75%
14768         (( $count > num * 75 / 100 )) ||
14769                 error "hit total $count is be > 75% of $num"
14770 }
14771 run_test 123g "Test for stat-ahead advise"
14772
14773 test_123h_base() {
14774         local dir=$DIR/$tdir
14775         local cmd="touch $dir/$tfile.{$1}"
14776         local fcnt=$2
14777
14778         stack_trap "rm -rf $dir"
14779         mkdir -p $dir || error "failed to mkdir $dir"
14780         eval $cmd
14781
14782         cancel_lru_locks mdc
14783         $LCTL set_param llite.*.statahead_stats=clear
14784         $LCTL set_param mdc.*.batch_stats=0
14785         $LCTL set_param llite.*.statahead_max=1024
14786         $LCTL set_param llite.*.statahead_batch_max=1024
14787         lctl get_param -n llite.*.statahead_stats
14788         du -a $dir > /dev/null
14789         echo "Wait 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 > fcnt * 75 / 100 )) ||
14803                 error "hit total is too low: $count"
14804         rm -rf $dir || error "rm -rf $dir failed"
14805 }
14806
14807 test_123h() {
14808         local max
14809         local batch_max
14810         local enabled
14811
14812         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14813                 skip "Server does not support batch RPC"
14814
14815         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14816         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14817         enabled=$($LCTL get_param -n llite.*.enable_statahead_fname | head -n 1)
14818         stack_trap "$LCTL set_param llite.*.statahead_max=$max"
14819         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max"
14820         stack_trap "$LCTL set_param llite.*.enable_statahead_fname=$enabled"
14821
14822         $LCTL set_param llite.*.enable_statahead_fname=1
14823
14824         echo "Scan a directory with number regularized fname"
14825         test_123h_base "0..10000" 10000
14826
14827         echo "Scan a directory with zeroed padding number regularized fname"
14828         test_123h_base "000000..010000" 10000
14829 }
14830 run_test 123h "Verify statahead work with the fname pattern via du"
14831
14832 test_123i_base() {
14833         local fmt=$1
14834         local iocmd=$2
14835         local dir=$DIR/$tdir
14836         local cmd="createmany -m $fmt"
14837
14838         echo "Command:"
14839         echo "- $cmd"
14840         echo "- $iocmd"
14841         stack_trap "unlinkmany $fmt"
14842         mkdir -p $dir || error "failed to mkdir $dir"
14843         eval $cmd
14844
14845         cancel_lru_locks mdc
14846         $LCTL set_param llite.*.statahead_stats=clear
14847         $LCTL set_param mdc.*.batch_stats=0
14848
14849         echo "statahead_stats (Pre):"
14850         lctl get_param -n llite.*.statahead_stats
14851         eval $iocmd || error "$iocmd failed"
14852         echo "statahead_stats (Post):"
14853         $LCTL get_param -n llite.*.statahead_stats
14854         $LCTL get_param -n mdc.*.batch_stats
14855
14856         echo "Wait the statahead thread (ll_sa_xxx) to exit ..."
14857         wait_update_facet client "pgrep ll_sa" "" 35 ||
14858                 error "ll_sa statahead thread does not quit in 35s"
14859         $LCTL get_param -n llite.*.statahead_stats
14860         $LCTL get_param -n mdc.*.batch_stats
14861
14862         local count=$($LCTL get_param -n llite.*.statahead_stats |
14863                         awk '/fname.total:/ {print $2}')
14864
14865         [ $count == 1 ] || error "File name pattern statahead not trigger"
14866         count=$($LCTL get_param -n llite.*.statahead_stats |
14867                 awk '/hit.total:/ {print $2}')
14868         # Hit ratio should be >= 75%
14869         (( $count > 750 )) || error "hit total is too low: $count"
14870 }
14871
14872 test_123i() {
14873         local dir=$DIR/$tdir
14874         local cnt=1000
14875         local max
14876         local batch_max
14877         local enabled
14878         local min
14879
14880         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14881                 skip "Server does not support batch RPC"
14882
14883         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14884         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14885         min=$($LCTL get_param -n llite.*.statahead_min | head -n 1)
14886         enabled=$($LCTL get_param -n llite.*.enable_statahead_fname | head -n 1)
14887         stack_trap "$LCTL set_param llite.*.statahead_max=$max"
14888         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max"
14889         stack_trap "$LCTL set_param llite.*.statahead_min=$min"
14890         stack_trap "$LCTL set_param llite.*.enable_statahead_fname=$enabled"
14891         $LCTL set_param llite.*.statahead_max=1024
14892         $LCTL set_param llite.*.statahead_batch_max=32
14893         $LCTL set_param llite.*.statahead_min=64
14894         $LCTL set_param llite.*.enable_statahead_fname=1
14895
14896         test_123i_base "$dir/$tfile.%06d $cnt" "ls $dir/* > /dev/null"
14897         test_123i_base "$dir/$tfile $cnt" \
14898                 "aheadmany -c stat -N -s 0 -e $cnt -b $tfile -d $dir"
14899 }
14900 run_test 123i "Verify statahead work with the fname indexing pattern"
14901
14902 test_124a() {
14903         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14904         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14905                 skip_env "no lru resize on server"
14906
14907         local NR=2000
14908
14909         test_mkdir $DIR/$tdir
14910
14911         log "create $NR files at $DIR/$tdir"
14912         createmany -o $DIR/$tdir/f $NR ||
14913                 error "failed to create $NR files in $DIR/$tdir"
14914
14915         cancel_lru_locks mdc
14916         ls -l $DIR/$tdir > /dev/null
14917
14918         local NSDIR=""
14919         local LRU_SIZE=0
14920         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
14921                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
14922                 LRU_SIZE=$($LCTL get_param -n $PARAM)
14923                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
14924                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
14925                         log "NSDIR=$NSDIR"
14926                         log "NS=$(basename $NSDIR)"
14927                         break
14928                 fi
14929         done
14930
14931         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
14932                 skip "Not enough cached locks created!"
14933         fi
14934         log "LRU=$LRU_SIZE"
14935
14936         local SLEEP=30
14937
14938         # We know that lru resize allows one client to hold $LIMIT locks
14939         # for 10h. After that locks begin to be killed by client.
14940         local MAX_HRS=10
14941         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
14942         log "LIMIT=$LIMIT"
14943         if [ $LIMIT -lt $LRU_SIZE ]; then
14944                 skip "Limit is too small $LIMIT"
14945         fi
14946
14947         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
14948         # killing locks. Some time was spent for creating locks. This means
14949         # that up to the moment of sleep finish we must have killed some of
14950         # them (10-100 locks). This depends on how fast ther were created.
14951         # Many of them were touched in almost the same moment and thus will
14952         # be killed in groups.
14953         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
14954
14955         # Use $LRU_SIZE_B here to take into account real number of locks
14956         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
14957         local LRU_SIZE_B=$LRU_SIZE
14958         log "LVF=$LVF"
14959         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
14960         log "OLD_LVF=$OLD_LVF"
14961         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
14962
14963         # Let's make sure that we really have some margin. Client checks
14964         # cached locks every 10 sec.
14965         SLEEP=$((SLEEP+20))
14966         log "Sleep ${SLEEP} sec"
14967         local SEC=0
14968         while ((SEC<$SLEEP)); do
14969                 echo -n "..."
14970                 sleep 5
14971                 SEC=$((SEC+5))
14972                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
14973                 echo -n "$LRU_SIZE"
14974         done
14975         echo ""
14976         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
14977         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
14978
14979         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
14980                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
14981                 unlinkmany $DIR/$tdir/f $NR
14982                 return
14983         }
14984
14985         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
14986         log "unlink $NR files at $DIR/$tdir"
14987         unlinkmany $DIR/$tdir/f $NR
14988 }
14989 run_test 124a "lru resize ======================================="
14990
14991 get_max_pool_limit()
14992 {
14993         local limit=$($LCTL get_param \
14994                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
14995         local max=0
14996         for l in $limit; do
14997                 if [[ $l -gt $max ]]; then
14998                         max=$l
14999                 fi
15000         done
15001         echo $max
15002 }
15003
15004 test_124b() {
15005         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15006         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
15007                 skip_env "no lru resize on server"
15008
15009         LIMIT=$(get_max_pool_limit)
15010
15011         NR=$(($(default_lru_size)*20))
15012         if [[ $NR -gt $LIMIT ]]; then
15013                 log "Limit lock number by $LIMIT locks"
15014                 NR=$LIMIT
15015         fi
15016
15017         IFree=$(mdsrate_inodes_available)
15018         if [ $IFree -lt $NR ]; then
15019                 log "Limit lock number by $IFree inodes"
15020                 NR=$IFree
15021         fi
15022
15023         lru_resize_disable mdc
15024         test_mkdir -p $DIR/$tdir/disable_lru_resize
15025
15026         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
15027         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
15028         cancel_lru_locks mdc
15029         stime=`date +%s`
15030         PID=""
15031         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
15032         PID="$PID $!"
15033         sleep 2
15034         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
15035         PID="$PID $!"
15036         sleep 2
15037         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
15038         PID="$PID $!"
15039         wait $PID
15040         etime=`date +%s`
15041         nolruresize_delta=$((etime-stime))
15042         log "ls -la time: $nolruresize_delta seconds"
15043         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
15044         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
15045
15046         lru_resize_enable mdc
15047         test_mkdir -p $DIR/$tdir/enable_lru_resize
15048
15049         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
15050         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
15051         cancel_lru_locks mdc
15052         stime=`date +%s`
15053         PID=""
15054         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
15055         PID="$PID $!"
15056         sleep 2
15057         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
15058         PID="$PID $!"
15059         sleep 2
15060         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
15061         PID="$PID $!"
15062         wait $PID
15063         etime=`date +%s`
15064         lruresize_delta=$((etime-stime))
15065         log "ls -la time: $lruresize_delta seconds"
15066         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
15067
15068         if [ $lruresize_delta -gt $nolruresize_delta ]; then
15069                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
15070         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
15071                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
15072         else
15073                 log "lru resize performs the same with no lru resize"
15074         fi
15075         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
15076 }
15077 run_test 124b "lru resize (performance test) ======================="
15078
15079 test_124c() {
15080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15081         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
15082                 skip_env "no lru resize on server"
15083
15084         # cache ununsed locks on client
15085         local nr=100
15086         cancel_lru_locks mdc
15087         test_mkdir $DIR/$tdir
15088         createmany -o $DIR/$tdir/f $nr ||
15089                 error "failed to create $nr files in $DIR/$tdir"
15090         ls -l $DIR/$tdir > /dev/null
15091
15092         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15093         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15094         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
15095         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
15096         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
15097
15098         # set lru_max_age to 1 sec
15099         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
15100         echo "sleep $((recalc_p * 2)) seconds..."
15101         sleep $((recalc_p * 2))
15102
15103         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
15104         # restore lru_max_age
15105         $LCTL set_param -n $nsdir.lru_max_age $max_age
15106         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
15107         unlinkmany $DIR/$tdir/f $nr
15108 }
15109 run_test 124c "LRUR cancel very aged locks"
15110
15111 test_124d() {
15112         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15113         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
15114                 skip_env "no lru resize on server"
15115
15116         # cache ununsed locks on client
15117         local nr=100
15118
15119         lru_resize_disable mdc
15120         stack_trap "lru_resize_enable mdc" EXIT
15121
15122         cancel_lru_locks mdc
15123
15124         # asynchronous object destroy at MDT could cause bl ast to client
15125         test_mkdir $DIR/$tdir
15126         createmany -o $DIR/$tdir/f $nr ||
15127                 error "failed to create $nr files in $DIR/$tdir"
15128         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
15129
15130         ls -l $DIR/$tdir > /dev/null
15131
15132         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15133         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15134         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
15135         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
15136
15137         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
15138
15139         # set lru_max_age to 1 sec
15140         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
15141         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
15142
15143         echo "sleep $((recalc_p * 2)) seconds..."
15144         sleep $((recalc_p * 2))
15145
15146         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
15147
15148         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
15149 }
15150 run_test 124d "cancel very aged locks if lru-resize disabled"
15151
15152 test_125() { # 13358
15153         $LCTL get_param -n llite.*.client_type | grep -q local ||
15154                 skip "must run as local client"
15155         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
15156                 skip_env "must have acl enabled"
15157         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15158         id $USER0 || skip_env "missing user $USER0"
15159
15160         test_mkdir $DIR/$tdir
15161         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
15162         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
15163                 error "setfacl $DIR/$tdir failed"
15164         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
15165 }
15166 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
15167
15168 test_126() { # bug 12829/13455
15169         $GSS && skip_env "must run as gss disabled"
15170         $LCTL get_param -n llite.*.client_type | grep -q local ||
15171                 skip "must run as local client"
15172         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
15173
15174         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
15175         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
15176         rm -f $DIR/$tfile
15177         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
15178 }
15179 run_test 126 "check that the fsgid provided by the client is taken into account"
15180
15181 test_127a() { # bug 15521
15182         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15183         local name count samp unit min max sum sumsq
15184         local tmpfile=$TMP/$tfile.tmp
15185
15186         # enable stats header if it is disabled
15187         $LCTL set_param enable_stats_header=1
15188
15189         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
15190         echo "stats before reset"
15191         stack_trap "rm -f $tmpfile"
15192         local now=$(date +%s)
15193
15194         $LCTL get_param osc.*.stats | tee $tmpfile
15195
15196         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
15197         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
15198         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
15199         local uptime=$(awk '{ print $1 }' /proc/uptime)
15200
15201         # snapshot_time should match POSIX epoch time, allow some delta for VMs
15202         (( ${snapshot_time%\.*} >= $now - 5 &&
15203            ${snapshot_time%\.*} <= $now + 5 )) ||
15204                 error "snapshot_time=$snapshot_time != now=$now"
15205         # elapsed _should_ be from mount, but at least less than uptime
15206         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
15207                 error "elapsed=$elapsed > uptime=$uptime"
15208         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
15209            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
15210                 error "elapsed=$elapsed != $snapshot_time - $start_time"
15211
15212         $LCTL set_param osc.*.stats=0
15213         local reset=$(date +%s)
15214         local fsize=$((2048 * 1024))
15215
15216         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
15217         cancel_lru_locks osc
15218         dd if=$DIR/$tfile of=/dev/null bs=$fsize
15219
15220         now=$(date +%s)
15221         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
15222         while read name count samp unit min max sum sumsq; do
15223                 [[ "$samp" == "samples" ]] || continue
15224
15225                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
15226                 [ ! $min ] && error "Missing min value for $name proc entry"
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                         (( $min >= 4096 )) || error "min is too small: $min"
15234                         (( $min <= $fsize )) || error "min is too big: $min"
15235                         (( $max >= 4096 )) || error "max is too small: $max"
15236                         (( $max <= $fsize )) || error "max is too big: $max"
15237                         (( $sum == $fsize )) || error "sum is wrong: $sum"
15238                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
15239                                 error "sumsquare is too small: $sumsq"
15240                         (( $sumsq <= $fsize * $fsize )) ||
15241                                 error "sumsquare is too big: $sumsq"
15242                         ;;
15243                 ost_read|ost_write)
15244                         [[ "$unit" =~ "usec" ]] ||
15245                                 error "unit is not 'usec': $unit"
15246                         ;;
15247                 *)      ;;
15248                 esac
15249         done < $tmpfile
15250
15251         #check that we actually got some stats
15252         [ "$read_bytes" ] || error "Missing read_bytes stats"
15253         [ "$write_bytes" ] || error "Missing write_bytes stats"
15254         [ "$read_bytes" != 0 ] || error "no read done"
15255         [ "$write_bytes" != 0 ] || error "no write done"
15256
15257         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
15258         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
15259         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
15260
15261         # snapshot_time should match POSIX epoch time, allow some delta for VMs
15262         (( ${snapshot_time%\.*} >= $now - 5 &&
15263            ${snapshot_time%\.*} <= $now + 5 )) ||
15264                 error "reset snapshot_time=$snapshot_time != now=$now"
15265         # elapsed should be from time of stats reset
15266         (( ${elapsed%\.*} >= $now - $reset - 2 &&
15267            ${elapsed%\.*} <= $now - $reset + 2 )) ||
15268                 error "reset elapsed=$elapsed > $now - $reset"
15269         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
15270            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
15271                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
15272 }
15273 run_test 127a "verify the client stats are sane"
15274
15275 test_127b() { # bug LU-333
15276         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15277         local name count samp unit min max sum sumsq
15278
15279         echo "stats before reset"
15280         $LCTL get_param llite.*.stats
15281         $LCTL set_param llite.*.stats=0
15282
15283         # perform 2 reads and writes so MAX is different from SUM.
15284         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
15285         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
15286         cancel_lru_locks osc
15287         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
15288         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
15289
15290         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
15291         stack_trap "rm -f $TMP/$tfile.tmp"
15292         while read name count samp unit min max sum sumsq; do
15293                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
15294                 eval $name=$count || error "Wrong proc format"
15295
15296                 case $name in
15297                 read_bytes|write_bytes)
15298                         [[ "$unit" =~ "bytes" ]] ||
15299                                 error "unit is not 'bytes': $unit"
15300                         (( $count == 2 )) || error "count is not 2: $count"
15301                         (( $min == $PAGE_SIZE )) ||
15302                                 error "min is not $PAGE_SIZE: $min"
15303                         (( $max == $PAGE_SIZE )) ||
15304                                 error "max is not $PAGE_SIZE: $max"
15305                         (( $sum == $PAGE_SIZE * 2 )) ||
15306                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
15307                         ;;
15308                 read|write)
15309                         [[ "$unit" =~ "usec" ]] ||
15310                                 error "unit is not 'usec': $unit"
15311                         ;;
15312                 *)      ;;
15313                 esac
15314         done < $TMP/$tfile.tmp
15315
15316         #check that we actually got some stats
15317         [ "$read_bytes" ] || error "Missing read_bytes stats"
15318         [ "$write_bytes" ] || error "Missing write_bytes stats"
15319         [ "$read_bytes" != 0 ] || error "no read done"
15320         [ "$write_bytes" != 0 ] || error "no write done"
15321 }
15322 run_test 127b "verify the llite client stats are sane"
15323
15324 test_127c() { # LU-12394
15325         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
15326         local size
15327         local bsize
15328         local reads
15329         local writes
15330         local count
15331
15332         $LCTL set_param llite.*.extents_stats=1
15333         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
15334
15335         # Use two stripes so there is enough space in default config
15336         $LFS setstripe -c 2 $DIR/$tfile
15337
15338         # Extent stats start at 0-4K and go in power of two buckets
15339         # LL_HIST_START = 12 --> 2^12 = 4K
15340         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
15341         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
15342         # small configs
15343         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
15344                 do
15345                 # Write and read, 2x each, second time at a non-zero offset
15346                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
15347                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
15348                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
15349                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
15350                 rm -f $DIR/$tfile
15351         done
15352
15353         $LCTL get_param llite.*.extents_stats
15354
15355         count=2
15356         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
15357                 do
15358                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
15359                                 grep -m 1 $bsize)
15360                 reads=$(echo $bucket | awk '{print $5}')
15361                 writes=$(echo $bucket | awk '{print $9}')
15362                 [ "$reads" -eq $count ] ||
15363                         error "$reads reads in < $bsize bucket, expect $count"
15364                 [ "$writes" -eq $count ] ||
15365                         error "$writes writes in < $bsize bucket, expect $count"
15366         done
15367
15368         # Test mmap write and read
15369         $LCTL set_param llite.*.extents_stats=c
15370         size=512
15371         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
15372         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
15373         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
15374
15375         $LCTL get_param llite.*.extents_stats
15376
15377         count=$(((size*1024) / PAGE_SIZE))
15378
15379         bsize=$((2 * PAGE_SIZE / 1024))K
15380
15381         bucket=$($LCTL get_param -n llite.*.extents_stats |
15382                         grep -m 1 $bsize)
15383         reads=$(echo $bucket | awk '{print $5}')
15384         writes=$(echo $bucket | awk '{print $9}')
15385         # mmap writes fault in the page first, creating an additonal read
15386         [ "$reads" -eq $((2 * count)) ] ||
15387                 error "$reads reads in < $bsize bucket, expect $count"
15388         [ "$writes" -eq $count ] ||
15389                 error "$writes writes in < $bsize bucket, expect $count"
15390 }
15391 run_test 127c "test llite extent stats with regular & mmap i/o"
15392
15393 test_128() { # bug 15212
15394         touch $DIR/$tfile
15395         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
15396                 find $DIR/$tfile
15397                 find $DIR/$tfile
15398         EOF
15399
15400         result=$(grep error $TMP/$tfile.log)
15401         rm -f $DIR/$tfile $TMP/$tfile.log
15402         [ -z "$result" ] ||
15403                 error "consecutive find's under interactive lfs failed"
15404 }
15405 run_test 128 "interactive lfs for 2 consecutive find's"
15406
15407 set_dir_limits () {
15408         local mntdev
15409         local canondev
15410         local node
15411
15412         local ldproc=/proc/fs/ldiskfs
15413         local facets=$(get_facets MDS)
15414
15415         for facet in ${facets//,/ }; do
15416                 canondev=$(ldiskfs_canon \
15417                            *.$(convert_facet2label $facet).mntdev $facet)
15418                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
15419                         ldproc=/sys/fs/ldiskfs
15420                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
15421                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
15422         done
15423 }
15424
15425 check_mds_dmesg() {
15426         local facets=$(get_facets MDS)
15427         for facet in ${facets//,/ }; do
15428                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
15429         done
15430         return 1
15431 }
15432
15433 test_129() {
15434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15435         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
15436                 skip "Need MDS version with at least 2.5.56"
15437         if [ "$mds1_FSTYPE" != ldiskfs ]; then
15438                 skip_env "ldiskfs only test"
15439         fi
15440         remote_mds_nodsh && skip "remote MDS with nodsh"
15441
15442         local ENOSPC=28
15443         local has_warning=false
15444
15445         rm -rf $DIR/$tdir
15446         mkdir -p $DIR/$tdir
15447
15448         # block size of mds1
15449         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
15450         set_dir_limits $maxsize $((maxsize * 6 / 8))
15451         stack_trap "set_dir_limits 0 0"
15452         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
15453         local dirsize=$(stat -c%s "$DIR/$tdir")
15454         local nfiles=0
15455         while (( $dirsize <= $maxsize )); do
15456                 $MCREATE $DIR/$tdir/file_base_$nfiles
15457                 rc=$?
15458                 # check two errors:
15459                 # ENOSPC for ext4 max_dir_size, which has been used since
15460                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
15461                 if (( rc == ENOSPC )); then
15462                         set_dir_limits 0 0
15463                         echo "rc=$rc returned as expected after $nfiles files"
15464
15465                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
15466                                 error "create failed w/o dir size limit"
15467
15468                         # messages may be rate limited if test is run repeatedly
15469                         check_mds_dmesg '"is approaching max"' ||
15470                                 echo "warning message should be output"
15471                         check_mds_dmesg '"has reached max"' ||
15472                                 echo "reached message should be output"
15473
15474                         dirsize=$(stat -c%s "$DIR/$tdir")
15475
15476                         [[ $dirsize -ge $maxsize ]] && return 0
15477                         error "dirsize $dirsize < $maxsize after $nfiles files"
15478                 elif (( rc != 0 )); then
15479                         break
15480                 fi
15481                 nfiles=$((nfiles + 1))
15482                 dirsize=$(stat -c%s "$DIR/$tdir")
15483         done
15484
15485         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
15486 }
15487 run_test 129 "test directory size limit ========================"
15488
15489 OLDIFS="$IFS"
15490 cleanup_130() {
15491         trap 0
15492         IFS="$OLDIFS"
15493         rm -f $DIR/$tfile
15494 }
15495
15496 test_130a() {
15497         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
15498         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
15499
15500         trap cleanup_130 EXIT RETURN
15501
15502         local fm_file=$DIR/$tfile
15503         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
15504         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
15505                 error "dd failed for $fm_file"
15506
15507         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
15508         filefrag -ves $fm_file
15509         local rc=$?
15510         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15511                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15512         (( $rc == 0 )) || error "filefrag $fm_file failed"
15513
15514         filefrag_op=$(filefrag -ve -k $fm_file |
15515                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15516         local lun=$($LFS getstripe -i $fm_file)
15517
15518         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
15519         IFS=$'\n'
15520         local tot_len=0
15521         for line in $filefrag_op; do
15522                 local frag_lun=$(echo $line | cut -d: -f5)
15523                 local ext_len=$(echo $line | cut -d: -f4)
15524
15525                 if (( $frag_lun != $lun )); then
15526                         error "FIEMAP on 1-stripe file($fm_file) failed"
15527                         return
15528                 fi
15529                 (( tot_len += ext_len ))
15530         done
15531
15532         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
15533                 error "FIEMAP on 1-stripe file($fm_file) failed"
15534                 return
15535         fi
15536
15537         echo "FIEMAP on single striped file succeeded"
15538 }
15539 run_test 130a "FIEMAP (1-stripe file)"
15540
15541 test_130b() {
15542         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15543
15544         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15545         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15546         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15547                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15548
15549         trap cleanup_130 EXIT RETURN
15550
15551         local fm_file=$DIR/$tfile
15552         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15553                 error "setstripe on $fm_file"
15554
15555         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
15556                 error "dd failed on $fm_file"
15557
15558         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15559         filefrag_op=$(filefrag -ve -k $fm_file |
15560                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15561
15562         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15563                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15564
15565         IFS=$'\n'
15566         local tot_len=0
15567         local num_luns=1
15568
15569         for line in $filefrag_op; do
15570                 local frag_lun=$(echo $line | cut -d: -f5 |
15571                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15572                 local ext_len=$(echo $line | cut -d: -f4)
15573                 if (( $frag_lun != $last_lun )); then
15574                         if (( tot_len != 1024 )); then
15575                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15576                                 return
15577                         else
15578                                 (( num_luns += 1 ))
15579                                 tot_len=0
15580                         fi
15581                 fi
15582                 (( tot_len += ext_len ))
15583                 last_lun=$frag_lun
15584         done
15585         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
15586                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15587                 return
15588         fi
15589
15590         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
15591 }
15592 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
15593
15594 test_130c() {
15595         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15596
15597         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15598         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15599         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15600                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15601
15602         trap cleanup_130 EXIT RETURN
15603
15604         local fm_file=$DIR/$tfile
15605         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
15606
15607         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
15608                 error "dd failed on $fm_file"
15609
15610         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15611         filefrag_op=$(filefrag -ve -k $fm_file |
15612                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15613
15614         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15615                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15616
15617         IFS=$'\n'
15618         local tot_len=0
15619         local num_luns=1
15620         for line in $filefrag_op; do
15621                 local frag_lun=$(echo $line | cut -d: -f5 |
15622                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15623                 local ext_len=$(echo $line | cut -d: -f4)
15624                 if (( $frag_lun != $last_lun )); then
15625                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
15626                         if (( logical != 512 )); then
15627                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
15628                                 return
15629                         fi
15630                         if (( tot_len != 512 )); then
15631                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15632                                 return
15633                         else
15634                                 (( num_luns += 1 ))
15635                                 tot_len=0
15636                         fi
15637                 fi
15638                 (( tot_len += ext_len ))
15639                 last_lun=$frag_lun
15640         done
15641         if (( num_luns != 2 || tot_len != 512 )); then
15642                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15643                 return
15644         fi
15645
15646         echo "FIEMAP on 2-stripe file with hole succeeded"
15647 }
15648 run_test 130c "FIEMAP (2-stripe file with hole)"
15649
15650 test_130d() {
15651         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
15652
15653         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15654         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15655         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15656                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15657
15658         trap cleanup_130 EXIT RETURN
15659
15660         local fm_file=$DIR/$tfile
15661         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15662                         error "setstripe on $fm_file"
15663
15664         local actual_stripe_count=$($LFS getstripe -c $fm_file)
15665         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
15666                 error "dd failed on $fm_file"
15667
15668         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15669         filefrag_op=$(filefrag -ve -k $fm_file |
15670                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15671
15672         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15673                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15674
15675         IFS=$'\n'
15676         local tot_len=0
15677         local num_luns=1
15678         for line in $filefrag_op; do
15679                 local frag_lun=$(echo $line | cut -d: -f5 |
15680                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15681                 local ext_len=$(echo $line | cut -d: -f4)
15682                 if (( $frag_lun != $last_lun )); then
15683                         if (( tot_len != 1024 )); then
15684                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15685                                 return
15686                         else
15687                                 (( num_luns += 1 ))
15688                                 local tot_len=0
15689                         fi
15690                 fi
15691                 (( tot_len += ext_len ))
15692                 last_lun=$frag_lun
15693         done
15694         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
15695                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15696                 return
15697         fi
15698
15699         echo "FIEMAP on N-stripe file succeeded"
15700 }
15701 run_test 130d "FIEMAP (N-stripe file)"
15702
15703 test_130e() {
15704         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15705
15706         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15707         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15708         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15709                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15710
15711         trap cleanup_130 EXIT RETURN
15712
15713         local fm_file=$DIR/$tfile
15714         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
15715         stack_trap "rm -f $fm_file"
15716
15717         local num_blks=512
15718         local expected_len=$(( (num_blks / 2) * 64 ))
15719         for ((i = 0; i < $num_blks; i++)); do
15720                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
15721                         conv=notrunc > /dev/null 2>&1
15722         done
15723
15724         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15725         filefrag_op=$(filefrag -ve -k $fm_file |
15726                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15727
15728         local last_lun=$(echo $filefrag_op | cut -d: -f5)
15729
15730         IFS=$'\n'
15731         local tot_len=0
15732         local num_luns=1
15733         for line in $filefrag_op; do
15734                 local frag_lun=$(echo $line | cut -d: -f5)
15735                 local ext_len=$(echo $line | cut -d: -f4)
15736                 if (( $frag_lun != $last_lun )); then
15737                         if (( tot_len != $expected_len )); then
15738                                 error "OST$last_lun $tot_len != $expected_len"
15739                         else
15740                                 (( num_luns += 1 ))
15741                                 tot_len=0
15742                         fi
15743                 fi
15744                 (( tot_len += ext_len ))
15745                 last_lun=$frag_lun
15746         done
15747         if (( num_luns != 2 || tot_len != $expected_len )); then
15748                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
15749         fi
15750
15751         echo "FIEMAP with continuation calls succeeded"
15752 }
15753 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
15754
15755 test_130f() {
15756         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15757         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15758         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15759                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15760
15761         local fm_file=$DIR/$tfile
15762         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
15763                 error "multiop create with lov_delay_create on $fm_file"
15764
15765         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15766         filefrag_extents=$(filefrag -vek $fm_file |
15767                            awk '/extents? found/ { print $2 }')
15768         if (( $filefrag_extents != 0 )); then
15769                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
15770         fi
15771
15772         rm -f $fm_file
15773 }
15774 run_test 130f "FIEMAP (unstriped file)"
15775
15776 test_130g() {
15777         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
15778                 skip "Need MDS version with at least 2.12.53 for overstriping"
15779         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15780         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15781         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15782                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15783
15784         local file=$DIR/$tfile
15785         local nr=$((OSTCOUNT * 100))
15786
15787         $LFS setstripe -C $nr -S1M $file ||
15788                 error "failed to setstripe -C $nr $file"
15789
15790         stack_trap "rm -f $file"
15791         dd if=/dev/zero of=$file count=$nr bs=1M
15792         sync
15793         nr=$($LFS getstripe -c $file)
15794
15795         local extents=$(filefrag -v $file |
15796                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
15797
15798         echo "filefrag list $extents extents in file with stripecount $nr"
15799         if (( extents < nr )); then
15800                 $LFS getstripe $file
15801                 filefrag -v $file
15802                 error "filefrag printed $extents < $nr extents"
15803         fi
15804 }
15805 run_test 130g "FIEMAP (overstripe file)"
15806
15807 # Test for writev/readv
15808 test_131a() {
15809         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
15810                 error "writev test failed"
15811         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
15812                 error "readv failed"
15813         rm -f $DIR/$tfile
15814 }
15815 run_test 131a "test iov's crossing stripe boundary for writev/readv"
15816
15817 test_131b() {
15818         local fsize=$((524288 + 1048576 + 1572864))
15819         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
15820                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15821                         error "append writev test failed"
15822
15823         ((fsize += 1572864 + 1048576))
15824         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
15825                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15826                         error "append writev test failed"
15827         rm -f $DIR/$tfile
15828 }
15829 run_test 131b "test append writev"
15830
15831 test_131c() {
15832         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
15833         error "NOT PASS"
15834 }
15835 run_test 131c "test read/write on file w/o objects"
15836
15837 test_131d() {
15838         rwv -f $DIR/$tfile -w -n 1 1572864
15839         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
15840         if [ "$NOB" != 1572864 ]; then
15841                 error "Short read filed: read $NOB bytes instead of 1572864"
15842         fi
15843         rm -f $DIR/$tfile
15844 }
15845 run_test 131d "test short read"
15846
15847 test_131e() {
15848         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
15849         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
15850         error "read hitting hole failed"
15851         rm -f $DIR/$tfile
15852 }
15853 run_test 131e "test read hitting hole"
15854
15855 check_stats() {
15856         local facet=$1
15857         local op=$2
15858         local want=${3:-0}
15859         local res
15860
15861         # open             11 samples [usecs] 468 4793 13658 35791898
15862         case $facet in
15863         mds*) res=($(do_facet $facet \
15864                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
15865                  ;;
15866         ost*) res=($(do_facet $facet \
15867                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
15868                  ;;
15869         *) error "Wrong facet '$facet'" ;;
15870         esac
15871         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
15872         # if $want is zero, it means any stat increment is ok.
15873         if (( $want > 0 )); then
15874                 local count=${res[1]}
15875
15876                 if (( $count != $want )); then
15877                         if [[ $facet =~ "mds" ]]; then
15878                                 do_nodes $(comma_list $(mdts_nodes)) \
15879                                         $LCTL get_param mdt.*.md_stats
15880                         else
15881                                 do_nodes $(comma_list $(osts-nodes)) \
15882                                         $LCTL get_param obdfilter.*.stats
15883                         fi
15884                         error "The $op counter on $facet is $count, not $want"
15885                 fi
15886         fi
15887 }
15888
15889 test_133a() {
15890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15891         remote_ost_nodsh && skip "remote OST with nodsh"
15892         remote_mds_nodsh && skip "remote MDS with nodsh"
15893         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15894                 skip_env "MDS doesn't support rename stats"
15895
15896         local testdir=$DIR/${tdir}/stats_testdir
15897
15898         mkdir_on_mdt0 $DIR/${tdir}
15899
15900         # clear stats.
15901         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15902         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15903
15904         # verify mdt stats first.
15905         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15906         check_stats $SINGLEMDS "mkdir" 1
15907
15908         # clear "open" from "lfs mkdir" above
15909         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15910         touch ${testdir}/${tfile} || error "touch failed"
15911         check_stats $SINGLEMDS "open" 1
15912         check_stats $SINGLEMDS "close" 1
15913         (( $MDS1_VERSION >= $(version_code 2.15.62) )) && {
15914                 # open should match close
15915                 ls -lR ${testdir}
15916                 check_stats $SINGLEMDS "open" 2
15917                 check_stats $SINGLEMDS "close" 2
15918         }
15919         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
15920                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
15921                 check_stats $SINGLEMDS "mknod" 2
15922         }
15923         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
15924         check_stats $SINGLEMDS "unlink" 1
15925         rm -f ${testdir}/${tfile} || error "file remove failed"
15926         check_stats $SINGLEMDS "unlink" 2
15927
15928         # remove working dir and check mdt stats again.
15929         rmdir ${testdir} || error "rmdir failed"
15930         check_stats $SINGLEMDS "rmdir" 1
15931
15932         local testdir1=$DIR/${tdir}/stats_testdir1
15933         mkdir_on_mdt0 ${testdir}
15934         mkdir_on_mdt0 ${testdir1}
15935         touch ${testdir1}/test1
15936         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
15937         check_stats $SINGLEMDS "crossdir_rename" 1
15938
15939         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
15940         check_stats $SINGLEMDS "samedir_rename" 1
15941
15942         rm -rf $DIR/${tdir}
15943 }
15944 run_test 133a "Verifying MDT stats ========================================"
15945
15946 test_133b() {
15947         local res
15948
15949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15950         remote_ost_nodsh && skip "remote OST with nodsh"
15951         remote_mds_nodsh && skip "remote MDS with nodsh"
15952
15953         local testdir=$DIR/${tdir}/stats_testdir
15954
15955         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15956         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15957         touch ${testdir}/${tfile} || error "touch failed"
15958         cancel_lru_locks mdc
15959
15960         # clear stats.
15961         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15962         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15963
15964         # extra mdt stats verification.
15965         chmod 444 ${testdir}/${tfile} || error "chmod failed"
15966         check_stats $SINGLEMDS "setattr" 1
15967         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15968         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
15969         then            # LU-1740
15970                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
15971                 check_stats $SINGLEMDS "getattr" 1
15972         fi
15973         rm -rf $DIR/${tdir}
15974
15975         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
15976         # so the check below is not reliable
15977         [ $MDSCOUNT -eq 1 ] || return 0
15978
15979         # Sleep to avoid a cached response.
15980         #define OBD_STATFS_CACHE_SECONDS 1
15981         sleep 2
15982         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15983         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15984         $LFS df || error "lfs failed"
15985         check_stats $SINGLEMDS "statfs" 1
15986
15987         # check aggregated statfs (LU-10018)
15988         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
15989                 return 0
15990         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
15991                 return 0
15992         sleep 2
15993         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15994         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15995         df $DIR
15996         check_stats $SINGLEMDS "statfs" 1
15997
15998         # We want to check that the client didn't send OST_STATFS to
15999         # ost1 but the MDT also uses OST_STATFS for precreate. So some
16000         # extra care is needed here.
16001         if remote_mds; then
16002                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
16003                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
16004
16005                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
16006                 [ "$res" ] && error "OST got STATFS"
16007         fi
16008
16009         return 0
16010 }
16011 run_test 133b "Verifying extra MDT stats =================================="
16012
16013 test_133c() {
16014         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16015         remote_ost_nodsh && skip "remote OST with nodsh"
16016         remote_mds_nodsh && skip "remote MDS with nodsh"
16017
16018         local testdir=$DIR/$tdir/stats_testdir
16019
16020         test_mkdir -p $testdir
16021
16022         # verify obdfilter stats.
16023         $LFS setstripe -c 1 -i 0 $testdir/$tfile
16024         sync
16025         cancel_lru_locks osc
16026         wait_delete_completed
16027
16028         # clear stats.
16029         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
16030         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
16031
16032         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
16033                 error "dd failed"
16034         sync
16035         cancel_lru_locks osc
16036         check_stats ost1 "write" 1
16037
16038         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
16039         check_stats ost1 "read" 1
16040
16041         > $testdir/$tfile || error "truncate failed"
16042         check_stats ost1 "punch" 1
16043
16044         rm -f $testdir/$tfile || error "file remove failed"
16045         wait_delete_completed
16046         check_stats ost1 "destroy" 1
16047
16048         rm -rf $DIR/$tdir
16049 }
16050 run_test 133c "Verifying OST stats ========================================"
16051
16052 order_2() {
16053         local value=$1
16054         local orig=$value
16055         local order=1
16056
16057         while [ $value -ge 2 ]; do
16058                 order=$((order*2))
16059                 value=$((value/2))
16060         done
16061
16062         if [ $orig -gt $order ]; then
16063                 order=$((order*2))
16064         fi
16065         echo $order
16066 }
16067
16068 size_in_KMGT() {
16069     local value=$1
16070     local size=('K' 'M' 'G' 'T');
16071     local i=0
16072     local size_string=$value
16073
16074     while [ $value -ge 1024 ]; do
16075         if [ $i -gt 3 ]; then
16076             #T is the biggest unit we get here, if that is bigger,
16077             #just return XXXT
16078             size_string=${value}T
16079             break
16080         fi
16081         value=$((value >> 10))
16082         if [ $value -lt 1024 ]; then
16083             size_string=${value}${size[$i]}
16084             break
16085         fi
16086         i=$((i + 1))
16087     done
16088
16089     echo $size_string
16090 }
16091
16092 get_rename_size() {
16093         local size=$1
16094         local context=${2:-.}
16095         local sample=$(do_facet $SINGLEMDS $LCTL \
16096                 get_param mdt.$FSNAME-MDT0000.rename_stats |
16097                 grep -A1 $context |
16098                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
16099         echo $sample
16100 }
16101
16102 test_133d() {
16103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16104         remote_ost_nodsh && skip "remote OST with nodsh"
16105         remote_mds_nodsh && skip "remote MDS with nodsh"
16106         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
16107                 skip_env "MDS doesn't support rename stats"
16108
16109         local testdir1=$DIR/${tdir}/stats_testdir1
16110         local testdir2=$DIR/${tdir}/stats_testdir2
16111         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
16112
16113         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
16114
16115         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
16116         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
16117
16118         createmany -o $testdir1/test 512 || error "createmany failed"
16119
16120         # check samedir rename size
16121         mv ${testdir1}/test0 ${testdir1}/test_0
16122
16123         local testdir1_size=$(ls -l $DIR/${tdir} |
16124                 awk '/stats_testdir1/ {print $5}')
16125         local testdir2_size=$(ls -l $DIR/${tdir} |
16126                 awk '/stats_testdir2/ {print $5}')
16127
16128         testdir1_size=$(order_2 $testdir1_size)
16129         testdir2_size=$(order_2 $testdir2_size)
16130
16131         testdir1_size=$(size_in_KMGT $testdir1_size)
16132         testdir2_size=$(size_in_KMGT $testdir2_size)
16133
16134         echo "source rename dir size: ${testdir1_size}"
16135         echo "target rename dir size: ${testdir2_size}"
16136
16137         local cmd="do_facet $SINGLEMDS $LCTL "
16138         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
16139
16140         eval $cmd || error "$cmd failed"
16141         local samedir=$($cmd | grep 'same_dir')
16142         local same_sample=$(get_rename_size $testdir1_size)
16143         [ -z "$samedir" ] && error "samedir_rename_size count error"
16144         [[ $same_sample -eq 1 ]] ||
16145                 error "samedir_rename_size error $same_sample"
16146         echo "Check same dir rename stats success"
16147
16148         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
16149
16150         # check crossdir rename size
16151         mv ${testdir1}/test_0 ${testdir2}/test_0
16152
16153         testdir1_size=$(ls -l $DIR/${tdir} |
16154                 awk '/stats_testdir1/ {print $5}')
16155         testdir2_size=$(ls -l $DIR/${tdir} |
16156                 awk '/stats_testdir2/ {print $5}')
16157
16158         testdir1_size=$(order_2 $testdir1_size)
16159         testdir2_size=$(order_2 $testdir2_size)
16160
16161         testdir1_size=$(size_in_KMGT $testdir1_size)
16162         testdir2_size=$(size_in_KMGT $testdir2_size)
16163
16164         echo "source rename dir size: ${testdir1_size}"
16165         echo "target rename dir size: ${testdir2_size}"
16166
16167         eval $cmd || error "$cmd failed"
16168         local crossdir=$($cmd | grep 'crossdir')
16169         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
16170         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
16171         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
16172         [[ $src_sample -eq 1 ]] ||
16173                 error "crossdir_rename_size error $src_sample"
16174         [[ $tgt_sample -eq 1 ]] ||
16175                 error "crossdir_rename_size error $tgt_sample"
16176         echo "Check cross dir rename stats success"
16177         rm -rf $DIR/${tdir}
16178 }
16179 run_test 133d "Verifying rename_stats ========================================"
16180
16181 test_133e() {
16182         remote_mds_nodsh && skip "remote MDS with nodsh"
16183         remote_ost_nodsh && skip "remote OST with nodsh"
16184         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16185
16186         local testdir=$DIR/${tdir}/stats_testdir
16187         local ctr f0 f1 bs=32768 count=42 sum
16188
16189         mkdir -p ${testdir} || error "mkdir failed"
16190
16191         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
16192
16193         for ctr in {write,read}_bytes; do
16194                 sync
16195                 cancel_lru_locks osc
16196
16197                 do_facet ost1 $LCTL set_param -n \
16198                         "obdfilter.*.exports.clear=clear"
16199
16200                 if [ $ctr = write_bytes ]; then
16201                         f0=/dev/zero
16202                         f1=${testdir}/${tfile}
16203                 else
16204                         f0=${testdir}/${tfile}
16205                         f1=/dev/null
16206                 fi
16207
16208                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
16209                         error "dd failed"
16210                 sync
16211                 cancel_lru_locks osc
16212
16213                 sum=$(do_facet ost1 $LCTL get_param \
16214                         "obdfilter.*.exports.*.stats" |
16215                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
16216                                 $1 == ctr { sum += $7 }
16217                                 END { printf("%0.0f", sum) }')
16218
16219                 if ((sum != bs * count)); then
16220                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
16221                 fi
16222         done
16223
16224         rm -rf $DIR/${tdir}
16225 }
16226 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
16227
16228 test_133f() {
16229         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
16230                 skip "too old lustre for get_param -R ($facet_ver)"
16231
16232         # verifying readability.
16233         $LCTL get_param -R '*' &> /dev/null
16234
16235         # Verifing writability with badarea_io.
16236         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
16237         local skipped_params='force_lbug|changelog_mask|daemon_file'
16238         $LCTL list_param -FR '*' | grep '=' | tr -d = |
16239                 egrep -v "$skipped_params" |
16240                 xargs -n 1 find $proc_dirs -name |
16241                 xargs -n 1 badarea_io ||
16242                 error "client badarea_io failed"
16243
16244         # remount the FS in case writes/reads /proc break the FS
16245         cleanup || error "failed to unmount"
16246         setup || error "failed to setup"
16247 }
16248 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
16249
16250 test_133g() {
16251         remote_mds_nodsh && skip "remote MDS with nodsh"
16252         remote_ost_nodsh && skip "remote OST with nodsh"
16253
16254         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
16255         local proc_dirs_str=$(eval echo $proc_dirs)
16256         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
16257         local facet
16258         for facet in mds1 ost1; do
16259                 local facet_ver=$(lustre_version_code $facet)
16260                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
16261                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
16262                 else
16263                         log "$facet: too old lustre for get_param -R"
16264                 fi
16265                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
16266                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
16267                                 tr -d = | egrep -v $skipped_params |
16268                                 xargs -n 1 find $proc_dirs_str -name |
16269                                 xargs -n 1 badarea_io" ||
16270                                         error "$facet badarea_io failed"
16271                 else
16272                         skip_noexit "$facet: too old lustre for get_param -R"
16273                 fi
16274         done
16275
16276         # remount the FS in case writes/reads /proc break the FS
16277         cleanup || error "failed to unmount"
16278         setup || error "failed to setup"
16279 }
16280 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
16281
16282 test_133h() {
16283         remote_mds_nodsh && skip "remote MDS with nodsh"
16284         remote_ost_nodsh && skip "remote OST with nodsh"
16285         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
16286                 skip "Need MDS version at least 2.9.54"
16287
16288         local facet
16289         for facet in client mds1 ost1; do
16290                 # Get the list of files that are missing the terminating newline
16291                 local plist=$(do_facet $facet
16292                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
16293                 local ent
16294                 for ent in $plist; do
16295                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
16296                                 awk -v FS='\v' -v RS='\v\v' \
16297                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
16298                                         print FILENAME}'" 2>/dev/null)
16299                         [ -z $missing ] || {
16300                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
16301                                 error "file does not end with newline: $facet-$ent"
16302                         }
16303                 done
16304         done
16305 }
16306 run_test 133h "Proc files should end with newlines"
16307
16308 test_134a() {
16309         remote_mds_nodsh && skip "remote MDS with nodsh"
16310         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
16311                 skip "Need MDS version at least 2.7.54"
16312
16313         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
16314         cancel_lru_locks mdc
16315
16316         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
16317         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
16318         [ $unused -eq 0 ] || error "$unused locks are not cleared"
16319
16320         local nr=1000
16321         createmany -o $DIR/$tdir/f $nr ||
16322                 error "failed to create $nr files in $DIR/$tdir"
16323         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
16324
16325         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
16326         do_facet mds1 $LCTL set_param fail_loc=0x327
16327         do_facet mds1 $LCTL set_param fail_val=500
16328         touch $DIR/$tdir/m
16329
16330         echo "sleep 10 seconds ..."
16331         sleep 10
16332         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
16333
16334         do_facet mds1 $LCTL set_param fail_loc=0
16335         do_facet mds1 $LCTL set_param fail_val=0
16336         [ $lck_cnt -lt $unused ] ||
16337                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
16338
16339         rm $DIR/$tdir/m
16340         unlinkmany $DIR/$tdir/f $nr
16341 }
16342 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
16343
16344 test_134b() {
16345         remote_mds_nodsh && skip "remote MDS with nodsh"
16346         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
16347                 skip "Need MDS version at least 2.7.54"
16348
16349         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
16350         cancel_lru_locks mdc
16351
16352         local low_wm=$(do_facet mds1 $LCTL get_param -n \
16353                         ldlm.lock_reclaim_threshold_mb)
16354         # disable reclaim temporarily
16355         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
16356
16357         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
16358         do_facet mds1 $LCTL set_param fail_loc=0x328
16359         do_facet mds1 $LCTL set_param fail_val=500
16360
16361         $LCTL set_param debug=+trace
16362
16363         local nr=600
16364         createmany -o $DIR/$tdir/f $nr &
16365         local create_pid=$!
16366
16367         echo "Sleep $TIMEOUT seconds ..."
16368         sleep $TIMEOUT
16369         if ! ps -p $create_pid  > /dev/null 2>&1; then
16370                 do_facet mds1 $LCTL set_param fail_loc=0
16371                 do_facet mds1 $LCTL set_param fail_val=0
16372                 do_facet mds1 $LCTL set_param \
16373                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
16374                 error "createmany finished incorrectly!"
16375         fi
16376         do_facet mds1 $LCTL set_param fail_loc=0
16377         do_facet mds1 $LCTL set_param fail_val=0
16378         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
16379         wait $create_pid || return 1
16380
16381         unlinkmany $DIR/$tdir/f $nr
16382 }
16383 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
16384
16385 test_135() {
16386         remote_mds_nodsh && skip "remote MDS with nodsh"
16387         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
16388                 skip "Need MDS version at least 2.13.50"
16389         local fname
16390
16391         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
16392
16393 #define OBD_FAIL_PLAIN_RECORDS 0x1319
16394         #set only one record at plain llog
16395         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
16396
16397         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
16398
16399         #fill already existed plain llog each 64767
16400         #wrapping whole catalog
16401         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
16402
16403         createmany -o $DIR/$tdir/$tfile_ 64700
16404         for (( i = 0; i < 64700; i = i + 2 ))
16405         do
16406                 rm $DIR/$tdir/$tfile_$i &
16407                 rm $DIR/$tdir/$tfile_$((i + 1)) &
16408                 local pid=$!
16409                 wait $pid
16410         done
16411
16412         #waiting osp synchronization
16413         wait_delete_completed
16414 }
16415 run_test 135 "Race catalog processing"
16416
16417 test_136() {
16418         remote_mds_nodsh && skip "remote MDS with nodsh"
16419         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
16420                 skip "Need MDS version at least 2.13.50"
16421         local fname
16422
16423         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
16424         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
16425         #set only one record at plain llog
16426 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
16427         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
16428
16429         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
16430
16431         #fill already existed 2 plain llogs each 64767
16432         #wrapping whole catalog
16433         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
16434         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
16435         wait_delete_completed
16436
16437         createmany -o $DIR/$tdir/$tfile_ 10
16438         sleep 25
16439
16440         do_facet $SINGLEMDS $LCTL set_param fail_val=3
16441         for (( i = 0; i < 10; i = i + 3 ))
16442         do
16443                 rm $DIR/$tdir/$tfile_$i &
16444                 rm $DIR/$tdir/$tfile_$((i + 1)) &
16445                 local pid=$!
16446                 wait $pid
16447                 sleep 7
16448                 rm $DIR/$tdir/$tfile_$((i + 2)) &
16449         done
16450
16451         #waiting osp synchronization
16452         wait_delete_completed
16453 }
16454 run_test 136 "Race catalog processing 2"
16455
16456 test_140() { #bug-17379
16457         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16458
16459         test_mkdir $DIR/$tdir
16460         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
16461         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
16462
16463         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
16464         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
16465         local i=0
16466         while i=$((i + 1)); do
16467                 test_mkdir $i
16468                 cd $i || error "Changing to $i"
16469                 ln -s ../stat stat || error "Creating stat symlink"
16470                 # Read the symlink until ELOOP present,
16471                 # not LBUGing the system is considered success,
16472                 # we didn't overrun the stack.
16473                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
16474                 if [ $ret -ne 0 ]; then
16475                         if [ $ret -eq 40 ]; then
16476                                 break  # -ELOOP
16477                         else
16478                                 error "Open stat symlink"
16479                                         return
16480                         fi
16481                 fi
16482         done
16483         i=$((i - 1))
16484         echo "The symlink depth = $i"
16485         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
16486                 error "Invalid symlink depth"
16487
16488         # Test recursive symlink
16489         ln -s symlink_self symlink_self
16490         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
16491         echo "open symlink_self returns $ret"
16492         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
16493 }
16494 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
16495
16496 test_150a() {
16497         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16498
16499         local TF="$TMP/$tfile"
16500
16501         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16502         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16503         cp $TF $DIR/$tfile
16504         cancel_lru_locks $OSC
16505         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
16506         remount_client $MOUNT
16507         df -P $MOUNT
16508         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
16509
16510         $TRUNCATE $TF 6000
16511         $TRUNCATE $DIR/$tfile 6000
16512         cancel_lru_locks $OSC
16513         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
16514
16515         echo "12345" >>$TF
16516         echo "12345" >>$DIR/$tfile
16517         cancel_lru_locks $OSC
16518         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
16519
16520         echo "12345" >>$TF
16521         echo "12345" >>$DIR/$tfile
16522         cancel_lru_locks $OSC
16523         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
16524 }
16525 run_test 150a "truncate/append tests"
16526
16527 test_150b() {
16528         check_set_fallocate_or_skip
16529         local out
16530
16531         touch $DIR/$tfile
16532         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16533         out=$(check_fallocate $DIR/$tfile 2>&1) ||
16534                 skip_eopnotsupp "$out|check_fallocate failed"
16535 }
16536 run_test 150b "Verify fallocate (prealloc) functionality"
16537
16538 test_150bb() {
16539         check_set_fallocate_or_skip
16540
16541         touch $DIR/$tfile
16542         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16543         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
16544         > $DIR/$tfile
16545         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
16546         # precomputed md5sum for 20MB of zeroes
16547         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
16548         local sum=($(md5sum $DIR/$tfile))
16549
16550         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
16551
16552         check_set_fallocate 1
16553
16554         > $DIR/$tfile
16555         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
16556         sum=($(md5sum $DIR/$tfile))
16557
16558         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
16559 }
16560 run_test 150bb "Verify fallocate modes both zero space"
16561
16562 test_150c() {
16563         check_set_fallocate_or_skip
16564         local striping="-c2"
16565
16566         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16567         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
16568         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
16569         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
16570         local want=$((OSTCOUNT * 1048576))
16571
16572         # Must allocate all requested space, not more than 5% extra
16573         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16574                 error "bytes $bytes is not $want"
16575
16576         rm -f $DIR/$tfile
16577
16578         echo "verify fallocate on PFL file"
16579
16580         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
16581
16582         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
16583                 error "Create $DIR/$tfile failed"
16584         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
16585         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
16586         want=$((512 * 1048576))
16587
16588         # Must allocate all requested space, not more than 5% extra
16589         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16590                 error "bytes $bytes is not $want"
16591 }
16592 run_test 150c "Verify fallocate Size and Blocks"
16593
16594 test_150d() {
16595         check_set_fallocate_or_skip
16596         local striping="-c2"
16597
16598         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
16599
16600         stack_trap "rm -f $DIR/$tdir; wait_delete_completed"
16601         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
16602                 error "setstripe failed"
16603         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
16604         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
16605         local want=$((OSTCOUNT * 1048576))
16606
16607         # Must allocate all requested space, not more than 5% extra
16608         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16609                 error "bytes $bytes is not $want"
16610 }
16611 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
16612
16613 test_150e() {
16614         check_set_fallocate_or_skip
16615
16616         echo "df before:"
16617         $LFS df
16618         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16619         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16620                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16621
16622         # Find OST with Minimum Size
16623         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16624                        sort -un | head -1)
16625
16626         # Get 100MB per OST of the available space to reduce run time
16627         # else 60% of the available space if we are running SLOW tests
16628         if [ $SLOW == "no" ]; then
16629                 local space=$((1024 * 100 * OSTCOUNT))
16630         else
16631                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
16632         fi
16633
16634         fallocate -l${space}k $DIR/$tfile ||
16635                 error "fallocate ${space}k $DIR/$tfile failed"
16636         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
16637
16638         # get size immediately after fallocate. This should be correctly
16639         # updated
16640         local size=$(stat -c '%s' $DIR/$tfile)
16641         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
16642
16643         # Sleep for a while for statfs to get updated. And not pull from cache.
16644         sleep 2
16645
16646         echo "df after fallocate:"
16647         $LFS df
16648
16649         (( size / 1024 == space )) || error "size $size != requested $space"
16650         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
16651                 error "used $used < space $space"
16652
16653         rm $DIR/$tfile || error "rm failed"
16654         sync
16655         wait_delete_completed
16656
16657         echo "df after unlink:"
16658         $LFS df
16659 }
16660 run_test 150e "Verify 60% of available OST space consumed by fallocate"
16661
16662 test_150f() {
16663         local size
16664         local blocks
16665         local want_size_before=20480 # in bytes
16666         local want_blocks_before=40 # 512 sized blocks
16667         local want_blocks_after=24  # 512 sized blocks
16668         local length=$(((want_blocks_before - want_blocks_after) * 512))
16669
16670         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16671                 skip "need at least 2.14.0 for fallocate punch"
16672
16673         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16674                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16675         fi
16676
16677         check_set_fallocate_or_skip
16678         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16679
16680         [[ "x$DOM" == "xyes" ]] &&
16681                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
16682
16683         echo "Verify fallocate punch: Range within the file range"
16684         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16685                 error "dd failed for bs 4096 and count 5"
16686
16687         # Call fallocate with punch range which is within the file range
16688         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
16689                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
16690         # client must see changes immediately after fallocate
16691         size=$(stat -c '%s' $DIR/$tfile)
16692         blocks=$(stat -c '%b' $DIR/$tfile)
16693
16694         # Verify punch worked.
16695         (( blocks == want_blocks_after )) ||
16696                 error "punch failed: blocks $blocks != $want_blocks_after"
16697
16698         (( size == want_size_before )) ||
16699                 error "punch failed: size $size != $want_size_before"
16700
16701         # Verify there is hole in file
16702         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
16703         # precomputed md5sum
16704         local expect="4a9a834a2db02452929c0a348273b4aa"
16705
16706         cksum=($(md5sum $DIR/$tfile))
16707         [[ "${cksum[0]}" == "$expect" ]] ||
16708                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16709
16710         # Start second sub-case for fallocate punch.
16711         echo "Verify fallocate punch: Range overlapping and less than blocksize"
16712         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16713                 error "dd failed for bs 4096 and count 5"
16714
16715         # Punch range less than block size will have no change in block count
16716         want_blocks_after=40  # 512 sized blocks
16717
16718         # Punch overlaps two blocks and less than blocksize
16719         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
16720                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
16721         size=$(stat -c '%s' $DIR/$tfile)
16722         blocks=$(stat -c '%b' $DIR/$tfile)
16723
16724         # Verify punch worked.
16725         (( blocks == want_blocks_after )) ||
16726                 error "punch failed: blocks $blocks != $want_blocks_after"
16727
16728         (( size == want_size_before )) ||
16729                 error "punch failed: size $size != $want_size_before"
16730
16731         # Verify if range is really zero'ed out. We expect Zeros.
16732         # precomputed md5sum
16733         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
16734         cksum=($(md5sum $DIR/$tfile))
16735         [[ "${cksum[0]}" == "$expect" ]] ||
16736                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16737 }
16738 run_test 150f "Verify fallocate punch functionality"
16739
16740 test_150g() {
16741         local space
16742         local size
16743         local blocks
16744         local blocks_after
16745         local size_after
16746         local BS=4096 # Block size in bytes
16747
16748         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16749                 skip "need at least 2.14.0 for fallocate punch"
16750
16751         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16752                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16753         fi
16754
16755         check_set_fallocate_or_skip
16756         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16757
16758         if [[ "x$DOM" == "xyes" ]]; then
16759                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
16760                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
16761         else
16762                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16763                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16764         fi
16765
16766         # Get 100MB per OST of the available space to reduce run time
16767         # else 60% of the available space if we are running SLOW tests
16768         if [ $SLOW == "no" ]; then
16769                 space=$((1024 * 100 * OSTCOUNT))
16770         else
16771                 # Find OST with Minimum Size
16772                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16773                         sort -un | head -1)
16774                 echo "min size OST: $space"
16775                 space=$(((space * 60)/100 * OSTCOUNT))
16776         fi
16777         # space in 1k units, round to 4k blocks
16778         local blkcount=$((space * 1024 / $BS))
16779
16780         echo "Verify fallocate punch: Very large Range"
16781         fallocate -l${space}k $DIR/$tfile ||
16782                 error "fallocate ${space}k $DIR/$tfile failed"
16783         # write 1M at the end, start and in the middle
16784         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
16785                 error "dd failed: bs $BS count 256"
16786         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
16787                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
16788         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
16789                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
16790
16791         # Gather stats.
16792         size=$(stat -c '%s' $DIR/$tfile)
16793
16794         # gather punch length.
16795         local punch_size=$((size - (BS * 2)))
16796
16797         echo "punch_size = $punch_size"
16798         echo "size - punch_size: $((size - punch_size))"
16799         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
16800
16801         # Call fallocate to punch all except 2 blocks. We leave the
16802         # first and the last block
16803         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
16804         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
16805                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
16806
16807         size_after=$(stat -c '%s' $DIR/$tfile)
16808         blocks_after=$(stat -c '%b' $DIR/$tfile)
16809
16810         # Verify punch worked.
16811         # Size should be kept
16812         (( size == size_after )) ||
16813                 error "punch failed: size $size != $size_after"
16814
16815         # two 4k data blocks to remain plus possible 1 extra extent block
16816         (( blocks_after <= ((BS / 512) * 3) )) ||
16817                 error "too many blocks remains: $blocks_after"
16818
16819         # Verify that file has hole between the first and the last blocks
16820         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
16821         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
16822
16823         echo "Hole at [$hole_start, $hole_end)"
16824         (( hole_start == BS )) ||
16825                 error "no hole at offset $BS after punch"
16826
16827         (( hole_end == BS + punch_size )) ||
16828                 error "data at offset $hole_end < $((BS + punch_size))"
16829 }
16830 run_test 150g "Verify fallocate punch on large range"
16831
16832 test_150h() {
16833         local file=$DIR/$tfile
16834         local size
16835
16836         check_set_fallocate_or_skip
16837         statx_supported || skip_env "Test must be statx() syscall supported"
16838
16839         # fallocate() does not update the size information on the MDT
16840         fallocate -l 16K $file || error "failed to fallocate $file"
16841         cancel_lru_locks $OSC
16842         # STATX with cached-always mode will not send glimpse RPCs to OST,
16843         # it uses the caching attrs on the client side as much as possible.
16844         size=$($STATX --cached=always -c %s $file)
16845         [ $size == 16384 ] ||
16846                 error "size after fallocate() is $size, expected 16384"
16847 }
16848 run_test 150h "Verify extend fallocate updates the file size"
16849
16850 #LU-2902 roc_hit was not able to read all values from lproc
16851 function roc_hit_init() {
16852         local list=$(comma_list $(osts_nodes))
16853         local dir=$DIR/$tdir-check
16854         local file=$dir/$tfile
16855         local BEFORE
16856         local AFTER
16857         local idx
16858
16859         test_mkdir $dir
16860         #use setstripe to do a write to every ost
16861         for i in $(seq 0 $((OSTCOUNT-1))); do
16862                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
16863                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
16864                 idx=$(printf %04x $i)
16865                 BEFORE=$(get_osd_param $list *OST*$idx stats |
16866                         awk '$1 == "cache_access" {sum += $7}
16867                                 END { printf("%0.0f", sum) }')
16868
16869                 cancel_lru_locks osc
16870                 cat $file >/dev/null
16871
16872                 AFTER=$(get_osd_param $list *OST*$idx stats |
16873                         awk '$1 == "cache_access" {sum += $7}
16874                                 END { printf("%0.0f", sum) }')
16875
16876                 echo BEFORE:$BEFORE AFTER:$AFTER
16877                 if ! let "AFTER - BEFORE == 4"; then
16878                         rm -rf $dir
16879                         error "roc_hit is not safe to use"
16880                 fi
16881                 rm $file
16882         done
16883
16884         rm -rf $dir
16885 }
16886
16887 function roc_hit() {
16888         local list=$(comma_list $(osts_nodes))
16889         echo $(get_osd_param $list '' stats |
16890                 awk '$1 == "cache_hit" {sum += $7}
16891                         END { printf("%0.0f", sum) }')
16892 }
16893
16894 function set_cache() {
16895         local on=1
16896
16897         if [ "$2" == "off" ]; then
16898                 on=0;
16899         fi
16900         local list=$(comma_list $(osts_nodes))
16901         set_osd_param $list '' $1_cache_enable $on
16902
16903         cancel_lru_locks osc
16904 }
16905
16906 test_151() {
16907         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16908         remote_ost_nodsh && skip "remote OST with nodsh"
16909         (( CLIENT_VERSION == OST1_VERSION )) ||
16910                 skip "LU-13081: no interop testing for OSS cache"
16911
16912         local CPAGES=3
16913         local list=$(comma_list $(osts_nodes))
16914
16915         # check whether obdfilter is cache capable at all
16916         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
16917                 skip "not cache-capable obdfilter"
16918         fi
16919
16920         # check cache is enabled on all obdfilters
16921         if get_osd_param $list '' read_cache_enable | grep 0; then
16922                 skip "oss cache is disabled"
16923         fi
16924
16925         set_osd_param $list '' writethrough_cache_enable 1
16926
16927         # check write cache is enabled on all obdfilters
16928         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
16929                 skip "oss write cache is NOT enabled"
16930         fi
16931
16932         roc_hit_init
16933
16934         #define OBD_FAIL_OBD_NO_LRU  0x609
16935         do_nodes $list $LCTL set_param fail_loc=0x609
16936
16937         # pages should be in the case right after write
16938         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
16939                 error "dd failed"
16940
16941         local BEFORE=$(roc_hit)
16942         cancel_lru_locks osc
16943         cat $DIR/$tfile >/dev/null
16944         local AFTER=$(roc_hit)
16945
16946         do_nodes $list $LCTL set_param fail_loc=0
16947
16948         if ! let "AFTER - BEFORE == CPAGES"; then
16949                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
16950         fi
16951
16952         cancel_lru_locks osc
16953         # invalidates OST cache
16954         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
16955         set_osd_param $list '' read_cache_enable 0
16956         cat $DIR/$tfile >/dev/null
16957
16958         # now data shouldn't be found in the cache
16959         BEFORE=$(roc_hit)
16960         cancel_lru_locks osc
16961         cat $DIR/$tfile >/dev/null
16962         AFTER=$(roc_hit)
16963         if let "AFTER - BEFORE != 0"; then
16964                 error "IN CACHE: before: $BEFORE, after: $AFTER"
16965         fi
16966
16967         set_osd_param $list '' read_cache_enable 1
16968         rm -f $DIR/$tfile
16969 }
16970 run_test 151 "test cache on oss and controls ==============================="
16971
16972 test_152() {
16973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16974
16975         local TF="$TMP/$tfile"
16976
16977         # simulate ENOMEM during write
16978 #define OBD_FAIL_OST_NOMEM      0x226
16979         lctl set_param fail_loc=0x80000226
16980         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16981         cp $TF $DIR/$tfile
16982         sync || error "sync failed"
16983         lctl set_param fail_loc=0
16984
16985         # discard client's cache
16986         cancel_lru_locks osc
16987
16988         # simulate ENOMEM during read
16989         lctl set_param fail_loc=0x80000226
16990         cmp $TF $DIR/$tfile || error "cmp failed"
16991         lctl set_param fail_loc=0
16992
16993         rm -f $TF
16994 }
16995 run_test 152 "test read/write with enomem ============================"
16996
16997 test_153() {
16998         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
16999 }
17000 run_test 153 "test if fdatasync does not crash ======================="
17001
17002 dot_lustre_fid_permission_check() {
17003         local fid=$1
17004         local ffid=$MOUNT/.lustre/fid/$fid
17005         local test_dir=$2
17006
17007         echo "stat fid $fid"
17008         stat $ffid || error "stat $ffid failed."
17009         echo "touch fid $fid"
17010         touch $ffid || error "touch $ffid failed."
17011         echo "write to fid $fid"
17012         cat /etc/hosts > $ffid || error "write $ffid failed."
17013         echo "read fid $fid"
17014         diff /etc/hosts $ffid || error "read $ffid failed."
17015         echo "append write to fid $fid"
17016         cat /etc/hosts >> $ffid || error "append write $ffid failed."
17017         echo "rename fid $fid"
17018         mv $ffid $test_dir/$tfile.1 &&
17019                 error "rename $ffid to $tfile.1 should fail."
17020         touch $test_dir/$tfile.1
17021         mv $test_dir/$tfile.1 $ffid &&
17022                 error "rename $tfile.1 to $ffid should fail."
17023         rm -f $test_dir/$tfile.1
17024         echo "truncate fid $fid"
17025         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
17026         echo "link fid $fid"
17027         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
17028         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
17029                 id $USER0 || skip_env "missing user $USER0"
17030                 echo "setfacl fid $fid"
17031                 setfacl -R -m u:$USER0:rwx $ffid ||
17032                         error "setfacl $ffid failed"
17033                 echo "getfacl fid $fid"
17034                 getfacl $ffid || error "getfacl $ffid failed."
17035         fi
17036         echo "unlink fid $fid"
17037         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
17038         echo "mknod fid $fid"
17039         mknod $ffid c 1 3 && error "mknod $ffid should fail."
17040
17041         fid=[0xf00000400:0x1:0x0]
17042         ffid=$MOUNT/.lustre/fid/$fid
17043
17044         echo "stat non-exist fid $fid"
17045         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
17046         echo "write to non-exist fid $fid"
17047         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
17048         echo "link new fid $fid"
17049         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
17050
17051         mkdir -p $test_dir/$tdir
17052         touch $test_dir/$tdir/$tfile
17053         fid=$($LFS path2fid $test_dir/$tdir)
17054         rc=$?
17055         [ $rc -ne 0 ] &&
17056                 error "error: could not get fid for $test_dir/$dir/$tfile."
17057
17058         ffid=$MOUNT/.lustre/fid/$fid
17059
17060         echo "ls $fid"
17061         ls $ffid || error "ls $ffid failed."
17062         echo "touch $fid/$tfile.1"
17063         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
17064
17065         echo "touch $MOUNT/.lustre/fid/$tfile"
17066         touch $MOUNT/.lustre/fid/$tfile && \
17067                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
17068
17069         echo "setxattr to $MOUNT/.lustre/fid"
17070         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
17071
17072         echo "listxattr for $MOUNT/.lustre/fid"
17073         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
17074
17075         echo "delxattr from $MOUNT/.lustre/fid"
17076         setfattr -x trusted.name1 $MOUNT/.lustre/fid
17077
17078         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
17079         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
17080                 error "touch invalid fid should fail."
17081
17082         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
17083         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
17084                 error "touch non-normal fid should fail."
17085
17086         echo "rename $tdir to $MOUNT/.lustre/fid"
17087         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
17088                 error "rename to $MOUNT/.lustre/fid should fail."
17089
17090         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
17091         then            # LU-3547
17092                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
17093                 local new_obf_mode=777
17094
17095                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
17096                 chmod $new_obf_mode $DIR/.lustre/fid ||
17097                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
17098
17099                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
17100                 [ $obf_mode -eq $new_obf_mode ] ||
17101                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
17102
17103                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
17104                 chmod $old_obf_mode $DIR/.lustre/fid ||
17105                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
17106         fi
17107
17108         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
17109         fid=$($LFS path2fid $test_dir/$tfile-2)
17110
17111         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
17112         then # LU-5424
17113                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
17114                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
17115                         error "create lov data thru .lustre failed"
17116         fi
17117         echo "cp /etc/passwd $test_dir/$tfile-2"
17118         cp /etc/passwd $test_dir/$tfile-2 ||
17119                 error "copy to $test_dir/$tfile-2 failed."
17120         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
17121         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
17122                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
17123
17124         rm -rf $test_dir/tfile.lnk
17125         rm -rf $test_dir/$tfile-2
17126 }
17127
17128 test_154A() {
17129         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
17130                 skip "Need MDS version at least 2.4.1"
17131
17132         local tf=$DIR/$tfile
17133         touch $tf
17134
17135         local fid=$($LFS path2fid $tf)
17136         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
17137
17138         # check that we get the same pathname back
17139         local rootpath
17140         local found
17141         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
17142                 echo "$rootpath $fid"
17143                 found=$($LFS fid2path $rootpath "$fid")
17144                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
17145                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
17146         done
17147
17148         # check wrong root path format
17149         rootpath=$MOUNT"_wrong"
17150         found=$($LFS fid2path $rootpath "$fid")
17151         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
17152 }
17153 run_test 154A "lfs path2fid and fid2path basic checks"
17154
17155 test_154B() {
17156         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
17157                 skip "Need MDS version at least 2.4.1"
17158
17159         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
17160         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
17161         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
17162         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
17163
17164         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
17165         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
17166
17167         # check that we get the same pathname
17168         echo "PFID: $PFID, name: $name"
17169         local FOUND=$($LFS fid2path $MOUNT "$PFID")
17170         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
17171         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
17172                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
17173
17174         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
17175 }
17176 run_test 154B "verify the ll_decode_linkea tool"
17177
17178 test_154a() {
17179         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17180         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17181         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
17182                 skip "Need MDS version at least 2.2.51"
17183         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
17184
17185         cp /etc/hosts $DIR/$tfile
17186
17187         fid=$($LFS path2fid $DIR/$tfile)
17188         rc=$?
17189         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
17190
17191         dot_lustre_fid_permission_check "$fid" $DIR ||
17192                 error "dot lustre permission check $fid failed"
17193
17194         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
17195
17196         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
17197
17198         touch $MOUNT/.lustre/file &&
17199                 error "creation is not allowed under .lustre"
17200
17201         mkdir $MOUNT/.lustre/dir &&
17202                 error "mkdir is not allowed under .lustre"
17203
17204         rm -rf $DIR/$tfile
17205 }
17206 run_test 154a "Open-by-FID"
17207
17208 test_154b() {
17209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17210         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17211         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17212         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
17213                 skip "Need MDS version at least 2.2.51"
17214
17215         local remote_dir=$DIR/$tdir/remote_dir
17216         local MDTIDX=1
17217         local rc=0
17218
17219         mkdir -p $DIR/$tdir
17220         $LFS mkdir -i $MDTIDX $remote_dir ||
17221                 error "create remote directory failed"
17222
17223         cp /etc/hosts $remote_dir/$tfile
17224
17225         fid=$($LFS path2fid $remote_dir/$tfile)
17226         rc=$?
17227         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
17228
17229         dot_lustre_fid_permission_check "$fid" $remote_dir ||
17230                 error "dot lustre permission check $fid failed"
17231         rm -rf $DIR/$tdir
17232 }
17233 run_test 154b "Open-by-FID for remote directory"
17234
17235 test_154c() {
17236         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
17237                 skip "Need MDS version at least 2.4.1"
17238
17239         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
17240         local FID1=$($LFS path2fid $DIR/$tfile.1)
17241         local FID2=$($LFS path2fid $DIR/$tfile.2)
17242         local FID3=$($LFS path2fid $DIR/$tfile.3)
17243
17244         local N=1
17245         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
17246                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
17247                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
17248                 local want=FID$N
17249                 [ "$FID" = "${!want}" ] ||
17250                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
17251                 N=$((N + 1))
17252         done
17253
17254         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
17255         do
17256                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
17257                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
17258                 N=$((N + 1))
17259         done
17260 }
17261 run_test 154c "lfs path2fid and fid2path multiple arguments"
17262
17263 test_154d() {
17264         remote_mds_nodsh && skip "remote MDS with nodsh"
17265         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
17266                 skip "Need MDS version at least 2.5.53"
17267
17268         if remote_mds; then
17269                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
17270         else
17271                 nid="0@lo"
17272         fi
17273         local proc_ofile="mdt.*.exports.'$nid'.open_files"
17274         local fd
17275         local cmd
17276
17277         rm -f $DIR/$tfile
17278         touch $DIR/$tfile
17279
17280         local fid=$($LFS path2fid $DIR/$tfile)
17281         # Open the file
17282         fd=$(free_fd)
17283         cmd="exec $fd<$DIR/$tfile"
17284         eval $cmd
17285         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
17286         echo "$fid_list" | grep "$fid"
17287         rc=$?
17288
17289         cmd="exec $fd>/dev/null"
17290         eval $cmd
17291         if [ $rc -ne 0 ]; then
17292                 error "FID $fid not found in open files list $fid_list"
17293         fi
17294 }
17295 run_test 154d "Verify open file fid"
17296
17297 test_154e()
17298 {
17299         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
17300                 skip "Need MDS version at least 2.6.50"
17301
17302         if ls -a $MOUNT | grep -q '^\.lustre$'; then
17303                 error ".lustre returned by readdir"
17304         fi
17305 }
17306 run_test 154e ".lustre is not returned by readdir"
17307
17308 test_154f() {
17309         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17310
17311         # create parent directory on a single MDT to avoid cross-MDT hardlinks
17312         mkdir_on_mdt0 $DIR/$tdir
17313         # test dirs inherit from its stripe
17314         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
17315         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
17316         cp /etc/hosts $DIR/$tdir/foo1/$tfile
17317         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
17318         touch $DIR/f
17319
17320         # get fid of parents
17321         local FID0=$($LFS path2fid $DIR/$tdir)
17322         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
17323         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
17324         local FID3=$($LFS path2fid $DIR)
17325
17326         # check that path2fid --parents returns expected <parent_fid>/name
17327         # 1) test for a directory (single parent)
17328         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
17329         [ "$parent" == "$FID0/foo1" ] ||
17330                 error "expected parent: $FID0/foo1, got: $parent"
17331
17332         # 2) test for a file with nlink > 1 (multiple parents)
17333         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
17334         echo "$parent" | grep -F "$FID1/$tfile" ||
17335                 error "$FID1/$tfile not returned in parent list"
17336         echo "$parent" | grep -F "$FID2/link" ||
17337                 error "$FID2/link not returned in parent list"
17338
17339         # 3) get parent by fid
17340         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
17341         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17342         echo "$parent" | grep -F "$FID1/$tfile" ||
17343                 error "$FID1/$tfile not returned in parent list (by fid)"
17344         echo "$parent" | grep -F "$FID2/link" ||
17345                 error "$FID2/link not returned in parent list (by fid)"
17346
17347         # 4) test for entry in root directory
17348         parent=$($LFS path2fid --parents $DIR/f)
17349         echo "$parent" | grep -F "$FID3/f" ||
17350                 error "$FID3/f not returned in parent list"
17351
17352         # 5) test it on root directory
17353         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
17354                 error "$MOUNT should not have parents"
17355
17356         # enable xattr caching and check that linkea is correctly updated
17357         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
17358         save_lustre_params client "llite.*.xattr_cache" > $save
17359         lctl set_param llite.*.xattr_cache 1
17360
17361         # 6.1) linkea update on rename
17362         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
17363
17364         # get parents by fid
17365         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17366         # foo1 should no longer be returned in parent list
17367         echo "$parent" | grep -F "$FID1" &&
17368                 error "$FID1 should no longer be in parent list"
17369         # the new path should appear
17370         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
17371                 error "$FID2/$tfile.moved is not in parent list"
17372
17373         # 6.2) linkea update on unlink
17374         rm -f $DIR/$tdir/foo2/link
17375         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17376         # foo2/link should no longer be returned in parent list
17377         echo "$parent" | grep -F "$FID2/link" &&
17378                 error "$FID2/link should no longer be in parent list"
17379         true
17380
17381         rm -f $DIR/f
17382         restore_lustre_params < $save
17383         rm -f $save
17384 }
17385 run_test 154f "get parent fids by reading link ea"
17386
17387 test_154g()
17388 {
17389         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
17390            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
17391                 skip "Need MDS version at least 2.6.92"
17392
17393         mkdir_on_mdt0 $DIR/$tdir
17394         llapi_fid_test -d $DIR/$tdir
17395 }
17396 run_test 154g "various llapi FID tests"
17397
17398 test_154h()
17399 {
17400         (( $CLIENT_VERSION >= $(version_code 2.15.55.1) )) ||
17401                 skip "Need client at least version 2.15.55.1"
17402
17403         # Create an empty file
17404         touch $DIR/$tfile
17405
17406         # Get FID (interactive mode) and save under $TMP/$tfile.log
17407         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
17408                 path2fid $DIR/$tfile
17409         EOF
17410
17411         fid=$(cat $TMP/$tfile.log)
17412         # $fid should not be empty
17413         [[ ! -z $fid ]] || error "FID is empty"
17414         $LFS rmfid $DIR "$fid" || error "rmfid failed for $fid"
17415 }
17416 run_test 154h "Verify interactive path2fid"
17417
17418 test_155_small_load() {
17419     local temp=$TMP/$tfile
17420     local file=$DIR/$tfile
17421
17422     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
17423         error "dd of=$temp bs=6096 count=1 failed"
17424     cp $temp $file
17425     cancel_lru_locks $OSC
17426     cmp $temp $file || error "$temp $file differ"
17427
17428     $TRUNCATE $temp 6000
17429     $TRUNCATE $file 6000
17430     cmp $temp $file || error "$temp $file differ (truncate1)"
17431
17432     echo "12345" >>$temp
17433     echo "12345" >>$file
17434     cmp $temp $file || error "$temp $file differ (append1)"
17435
17436     echo "12345" >>$temp
17437     echo "12345" >>$file
17438     cmp $temp $file || error "$temp $file differ (append2)"
17439
17440     rm -f $temp $file
17441     true
17442 }
17443
17444 test_155_big_load() {
17445         remote_ost_nodsh && skip "remote OST with nodsh"
17446
17447         local temp=$TMP/$tfile
17448         local file=$DIR/$tfile
17449
17450         free_min_max
17451         local cache_size=$(do_facet ost$((MAXI+1)) \
17452                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
17453
17454         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
17455         # pre-set value
17456         if [ -z "$cache_size" ]; then
17457                 cache_size=256
17458         fi
17459         local large_file_size=$((cache_size * 2))
17460
17461         echo "OSS cache size: $cache_size KB"
17462         echo "Large file size: $large_file_size KB"
17463
17464         [ $MAXV -le $large_file_size ] &&
17465                 skip_env "max available OST size needs > $large_file_size KB"
17466
17467         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
17468
17469         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
17470                 error "dd of=$temp bs=$large_file_size count=1k failed"
17471         cp $temp $file
17472         ls -lh $temp $file
17473         cancel_lru_locks osc
17474         cmp $temp $file || error "$temp $file differ"
17475
17476         rm -f $temp $file
17477         true
17478 }
17479
17480 save_writethrough() {
17481         local facets=$(get_facets OST)
17482
17483         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
17484 }
17485
17486 test_155a() {
17487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17488
17489         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17490
17491         save_writethrough $p
17492
17493         set_cache read on
17494         set_cache writethrough on
17495         test_155_small_load
17496         restore_lustre_params < $p
17497         rm -f $p
17498 }
17499 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
17500
17501 test_155b() {
17502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17503
17504         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17505
17506         save_writethrough $p
17507
17508         set_cache read on
17509         set_cache writethrough off
17510         test_155_small_load
17511         restore_lustre_params < $p
17512         rm -f $p
17513 }
17514 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
17515
17516 test_155c() {
17517         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17518
17519         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17520
17521         save_writethrough $p
17522
17523         set_cache read off
17524         set_cache writethrough on
17525         test_155_small_load
17526         restore_lustre_params < $p
17527         rm -f $p
17528 }
17529 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
17530
17531 test_155d() {
17532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17533
17534         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17535
17536         save_writethrough $p
17537
17538         set_cache read off
17539         set_cache writethrough off
17540         test_155_small_load
17541         restore_lustre_params < $p
17542         rm -f $p
17543 }
17544 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
17545
17546 test_155e() {
17547         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17548
17549         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17550
17551         save_writethrough $p
17552
17553         set_cache read on
17554         set_cache writethrough on
17555         test_155_big_load
17556         restore_lustre_params < $p
17557         rm -f $p
17558 }
17559 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
17560
17561 test_155f() {
17562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17563
17564         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17565
17566         save_writethrough $p
17567
17568         set_cache read on
17569         set_cache writethrough off
17570         test_155_big_load
17571         restore_lustre_params < $p
17572         rm -f $p
17573 }
17574 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
17575
17576 test_155g() {
17577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17578
17579         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17580
17581         save_writethrough $p
17582
17583         set_cache read off
17584         set_cache writethrough on
17585         test_155_big_load
17586         restore_lustre_params < $p
17587         rm -f $p
17588 }
17589 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
17590
17591 test_155h() {
17592         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17593
17594         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17595
17596         save_writethrough $p
17597
17598         set_cache read off
17599         set_cache writethrough off
17600         test_155_big_load
17601         restore_lustre_params < $p
17602         rm -f $p
17603 }
17604 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
17605
17606 test_156() {
17607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17608         remote_ost_nodsh && skip "remote OST with nodsh"
17609         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
17610                 skip "stats not implemented on old servers"
17611         [ "$ost1_FSTYPE" = "zfs" ] &&
17612                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
17613         (( CLIENT_VERSION == OST1_VERSION )) ||
17614                 skip "LU-13081: no interop testing for OSS cache"
17615
17616         local CPAGES=3
17617         local BEFORE
17618         local AFTER
17619         local file="$DIR/$tfile"
17620         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17621
17622         save_writethrough $p
17623         roc_hit_init
17624
17625         log "Turn on read and write cache"
17626         set_cache read on
17627         set_cache writethrough on
17628
17629         log "Write data and read it back."
17630         log "Read should be satisfied from the cache."
17631         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17632         BEFORE=$(roc_hit)
17633         cancel_lru_locks osc
17634         cat $file >/dev/null
17635         AFTER=$(roc_hit)
17636         if ! let "AFTER - BEFORE == CPAGES"; then
17637                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
17638         else
17639                 log "cache hits: before: $BEFORE, after: $AFTER"
17640         fi
17641
17642         log "Read again; it should be satisfied from the cache."
17643         BEFORE=$AFTER
17644         cancel_lru_locks osc
17645         cat $file >/dev/null
17646         AFTER=$(roc_hit)
17647         if ! let "AFTER - BEFORE == CPAGES"; then
17648                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
17649         else
17650                 log "cache hits:: before: $BEFORE, after: $AFTER"
17651         fi
17652
17653         log "Turn off the read cache and turn on the write cache"
17654         set_cache read off
17655         set_cache writethrough on
17656
17657         log "Read again; it should be satisfied from the cache."
17658         BEFORE=$(roc_hit)
17659         cancel_lru_locks osc
17660         cat $file >/dev/null
17661         AFTER=$(roc_hit)
17662         if ! let "AFTER - BEFORE == CPAGES"; then
17663                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
17664         else
17665                 log "cache hits:: before: $BEFORE, after: $AFTER"
17666         fi
17667
17668         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17669                 # > 2.12.56 uses pagecache if cached
17670                 log "Read again; it should not be satisfied from the cache."
17671                 BEFORE=$AFTER
17672                 cancel_lru_locks osc
17673                 cat $file >/dev/null
17674                 AFTER=$(roc_hit)
17675                 if ! let "AFTER - BEFORE == 0"; then
17676                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
17677                 else
17678                         log "cache hits:: before: $BEFORE, after: $AFTER"
17679                 fi
17680         fi
17681
17682         log "Write data and read it back."
17683         log "Read should be satisfied from the cache."
17684         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17685         BEFORE=$(roc_hit)
17686         cancel_lru_locks osc
17687         cat $file >/dev/null
17688         AFTER=$(roc_hit)
17689         if ! let "AFTER - BEFORE == CPAGES"; then
17690                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
17691         else
17692                 log "cache hits:: before: $BEFORE, after: $AFTER"
17693         fi
17694
17695         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17696                 # > 2.12.56 uses pagecache if cached
17697                 log "Read again; it should not be satisfied from the cache."
17698                 BEFORE=$AFTER
17699                 cancel_lru_locks osc
17700                 cat $file >/dev/null
17701                 AFTER=$(roc_hit)
17702                 if ! let "AFTER - BEFORE == 0"; then
17703                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
17704                 else
17705                         log "cache hits:: before: $BEFORE, after: $AFTER"
17706                 fi
17707         fi
17708
17709         log "Turn off read and write cache"
17710         set_cache read off
17711         set_cache writethrough off
17712
17713         log "Write data and read it back"
17714         log "It should not be satisfied from the cache."
17715         rm -f $file
17716         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17717         cancel_lru_locks osc
17718         BEFORE=$(roc_hit)
17719         cat $file >/dev/null
17720         AFTER=$(roc_hit)
17721         if ! let "AFTER - BEFORE == 0"; then
17722                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
17723         else
17724                 log "cache hits:: before: $BEFORE, after: $AFTER"
17725         fi
17726
17727         log "Turn on the read cache and turn off the write cache"
17728         set_cache read on
17729         set_cache writethrough off
17730
17731         log "Write data and read it back"
17732         log "It should not be satisfied from the cache."
17733         rm -f $file
17734         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17735         BEFORE=$(roc_hit)
17736         cancel_lru_locks osc
17737         cat $file >/dev/null
17738         AFTER=$(roc_hit)
17739         if ! let "AFTER - BEFORE == 0"; then
17740                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
17741         else
17742                 log "cache hits:: before: $BEFORE, after: $AFTER"
17743         fi
17744
17745         log "Read again; it should be satisfied from the cache."
17746         BEFORE=$(roc_hit)
17747         cancel_lru_locks osc
17748         cat $file >/dev/null
17749         AFTER=$(roc_hit)
17750         if ! let "AFTER - BEFORE == CPAGES"; then
17751                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
17752         else
17753                 log "cache hits:: before: $BEFORE, after: $AFTER"
17754         fi
17755
17756         restore_lustre_params < $p
17757         rm -f $p $file
17758 }
17759 run_test 156 "Verification of tunables"
17760
17761 test_160a() {
17762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17763         remote_mds_nodsh && skip "remote MDS with nodsh"
17764         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17765                 skip "Need MDS version at least 2.2.0"
17766
17767         changelog_register || error "changelog_register failed"
17768         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17769         changelog_users $SINGLEMDS | grep -q $cl_user ||
17770                 error "User $cl_user not found in changelog_users"
17771
17772         mkdir_on_mdt0 $DIR/$tdir
17773
17774         # change something
17775         test_mkdir -p $DIR/$tdir/pics/2008/zachy
17776         changelog_clear 0 || error "changelog_clear failed"
17777         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
17778         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
17779         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17780         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17781         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17782         rm $DIR/$tdir/pics/desktop.jpg
17783
17784         echo "verifying changelog mask"
17785         changelog_chmask "-MKDIR"
17786         changelog_chmask "-CLOSE"
17787
17788         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
17789         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
17790
17791         changelog_chmask "+MKDIR"
17792         changelog_chmask "+CLOSE"
17793
17794         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
17795         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
17796
17797         MKDIRS=$(changelog_dump | grep -c "MKDIR")
17798         CLOSES=$(changelog_dump | grep -c "CLOSE")
17799         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
17800         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
17801
17802         # verify contents
17803         echo "verifying target fid"
17804         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
17805         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
17806         [ "$fidc" == "$fidf" ] ||
17807                 error "changelog '$tfile' fid $fidc != file fid $fidf"
17808         echo "verifying parent fid"
17809         # The FID returned from the Changelog may be the directory shard on
17810         # a different MDT, and not the FID returned by path2fid on the parent.
17811         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
17812         # since this is what will matter when recreating this file in the tree.
17813         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
17814         local pathp=$($LFS fid2path $MOUNT "$fidp")
17815         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
17816                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
17817
17818         echo "getting records for $cl_user"
17819         changelog_users $SINGLEMDS
17820         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
17821         local nclr=3
17822         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
17823                 error "changelog_clear failed"
17824         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
17825         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
17826         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
17827                 error "user index expect $user_rec1 + $nclr != $user_rec2"
17828
17829         local min0_rec=$(changelog_users $SINGLEMDS |
17830                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
17831         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
17832                           awk '{ print $1; exit; }')
17833
17834         changelog_dump | tail -n 5
17835         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
17836         [ $first_rec == $((min0_rec + 1)) ] ||
17837                 error "first index should be $min0_rec + 1 not $first_rec"
17838
17839         # LU-3446 changelog index reset on MDT restart
17840         local cur_rec1=$(changelog_users $SINGLEMDS |
17841                          awk '/^current.index:/ { print $NF }')
17842         changelog_clear 0 ||
17843                 error "clear all changelog records for $cl_user failed"
17844         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
17845         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
17846                 error "Fail to start $SINGLEMDS"
17847         local cur_rec2=$(changelog_users $SINGLEMDS |
17848                          awk '/^current.index:/ { print $NF }')
17849         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
17850         [ $cur_rec1 == $cur_rec2 ] ||
17851                 error "current index should be $cur_rec1 not $cur_rec2"
17852
17853         echo "verifying users from this test are deregistered"
17854         changelog_deregister || error "changelog_deregister failed"
17855         changelog_users $SINGLEMDS | grep -q $cl_user &&
17856                 error "User '$cl_user' still in changelog_users"
17857
17858         # lctl get_param -n mdd.*.changelog_users
17859         # current_index: 144
17860         # ID    index (idle seconds)
17861         # cl3   144   (2) mask=<list>
17862         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
17863                 # this is the normal case where all users were deregistered
17864                 # make sure no new records are added when no users are present
17865                 local last_rec1=$(changelog_users $SINGLEMDS |
17866                                   awk '/^current.index:/ { print $NF }')
17867                 touch $DIR/$tdir/chloe
17868                 local last_rec2=$(changelog_users $SINGLEMDS |
17869                                   awk '/^current.index:/ { print $NF }')
17870                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
17871                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
17872         else
17873                 # any changelog users must be leftovers from a previous test
17874                 changelog_users $SINGLEMDS
17875                 echo "other changelog users; can't verify off"
17876         fi
17877 }
17878 run_test 160a "changelog sanity"
17879
17880 test_160b() { # LU-3587
17881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17882         remote_mds_nodsh && skip "remote MDS with nodsh"
17883         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17884                 skip "Need MDS version at least 2.2.0"
17885
17886         changelog_register || error "changelog_register failed"
17887         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17888         changelog_users $SINGLEMDS | grep -q $cl_user ||
17889                 error "User '$cl_user' not found in changelog_users"
17890
17891         local longname1=$(str_repeat a 255)
17892         local longname2=$(str_repeat b 255)
17893
17894         cd $DIR
17895         echo "creating very long named file"
17896         touch $longname1 || error "create of '$longname1' failed"
17897         echo "renaming very long named file"
17898         mv $longname1 $longname2
17899
17900         changelog_dump | grep RENME | tail -n 5
17901         rm -f $longname2
17902 }
17903 run_test 160b "Verify that very long rename doesn't crash in changelog"
17904
17905 test_160c() {
17906         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17907         remote_mds_nodsh && skip "remote MDS with nodsh"
17908
17909         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
17910                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
17911                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
17912                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
17913
17914         local rc=0
17915
17916         # Registration step
17917         changelog_register || error "changelog_register failed"
17918
17919         rm -rf $DIR/$tdir
17920         mkdir -p $DIR/$tdir
17921         $MCREATE $DIR/$tdir/foo_160c
17922         changelog_chmask "-TRUNC"
17923         $TRUNCATE $DIR/$tdir/foo_160c 200
17924         changelog_chmask "+TRUNC"
17925         $TRUNCATE $DIR/$tdir/foo_160c 199
17926         changelog_dump | tail -n 5
17927         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
17928         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
17929 }
17930 run_test 160c "verify that changelog log catch the truncate event"
17931
17932 test_160d() {
17933         remote_mds_nodsh && skip "remote MDS with nodsh"
17934         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17936         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
17937                 skip "Need MDS version at least 2.7.60"
17938
17939         # Registration step
17940         changelog_register || error "changelog_register failed"
17941
17942         mkdir -p $DIR/$tdir/migrate_dir
17943         changelog_clear 0 || error "changelog_clear failed"
17944
17945         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
17946         changelog_dump | tail -n 5
17947         local migrates=$(changelog_dump | grep -c "MIGRT")
17948         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
17949 }
17950 run_test 160d "verify that changelog log catch the migrate event"
17951
17952 test_160e() {
17953         remote_mds_nodsh && skip "remote MDS with nodsh"
17954
17955         # Create a user
17956         changelog_register || error "changelog_register failed"
17957
17958         local MDT0=$(facet_svc $SINGLEMDS)
17959         local rc
17960
17961         # No user (expect fail)
17962         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
17963         rc=$?
17964         if [ $rc -eq 0 ]; then
17965                 error "Should fail without user"
17966         elif [ $rc -ne 4 ]; then
17967                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
17968         fi
17969
17970         # Delete a future user (expect fail)
17971         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
17972         rc=$?
17973         if [ $rc -eq 0 ]; then
17974                 error "Deleted non-existant user cl77"
17975         elif [ $rc -ne 2 ]; then
17976                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
17977         fi
17978
17979         # Clear to a bad index (1 billion should be safe)
17980         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
17981         rc=$?
17982
17983         if [ $rc -eq 0 ]; then
17984                 error "Successfully cleared to invalid CL index"
17985         elif [ $rc -ne 22 ]; then
17986                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
17987         fi
17988 }
17989 run_test 160e "changelog negative testing (should return errors)"
17990
17991 test_160f() {
17992         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17993         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17994                 skip "Need MDS version at least 2.10.56"
17995
17996         local mdts=$(comma_list $(mdts_nodes))
17997
17998         # Create a user
17999         changelog_register || error "first changelog_register failed"
18000         changelog_register || error "second changelog_register failed"
18001         local cl_users
18002         declare -A cl_user1
18003         declare -A cl_user2
18004         local user_rec1
18005         local user_rec2
18006         local i
18007
18008         # generate some changelog records to accumulate on each MDT
18009         # use all_char because created files should be evenly distributed
18010         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18011                 error "test_mkdir $tdir failed"
18012         log "$(date +%s): creating first files"
18013         for ((i = 0; i < MDSCOUNT * 2; i++)); do
18014                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
18015                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
18016         done
18017
18018         # check changelogs have been generated
18019         local start=$SECONDS
18020         local idle_time=$((MDSCOUNT * 5 + 5))
18021         local nbcl=$(changelog_dump | wc -l)
18022         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18023
18024         for param in "changelog_max_idle_time=$idle_time" \
18025                      "changelog_gc=1" \
18026                      "changelog_min_gc_interval=2" \
18027                      "changelog_min_free_cat_entries=3"; do
18028                 local MDT0=$(facet_svc $SINGLEMDS)
18029                 local var="${param%=*}"
18030                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18031
18032                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18033                 do_nodes $mdts $LCTL set_param mdd.*.$param
18034         done
18035
18036         # force cl_user2 to be idle (1st part), but also cancel the
18037         # cl_user1 records so that it is not evicted later in the test.
18038         local sleep1=$((idle_time / 2))
18039         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
18040         sleep $sleep1
18041
18042         # simulate changelog catalog almost full
18043         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
18044         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
18045
18046         for i in $(seq $MDSCOUNT); do
18047                 cl_users=(${CL_USERS[mds$i]})
18048                 cl_user1[mds$i]="${cl_users[0]}"
18049                 cl_user2[mds$i]="${cl_users[1]}"
18050
18051                 [ -n "${cl_user1[mds$i]}" ] ||
18052                         error "mds$i: no user registered"
18053                 [ -n "${cl_user2[mds$i]}" ] ||
18054                         error "mds$i: only ${cl_user2[mds$i]} is registered"
18055
18056                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18057                 [ -n "$user_rec1" ] ||
18058                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18059                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
18060                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18061                 [ -n "$user_rec2" ] ||
18062                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18063                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
18064                      "$user_rec1 + 2 == $user_rec2"
18065                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
18066                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
18067                               "$user_rec1 + 2, but is $user_rec2"
18068                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
18069                 [ -n "$user_rec2" ] ||
18070                         error "mds$i: User ${cl_user2[mds$i]} not registered"
18071                 [ $user_rec1 == $user_rec2 ] ||
18072                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
18073                               "$user_rec1, but is $user_rec2"
18074         done
18075
18076         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
18077         local sleep2=$((idle_time - (SECONDS - start) + 1))
18078         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
18079         sleep $sleep2
18080
18081         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
18082         # cl_user1 should be OK because it recently processed records.
18083         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
18084         for ((i = 0; i < MDSCOUNT * 2; i++)); do
18085                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
18086                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
18087         done
18088
18089         # ensure gc thread is done
18090         for i in $(mdts_nodes); do
18091                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
18092                         error "$i: GC-thread not done"
18093         done
18094
18095         local first_rec
18096         for (( i = 1; i <= MDSCOUNT; i++ )); do
18097                 # check cl_user1 still registered
18098                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
18099                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18100                 # check cl_user2 unregistered
18101                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
18102                         error "mds$i: User ${cl_user2[mds$i]} still registered"
18103
18104                 # check changelogs are present and starting at $user_rec1 + 1
18105                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18106                 [ -n "$user_rec1" ] ||
18107                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18108                 first_rec=$($LFS changelog $(facet_svc mds$i) |
18109                             awk '{ print $1; exit; }')
18110
18111                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
18112                 [ $((user_rec1 + 1)) == $first_rec ] ||
18113                         error "mds$i: rec $first_rec != $user_rec1 + 1"
18114         done
18115 }
18116 run_test 160f "changelog garbage collect (timestamped users)"
18117
18118 test_160g() {
18119         remote_mds_nodsh && skip "remote MDS with nodsh"
18120         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
18121                 skip "Need MDS version at least 2.14.55"
18122
18123         local mdts=$(comma_list $(mdts_nodes))
18124
18125         # Create a user
18126         changelog_register || error "first changelog_register failed"
18127         changelog_register || error "second changelog_register failed"
18128         local cl_users
18129         declare -A cl_user1
18130         declare -A cl_user2
18131         local user_rec1
18132         local user_rec2
18133         local i
18134
18135         # generate some changelog records to accumulate on each MDT
18136         # use all_char because created files should be evenly distributed
18137         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18138                 error "test_mkdir $tdir failed"
18139         for ((i = 0; i < MDSCOUNT; i++)); do
18140                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18141                         error "create $DIR/$tdir/d$i.1 failed"
18142         done
18143
18144         # check changelogs have been generated
18145         local nbcl=$(changelog_dump | wc -l)
18146         (( $nbcl > 0 )) || error "no changelogs found"
18147
18148         # reduce the max_idle_indexes value to make sure we exceed it
18149         for param in "changelog_max_idle_indexes=2" \
18150                      "changelog_gc=1" \
18151                      "changelog_min_gc_interval=2"; do
18152                 local MDT0=$(facet_svc $SINGLEMDS)
18153                 local var="${param%=*}"
18154                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18155
18156                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18157                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
18158                         error "unable to set mdd.*.$param"
18159         done
18160
18161         local start=$SECONDS
18162         for i in $(seq $MDSCOUNT); do
18163                 cl_users=(${CL_USERS[mds$i]})
18164                 cl_user1[mds$i]="${cl_users[0]}"
18165                 cl_user2[mds$i]="${cl_users[1]}"
18166
18167                 [ -n "${cl_user1[mds$i]}" ] ||
18168                         error "mds$i: user1 is not registered"
18169                 [ -n "${cl_user2[mds$i]}" ] ||
18170                         error "mds$i: only ${cl_user1[mds$i]} is registered"
18171
18172                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18173                 [ -n "$user_rec1" ] ||
18174                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
18175                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
18176                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18177                 [ -n "$user_rec2" ] ||
18178                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
18179                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
18180                      "$user_rec1 + 2 == $user_rec2"
18181                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
18182                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
18183                               "expected $user_rec1 + 2, but is $user_rec2"
18184                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
18185                 [ -n "$user_rec2" ] ||
18186                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
18187                 [ $user_rec1 == $user_rec2 ] ||
18188                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
18189                               "expected $user_rec1, but is $user_rec2"
18190         done
18191
18192         # ensure we are past the previous changelog_min_gc_interval set above
18193         local sleep2=$((start + 2 - SECONDS))
18194         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18195         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
18196         # cl_user1 should be OK because it recently processed records.
18197         for ((i = 0; i < MDSCOUNT; i++)); do
18198                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
18199                         error "create $DIR/$tdir/d$i.3 failed"
18200         done
18201
18202         # ensure gc thread is done
18203         for i in $(mdts_nodes); do
18204                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
18205                         error "$i: GC-thread not done"
18206         done
18207
18208         local first_rec
18209         for (( i = 1; i <= MDSCOUNT; i++ )); do
18210                 # check cl_user1 still registered
18211                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
18212                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
18213                 # check cl_user2 unregistered
18214                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
18215                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
18216
18217                 # check changelogs are present and starting at $user_rec1 + 1
18218                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18219                 [ -n "$user_rec1" ] ||
18220                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
18221                 first_rec=$($LFS changelog $(facet_svc mds$i) |
18222                             awk '{ print $1; exit; }')
18223
18224                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
18225                 [ $((user_rec1 + 1)) == $first_rec ] ||
18226                         error "mds$i: rec $first_rec != $user_rec1 + 1"
18227         done
18228 }
18229 run_test 160g "changelog garbage collect on idle records"
18230
18231 test_160h() {
18232         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18233         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
18234                 skip "Need MDS version at least 2.10.56"
18235
18236         local mdts=$(comma_list $(mdts_nodes))
18237
18238         # Create a user
18239         changelog_register || error "first changelog_register failed"
18240         changelog_register || error "second changelog_register failed"
18241         local cl_users
18242         declare -A cl_user1
18243         declare -A cl_user2
18244         local user_rec1
18245         local user_rec2
18246         local i
18247
18248         # generate some changelog records to accumulate on each MDT
18249         # use all_char because created files should be evenly distributed
18250         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18251                 error "test_mkdir $tdir failed"
18252         for ((i = 0; i < MDSCOUNT; i++)); do
18253                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18254                         error "create $DIR/$tdir/d$i.1 failed"
18255         done
18256
18257         # check changelogs have been generated
18258         local nbcl=$(changelog_dump | wc -l)
18259         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18260
18261         for param in "changelog_max_idle_time=10" \
18262                      "changelog_gc=1" \
18263                      "changelog_min_gc_interval=2"; do
18264                 local MDT0=$(facet_svc $SINGLEMDS)
18265                 local var="${param%=*}"
18266                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18267
18268                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18269                 do_nodes $mdts $LCTL set_param mdd.*.$param
18270         done
18271
18272         # force cl_user2 to be idle (1st part)
18273         sleep 9
18274
18275         for i in $(seq $MDSCOUNT); do
18276                 cl_users=(${CL_USERS[mds$i]})
18277                 cl_user1[mds$i]="${cl_users[0]}"
18278                 cl_user2[mds$i]="${cl_users[1]}"
18279
18280                 [ -n "${cl_user1[mds$i]}" ] ||
18281                         error "mds$i: no user registered"
18282                 [ -n "${cl_user2[mds$i]}" ] ||
18283                         error "mds$i: only ${cl_user2[mds$i]} is registered"
18284
18285                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18286                 [ -n "$user_rec1" ] ||
18287                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18288                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
18289                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18290                 [ -n "$user_rec2" ] ||
18291                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18292                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
18293                      "$user_rec1 + 2 == $user_rec2"
18294                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
18295                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
18296                               "$user_rec1 + 2, but is $user_rec2"
18297                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
18298                 [ -n "$user_rec2" ] ||
18299                         error "mds$i: User ${cl_user2[mds$i]} not registered"
18300                 [ $user_rec1 == $user_rec2 ] ||
18301                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
18302                               "$user_rec1, but is $user_rec2"
18303         done
18304
18305         # force cl_user2 to be idle (2nd part) and to reach
18306         # changelog_max_idle_time
18307         sleep 2
18308
18309         # force each GC-thread start and block then
18310         # one per MDT/MDD, set fail_val accordingly
18311         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
18312         do_nodes $mdts $LCTL set_param fail_loc=0x1316
18313
18314         # generate more changelogs to trigger fail_loc
18315         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
18316                 error "create $DIR/$tdir/${tfile}bis failed"
18317
18318         # stop MDT to stop GC-thread, should be done in back-ground as it will
18319         # block waiting for the thread to be released and exit
18320         declare -A stop_pids
18321         for i in $(seq $MDSCOUNT); do
18322                 stop mds$i &
18323                 stop_pids[mds$i]=$!
18324         done
18325
18326         for i in $(mdts_nodes); do
18327                 local facet
18328                 local nb=0
18329                 local facets=$(facets_up_on_host $i)
18330
18331                 for facet in ${facets//,/ }; do
18332                         if [[ $facet == mds* ]]; then
18333                                 nb=$((nb + 1))
18334                         fi
18335                 done
18336                 # ensure each MDS's gc threads are still present and all in "R"
18337                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
18338                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
18339                         error "$i: expected $nb GC-thread"
18340                 wait_update $i \
18341                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
18342                         "R" 20 ||
18343                         error "$i: GC-thread not found in R-state"
18344                 # check umounts of each MDT on MDS have reached kthread_stop()
18345                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
18346                         error "$i: expected $nb umount"
18347                 wait_update $i \
18348                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
18349                         error "$i: umount not found in D-state"
18350         done
18351
18352         # release all GC-threads
18353         do_nodes $mdts $LCTL set_param fail_loc=0
18354
18355         # wait for MDT stop to complete
18356         for i in $(seq $MDSCOUNT); do
18357                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
18358         done
18359
18360         # XXX
18361         # may try to check if any orphan changelog records are present
18362         # via ldiskfs/zfs and llog_reader...
18363
18364         # re-start/mount MDTs
18365         for i in $(seq $MDSCOUNT); do
18366                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
18367                         error "Fail to start mds$i"
18368         done
18369
18370         local first_rec
18371         for i in $(seq $MDSCOUNT); do
18372                 # check cl_user1 still registered
18373                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
18374                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18375                 # check cl_user2 unregistered
18376                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
18377                         error "mds$i: User ${cl_user2[mds$i]} still registered"
18378
18379                 # check changelogs are present and starting at $user_rec1 + 1
18380                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18381                 [ -n "$user_rec1" ] ||
18382                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18383                 first_rec=$($LFS changelog $(facet_svc mds$i) |
18384                             awk '{ print $1; exit; }')
18385
18386                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
18387                 [ $((user_rec1 + 1)) == $first_rec ] ||
18388                         error "mds$i: first index should be $user_rec1 + 1, " \
18389                               "but is $first_rec"
18390         done
18391 }
18392 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
18393               "during mount"
18394
18395 test_160i() {
18396
18397         local mdts=$(comma_list $(mdts_nodes))
18398
18399         changelog_register || error "first changelog_register failed"
18400
18401         # generate some changelog records to accumulate on each MDT
18402         # use all_char because created files should be evenly distributed
18403         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18404                 error "test_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         # check changelogs have been generated
18411         local nbcl=$(changelog_dump | wc -l)
18412         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18413
18414         # simulate race between register and unregister
18415         # XXX as fail_loc is set per-MDS, with DNE configs the race
18416         # simulation will only occur for one MDT per MDS and for the
18417         # others the normal race scenario will take place
18418         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
18419         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
18420         do_nodes $mdts $LCTL set_param fail_val=1
18421
18422         # unregister 1st user
18423         changelog_deregister &
18424         local pid1=$!
18425         # wait some time for deregister work to reach race rdv
18426         sleep 2
18427         # register 2nd user
18428         changelog_register || error "2nd user register failed"
18429
18430         wait $pid1 || error "1st user deregister failed"
18431
18432         local i
18433         local last_rec
18434         declare -A LAST_REC
18435         for i in $(seq $MDSCOUNT); do
18436                 if changelog_users mds$i | grep "^cl"; then
18437                         # make sure new records are added with one user present
18438                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
18439                                           awk '/^current.index:/ { print $NF }')
18440                 else
18441                         error "mds$i has no user registered"
18442                 fi
18443         done
18444
18445         # generate more changelog records to accumulate on each MDT
18446         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
18447                 error "create $DIR/$tdir/${tfile}bis failed"
18448
18449         for i in $(seq $MDSCOUNT); do
18450                 last_rec=$(changelog_users $SINGLEMDS |
18451                            awk '/^current.index:/ { print $NF }')
18452                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
18453                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
18454                         error "changelogs are off on mds$i"
18455         done
18456 }
18457 run_test 160i "changelog user register/unregister race"
18458
18459 test_160j() {
18460         remote_mds_nodsh && skip "remote MDS with nodsh"
18461         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
18462                 skip "Need MDS version at least 2.12.56"
18463
18464         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
18465         stack_trap "umount $MOUNT2" EXIT
18466
18467         changelog_register || error "first changelog_register failed"
18468         stack_trap "changelog_deregister" EXIT
18469
18470         # generate some changelog
18471         # use all_char because created files should be evenly distributed
18472         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18473                 error "mkdir $tdir failed"
18474         for ((i = 0; i < MDSCOUNT; i++)); do
18475                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18476                         error "create $DIR/$tdir/d$i.1 failed"
18477         done
18478
18479         # open the changelog device
18480         exec 3>/dev/changelog-$FSNAME-MDT0000
18481         stack_trap "exec 3>&-" EXIT
18482         exec 4</dev/changelog-$FSNAME-MDT0000
18483         stack_trap "exec 4<&-" EXIT
18484
18485         # umount the first lustre mount
18486         umount $MOUNT
18487         stack_trap "mount_client $MOUNT" EXIT
18488
18489         # read changelog, which may or may not fail, but should not crash
18490         cat <&4 >/dev/null
18491
18492         # clear changelog
18493         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18494         changelog_users $SINGLEMDS | grep -q $cl_user ||
18495                 error "User $cl_user not found in changelog_users"
18496
18497         printf 'clear:'$cl_user':0' >&3
18498 }
18499 run_test 160j "client can be umounted while its chanangelog is being used"
18500
18501 test_160k() {
18502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18503         remote_mds_nodsh && skip "remote MDS with nodsh"
18504
18505         mkdir -p $DIR/$tdir/1/1
18506
18507         changelog_register || error "changelog_register failed"
18508         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18509
18510         changelog_users $SINGLEMDS | grep -q $cl_user ||
18511                 error "User '$cl_user' not found in changelog_users"
18512 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
18513         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
18514         rmdir $DIR/$tdir/1/1 & sleep 1
18515         mkdir $DIR/$tdir/2
18516         touch $DIR/$tdir/2/2
18517         rm -rf $DIR/$tdir/2
18518
18519         wait
18520         sleep 4
18521
18522         changelog_dump | grep rmdir || error "rmdir not recorded"
18523 }
18524 run_test 160k "Verify that changelog records are not lost"
18525
18526 # Verifies that a file passed as a parameter has recently had an operation
18527 # performed on it that has generated an MTIME changelog which contains the
18528 # correct parent FID. As files might reside on a different MDT from the
18529 # parent directory in DNE configurations, the FIDs are translated to paths
18530 # before being compared, which should be identical
18531 compare_mtime_changelog() {
18532         local file="${1}"
18533         local mdtidx
18534         local mtime
18535         local cl_fid
18536         local pdir
18537         local dir
18538
18539         mdtidx=$($LFS getstripe --mdt-index $file)
18540         mdtidx=$(printf "%04x" $mdtidx)
18541
18542         # Obtain the parent FID from the MTIME changelog
18543         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
18544         [ -z "$mtime" ] && error "MTIME changelog not recorded"
18545
18546         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
18547         [ -z "$cl_fid" ] && error "parent FID not present"
18548
18549         # Verify that the path for the parent FID is the same as the path for
18550         # the test directory
18551         pdir=$($LFS fid2path $MOUNT "$cl_fid")
18552
18553         dir=$(dirname $1)
18554
18555         [[ "${pdir%/}" == "$dir" ]] ||
18556                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
18557 }
18558
18559 test_160l() {
18560         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18561
18562         remote_mds_nodsh && skip "remote MDS with nodsh"
18563         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
18564                 skip "Need MDS version at least 2.13.55"
18565
18566         local cl_user
18567
18568         changelog_register || error "changelog_register failed"
18569         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18570
18571         changelog_users $SINGLEMDS | grep -q $cl_user ||
18572                 error "User '$cl_user' not found in changelog_users"
18573
18574         # Clear some types so that MTIME changelogs are generated
18575         changelog_chmask "-CREAT"
18576         changelog_chmask "-CLOSE"
18577
18578         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
18579
18580         # Test CL_MTIME during setattr
18581         touch $DIR/$tdir/$tfile
18582         compare_mtime_changelog $DIR/$tdir/$tfile
18583
18584         # Test CL_MTIME during close
18585         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
18586         compare_mtime_changelog $DIR/$tdir/${tfile}_2
18587 }
18588 run_test 160l "Verify that MTIME changelog records contain the parent FID"
18589
18590 test_160m() {
18591         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18592         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18593                 skip "Need MDS version at least 2.14.51"
18594         local cl_users
18595         local cl_user1
18596         local cl_user2
18597         local pid1
18598
18599         # Create a user
18600         changelog_register || error "first changelog_register failed"
18601         changelog_register || error "second changelog_register failed"
18602
18603         cl_users=(${CL_USERS[mds1]})
18604         cl_user1="${cl_users[0]}"
18605         cl_user2="${cl_users[1]}"
18606         # generate some changelog records to accumulate on MDT0
18607         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18608         createmany -m $DIR/$tdir/$tfile 50 ||
18609                 error "create $DIR/$tdir/$tfile failed"
18610         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18611         rm -f $DIR/$tdir
18612
18613         # check changelogs have been generated
18614         local nbcl=$(changelog_dump | wc -l)
18615         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18616
18617 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
18618         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
18619
18620         __changelog_clear mds1 $cl_user1 +10
18621         __changelog_clear mds1 $cl_user2 0 &
18622         pid1=$!
18623         sleep 2
18624         __changelog_clear mds1 $cl_user1 0 ||
18625                 error "fail to cancel record for $cl_user1"
18626         wait $pid1
18627         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
18628 }
18629 run_test 160m "Changelog clear race"
18630
18631 test_160n() {
18632         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18633         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18634                 skip "Need MDS version at least 2.14.51"
18635         local cl_users
18636         local cl_user1
18637         local cl_user2
18638         local pid1
18639         local first_rec
18640         local last_rec=0
18641
18642         # Create a user
18643         changelog_register || error "first changelog_register failed"
18644
18645         cl_users=(${CL_USERS[mds1]})
18646         cl_user1="${cl_users[0]}"
18647
18648         # generate some changelog records to accumulate on MDT0
18649         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18650         first_rec=$(changelog_users $SINGLEMDS |
18651                         awk '/^current.index:/ { print $NF }')
18652         while (( last_rec < (( first_rec + 65000)) )); do
18653                 createmany -m $DIR/$tdir/$tfile 10000 ||
18654                         error "create $DIR/$tdir/$tfile failed"
18655
18656                 for i in $(seq 0 10000); do
18657                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
18658                                 > /dev/null
18659                 done
18660
18661                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
18662                         error "unlinkmany failed unlink"
18663                 last_rec=$(changelog_users $SINGLEMDS |
18664                         awk '/^current.index:/ { print $NF }')
18665                 echo last record $last_rec
18666                 (( last_rec == 0 )) && error "no changelog found"
18667         done
18668
18669 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
18670         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
18671
18672         __changelog_clear mds1 $cl_user1 0 &
18673         pid1=$!
18674         sleep 2
18675         __changelog_clear mds1 $cl_user1 0 ||
18676                 error "fail to cancel record for $cl_user1"
18677         wait $pid1
18678         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
18679 }
18680 run_test 160n "Changelog destroy race"
18681
18682 test_160o() {
18683         local mdt="$(facet_svc $SINGLEMDS)"
18684
18685         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18686         remote_mds_nodsh && skip "remote MDS with nodsh"
18687         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
18688                 skip "Need MDS version at least 2.14.52"
18689
18690         changelog_register --user test_160o -m unlnk+close+open ||
18691                 error "changelog_register failed"
18692
18693         do_facet $SINGLEMDS $LCTL --device $mdt \
18694                                 changelog_register -u "Tt3_-#" &&
18695                 error "bad symbols in name should fail"
18696
18697         do_facet $SINGLEMDS $LCTL --device $mdt \
18698                                 changelog_register -u test_160o &&
18699                 error "the same name registration should fail"
18700
18701         do_facet $SINGLEMDS $LCTL --device $mdt \
18702                         changelog_register -u test_160toolongname &&
18703                 error "too long name registration should fail"
18704
18705         changelog_chmask "MARK+HSM"
18706         lctl get_param mdd.*.changelog*mask
18707         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18708         changelog_users $SINGLEMDS | grep -q $cl_user ||
18709                 error "User $cl_user not found in changelog_users"
18710         #verify username
18711         echo $cl_user | grep -q test_160o ||
18712                 error "User $cl_user has no specific name 'test160o'"
18713
18714         # change something
18715         changelog_clear 0 || error "changelog_clear failed"
18716         # generate some changelog records to accumulate on MDT0
18717         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18718         touch $DIR/$tdir/$tfile                 # open 1
18719
18720         OPENS=$(changelog_dump | grep -c "OPEN")
18721         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
18722
18723         # must be no MKDIR it wasn't set as user mask
18724         MKDIR=$(changelog_dump | grep -c "MKDIR")
18725         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
18726
18727         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
18728                                 mdd.$mdt.changelog_current_mask -n)
18729         # register maskless user
18730         changelog_register || error "changelog_register failed"
18731         # effective mask should be not changed because it is not minimal
18732         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18733                                 mdd.$mdt.changelog_current_mask -n)
18734         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
18735         # set server mask to minimal value
18736         changelog_chmask "MARK"
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         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18741
18742         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
18743                 # set server mask back to some value
18744                 changelog_chmask "CLOSE,UNLNK"
18745                 # check effective mask again, should not remain as DEFMASK
18746                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
18747                                 mdd.$mdt.changelog_current_mask -n)
18748                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
18749         fi
18750
18751         do_facet $SINGLEMDS $LCTL --device $mdt \
18752                                 changelog_deregister -u test_160o ||
18753                 error "cannot deregister by name"
18754 }
18755 run_test 160o "changelog user name and mask"
18756
18757 test_160p() {
18758         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18759         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18760                 skip "Need MDS version at least 2.14.51"
18761         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
18762         local cl_users
18763         local cl_user1
18764         local entry_count
18765
18766         # Create a user
18767         changelog_register || error "first changelog_register failed"
18768
18769         cl_users=(${CL_USERS[mds1]})
18770         cl_user1="${cl_users[0]}"
18771
18772         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18773         createmany -m $DIR/$tdir/$tfile 50 ||
18774                 error "create $DIR/$tdir/$tfile failed"
18775         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18776         rm -rf $DIR/$tdir
18777
18778         # check changelogs have been generated
18779         entry_count=$(changelog_dump | wc -l)
18780         ((entry_count != 0)) || error "no changelog entries found"
18781
18782         # remove changelog_users and check that orphan entries are removed
18783         stop mds1
18784         local dev=$(mdsdevname 1)
18785         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
18786         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
18787         entry_count=$(changelog_dump | wc -l)
18788         ((entry_count == 0)) ||
18789                 error "found $entry_count changelog entries, expected none"
18790 }
18791 run_test 160p "Changelog orphan cleanup with no users"
18792
18793 test_160q() {
18794         local mdt="$(facet_svc $SINGLEMDS)"
18795         local clu
18796
18797         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18798         remote_mds_nodsh && skip "remote MDS with nodsh"
18799         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
18800                 skip "Need MDS version at least 2.14.54"
18801
18802         # set server mask to minimal value like server init does
18803         changelog_chmask "MARK"
18804         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
18805                 error "changelog_register failed"
18806         # check effective mask again, should be treated as DEFMASK now
18807         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18808                                 mdd.$mdt.changelog_current_mask -n)
18809         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
18810                 error "changelog_deregister failed"
18811         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18812 }
18813 run_test 160q "changelog effective mask is DEFMASK if not set"
18814
18815 test_160s() {
18816         remote_mds_nodsh && skip "remote MDS with nodsh"
18817         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
18818                 skip "Need MDS version at least 2.14.55"
18819
18820         local mdts=$(comma_list $(mdts_nodes))
18821
18822         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
18823         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
18824                                        fail_val=$((24 * 3600 * 10))
18825
18826         # Create a user which is 10 days old
18827         changelog_register || error "first changelog_register failed"
18828         local cl_users
18829         declare -A cl_user1
18830         local i
18831
18832         # generate some changelog records to accumulate on each MDT
18833         # use all_char because created files should be evenly distributed
18834         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18835                 error "test_mkdir $tdir failed"
18836         for ((i = 0; i < MDSCOUNT; i++)); do
18837                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18838                         error "create $DIR/$tdir/d$i.1 failed"
18839         done
18840
18841         # check changelogs have been generated
18842         local nbcl=$(changelog_dump | wc -l)
18843         (( nbcl > 0 )) || error "no changelogs found"
18844
18845         # reduce the max_idle_indexes value to make sure we exceed it
18846         for param in "changelog_max_idle_indexes=2097446912" \
18847                      "changelog_max_idle_time=2592000" \
18848                      "changelog_gc=1" \
18849                      "changelog_min_gc_interval=2"; do
18850                 local MDT0=$(facet_svc $SINGLEMDS)
18851                 local var="${param%=*}"
18852                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18853
18854                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18855                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
18856                         error "unable to set mdd.*.$param"
18857         done
18858
18859         local start=$SECONDS
18860         for i in $(seq $MDSCOUNT); do
18861                 cl_users=(${CL_USERS[mds$i]})
18862                 cl_user1[mds$i]="${cl_users[0]}"
18863
18864                 [[ -n "${cl_user1[mds$i]}" ]] ||
18865                         error "mds$i: no user registered"
18866         done
18867
18868         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
18869         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
18870
18871         # ensure we are past the previous changelog_min_gc_interval set above
18872         local sleep2=$((start + 2 - SECONDS))
18873         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18874
18875         # Generate one more changelog to trigger GC
18876         for ((i = 0; i < MDSCOUNT; i++)); do
18877                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
18878                         error "create $DIR/$tdir/d$i.3 failed"
18879         done
18880
18881         # ensure gc thread is done
18882         for node in $(mdts_nodes); do
18883                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
18884                         error "$node: GC-thread not done"
18885         done
18886
18887         do_nodes $mdts $LCTL set_param fail_loc=0
18888
18889         for (( i = 1; i <= MDSCOUNT; i++ )); do
18890                 # check cl_user1 is purged
18891                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
18892                         error "mds$i: User ${cl_user1[mds$i]} is registered"
18893         done
18894         return 0
18895 }
18896 run_test 160s "changelog garbage collect on idle records * time"
18897
18898 test_160t() {
18899         remote_mds_nodsh && skip "remote MDS with nodsh"
18900         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
18901                 skip "Need MDS version at least 2.15.50"
18902
18903         local MDT0=$(facet_svc $SINGLEMDS)
18904         local cl_users
18905         local cl_user1
18906         local cl_user2
18907         local start
18908
18909         changelog_register --user user1 -m all ||
18910                 error "user1 failed to register"
18911
18912         mkdir_on_mdt0 $DIR/$tdir
18913         # create default overstripe to maximize changelog size
18914         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
18915         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
18916         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18917
18918         # user2 consumes less records so less space
18919         changelog_register --user user2 || error "user2 failed to register"
18920         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
18921         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18922
18923         # check changelogs have been generated
18924         local nbcl=$(changelog_dump | wc -l)
18925         (( nbcl > 0 )) || error "no changelogs found"
18926
18927         # reduce the changelog_min_gc_interval to force check
18928         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
18929                 local var="${param%=*}"
18930                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18931
18932                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
18933                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
18934                         error "unable to set mdd.*.$param"
18935         done
18936
18937         start=$SECONDS
18938         cl_users=(${CL_USERS[mds1]})
18939         cl_user1="${cl_users[0]}"
18940         cl_user2="${cl_users[1]}"
18941
18942         [[ -n $cl_user1 ]] ||
18943                 error "mds1: user #1 isn't registered"
18944         [[ -n $cl_user2 ]] ||
18945                 error "mds1: user #2 isn't registered"
18946
18947         # ensure we are past the previous changelog_min_gc_interval set above
18948         local sleep2=$((start + 2 - SECONDS))
18949         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18950
18951         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
18952         do_facet mds1 $LCTL set_param fail_loc=0x018c \
18953                         fail_val=$(((llog_size1 + llog_size2) / 2))
18954
18955         # Generate more changelog to trigger GC
18956         createmany -o $DIR/$tdir/u3_ 4 ||
18957                 error "create failed for more files"
18958
18959         # ensure gc thread is done
18960         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
18961                 error "mds1: GC-thread not done"
18962
18963         do_facet mds1 $LCTL set_param fail_loc=0
18964
18965         # check cl_user1 is purged
18966         changelog_users mds1 | grep -q "$cl_user1" &&
18967                 error "User $cl_user1 is registered"
18968         # check cl_user2 is not purged
18969         changelog_users mds1 | grep -q "$cl_user2" ||
18970                 error "User $cl_user2 is not registered"
18971 }
18972 run_test 160t "changelog garbage collect on lack of space"
18973
18974 test_160u() { # LU-17400
18975         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18976         remote_mds_nodsh && skip "remote MDS with nodsh"
18977         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
18978                 skip "Need MDS version at least 2.2.0"
18979
18980         cd $DIR || error "cd $DIR failed"
18981
18982         # ensure changelog has a clean view if tests are run multiple times
18983         [ -d rename ] && rm -rf rename
18984
18985         changelog_register || error "changelog_register failed"
18986         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18987
18988         changelog_users $SINGLEMDS | grep -q $cl_user ||
18989                 error "User '$cl_user' not found in changelog_users"
18990
18991         local longname1=$(str_repeat a 255)
18992
18993         echo "creating simple directory tree"
18994         mkdir -p rename/a || error "create of simple directory tree failed"
18995         echo "creating rename/hw file"
18996         echo "hello world" > rename/hw || error "create of rename/hw failed"
18997         echo "creating very long named file"
18998         touch rename/$longname1 || error "create of 'rename/$longname1' failed"
18999         echo "move rename/hw to rename/a/a.hw"
19000         mv rename/hw rename/a/a.hw || error "mv failed"
19001
19002         RENME=($(changelog_dump | grep "RENME"))
19003         #declare -p RENME # for debugging captured value with indexes
19004
19005         [[ "${RENME[11]}" == "a.hw" && "${RENME[14]}" == "hw" ]] ||
19006                 error "changelog rename record type name/sname error"
19007 }
19008 run_test 160u "changelog rename record type name and sname strings are correct"
19009
19010 test_161a() {
19011         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19012
19013         test_mkdir -c1 $DIR/$tdir
19014         cp /etc/hosts $DIR/$tdir/$tfile
19015         test_mkdir -c1 $DIR/$tdir/foo1
19016         test_mkdir -c1 $DIR/$tdir/foo2
19017         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
19018         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
19019         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
19020         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
19021         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
19022         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
19023                 $LFS fid2path $DIR $FID
19024                 error "bad link ea"
19025         fi
19026         # middle
19027         rm $DIR/$tdir/foo2/zachary
19028         # last
19029         rm $DIR/$tdir/foo2/thor
19030         # first
19031         rm $DIR/$tdir/$tfile
19032         # rename
19033         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
19034         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
19035                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
19036         rm $DIR/$tdir/foo2/maggie
19037
19038         # overflow the EA
19039         local longname=$tfile.avg_len_is_thirty_two_
19040         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
19041                 error_noexit 'failed to unlink many hardlinks'" EXIT
19042         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
19043                 error "failed to hardlink many files"
19044         links=$($LFS fid2path $DIR $FID | wc -l)
19045         echo -n "${links}/1000 links in link EA"
19046         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
19047 }
19048 run_test 161a "link ea sanity"
19049
19050 test_161b() {
19051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19052         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
19053
19054         local MDTIDX=1
19055         local remote_dir=$DIR/$tdir/remote_dir
19056
19057         mkdir -p $DIR/$tdir
19058         $LFS mkdir -i $MDTIDX $remote_dir ||
19059                 error "create remote directory failed"
19060
19061         cp /etc/hosts $remote_dir/$tfile
19062         mkdir -p $remote_dir/foo1
19063         mkdir -p $remote_dir/foo2
19064         ln $remote_dir/$tfile $remote_dir/foo1/sofia
19065         ln $remote_dir/$tfile $remote_dir/foo2/zachary
19066         ln $remote_dir/$tfile $remote_dir/foo1/luna
19067         ln $remote_dir/$tfile $remote_dir/foo2/thor
19068
19069         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
19070                      tr -d ']')
19071         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
19072                 $LFS fid2path $DIR $FID
19073                 error "bad link ea"
19074         fi
19075         # middle
19076         rm $remote_dir/foo2/zachary
19077         # last
19078         rm $remote_dir/foo2/thor
19079         # first
19080         rm $remote_dir/$tfile
19081         # rename
19082         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
19083         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
19084         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
19085                 $LFS fid2path $DIR $FID
19086                 error "bad link rename"
19087         fi
19088         rm $remote_dir/foo2/maggie
19089
19090         # overflow the EA
19091         local longname=filename_avg_len_is_thirty_two_
19092         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
19093                 error "failed to hardlink many files"
19094         links=$($LFS fid2path $DIR $FID | wc -l)
19095         echo -n "${links}/1000 links in link EA"
19096         [[ ${links} -gt 60 ]] ||
19097                 error "expected at least 60 links in link EA"
19098         unlinkmany $remote_dir/foo2/$longname 1000 ||
19099         error "failed to unlink many hardlinks"
19100 }
19101 run_test 161b "link ea sanity under remote directory"
19102
19103 test_161c() {
19104         remote_mds_nodsh && skip "remote MDS with nodsh"
19105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19106         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
19107                 skip "Need MDS version at least 2.1.5"
19108
19109         # define CLF_RENAME_LAST 0x0001
19110         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
19111         changelog_register || error "changelog_register failed"
19112
19113         rm -rf $DIR/$tdir
19114         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
19115         touch $DIR/$tdir/foo_161c
19116         touch $DIR/$tdir/bar_161c
19117         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
19118         changelog_dump | grep RENME | tail -n 5
19119         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
19120         changelog_clear 0 || error "changelog_clear failed"
19121         if [ x$flags != "x0x1" ]; then
19122                 error "flag $flags is not 0x1"
19123         fi
19124
19125         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
19126         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
19127         touch $DIR/$tdir/foo_161c
19128         touch $DIR/$tdir/bar_161c
19129         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
19130         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
19131         changelog_dump | grep RENME | tail -n 5
19132         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
19133         changelog_clear 0 || error "changelog_clear failed"
19134         if [ x$flags != "x0x0" ]; then
19135                 error "flag $flags is not 0x0"
19136         fi
19137         echo "rename overwrite a target having nlink > 1," \
19138                 "changelog record has flags of $flags"
19139
19140         # rename doesn't overwrite a target (changelog flag 0x0)
19141         touch $DIR/$tdir/foo_161c
19142         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
19143         changelog_dump | grep RENME | tail -n 5
19144         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
19145         changelog_clear 0 || error "changelog_clear failed"
19146         if [ x$flags != "x0x0" ]; then
19147                 error "flag $flags is not 0x0"
19148         fi
19149         echo "rename doesn't overwrite a target," \
19150                 "changelog record has flags of $flags"
19151
19152         # define CLF_UNLINK_LAST 0x0001
19153         # unlink a file having nlink = 1 (changelog flag 0x1)
19154         rm -f $DIR/$tdir/foo2_161c
19155         changelog_dump | grep UNLNK | tail -n 5
19156         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
19157         changelog_clear 0 || error "changelog_clear failed"
19158         if [ x$flags != "x0x1" ]; then
19159                 error "flag $flags is not 0x1"
19160         fi
19161         echo "unlink a file having nlink = 1," \
19162                 "changelog record has flags of $flags"
19163
19164         # unlink a file having nlink > 1 (changelog flag 0x0)
19165         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
19166         rm -f $DIR/$tdir/foobar_161c
19167         changelog_dump | grep UNLNK | tail -n 5
19168         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
19169         changelog_clear 0 || error "changelog_clear failed"
19170         if [ x$flags != "x0x0" ]; then
19171                 error "flag $flags is not 0x0"
19172         fi
19173         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
19174 }
19175 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
19176
19177 test_161d() {
19178         remote_mds_nodsh && skip "remote MDS with nodsh"
19179         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
19180
19181         local pid
19182         local fid
19183
19184         changelog_register || error "changelog_register failed"
19185
19186         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
19187         # interfer with $MOUNT/.lustre/fid/ access
19188         mkdir $DIR/$tdir
19189         [[ $? -eq 0 ]] || error "mkdir failed"
19190
19191         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | CFS_FAIL_ONCE
19192         $LCTL set_param fail_loc=0x8000140c
19193         # 5s pause
19194         $LCTL set_param fail_val=5
19195
19196         # create file
19197         echo foofoo > $DIR/$tdir/$tfile &
19198         pid=$!
19199
19200         # wait for create to be delayed
19201         sleep 2
19202
19203         ps -p $pid
19204         [[ $? -eq 0 ]] || error "create should be blocked"
19205
19206         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
19207         stack_trap "rm -f $tempfile"
19208         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
19209         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
19210         # some delay may occur during ChangeLog publishing and file read just
19211         # above, that could allow file write to happen finally
19212         [[ -s $tempfile ]] && echo "file should be empty"
19213
19214         $LCTL set_param fail_loc=0
19215
19216         wait $pid
19217         [[ $? -eq 0 ]] || error "create failed"
19218 }
19219 run_test 161d "create with concurrent .lustre/fid access"
19220
19221 check_path() {
19222         local expected="$1"
19223         shift
19224         local fid="$2"
19225
19226         local path
19227         path=$($LFS fid2path "$@")
19228         local rc=$?
19229
19230         if [ $rc -ne 0 ]; then
19231                 error "path looked up of '$expected' failed: rc=$rc"
19232         elif [ "$path" != "$expected" ]; then
19233                 error "path looked up '$path' instead of '$expected'"
19234         else
19235                 echo "FID '$fid' resolves to path '$path' as expected"
19236         fi
19237 }
19238
19239 test_162a() { # was test_162
19240         test_mkdir -p -c1 $DIR/$tdir/d2
19241         touch $DIR/$tdir/d2/$tfile
19242         touch $DIR/$tdir/d2/x1
19243         touch $DIR/$tdir/d2/x2
19244         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
19245         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
19246         # regular file
19247         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
19248         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
19249
19250         # softlink
19251         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
19252         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
19253         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
19254
19255         # softlink to wrong file
19256         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
19257         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
19258         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
19259
19260         # hardlink
19261         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
19262         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
19263         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
19264         # fid2path dir/fsname should both work
19265         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
19266         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
19267
19268         # hardlink count: check that there are 2 links
19269         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
19270         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
19271
19272         # hardlink indexing: remove the first link
19273         rm $DIR/$tdir/d2/p/q/r/hlink
19274         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
19275 }
19276 run_test 162a "path lookup sanity"
19277
19278 test_162b() {
19279         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19280         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19281
19282         mkdir $DIR/$tdir
19283         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19284                                 error "create striped dir failed"
19285
19286         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
19287                                         tail -n 1 | awk '{print $2}')
19288         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
19289
19290         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
19291         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
19292
19293         # regular file
19294         for ((i=0;i<5;i++)); do
19295                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
19296                         error "get fid for f$i failed"
19297                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
19298
19299                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
19300                         error "get fid for d$i failed"
19301                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
19302         done
19303
19304         return 0
19305 }
19306 run_test 162b "striped directory path lookup sanity"
19307
19308 # LU-4239: Verify fid2path works with paths 100 or more directories deep
19309 test_162c() {
19310         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
19311                 skip "Need MDS version at least 2.7.51"
19312
19313         local lpath=$tdir.local
19314         local rpath=$tdir.remote
19315
19316         test_mkdir $DIR/$lpath
19317         test_mkdir $DIR/$rpath
19318
19319         for ((i = 0; i <= 101; i++)); do
19320                 lpath="$lpath/$i"
19321                 mkdir $DIR/$lpath
19322                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
19323                         error "get fid for local directory $DIR/$lpath failed"
19324                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
19325
19326                 rpath="$rpath/$i"
19327                 test_mkdir $DIR/$rpath
19328                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
19329                         error "get fid for remote directory $DIR/$rpath failed"
19330                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
19331         done
19332
19333         return 0
19334 }
19335 run_test 162c "fid2path works with paths 100 or more directories deep"
19336
19337 oalr_event_count() {
19338         local event="${1}"
19339         local trace="${2}"
19340
19341         awk -v name="${FSNAME}-OST0000" \
19342             -v event="${event}" \
19343             '$1 == "TRACE" && $2 == event && $3 == name' \
19344             "${trace}" |
19345         wc -l
19346 }
19347
19348 oalr_expect_event_count() {
19349         local event="${1}"
19350         local trace="${2}"
19351         local expect="${3}"
19352         local count
19353
19354         count=$(oalr_event_count "${event}" "${trace}")
19355         if ((count == expect)); then
19356                 return 0
19357         fi
19358
19359         error_noexit "${event} event count was '${count}', expected ${expect}"
19360         cat "${trace}" >&2
19361         exit 1
19362 }
19363
19364 cleanup_165() {
19365         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
19366         stop ost1
19367         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
19368 }
19369
19370 setup_165() {
19371         sync # Flush previous IOs so we can count log entries.
19372         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
19373         stack_trap cleanup_165 EXIT
19374 }
19375
19376 test_165a() {
19377         local trace="/tmp/${tfile}.trace"
19378         local rc
19379         local count
19380
19381         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19382                 skip "OFD access log unsupported"
19383
19384         setup_165
19385         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19386         sleep 5
19387
19388         do_facet ost1 ofd_access_log_reader --list
19389         stop ost1
19390
19391         do_facet ost1 killall -TERM ofd_access_log_reader
19392         wait
19393         rc=$?
19394
19395         if ((rc != 0)); then
19396                 error "ofd_access_log_reader exited with rc = '${rc}'"
19397         fi
19398
19399         # Parse trace file for discovery events:
19400         oalr_expect_event_count alr_log_add "${trace}" 1
19401         oalr_expect_event_count alr_log_eof "${trace}" 1
19402         oalr_expect_event_count alr_log_free "${trace}" 1
19403 }
19404 run_test 165a "ofd access log discovery"
19405
19406 test_165b() {
19407         local trace="/tmp/${tfile}.trace"
19408         local file="${DIR}/${tfile}"
19409         local pfid1
19410         local pfid2
19411         local -a entry
19412         local rc
19413         local count
19414         local size
19415         local flags
19416
19417         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19418                 skip "OFD access log unsupported"
19419
19420         setup_165
19421         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19422         sleep 5
19423
19424         do_facet ost1 ofd_access_log_reader --list
19425
19426         lfs setstripe -c 1 -i 0 "${file}"
19427         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19428                 error "cannot create '${file}'"
19429
19430         sleep 5
19431         do_facet ost1 killall -TERM ofd_access_log_reader
19432         wait
19433         rc=$?
19434
19435         if ((rc != 0)); then
19436                 error "ofd_access_log_reader exited with rc = '${rc}'"
19437         fi
19438
19439         oalr_expect_event_count alr_log_entry "${trace}" 1
19440
19441         pfid1=$($LFS path2fid "${file}")
19442
19443         # 1     2             3   4    5     6   7    8    9     10
19444         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
19445         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
19446
19447         echo "entry = '${entry[*]}'" >&2
19448
19449         pfid2=${entry[4]}
19450         if [[ "${pfid1}" != "${pfid2}" ]]; then
19451                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
19452         fi
19453
19454         size=${entry[8]}
19455         if ((size != 1048576)); then
19456                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
19457         fi
19458
19459         flags=${entry[10]}
19460         if [[ "${flags}" != "w" ]]; then
19461                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
19462         fi
19463
19464         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19465         sleep 5
19466
19467         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
19468                 error "cannot read '${file}'"
19469         sleep 5
19470
19471         do_facet ost1 killall -TERM ofd_access_log_reader
19472         wait
19473         rc=$?
19474
19475         if ((rc != 0)); then
19476                 error "ofd_access_log_reader exited with rc = '${rc}'"
19477         fi
19478
19479         oalr_expect_event_count alr_log_entry "${trace}" 1
19480
19481         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
19482         echo "entry = '${entry[*]}'" >&2
19483
19484         pfid2=${entry[4]}
19485         if [[ "${pfid1}" != "${pfid2}" ]]; then
19486                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
19487         fi
19488
19489         size=${entry[8]}
19490         if ((size != 524288)); then
19491                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
19492         fi
19493
19494         flags=${entry[10]}
19495         if [[ "${flags}" != "r" ]]; then
19496                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
19497         fi
19498 }
19499 run_test 165b "ofd access log entries are produced and consumed"
19500
19501 test_165c() {
19502         local trace="/tmp/${tfile}.trace"
19503         local file="${DIR}/${tdir}/${tfile}"
19504
19505         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19506                 skip "OFD access log unsupported"
19507
19508         test_mkdir "${DIR}/${tdir}"
19509
19510         setup_165
19511         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19512         sleep 5
19513
19514         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
19515
19516         # 4096 / 64 = 64. Create twice as many entries.
19517         for ((i = 0; i < 128; i++)); do
19518                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
19519                         error "cannot create file"
19520         done
19521
19522         sync
19523
19524         do_facet ost1 killall -TERM ofd_access_log_reader
19525         wait
19526         rc=$?
19527         if ((rc != 0)); then
19528                 error "ofd_access_log_reader exited with rc = '${rc}'"
19529         fi
19530
19531         unlinkmany  "${file}-%d" 128
19532 }
19533 run_test 165c "full ofd access logs do not block IOs"
19534
19535 oal_get_read_count() {
19536         local stats="$1"
19537
19538         # STATS lustre-OST0001 alr_read_count 1
19539
19540         do_facet ost1 cat "${stats}" |
19541         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
19542              END { print count; }'
19543 }
19544
19545 oal_expect_read_count() {
19546         local stats="$1"
19547         local count
19548         local expect="$2"
19549
19550         # Ask ofd_access_log_reader to write stats.
19551         do_facet ost1 killall -USR1 ofd_access_log_reader
19552
19553         # Allow some time for things to happen.
19554         sleep 1
19555
19556         count=$(oal_get_read_count "${stats}")
19557         if ((count == expect)); then
19558                 return 0
19559         fi
19560
19561         error_noexit "bad read count, got ${count}, expected ${expect}"
19562         do_facet ost1 cat "${stats}" >&2
19563         exit 1
19564 }
19565
19566 test_165d() {
19567         local stats="/tmp/${tfile}.stats"
19568         local file="${DIR}/${tdir}/${tfile}"
19569         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
19570
19571         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19572                 skip "OFD access log unsupported"
19573
19574         test_mkdir "${DIR}/${tdir}"
19575
19576         setup_165
19577         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
19578         sleep 5
19579
19580         lfs setstripe -c 1 -i 0 "${file}"
19581
19582         do_facet ost1 lctl set_param "${param}=rw"
19583         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19584                 error "cannot create '${file}'"
19585         oal_expect_read_count "${stats}" 1
19586
19587         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19588                 error "cannot read '${file}'"
19589         oal_expect_read_count "${stats}" 2
19590
19591         do_facet ost1 lctl set_param "${param}=r"
19592         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19593                 error "cannot create '${file}'"
19594         oal_expect_read_count "${stats}" 2
19595
19596         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19597                 error "cannot read '${file}'"
19598         oal_expect_read_count "${stats}" 3
19599
19600         do_facet ost1 lctl set_param "${param}=w"
19601         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19602                 error "cannot create '${file}'"
19603         oal_expect_read_count "${stats}" 4
19604
19605         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19606                 error "cannot read '${file}'"
19607         oal_expect_read_count "${stats}" 4
19608
19609         do_facet ost1 lctl set_param "${param}=0"
19610         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19611                 error "cannot create '${file}'"
19612         oal_expect_read_count "${stats}" 4
19613
19614         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19615                 error "cannot read '${file}'"
19616         oal_expect_read_count "${stats}" 4
19617
19618         do_facet ost1 killall -TERM ofd_access_log_reader
19619         wait
19620         rc=$?
19621         if ((rc != 0)); then
19622                 error "ofd_access_log_reader exited with rc = '${rc}'"
19623         fi
19624 }
19625 run_test 165d "ofd_access_log mask works"
19626
19627 test_165e() {
19628         local stats="/tmp/${tfile}.stats"
19629         local file0="${DIR}/${tdir}-0/${tfile}"
19630         local file1="${DIR}/${tdir}-1/${tfile}"
19631
19632         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19633                 skip "OFD access log unsupported"
19634
19635         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
19636
19637         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
19638         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
19639
19640         lfs setstripe -c 1 -i 0 "${file0}"
19641         lfs setstripe -c 1 -i 0 "${file1}"
19642
19643         setup_165
19644         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
19645         sleep 5
19646
19647         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
19648                 error "cannot create '${file0}'"
19649         sync
19650         oal_expect_read_count "${stats}" 0
19651
19652         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
19653                 error "cannot create '${file1}'"
19654         sync
19655         oal_expect_read_count "${stats}" 1
19656
19657         do_facet ost1 killall -TERM ofd_access_log_reader
19658         wait
19659         rc=$?
19660         if ((rc != 0)); then
19661                 error "ofd_access_log_reader exited with rc = '${rc}'"
19662         fi
19663 }
19664 run_test 165e "ofd_access_log MDT index filter works"
19665
19666 test_165f() {
19667         local trace="/tmp/${tfile}.trace"
19668         local rc
19669         local count
19670
19671         setup_165
19672         do_facet ost1 timeout 60 ofd_access_log_reader \
19673                 --exit-on-close --debug=- --trace=- > "${trace}" &
19674         sleep 5
19675         stop ost1
19676
19677         wait
19678         rc=$?
19679
19680         if ((rc != 0)); then
19681                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
19682                 cat "${trace}"
19683                 exit 1
19684         fi
19685 }
19686 run_test 165f "ofd_access_log_reader --exit-on-close works"
19687
19688 test_169() {
19689         # do directio so as not to populate the page cache
19690         log "creating a 10 Mb file"
19691         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
19692                 error "multiop failed while creating a file"
19693         log "starting reads"
19694         dd if=$DIR/$tfile of=/dev/null bs=4096 &
19695         log "truncating the file"
19696         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
19697                 error "multiop failed while truncating the file"
19698         log "killing dd"
19699         kill %+ || true # reads might have finished
19700         echo "wait until dd is finished"
19701         wait
19702         log "removing the temporary file"
19703         rm -rf $DIR/$tfile || error "tmp file removal failed"
19704 }
19705 run_test 169 "parallel read and truncate should not deadlock"
19706
19707 test_170() {
19708         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19709
19710         $LCTL clear     # bug 18514
19711         $LCTL debug_daemon start $TMP/${tfile}_log_good
19712         touch $DIR/$tfile
19713         $LCTL debug_daemon stop
19714         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
19715                 error "sed failed to read log_good"
19716
19717         $LCTL debug_daemon start $TMP/${tfile}_log_good
19718         rm -rf $DIR/$tfile
19719         $LCTL debug_daemon stop
19720
19721         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
19722                error "lctl df log_bad failed"
19723
19724         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19725         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19726
19727         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
19728         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
19729
19730         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
19731                 error "bad_line good_line1 good_line2 are empty"
19732
19733         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19734         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
19735         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19736
19737         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
19738         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19739         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19740
19741         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
19742                 error "bad_line_new good_line_new are empty"
19743
19744         local expected_good=$((good_line1 + good_line2*2))
19745
19746         rm -f $TMP/${tfile}*
19747         # LU-231, short malformed line may not be counted into bad lines
19748         if [ $bad_line -ne $bad_line_new ] &&
19749                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
19750                 error "expected $bad_line bad lines, but got $bad_line_new"
19751                 return 1
19752         fi
19753
19754         if [ $expected_good -ne $good_line_new ]; then
19755                 error "expected $expected_good good lines, but got $good_line_new"
19756                 return 2
19757         fi
19758         true
19759 }
19760 run_test 170 "test lctl df to handle corrupted log ====================="
19761
19762 test_171() { # bug20592
19763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19764
19765         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
19766         $LCTL set_param fail_loc=0x50e
19767         $LCTL set_param fail_val=3000
19768         multiop_bg_pause $DIR/$tfile O_s || true
19769         local MULTIPID=$!
19770         kill -USR1 $MULTIPID
19771         # cause log dump
19772         sleep 3
19773         wait $MULTIPID
19774         if dmesg | grep "recursive fault"; then
19775                 error "caught a recursive fault"
19776         fi
19777         $LCTL set_param fail_loc=0
19778         true
19779 }
19780 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
19781
19782 test_172() {
19783
19784         #define OBD_FAIL_OBD_CLEANUP  0x60e
19785         $LCTL set_param fail_loc=0x60e
19786         umount $MOUNT || error "umount $MOUNT failed"
19787         stack_trap "mount_client $MOUNT"
19788
19789         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
19790                 error "no client OBDs are remained"
19791
19792         $LCTL dl | while read devno state type name foo; do
19793                 case $type in
19794                 lov|osc|lmv|mdc)
19795                         $LCTL --device $name cleanup
19796                         $LCTL --device $name detach
19797                         ;;
19798                 *)
19799                         # skip server devices
19800                         ;;
19801                 esac
19802         done
19803
19804         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
19805                 $LCTL dl | egrep " osc | lov | lmv | mdc "
19806                 error "some client OBDs are still remained"
19807         fi
19808
19809 }
19810 run_test 172 "manual device removal with lctl cleanup/detach ======"
19811
19812 # it would be good to share it with obdfilter-survey/iokit-libecho code
19813 setup_obdecho_osc () {
19814         local rc=0
19815         local ost_nid=$1
19816         local obdfilter_name=$2
19817         echo "Creating new osc for $obdfilter_name on $ost_nid"
19818         # make sure we can find loopback nid
19819         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
19820
19821         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
19822                            ${obdfilter_name}_osc_UUID || rc=2; }
19823         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
19824                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
19825         return $rc
19826 }
19827
19828 cleanup_obdecho_osc () {
19829         local obdfilter_name=$1
19830         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
19831         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
19832         return 0
19833 }
19834
19835 obdecho_test() {
19836         local OBD=$1
19837         local node=$2
19838         local pages=${3:-64}
19839         local rc=0
19840         local id
19841
19842         local count=10
19843         local obd_size=$(get_obd_size $node $OBD)
19844         local page_size=$(get_page_size $node)
19845         if [[ -n "$obd_size" ]]; then
19846                 local new_count=$((obd_size / (pages * page_size / 1024)))
19847                 [[ $new_count -ge $count ]] || count=$new_count
19848         fi
19849
19850         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
19851         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
19852                            rc=2; }
19853         if [ $rc -eq 0 ]; then
19854             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
19855             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
19856         fi
19857         echo "New object id is $id"
19858         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
19859                            rc=4; }
19860         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
19861                            "test_brw $count w v $pages $id" || rc=4; }
19862         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
19863                            rc=4; }
19864         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
19865                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
19866         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
19867                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
19868         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
19869         return $rc
19870 }
19871
19872 test_180a() {
19873         skip "obdecho on osc is no longer supported"
19874 }
19875 run_test 180a "test obdecho on osc"
19876
19877 test_180b() {
19878         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19879         remote_ost_nodsh && skip "remote OST with nodsh"
19880
19881         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19882                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19883                 error "failed to load module obdecho"
19884
19885         local target=$(do_facet ost1 $LCTL dl |
19886                        awk '/obdfilter/ { print $4; exit; }')
19887
19888         if [ -n "$target" ]; then
19889                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
19890         else
19891                 do_facet ost1 $LCTL dl
19892                 error "there is no obdfilter target on ost1"
19893         fi
19894 }
19895 run_test 180b "test obdecho directly on obdfilter"
19896
19897 test_180c() { # LU-2598
19898         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19899         remote_ost_nodsh && skip "remote OST with nodsh"
19900         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
19901                 skip "Need MDS version at least 2.4.0"
19902
19903         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19904                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19905                 error "failed to load module obdecho"
19906
19907         local target=$(do_facet ost1 $LCTL dl |
19908                        awk '/obdfilter/ { print $4; exit; }')
19909
19910         if [ -n "$target" ]; then
19911                 local pages=16384 # 64MB bulk I/O RPC size
19912
19913                 obdecho_test "$target" ost1 "$pages" ||
19914                         error "obdecho_test with pages=$pages failed with $?"
19915         else
19916                 do_facet ost1 $LCTL dl
19917                 error "there is no obdfilter target on ost1"
19918         fi
19919 }
19920 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
19921
19922 test_181() { # bug 22177
19923         test_mkdir $DIR/$tdir
19924         # create enough files to index the directory
19925         createmany -o $DIR/$tdir/foobar 4000
19926         # print attributes for debug purpose
19927         lsattr -d .
19928         # open dir
19929         multiop_bg_pause $DIR/$tdir D_Sc || return 1
19930         MULTIPID=$!
19931         # remove the files & current working dir
19932         unlinkmany $DIR/$tdir/foobar 4000
19933         rmdir $DIR/$tdir
19934         kill -USR1 $MULTIPID
19935         wait $MULTIPID
19936         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
19937         return 0
19938 }
19939 run_test 181 "Test open-unlinked dir ========================"
19940
19941 test_182a() {
19942         local fcount=1000
19943         local tcount=10
19944
19945         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19946
19947         $LCTL set_param mdc.*.rpc_stats=clear
19948
19949         for (( i = 0; i < $tcount; i++ )) ; do
19950                 mkdir $DIR/$tdir/$i
19951         done
19952
19953         for (( i = 0; i < $tcount; i++ )) ; do
19954                 createmany -o $DIR/$tdir/$i/f- $fcount &
19955         done
19956         wait
19957
19958         for (( i = 0; i < $tcount; i++ )) ; do
19959                 unlinkmany $DIR/$tdir/$i/f- $fcount &
19960         done
19961         wait
19962
19963         $LCTL get_param mdc.*.rpc_stats
19964
19965         rm -rf $DIR/$tdir
19966 }
19967 run_test 182a "Test parallel modify metadata operations from mdc"
19968
19969 test_182b() {
19970         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19971         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19972         local dcount=1000
19973         local tcount=10
19974         local stime
19975         local etime
19976         local delta
19977
19978         do_facet mds1 $LCTL list_param \
19979                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
19980                 skip "MDS lacks parallel RPC handling"
19981
19982         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19983
19984         rpc_count=$(do_facet mds1 $LCTL get_param -n \
19985                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
19986
19987         stime=$(date +%s)
19988         createmany -i 0 -d $DIR/$tdir/t- $tcount
19989
19990         for (( i = 0; i < $tcount; i++ )) ; do
19991                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19992         done
19993         wait
19994         etime=$(date +%s)
19995         delta=$((etime - stime))
19996         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
19997
19998         stime=$(date +%s)
19999         for (( i = 0; i < $tcount; i++ )) ; do
20000                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
20001         done
20002         wait
20003         etime=$(date +%s)
20004         delta=$((etime - stime))
20005         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
20006
20007         rm -rf $DIR/$tdir
20008
20009         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
20010
20011         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
20012
20013         stime=$(date +%s)
20014         createmany -i 0 -d $DIR/$tdir/t- $tcount
20015
20016         for (( i = 0; i < $tcount; i++ )) ; do
20017                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
20018         done
20019         wait
20020         etime=$(date +%s)
20021         delta=$((etime - stime))
20022         echo "Time for file creation $delta sec for 1 RPC sent at a time"
20023
20024         stime=$(date +%s)
20025         for (( i = 0; i < $tcount; i++ )) ; do
20026                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
20027         done
20028         wait
20029         etime=$(date +%s)
20030         delta=$((etime - stime))
20031         echo "Time for file removal $delta sec for 1 RPC sent at a time"
20032
20033         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
20034 }
20035 run_test 182b "Test parallel modify metadata operations from osp"
20036
20037 test_183() { # LU-2275
20038         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20039         remote_mds_nodsh && skip "remote MDS with nodsh"
20040         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
20041                 skip "Need MDS version at least 2.3.56"
20042
20043         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
20044         echo aaa > $DIR/$tdir/$tfile
20045
20046 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
20047         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
20048
20049         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
20050         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
20051
20052         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20053
20054         # Flush negative dentry cache
20055         touch $DIR/$tdir/$tfile
20056
20057         # We are not checking for any leaked references here, they'll
20058         # become evident next time we do cleanup with module unload.
20059         rm -rf $DIR/$tdir
20060 }
20061 run_test 183 "No crash or request leak in case of strange dispositions ========"
20062
20063 # test suite 184 is for LU-2016, LU-2017
20064 test_184a() {
20065         check_swap_layouts_support
20066
20067         dir0=$DIR/$tdir/$testnum
20068         test_mkdir -p -c1 $dir0
20069         ref1=/etc/passwd
20070         ref2=/etc/group
20071         file1=$dir0/f1
20072         file2=$dir0/f2
20073         $LFS setstripe -c1 $file1
20074         cp $ref1 $file1
20075         $LFS setstripe -c2 $file2
20076         cp $ref2 $file2
20077         gen1=$($LFS getstripe -g $file1)
20078         gen2=$($LFS getstripe -g $file2)
20079
20080         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
20081         gen=$($LFS getstripe -g $file1)
20082         [[ $gen1 != $gen ]] ||
20083                 error "Layout generation on $file1 does not change"
20084         gen=$($LFS getstripe -g $file2)
20085         [[ $gen2 != $gen ]] ||
20086                 error "Layout generation on $file2 does not change"
20087
20088         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
20089         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20090
20091         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
20092 }
20093 run_test 184a "Basic layout swap"
20094
20095 test_184b() {
20096         check_swap_layouts_support
20097
20098         dir0=$DIR/$tdir/$testnum
20099         mkdir -p $dir0 || error "creating dir $dir0"
20100         file1=$dir0/f1
20101         file2=$dir0/f2
20102         file3=$dir0/f3
20103         dir1=$dir0/d1
20104         dir2=$dir0/d2
20105         mkdir $dir1 $dir2
20106         $LFS setstripe -c1 $file1
20107         $LFS setstripe -c2 $file2
20108         $LFS setstripe -c1 $file3
20109         chown $RUNAS_ID $file3
20110         gen1=$($LFS getstripe -g $file1)
20111         gen2=$($LFS getstripe -g $file2)
20112
20113         $LFS swap_layouts $dir1 $dir2 &&
20114                 error "swap of directories layouts should fail"
20115         $LFS swap_layouts $dir1 $file1 &&
20116                 error "swap of directory and file layouts should fail"
20117         $RUNAS $LFS swap_layouts $file1 $file2 &&
20118                 error "swap of file we cannot write should fail"
20119         $LFS swap_layouts $file1 $file3 &&
20120                 error "swap of file with different owner should fail"
20121         /bin/true # to clear error code
20122 }
20123 run_test 184b "Forbidden layout swap (will generate errors)"
20124
20125 test_184c() {
20126         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
20127         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
20128         check_swap_layouts_support
20129         check_swap_layout_no_dom $DIR
20130
20131         local dir0=$DIR/$tdir/$testnum
20132         mkdir -p $dir0 || error "creating dir $dir0"
20133
20134         local ref1=$dir0/ref1
20135         local ref2=$dir0/ref2
20136         local file1=$dir0/file1
20137         local file2=$dir0/file2
20138         # create a file large enough for the concurrent test
20139         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
20140         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
20141         echo "ref file size: ref1($(stat -c %s $ref1))," \
20142              "ref2($(stat -c %s $ref2))"
20143
20144         cp $ref2 $file2
20145         dd if=$ref1 of=$file1 bs=16k &
20146         local DD_PID=$!
20147
20148         # Make sure dd starts to copy file, but wait at most 5 seconds
20149         local loops=0
20150         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
20151
20152         $LFS swap_layouts $file1 $file2
20153         local rc=$?
20154         wait $DD_PID
20155         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
20156         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
20157
20158         # how many bytes copied before swapping layout
20159         local copied=$(stat -c %s $file2)
20160         local remaining=$(stat -c %s $ref1)
20161         remaining=$((remaining - copied))
20162         echo "Copied $copied bytes before swapping layout..."
20163
20164         cmp -n $copied $file1 $ref2 | grep differ &&
20165                 error "Content mismatch [0, $copied) of ref2 and file1"
20166         cmp -n $copied $file2 $ref1 ||
20167                 error "Content mismatch [0, $copied) of ref1 and file2"
20168         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
20169                 error "Content mismatch [$copied, EOF) of ref1 and file1"
20170
20171         # clean up
20172         rm -f $ref1 $ref2 $file1 $file2
20173 }
20174 run_test 184c "Concurrent write and layout swap"
20175
20176 test_184d() {
20177         check_swap_layouts_support
20178         check_swap_layout_no_dom $DIR
20179         [ -z "$(which getfattr 2>/dev/null)" ] &&
20180                 skip_env "no getfattr command"
20181
20182         local file1=$DIR/$tdir/$tfile-1
20183         local file2=$DIR/$tdir/$tfile-2
20184         local file3=$DIR/$tdir/$tfile-3
20185         local lovea1
20186         local lovea2
20187
20188         mkdir -p $DIR/$tdir
20189         touch $file1 || error "create $file1 failed"
20190         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
20191                 error "create $file2 failed"
20192         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
20193                 error "create $file3 failed"
20194         lovea1=$(get_layout_param $file1)
20195
20196         $LFS swap_layouts $file2 $file3 ||
20197                 error "swap $file2 $file3 layouts failed"
20198         $LFS swap_layouts $file1 $file2 ||
20199                 error "swap $file1 $file2 layouts failed"
20200
20201         lovea2=$(get_layout_param $file2)
20202         echo "$lovea1"
20203         echo "$lovea2"
20204         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
20205
20206         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
20207         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
20208 }
20209 run_test 184d "allow stripeless layouts swap"
20210
20211 test_184e() {
20212         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
20213                 skip "Need MDS version at least 2.6.94"
20214         check_swap_layouts_support
20215         check_swap_layout_no_dom $DIR
20216         [ -z "$(which getfattr 2>/dev/null)" ] &&
20217                 skip_env "no getfattr command"
20218
20219         local file1=$DIR/$tdir/$tfile-1
20220         local file2=$DIR/$tdir/$tfile-2
20221         local file3=$DIR/$tdir/$tfile-3
20222         local lovea
20223
20224         mkdir -p $DIR/$tdir
20225         touch $file1 || error "create $file1 failed"
20226         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
20227                 error "create $file2 failed"
20228         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
20229                 error "create $file3 failed"
20230
20231         $LFS swap_layouts $file1 $file2 ||
20232                 error "swap $file1 $file2 layouts failed"
20233
20234         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
20235         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
20236
20237         echo 123 > $file1 || error "Should be able to write into $file1"
20238
20239         $LFS swap_layouts $file1 $file3 ||
20240                 error "swap $file1 $file3 layouts failed"
20241
20242         echo 123 > $file1 || error "Should be able to write into $file1"
20243
20244         rm -rf $file1 $file2 $file3
20245 }
20246 run_test 184e "Recreate layout after stripeless layout swaps"
20247
20248 test_184f() {
20249         # Create a file with name longer than sizeof(struct stat) ==
20250         # 144 to see if we can get chars from the file name to appear
20251         # in the returned striping. Note that 'f' == 0x66.
20252         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
20253
20254         mkdir -p $DIR/$tdir
20255         mcreate $DIR/$tdir/$file
20256         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
20257                 error "IOC_MDC_GETFILEINFO returned garbage striping"
20258         fi
20259 }
20260 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
20261
20262 test_185() { # LU-2441
20263         # LU-3553 - no volatile file support in old servers
20264         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
20265                 skip "Need MDS version at least 2.3.60"
20266
20267         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
20268         touch $DIR/$tdir/spoo
20269         local mtime1=$(stat -c "%Y" $DIR/$tdir)
20270         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
20271                 error "cannot create/write a volatile file"
20272         [ "$FILESET" == "" ] &&
20273         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
20274                 error "FID is still valid after close"
20275
20276         multiop_bg_pause $DIR/$tdir Vw4096_c
20277         local multi_pid=$!
20278
20279         local OLD_IFS=$IFS
20280         IFS=":"
20281         local fidv=($fid)
20282         IFS=$OLD_IFS
20283         # assume that the next FID for this client is sequential, since stdout
20284         # is unfortunately eaten by multiop_bg_pause
20285         local n=$((${fidv[1]} + 1))
20286         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
20287         if [ "$FILESET" == "" ]; then
20288                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
20289                         error "FID is missing before close"
20290         fi
20291         kill -USR1 $multi_pid
20292         # 1 second delay, so if mtime change we will see it
20293         sleep 1
20294         local mtime2=$(stat -c "%Y" $DIR/$tdir)
20295         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
20296 }
20297 run_test 185 "Volatile file support"
20298
20299 function create_check_volatile() {
20300         local idx=$1
20301         local tgt
20302
20303         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
20304         local PID=$!
20305         sleep 1
20306         local FID=$(cat /tmp/${tfile}.fid)
20307         [ "$FID" == "" ] && error "can't get FID for volatile"
20308         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
20309         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
20310         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
20311         kill -USR1 $PID
20312         wait
20313         sleep 1
20314         cancel_lru_locks mdc # flush opencache
20315         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
20316         return 0
20317 }
20318
20319 test_185a(){
20320         # LU-12516 - volatile creation via .lustre
20321         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
20322                 skip "Need MDS version at least 2.3.55"
20323
20324         create_check_volatile 0
20325         [ $MDSCOUNT -lt 2 ] && return 0
20326
20327         # DNE case
20328         create_check_volatile 1
20329
20330         return 0
20331 }
20332 run_test 185a "Volatile file creation in .lustre/fid/"
20333
20334 test_187a() {
20335         remote_mds_nodsh && skip "remote MDS with nodsh"
20336         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
20337                 skip "Need MDS version at least 2.3.0"
20338
20339         local dir0=$DIR/$tdir/$testnum
20340         mkdir -p $dir0 || error "creating dir $dir0"
20341
20342         local file=$dir0/file1
20343         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
20344         stack_trap "rm -f $file"
20345         local dv1=$($LFS data_version $file)
20346         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
20347         local dv2=$($LFS data_version $file)
20348         [[ $dv1 != $dv2 ]] ||
20349                 error "data version did not change on write $dv1 == $dv2"
20350 }
20351 run_test 187a "Test data version change"
20352
20353 test_187b() {
20354         remote_mds_nodsh && skip "remote MDS with nodsh"
20355         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
20356                 skip "Need MDS version at least 2.3.0"
20357
20358         local dir0=$DIR/$tdir/$testnum
20359         mkdir -p $dir0 || error "creating dir $dir0"
20360
20361         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
20362         [[ ${DV[0]} != ${DV[1]} ]] ||
20363                 error "data version did not change on write"\
20364                       " ${DV[0]} == ${DV[1]}"
20365
20366         # clean up
20367         rm -f $file1
20368 }
20369 run_test 187b "Test data version change on volatile file"
20370
20371 test_200() {
20372         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20373         remote_mgs_nodsh && skip "remote MGS with nodsh"
20374         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
20375
20376         local POOL=${POOL:-cea1}
20377         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
20378         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
20379         # Pool OST targets
20380         local first_ost=0
20381         local last_ost=$(($OSTCOUNT - 1))
20382         local ost_step=2
20383         local ost_list=$(seq $first_ost $ost_step $last_ost)
20384         local ost_range="$first_ost $last_ost $ost_step"
20385         local test_path=$POOL_ROOT/$POOL_DIR_NAME
20386         local file_dir=$POOL_ROOT/file_tst
20387         local subdir=$test_path/subdir
20388         local rc=0
20389
20390         while : ; do
20391                 # former test_200a test_200b
20392                 pool_add $POOL                          || { rc=$? ; break; }
20393                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
20394                 # former test_200c test_200d
20395                 mkdir -p $test_path
20396                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
20397                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
20398                 mkdir -p $subdir
20399                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
20400                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
20401                                                         || { rc=$? ; break; }
20402                 # former test_200e test_200f
20403                 local files=$((OSTCOUNT*3))
20404                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
20405                                                         || { rc=$? ; break; }
20406                 pool_create_files $POOL $file_dir $files "$ost_list" \
20407                                                         || { rc=$? ; break; }
20408                 # former test_200g test_200h
20409                 pool_lfs_df $POOL                       || { rc=$? ; break; }
20410                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
20411
20412                 # former test_201a test_201b test_201c
20413                 pool_remove_first_target $POOL          || { rc=$? ; break; }
20414
20415                 local f=$test_path/$tfile
20416                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
20417                 pool_remove $POOL $f                    || { rc=$? ; break; }
20418                 break
20419         done
20420
20421         destroy_test_pools
20422
20423         return $rc
20424 }
20425 run_test 200 "OST pools"
20426
20427 # usage: default_attr <count | size | offset>
20428 default_attr() {
20429         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
20430 }
20431
20432 # usage: check_default_stripe_attr
20433 check_default_stripe_attr() {
20434         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
20435         case $1 in
20436         --stripe-count|-c)
20437                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
20438         --stripe-size|-S)
20439                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
20440         --stripe-index|-i)
20441                 EXPECTED=-1;;
20442         *)
20443                 error "unknown getstripe attr '$1'"
20444         esac
20445
20446         [ $ACTUAL == $EXPECTED ] ||
20447                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
20448 }
20449
20450 test_204a() {
20451         test_mkdir $DIR/$tdir
20452         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
20453
20454         check_default_stripe_attr --stripe-count
20455         check_default_stripe_attr --stripe-size
20456         check_default_stripe_attr --stripe-index
20457 }
20458 run_test 204a "Print default stripe attributes"
20459
20460 test_204b() {
20461         test_mkdir $DIR/$tdir
20462         $LFS setstripe --stripe-count 1 $DIR/$tdir
20463
20464         check_default_stripe_attr --stripe-size
20465         check_default_stripe_attr --stripe-index
20466 }
20467 run_test 204b "Print default stripe size and offset"
20468
20469 test_204c() {
20470         test_mkdir $DIR/$tdir
20471         $LFS setstripe --stripe-size 65536 $DIR/$tdir
20472
20473         check_default_stripe_attr --stripe-count
20474         check_default_stripe_attr --stripe-index
20475 }
20476 run_test 204c "Print default stripe count and offset"
20477
20478 test_204d() {
20479         test_mkdir $DIR/$tdir
20480         $LFS setstripe --stripe-index 0 $DIR/$tdir
20481
20482         check_default_stripe_attr --stripe-count
20483         check_default_stripe_attr --stripe-size
20484 }
20485 run_test 204d "Print default stripe count and size"
20486
20487 test_204e() {
20488         test_mkdir $DIR/$tdir
20489         $LFS setstripe -d $DIR/$tdir
20490
20491         # LU-16904 check if root is set as PFL layout
20492         local numcomp=$($LFS getstripe --component-count $MOUNT)
20493
20494         if [[ $numcomp -gt 0 ]]; then
20495                 check_default_stripe_attr --stripe-count
20496         else
20497                 check_default_stripe_attr --stripe-count --raw
20498         fi
20499         check_default_stripe_attr --stripe-size --raw
20500         check_default_stripe_attr --stripe-index --raw
20501 }
20502 run_test 204e "Print raw stripe attributes"
20503
20504 test_204f() {
20505         test_mkdir $DIR/$tdir
20506         $LFS setstripe --stripe-count 1 $DIR/$tdir
20507
20508         check_default_stripe_attr --stripe-size --raw
20509         check_default_stripe_attr --stripe-index --raw
20510 }
20511 run_test 204f "Print raw stripe size and offset"
20512
20513 test_204g() {
20514         test_mkdir $DIR/$tdir
20515         $LFS setstripe --stripe-size 65536 $DIR/$tdir
20516
20517         check_default_stripe_attr --stripe-count --raw
20518         check_default_stripe_attr --stripe-index --raw
20519 }
20520 run_test 204g "Print raw stripe count and offset"
20521
20522 test_204h() {
20523         test_mkdir $DIR/$tdir
20524         $LFS setstripe --stripe-index 0 $DIR/$tdir
20525
20526         check_default_stripe_attr --stripe-count --raw
20527         check_default_stripe_attr --stripe-size --raw
20528 }
20529 run_test 204h "Print raw stripe count and size"
20530
20531 # Figure out which job scheduler is being used, if any,
20532 # or use a fake one
20533 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
20534         JOBENV=SLURM_JOB_ID
20535 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
20536         JOBENV=LSB_JOBID
20537 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
20538         JOBENV=PBS_JOBID
20539 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
20540         JOBENV=LOADL_STEP_ID
20541 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
20542         JOBENV=JOB_ID
20543 else
20544         $LCTL list_param jobid_name > /dev/null 2>&1
20545         if [ $? -eq 0 ]; then
20546                 JOBENV=nodelocal
20547         else
20548                 JOBENV=FAKE_JOBID
20549         fi
20550 fi
20551 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
20552
20553 verify_jobstats() {
20554         local cmd=($1)
20555         shift
20556         local facets="$@"
20557
20558 # we don't really need to clear the stats for this test to work, since each
20559 # command has a unique jobid, but it makes debugging easier if needed.
20560 #       for facet in $facets; do
20561 #               local dev=$(convert_facet2label $facet)
20562 #               # clear old jobstats
20563 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
20564 #       done
20565
20566         # use a new JobID for each test, or we might see an old one
20567         [ "$JOBENV" = "FAKE_JOBID" ] &&
20568                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
20569
20570         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
20571
20572         [ "$JOBENV" = "nodelocal" ] && {
20573                 FAKE_JOBID=id.$testnum.%e.$RANDOM
20574                 $LCTL set_param jobid_name=$FAKE_JOBID
20575                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
20576         }
20577
20578         log "Test: ${cmd[*]}"
20579         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
20580
20581         if [ $JOBENV = "FAKE_JOBID" ]; then
20582                 FAKE_JOBID=$JOBVAL ${cmd[*]}
20583         else
20584                 ${cmd[*]}
20585         fi
20586
20587         # all files are created on OST0000
20588         for facet in $facets; do
20589                 local stats="*.$(convert_facet2label $facet).job_stats"
20590
20591                 # strip out libtool wrappers for in-tree executables
20592                 if (( $(do_facet $facet lctl get_param $stats |
20593                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
20594                         do_facet $facet lctl get_param $stats
20595                         error "No jobstats for $JOBVAL found on $facet::$stats"
20596                 fi
20597         done
20598 }
20599
20600 jobstats_set() {
20601         local new_jobenv=$1
20602
20603         set_persistent_param_and_check client "jobid_var" \
20604                 "$FSNAME.sys.jobid_var" $new_jobenv
20605 }
20606
20607 test_205a() { # Job stats
20608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20609         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
20610                 skip "Need MDS version with at least 2.7.1"
20611         remote_mgs_nodsh && skip "remote MGS with nodsh"
20612         remote_mds_nodsh && skip "remote MDS with nodsh"
20613         remote_ost_nodsh && skip "remote OST with nodsh"
20614         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
20615                 skip "Server doesn't support jobstats"
20616         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
20617
20618         local old_jobenv=$($LCTL get_param -n jobid_var)
20619         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
20620         stack_trap "jobstats_set $old_jobenv" EXIT
20621
20622         changelog_register
20623
20624         local old_jobid_name=$($LCTL get_param jobid_name)
20625         stack_trap "$LCTL set_param $old_jobid_name" EXIT
20626
20627         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
20628                                 mdt.*.job_cleanup_interval | head -n 1)
20629         local new_interval=5
20630         do_facet $SINGLEMDS \
20631                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
20632         stack_trap "do_facet $SINGLEMDS \
20633                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
20634         local start=$SECONDS
20635
20636         local cmd
20637         # mkdir
20638         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
20639         verify_jobstats "$cmd" "$SINGLEMDS"
20640         # rmdir
20641         cmd="rmdir $DIR/$tdir"
20642         verify_jobstats "$cmd" "$SINGLEMDS"
20643         # mkdir on secondary MDT
20644         if [ $MDSCOUNT -gt 1 ]; then
20645                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
20646                 verify_jobstats "$cmd" "mds2"
20647         fi
20648         # mknod
20649         cmd="mknod $DIR/$tfile c 1 3"
20650         verify_jobstats "$cmd" "$SINGLEMDS"
20651         # unlink
20652         cmd="rm -f $DIR/$tfile"
20653         verify_jobstats "$cmd" "$SINGLEMDS"
20654         # create all files on OST0000 so verify_jobstats can find OST stats
20655         # open & close
20656         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
20657         verify_jobstats "$cmd" "$SINGLEMDS"
20658         # setattr
20659         cmd="touch $DIR/$tfile"
20660         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20661         # write
20662         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
20663         verify_jobstats "$cmd" "ost1"
20664         # read
20665         cancel_lru_locks osc
20666         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
20667         verify_jobstats "$cmd" "ost1"
20668         # truncate
20669         cmd="$TRUNCATE $DIR/$tfile 0"
20670         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20671         # rename
20672         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
20673         verify_jobstats "$cmd" "$SINGLEMDS"
20674         # jobstats expiry - sleep until old stats should be expired
20675         local left=$((new_interval + 5 - (SECONDS - start)))
20676         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
20677                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
20678                         "0" $left
20679         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
20680         verify_jobstats "$cmd" "$SINGLEMDS"
20681         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
20682             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
20683
20684         # Ensure that jobid are present in changelog (if supported by MDS)
20685         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
20686                 changelog_dump | tail -10
20687                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
20688                 [ $jobids -eq 9 ] ||
20689                         error "Wrong changelog jobid count $jobids != 9"
20690
20691                 # LU-5862
20692                 JOBENV="disable"
20693                 jobstats_set $JOBENV
20694                 touch $DIR/$tfile
20695                 changelog_dump | grep $tfile
20696                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
20697                 [ $jobids -eq 0 ] ||
20698                         error "Unexpected jobids when jobid_var=$JOBENV"
20699         fi
20700
20701         # test '%j' access to environment variable - if supported
20702         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
20703                 JOBENV="JOBCOMPLEX"
20704                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20705
20706                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20707         fi
20708
20709         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
20710                 JOBENV="JOBCOMPLEX"
20711                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
20712
20713                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20714         fi
20715
20716         # test '%j' access to per-session jobid - if supported
20717         if lctl list_param jobid_this_session > /dev/null 2>&1
20718         then
20719                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
20720                 lctl set_param jobid_this_session=$USER
20721
20722                 JOBENV="JOBCOMPLEX"
20723                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20724
20725                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20726         fi
20727 }
20728 run_test 205a "Verify job stats"
20729
20730 # LU-13117, LU-13597, LU-16599
20731 test_205b() {
20732         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
20733                 skip "Need MDS version at least 2.13.54.91"
20734
20735         local job_stats="mdt.*.job_stats"
20736         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
20737
20738         do_facet mds1 $LCTL set_param $job_stats=clear
20739
20740         # Setting jobid_var to USER might not be supported
20741         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
20742         $LCTL set_param jobid_var=USER || true
20743         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
20744         $LCTL set_param jobid_name="%j.%e.%u"
20745
20746         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
20747         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
20748                 { do_facet mds1 $LCTL get_param $job_stats;
20749                   error "Unexpected jobid found"; }
20750         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
20751                 { do_facet mds1 $LCTL get_param $job_stats;
20752                   error "wrong job_stats format found"; }
20753
20754         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
20755                 echo "MDS does not yet escape jobid" && return 0
20756
20757         mkdir_on_mdt0 $DIR/$tdir
20758         $LCTL set_param jobid_var=TEST205b
20759         env -i TEST205b="has sp" touch $DIR/$tdir/$tfile.2
20760         local jobid=$(do_facet mds1 $LCTL get_param $job_stats |
20761                       awk '/has\\x20sp/ {print $3}')
20762         [[ -n "$jobid" ]] || { do_facet mds1 $LCTL get_param $job_stats;
20763                   error "jobid not escaped"; }
20764
20765         if (( $MDS1_VERSION >= $(version_code 2.15.53.139) )); then
20766                 # need to run such a command on mds1:
20767                 # lctl set_param mdt.$FSNAME-MDT0000.job_stats='"has\x20sp.touch.0"'
20768                 #
20769                 # there might be multiple MDTs on single mds server, so need to
20770                 # specifiy MDT0000. Or the command will fail due to other MDTs
20771                 do_facet_vp mds1 $LCTL set_param mdt.$FSNAME-MDT0000.job_stats=$jobid ||
20772                         error "cannot clear escaped jobid in job_stats";
20773         else
20774                 echo "MDS does not support clearing escaped jobid"
20775         fi
20776 }
20777 run_test 205b "Verify job stats jobid and output format"
20778
20779 # LU-13733
20780 test_205c() {
20781         $LCTL set_param llite.*.stats=0
20782         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
20783         $LCTL get_param llite.*.stats
20784         $LCTL get_param llite.*.stats | grep \
20785                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
20786                         error "wrong client stats format found"
20787 }
20788 run_test 205c "Verify client stats format"
20789
20790 test_205d() {
20791         local file=$DIR/$tdir/$tfile
20792
20793         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20794                 skip "need lustre >= 2.15.53 for lljobstat"
20795         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20796                 skip "need lustre >= 2.15.53 for lljobstat"
20797         verify_yaml_available || skip_env "YAML verification not installed"
20798
20799         test_mkdir -i 0 $DIR/$tdir
20800         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
20801         stack_trap "rm -rf $DIR/$tdir"
20802
20803         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
20804                 error "failed to write data to $file"
20805         mv $file $file.2
20806
20807         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
20808         echo -n 'verify rename_stats...'
20809         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
20810                 verify_yaml || error "rename_stats is not valid YAML"
20811         echo " OK"
20812
20813         echo -n 'verify mdt job_stats...'
20814         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
20815                 verify_yaml || error "job_stats on mds1 is not valid YAML"
20816         echo " OK"
20817
20818         echo -n 'verify ost job_stats...'
20819         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
20820                 verify_yaml || error "job_stats on ost1 is not valid YAML"
20821         echo " OK"
20822 }
20823 run_test 205d "verify the format of some stats files"
20824
20825 test_205e() {
20826         local ops_comma
20827         local file=$DIR/$tdir/$tfile
20828         local -a cli_params
20829
20830         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20831                 skip "need lustre >= 2.15.53 for lljobstat"
20832         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20833                 skip "need lustre >= 2.15.53 for lljobstat"
20834         verify_yaml_available || skip_env "YAML verification not installed"
20835
20836         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20837         $LCTL set_param jobid_var=nodelocal jobid_name=205e.%e.%u
20838         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20839
20840         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
20841         stack_trap "rm -rf $DIR/$tdir"
20842
20843         $LFS setstripe -E EOF -i 0 -c 1 $file ||
20844                 error "failed to create $file on ost1"
20845         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
20846                 error "failed to write data to $file"
20847
20848         do_facet mds1 "$LCTL get_param *.*.job_stats"
20849         do_facet ost1 "$LCTL get_param *.*.job_stats"
20850
20851         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
20852         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
20853                 error "The output of lljobstat is not an valid YAML"
20854
20855         # verify that job dd.0 does exist and has some ops on ost1
20856         # typically this line is like:
20857         # - 205e.dd.0:            {ops: 20, ...}
20858         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
20859                     awk '$2=="205e.dd.0:" {print $4}')
20860
20861         (( ${ops_comma%,} >= 10 )) ||
20862                 error "cannot find job 205e.dd.0 with ops >= 10"
20863 }
20864 run_test 205e "verify the output of lljobstat"
20865
20866 test_205f() {
20867         verify_yaml_available || skip_env "YAML verification not installed"
20868
20869         # check both qos_ost_weights and qos_mdt_weights
20870         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
20871         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
20872                 error "qos_ost_weights is not valid YAML"
20873 }
20874 run_test 205f "verify qos_ost_weights YAML format "
20875
20876 __test_205_jobstats_dump() {
20877         local -a pids
20878         local nbr_instance=$1
20879
20880         while true; do
20881                 if (( ${#pids[@]} >= nbr_instance )); then
20882                         wait ${pids[@]}
20883                         pids=()
20884                 fi
20885
20886                 do_facet mds1 "$LCTL get_param mdt.*.job_stats > /dev/null" &
20887                 pids+=( $! )
20888         done
20889 }
20890
20891 __test_205_cleanup() {
20892         kill $@
20893         # Clear all job entries
20894         do_facet mds1 "$LCTL set_param mdt.*.job_stats=clear"
20895 }
20896
20897 test_205g() {
20898         local -a mds1_params
20899         local -a cli_params
20900         local pids
20901         local interval=5
20902
20903         mds1_params=( $(do_facet mds1 $LCTL get_param mdt.*.job_cleanup_interval) )
20904         do_facet mds1 $LCTL set_param mdt.*.job_cleanup_interval=$interval
20905         stack_trap "do_facet mds1 $LCTL set_param ${mds1_params[*]}" EXIT
20906
20907         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20908         $LCTL set_param jobid_var=TEST205G_ID jobid_name=%j.%p
20909         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20910
20911         # start jobs loop
20912         export TEST205G_ID=205g
20913         stack_trap "unset TEST205G_ID" EXIT
20914         while true; do
20915                 printf $DIR/$tfile.{0001..1000} | xargs -P10 -n1 touch
20916         done & pids="$! "
20917
20918         __test_205_jobstats_dump 4 & pids+="$! "
20919         stack_trap "__test_205_cleanup $pids" EXIT INT
20920
20921         [[ $SLOW == "no" ]] && sleep 90 || sleep 240
20922 }
20923 run_test 205g "stress test for job_stats procfile"
20924
20925 test_205h() {
20926         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
20927                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
20928         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
20929
20930         local dir=$DIR/$tdir
20931         local f=$dir/$tfile
20932         local f2=$dir/$tfile-2
20933         local f3=$dir/$tfile-3
20934         local subdir=$DIR/dir
20935         local val
20936
20937         local mdts=$(comma_list $(mdts_nodes))
20938         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20939         local client_saved=$($LCTL get_param -n jobid_var)
20940
20941         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20942         stack_trap "$LCTL set_param jobid_var=$client_saved" EXIT
20943
20944         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job ||
20945                 error "failed to set job_xattr parameter to user.job"
20946         $LCTL set_param jobid_var=procname.uid ||
20947                 error "failed to set jobid_var parameter"
20948
20949         test_mkdir $dir
20950
20951         touch $f
20952         val=$(getfattr -n user.job $f | grep user.job)
20953         [[ $val = user.job=\"touch.0\" ]] ||
20954                 error "expected user.job=\"touch.0\", got '$val'"
20955
20956         mkdir $subdir
20957         val=$(getfattr -n user.job $subdir | grep user.job)
20958         [[ $val = user.job=\"mkdir.0\" ]] ||
20959                 error "expected user.job=\"mkdir.0\", got '$val'"
20960
20961         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE ||
20962                 error "failed to set job_xattr parameter to NONE"
20963
20964         touch $f2
20965         val=$(getfattr -d $f2)
20966         [[ -z $val ]] ||
20967                 error "expected no user xattr, got '$val'"
20968
20969         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=trusted.job ||
20970                 error "failed to set job_xattr parameter to trusted.job"
20971
20972         touch $f3
20973         val=$(getfattr -n trusted.job $f3 | grep trusted.job)
20974         [[ $val = trusted.job=\"touch.0\" ]] ||
20975                 error "expected trusted.job=\"touch.0\", got '$val'"
20976 }
20977 run_test 205h "check jobid xattr is stored correctly"
20978
20979 test_205i() {
20980         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
20981                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
20982
20983         local mdts=$(comma_list $(mdts_nodes))
20984         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20985
20986         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20987
20988         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.1234567 ||
20989                 error "failed to set mdt.*.job_xattr to user.1234567"
20990
20991         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.12345678 &&
20992                 error "failed to reject too long job_xattr name"
20993
20994         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=userjob &&
20995                 error "failed to reject job_xattr name in bad format"
20996
20997         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job/ &&
20998                 error "failed to reject job_xattr name with invalid character"
20999
21000         do_nodes $mdts "printf 'mdt.*.job_xattr=user.job\x80' |
21001                         xargs $LCTL set_param" &&
21002                 error "failed to reject job_xattr name with non-ascii character"
21003
21004         return 0
21005 }
21006 run_test 205i "check job_xattr parameter accepts and rejects values correctly"
21007
21008 # LU-1480, LU-1773 and LU-1657
21009 test_206() {
21010         mkdir -p $DIR/$tdir
21011         $LFS setstripe -c -1 $DIR/$tdir
21012 #define OBD_FAIL_LOV_INIT 0x1403
21013         $LCTL set_param fail_loc=0xa0001403
21014         $LCTL set_param fail_val=1
21015         touch $DIR/$tdir/$tfile || true
21016 }
21017 run_test 206 "fail lov_init_raid0() doesn't lbug"
21018
21019 test_207a() {
21020         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
21021         local fsz=`stat -c %s $DIR/$tfile`
21022         cancel_lru_locks mdc
21023
21024         # do not return layout in getattr intent
21025 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
21026         $LCTL set_param fail_loc=0x170
21027         local sz=`stat -c %s $DIR/$tfile`
21028
21029         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
21030
21031         rm -rf $DIR/$tfile
21032 }
21033 run_test 207a "can refresh layout at glimpse"
21034
21035 test_207b() {
21036         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
21037         local cksum=`md5sum $DIR/$tfile`
21038         local fsz=`stat -c %s $DIR/$tfile`
21039         cancel_lru_locks mdc
21040         cancel_lru_locks osc
21041
21042         # do not return layout in getattr intent
21043 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
21044         $LCTL set_param fail_loc=0x171
21045
21046         # it will refresh layout after the file is opened but before read issues
21047         echo checksum is "$cksum"
21048         echo "$cksum" |md5sum -c --quiet || error "file differs"
21049
21050         rm -rf $DIR/$tfile
21051 }
21052 run_test 207b "can refresh layout at open"
21053
21054 test_208() {
21055         # FIXME: in this test suite, only RD lease is used. This is okay
21056         # for now as only exclusive open is supported. After generic lease
21057         # is done, this test suite should be revised. - Jinshan
21058
21059         remote_mds_nodsh && skip "remote MDS with nodsh"
21060         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
21061                 skip "Need MDS version at least 2.4.52"
21062
21063         echo "==== test 1: verify get lease work"
21064         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
21065
21066         echo "==== test 2: verify lease can be broken by upcoming open"
21067         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
21068         local PID=$!
21069         sleep 2
21070
21071         $MULTIOP $DIR/$tfile oO_RDWR:c
21072         kill -USR1 $PID && wait $PID || error "break lease error"
21073
21074         echo "==== test 3: verify lease can't be granted if an open already exists"
21075         $MULTIOP $DIR/$tfile oO_RDWR:_c &
21076         local PID=$!
21077         sleep 2
21078
21079         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
21080         kill -USR1 $PID && wait $PID || error "open file error"
21081
21082         echo "==== test 4: lease can sustain over recovery"
21083         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
21084         PID=$!
21085         sleep 2
21086
21087         fail mds1
21088
21089         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
21090
21091         echo "==== test 5: lease broken can't be regained by replay"
21092         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
21093         PID=$!
21094         sleep 2
21095
21096         # open file to break lease and then recovery
21097         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
21098         fail mds1
21099
21100         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
21101
21102         rm -f $DIR/$tfile
21103 }
21104 run_test 208 "Exclusive open"
21105
21106 test_209() {
21107         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
21108                 skip_env "must have disp_stripe"
21109
21110         touch $DIR/$tfile
21111         sync; sleep 5; sync;
21112
21113         echo 3 > /proc/sys/vm/drop_caches
21114         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
21115                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
21116         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
21117
21118         # open/close 500 times
21119         for i in $(seq 500); do
21120                 cat $DIR/$tfile
21121         done
21122
21123         echo 3 > /proc/sys/vm/drop_caches
21124         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
21125                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
21126         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
21127
21128         echo "before: $req_before, after: $req_after"
21129         [ $((req_after - req_before)) -ge 300 ] &&
21130                 error "open/close requests are not freed"
21131         return 0
21132 }
21133 run_test 209 "read-only open/close requests should be freed promptly"
21134
21135 test_210() {
21136         local pid
21137
21138         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
21139         pid=$!
21140         sleep 1
21141
21142         $LFS getstripe $DIR/$tfile
21143         kill -USR1 $pid
21144         wait $pid || error "multiop failed"
21145
21146         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
21147         pid=$!
21148         sleep 1
21149
21150         $LFS getstripe $DIR/$tfile
21151         kill -USR1 $pid
21152         wait $pid || error "multiop failed"
21153 }
21154 run_test 210 "lfs getstripe does not break leases"
21155
21156 function test_211() {
21157         local PID
21158         local id
21159         local rc
21160
21161         stack_trap "rm -f $DIR/$tfile" EXIT
21162         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=10 oflag=direct ||
21163                 error "can't create file"
21164         $LFS mirror extend -N $DIR/$tfile ||
21165                 error "can't create a replica"
21166         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
21167         $LFS getstripe $DIR/$tfile
21168         stale=$($LFS getstripe $DIR/$tfile | grep stale | wc -l)
21169         (( $stale != 1 )) && error "expected 1 stale, found $stale"
21170
21171         $MULTIOP $DIR/$tfile OeW_E+eUc &
21172         PID=$!
21173         sleep 0.3
21174
21175         id=$($LFS getstripe $DIR/$tfile |
21176                 awk '/lcme_mirror_id:/{id=$2}/lcme_flags.*init$/{print id}')
21177         $LFS mirror split -d --mirror-id $id $DIR/$tfile &&
21178                 error "removed last in-sync replica?"
21179
21180         kill -USR1 $PID
21181         wait $PID
21182         (( $? == 0 )) || error "failed split broke the lease"
21183 }
21184 run_test 211 "failed mirror split doesn't break write lease"
21185
21186 test_212() {
21187         size=`date +%s`
21188         size=$((size % 8192 + 1))
21189         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
21190         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
21191         rm -f $DIR/f212 $DIR/f212.xyz
21192 }
21193 run_test 212 "Sendfile test ============================================"
21194
21195 test_213() {
21196         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
21197         cancel_lru_locks osc
21198         lctl set_param fail_loc=0x8000040f
21199         # generate a read lock
21200         cat $DIR/$tfile > /dev/null
21201         # write to the file, it will try to cancel the above read lock.
21202         cat /etc/hosts >> $DIR/$tfile
21203 }
21204 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
21205
21206 test_214() { # for bug 20133
21207         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
21208         for (( i=0; i < 340; i++ )) ; do
21209                 touch $DIR/$tdir/d214c/a$i
21210         done
21211
21212         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
21213         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
21214         ls $DIR/d214c || error "ls $DIR/d214c failed"
21215         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
21216         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
21217 }
21218 run_test 214 "hash-indexed directory test - bug 20133"
21219
21220 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
21221 create_lnet_proc_files() {
21222         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
21223 }
21224
21225 # counterpart of create_lnet_proc_files
21226 remove_lnet_proc_files() {
21227         rm -f $TMP/lnet_$1.sys
21228 }
21229
21230 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
21231 # 3rd arg as regexp for body
21232 check_lnet_proc_stats() {
21233         local l=$(cat "$TMP/lnet_$1" |wc -l)
21234         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
21235
21236         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
21237 }
21238
21239 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
21240 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
21241 # optional and can be regexp for 2nd line (lnet.routes case)
21242 check_lnet_proc_entry() {
21243         local blp=2          # blp stands for 'position of 1st line of body'
21244         [ -z "$5" ] || blp=3 # lnet.routes case
21245
21246         local l=$(cat "$TMP/lnet_$1" |wc -l)
21247         # subtracting one from $blp because the body can be empty
21248         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
21249
21250         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
21251                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
21252
21253         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
21254                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
21255
21256         # bail out if any unexpected line happened
21257         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
21258         [ "$?" != 0 ] || error "$2 misformatted"
21259 }
21260
21261 test_215() { # for bugs 18102, 21079, 21517
21262         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21263
21264         local N='(0|[1-9][0-9]*)'       # non-negative numeric
21265         local P='[1-9][0-9]*'           # positive numeric
21266         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
21267         local NET='[a-z][a-z0-9]*'      # LNet net like o2ib2
21268         local ADDR='[0-9.]+'            # LNet addr like 10.0.0.1
21269         local ADDR6='([0-9a-f]{0,4}:){2,7}[0-9a-f]{0,4}' # IPv6 LNet addr
21270         local NID="$ADDR@$NET"          # LNet nid like 10.0.0.1@o2ib2
21271         local NID6="$ADDR6@$NET"        # LNet nid like 2601:8c1:c180::cbdd@tcp
21272
21273         local L1 # regexp for 1st line
21274         local L2 # regexp for 2nd line (optional)
21275         local BR # regexp for the rest (body)
21276
21277         # lnet.stats should look as 11 space-separated non-negative numerics
21278         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
21279         create_lnet_proc_files "stats"
21280         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
21281         remove_lnet_proc_files "stats"
21282
21283         # lnet.routes should look like this:
21284         # Routing disabled/enabled
21285         # net hops priority state router
21286         # where net is a string like tcp0, hops > 0, priority >= 0,
21287         # state is up/down,
21288         # router is a string like 192.168.1.1@tcp2
21289         L1="^Routing (disabled|enabled)$"
21290         L2="^net +hops +priority +state +router$"
21291         BR="^$NET +$N +(0|1) +(up|down) +($NID|$NID6)$"
21292         create_lnet_proc_files "routes"
21293         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
21294         remove_lnet_proc_files "routes"
21295
21296         # lnet.routers should look like this:
21297         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
21298         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
21299         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
21300         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
21301         L1="^ref +rtr_ref +alive +router$"
21302         BR="^$P +$P +(up|down) +($NID|$NID6)$"
21303         create_lnet_proc_files "routers"
21304         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
21305         remove_lnet_proc_files "routers"
21306
21307         # lnet.peers should look like this:
21308         # nid refs state last max rtr min tx min queue
21309         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
21310         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
21311         # numeric (0 or >0 or <0), queue >= 0.
21312         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
21313         BR="^($NID|$NID6) +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
21314         create_lnet_proc_files "peers"
21315         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
21316         remove_lnet_proc_files "peers"
21317
21318         # lnet.buffers  should look like this:
21319         # pages count credits min
21320         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
21321         L1="^pages +count +credits +min$"
21322         BR="^ +$N +$N +$I +$I$"
21323         create_lnet_proc_files "buffers"
21324         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
21325         remove_lnet_proc_files "buffers"
21326
21327         # lnet.nis should look like this:
21328         # nid status alive refs peer rtr max tx min
21329         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
21330         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
21331         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
21332         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
21333         BR="^($NID|$NID6) +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
21334         create_lnet_proc_files "nis"
21335         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
21336         remove_lnet_proc_files "nis"
21337
21338         # can we successfully write to lnet.stats?
21339         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
21340 }
21341 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
21342
21343 test_216() { # bug 20317
21344         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21345         remote_ost_nodsh && skip "remote OST with nodsh"
21346
21347         local node
21348         local facets=$(get_facets OST)
21349         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
21350
21351         save_lustre_params client "osc.*.contention_seconds" > $p
21352         save_lustre_params $facets \
21353                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
21354         save_lustre_params $facets \
21355                 "ldlm.namespaces.filter-*.contended_locks" >> $p
21356         save_lustre_params $facets \
21357                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
21358         clear_stats osc.*.osc_stats
21359
21360         # agressive lockless i/o settings
21361         do_nodes $(comma_list $(osts_nodes)) \
21362                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
21363                         ldlm.namespaces.filter-*.contended_locks=0 \
21364                         ldlm.namespaces.filter-*.contention_seconds=60"
21365         lctl set_param -n osc.*.contention_seconds=60
21366
21367         $DIRECTIO write $DIR/$tfile 0 10 4096
21368         $CHECKSTAT -s 40960 $DIR/$tfile
21369
21370         # disable lockless i/o
21371         do_nodes $(comma_list $(osts_nodes)) \
21372                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
21373                         ldlm.namespaces.filter-*.contended_locks=32 \
21374                         ldlm.namespaces.filter-*.contention_seconds=0"
21375         lctl set_param -n osc.*.contention_seconds=0
21376         clear_stats osc.*.osc_stats
21377
21378         dd if=/dev/zero of=$DIR/$tfile count=0
21379         $CHECKSTAT -s 0 $DIR/$tfile
21380
21381         restore_lustre_params <$p
21382         rm -f $p
21383         rm $DIR/$tfile
21384 }
21385 run_test 216 "check lockless direct write updates file size and kms correctly"
21386
21387 test_217() { # bug 22430
21388         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21389
21390         local node
21391
21392         for node in $(nodes_list); do
21393                 local nid=$(host_nids_address $node $NETTYPE)
21394                 local node_ip=$(do_node $node getent ahostsv4 $node |
21395                                 awk '{ print $1; exit; }')
21396
21397                 echo "node: '$node', nid: '$nid', node_ip='$node_ip'"
21398                 # if hostname matches any NID, use hostname for better testing
21399                 if [[ -z "$nid" || "$nid" =~ "$node_ip" ]]; then
21400                         echo "lctl ping node $node@$NETTYPE"
21401                         lctl ping $node@$NETTYPE ||
21402                                 error "ping $node@$NETTYPE failed rc=$?"
21403                 else # otherwise, at least test 'lctl ping' is working
21404                         echo "lctl ping nid $(h2nettype $nid)"
21405                         lctl ping $(h2nettype $nid) ||
21406                                 error "ping $(h2nettype $nid) failed rc=$?"
21407                         echo "skipping $node (no hyphen detected)"
21408                 fi
21409         done
21410
21411         return 0
21412 }
21413 run_test 217 "check lctl ping for hostnames with embedded hyphen ('-')"
21414
21415 test_218() {
21416         # do directio so as not to populate the page cache
21417         log "creating a 10 Mb file"
21418         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
21419                 error "multiop failed while creating a file"
21420         log "starting reads"
21421         dd if=$DIR/$tfile of=/dev/null bs=4096 &
21422         log "truncating the file"
21423         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
21424                 error "multiop failed while truncating the file"
21425         log "killing dd"
21426         kill %+ || true # reads might have finished
21427         echo "wait until dd is finished"
21428         wait
21429         log "removing the temporary file"
21430         rm -rf $DIR/$tfile || error "tmp file removal failed"
21431 }
21432 run_test 218 "parallel read and truncate should not deadlock"
21433
21434 test_219() {
21435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21436
21437         # write one partial page
21438         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
21439         # set no grant so vvp_io_commit_write will do sync write
21440         $LCTL set_param fail_loc=0x411
21441         # write a full page at the end of file
21442         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
21443
21444         $LCTL set_param fail_loc=0
21445         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
21446         $LCTL set_param fail_loc=0x411
21447         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
21448
21449         # LU-4201
21450         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
21451         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
21452 }
21453 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
21454
21455 test_220() { #LU-325
21456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21457         remote_ost_nodsh && skip "remote OST with nodsh"
21458         remote_mds_nodsh && skip "remote MDS with nodsh"
21459         remote_mgs_nodsh && skip "remote MGS with nodsh"
21460
21461         local OSTIDX=0
21462
21463         # create on MDT0000 so the last_id and next_id are correct
21464         mkdir_on_mdt0 $DIR/$tdir
21465         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
21466         OST=${OST%_UUID}
21467
21468         # on the mdt's osc
21469         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
21470         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
21471                         osp.$mdtosc_proc1.prealloc_last_id)
21472         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
21473                         osp.$mdtosc_proc1.prealloc_next_id)
21474
21475         $LFS df -i
21476
21477         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
21478         #define OBD_FAIL_OST_ENOINO              0x229
21479         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
21480         create_pool $FSNAME.$TESTNAME || return 1
21481         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
21482
21483         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
21484
21485         MDSOBJS=$((last_id - next_id))
21486         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
21487
21488         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
21489         echo "OST still has $count kbytes free"
21490
21491         echo "create $MDSOBJS files @next_id..."
21492         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
21493
21494         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
21495                         osp.$mdtosc_proc1.prealloc_last_id)
21496         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
21497                         osp.$mdtosc_proc1.prealloc_next_id)
21498
21499         echo "after creation, last_id=$last_id2, next_id=$next_id2"
21500         $LFS df -i
21501
21502         echo "cleanup..."
21503
21504         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
21505         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
21506
21507         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
21508                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
21509         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
21510                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
21511         echo "unlink $MDSOBJS files @$next_id..."
21512         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
21513 }
21514 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
21515
21516 test_221() {
21517         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21518
21519         dd if=`which date` of=$MOUNT/date oflag=sync
21520         chmod +x $MOUNT/date
21521
21522         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
21523         $LCTL set_param fail_loc=0x80001401
21524
21525         $MOUNT/date > /dev/null
21526         rm -f $MOUNT/date
21527 }
21528 run_test 221 "make sure fault and truncate race to not cause OOM"
21529
21530 test_222a () {
21531         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21532
21533         rm -rf $DIR/$tdir
21534         test_mkdir $DIR/$tdir
21535         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21536         createmany -o $DIR/$tdir/$tfile 10
21537         cancel_lru_locks mdc
21538         cancel_lru_locks osc
21539         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21540         $LCTL set_param fail_loc=0x31a
21541         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
21542         $LCTL set_param fail_loc=0
21543         rm -r $DIR/$tdir
21544 }
21545 run_test 222a "AGL for ls should not trigger CLIO lock failure"
21546
21547 test_222b () {
21548         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21549
21550         rm -rf $DIR/$tdir
21551         test_mkdir $DIR/$tdir
21552         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21553         createmany -o $DIR/$tdir/$tfile 10
21554         cancel_lru_locks mdc
21555         cancel_lru_locks osc
21556         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21557         $LCTL set_param fail_loc=0x31a
21558         rm -r $DIR/$tdir || error "AGL for rmdir failed"
21559         $LCTL set_param fail_loc=0
21560 }
21561 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
21562
21563 test_223 () {
21564         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21565
21566         rm -rf $DIR/$tdir
21567         test_mkdir $DIR/$tdir
21568         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21569         createmany -o $DIR/$tdir/$tfile 10
21570         cancel_lru_locks mdc
21571         cancel_lru_locks osc
21572         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
21573         $LCTL set_param fail_loc=0x31b
21574         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
21575         $LCTL set_param fail_loc=0
21576         rm -r $DIR/$tdir
21577 }
21578 run_test 223 "osc reenqueue if without AGL lock granted ======================="
21579
21580 test_224a() { # LU-1039, MRP-303
21581         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21582         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
21583         $LCTL set_param fail_loc=0x508
21584         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
21585         $LCTL set_param fail_loc=0
21586         df $DIR
21587 }
21588 run_test 224a "Don't panic on bulk IO failure"
21589
21590 test_224bd_sub() { # LU-1039, MRP-303
21591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21592         local timeout=$1
21593
21594         shift
21595         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
21596
21597         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21598
21599         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
21600         cancel_lru_locks osc
21601         set_checksums 0
21602         stack_trap "set_checksums $ORIG_CSUM" EXIT
21603         local at_max_saved=0
21604
21605         # adaptive timeouts may prevent seeing the issue
21606         if at_is_enabled; then
21607                 at_max_saved=$(at_max_get mds)
21608                 at_max_set 0 mds client
21609                 stack_trap "at_max_set $at_max_saved mds client" EXIT
21610         fi
21611
21612         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
21613         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
21614         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
21615
21616         do_facet ost1 $LCTL set_param fail_loc=0
21617         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
21618         df $DIR
21619 }
21620
21621 test_224b() {
21622         test_224bd_sub 3 error "dd failed"
21623 }
21624 run_test 224b "Don't panic on bulk IO failure"
21625
21626 test_224c() { # LU-6441
21627         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21628         remote_mds_nodsh && skip "remote MDS with nodsh"
21629
21630         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
21631         save_writethrough $p
21632         set_cache writethrough on
21633
21634         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
21635         local at_max=$($LCTL get_param -n at_max)
21636         local timeout=$($LCTL get_param -n timeout)
21637         local test_at="at_max"
21638         local param_at="$FSNAME.sys.at_max"
21639         local test_timeout="timeout"
21640         local param_timeout="$FSNAME.sys.timeout"
21641
21642         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
21643
21644         set_persistent_param_and_check client "$test_at" "$param_at" 0
21645         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
21646
21647         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
21648         do_facet ost1 "$LCTL set_param fail_loc=0x520"
21649         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21650         stack_trap "rm -f $DIR/$tfile"
21651         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
21652         sync
21653         do_facet ost1 "$LCTL set_param fail_loc=0"
21654
21655         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
21656         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
21657                 $timeout
21658
21659         $LCTL set_param -n $pages_per_rpc
21660         restore_lustre_params < $p
21661         rm -f $p
21662 }
21663 run_test 224c "Don't hang if one of md lost during large bulk RPC"
21664
21665 test_224d() { # LU-11169
21666         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
21667 }
21668 run_test 224d "Don't corrupt data on bulk IO timeout"
21669
21670 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
21671 test_225a () {
21672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21673         if [ -z ${MDSSURVEY} ]; then
21674                 skip_env "mds-survey not found"
21675         fi
21676         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21677                 skip "Need MDS version at least 2.2.51"
21678
21679         local mds=$(facet_host $SINGLEMDS)
21680         local target=$(do_nodes $mds 'lctl dl' |
21681                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21682
21683         local cmd1="file_count=1000 thrhi=4"
21684         local cmd2="dir_count=2 layer=mdd stripe_count=0"
21685         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21686         local cmd="$cmd1 $cmd2 $cmd3"
21687
21688         rm -f ${TMP}/mds_survey*
21689         echo + $cmd
21690         eval $cmd || error "mds-survey with zero-stripe failed"
21691         cat ${TMP}/mds_survey*
21692         rm -f ${TMP}/mds_survey*
21693 }
21694 run_test 225a "Metadata survey sanity with zero-stripe"
21695
21696 test_225b () {
21697         if [ -z ${MDSSURVEY} ]; then
21698                 skip_env "mds-survey not found"
21699         fi
21700         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21701                 skip "Need MDS version at least 2.2.51"
21702         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21703         remote_mds_nodsh && skip "remote MDS with nodsh"
21704         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
21705                 skip_env "Need to mount OST to test"
21706         fi
21707
21708         local mds=$(facet_host $SINGLEMDS)
21709         local target=$(do_nodes $mds 'lctl dl' |
21710                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21711
21712         local cmd1="file_count=1000 thrhi=4"
21713         local cmd2="dir_count=2 layer=mdd stripe_count=1"
21714         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21715         local cmd="$cmd1 $cmd2 $cmd3"
21716
21717         rm -f ${TMP}/mds_survey*
21718         echo + $cmd
21719         eval $cmd || error "mds-survey with stripe_count failed"
21720         cat ${TMP}/mds_survey*
21721         rm -f ${TMP}/mds_survey*
21722 }
21723 run_test 225b "Metadata survey sanity with stripe_count = 1"
21724
21725 mcreate_path2fid () {
21726         local mode=$1
21727         local major=$2
21728         local minor=$3
21729         local name=$4
21730         local desc=$5
21731         local path=$DIR/$tdir/$name
21732         local fid
21733         local rc
21734         local fid_path
21735
21736         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
21737                 error "cannot create $desc"
21738
21739         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
21740         rc=$?
21741         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
21742
21743         fid_path=$($LFS fid2path $MOUNT $fid)
21744         rc=$?
21745         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
21746
21747         [ "$path" == "$fid_path" ] ||
21748                 error "fid2path returned $fid_path, expected $path"
21749
21750         echo "pass with $path and $fid"
21751 }
21752
21753 test_226a () {
21754         rm -rf $DIR/$tdir
21755         mkdir -p $DIR/$tdir
21756
21757         mcreate_path2fid 0010666 0 0 fifo "FIFO"
21758         mcreate_path2fid 0020666 1 3 null "character special file (null)"
21759         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
21760         mcreate_path2fid 0040666 0 0 dir "directory"
21761         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
21762         mcreate_path2fid 0100666 0 0 file "regular file"
21763         mcreate_path2fid 0120666 0 0 link "symbolic link"
21764         mcreate_path2fid 0140666 0 0 sock "socket"
21765 }
21766 run_test 226a "call path2fid and fid2path on files of all type"
21767
21768 test_226b () {
21769         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21770
21771         local MDTIDX=1
21772
21773         rm -rf $DIR/$tdir
21774         mkdir -p $DIR/$tdir
21775         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
21776                 error "create remote directory failed"
21777         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
21778         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
21779                                 "character special file (null)"
21780         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
21781                                 "character special file (no device)"
21782         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
21783         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
21784                                 "block special file (loop)"
21785         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
21786         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
21787         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
21788 }
21789 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
21790
21791 test_226c () {
21792         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21793         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
21794                 skip "Need MDS version at least 2.13.55"
21795
21796         local submnt=/mnt/submnt
21797         local srcfile=/etc/passwd
21798         local dstfile=$submnt/passwd
21799         local path
21800         local fid
21801
21802         rm -rf $DIR/$tdir
21803         rm -rf $submnt
21804         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
21805                 error "create remote directory failed"
21806         mkdir -p $submnt || error "create $submnt failed"
21807         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
21808                 error "mount $submnt failed"
21809         stack_trap "umount $submnt" EXIT
21810
21811         cp $srcfile $dstfile
21812         fid=$($LFS path2fid $dstfile)
21813         path=$($LFS fid2path $submnt "$fid")
21814         [ "$path" = "$dstfile" ] ||
21815                 error "fid2path $submnt $fid failed ($path != $dstfile)"
21816 }
21817 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
21818
21819 test_226d () {
21820         (( $CLIENT_VERSION >= $(version_code 2.15.57) )) ||
21821                 skip "Need client at least version 2.15.57"
21822
21823         # Define First test dataset
21824         local testdirs_01=$DIR/$tdir
21825         local testdata_01=$testdirs_01/${tdir}_01
21826         local testresult_01=${tdir}_01
21827         # Define Second test dataset
21828         local testdirs_02=$DIR/$tdir/$tdir
21829         local testdata_02=$testdirs_02/${tdir}_02
21830         local testresult_02=${tdir}_02
21831         # Define third test dataset (top level)
21832         local testdata_03=$DIR/${tdir}_03
21833         local testresult_03=${tdir}_03
21834
21835         # Create first test dataset
21836         mkdir -p $testdirs_01 || error "cannot create dir $testdirs_01"
21837         touch $testdata_01 || error "cannot create file $testdata_01"
21838
21839         # Create second test dataset
21840         mkdir -p $testdirs_02 || error "cannot create dir $testdirs_02"
21841         touch $testdata_02 || error "cannot create file $testdata_02"
21842
21843         # Create third test dataset
21844         touch $testdata_03 || error "cannot create file $testdata_03"
21845
21846         local fid01=$($LFS getstripe -F "$testdata_01") ||
21847                 error "getstripe failed on $testdata_01"
21848         local fid02=$($LFS getstripe -F "$testdata_02") ||
21849                 error "getstripe failed on $testdata_01"
21850         local fid03=$($LFS getstripe -F "$testdata_03") ||
21851                 error "getstripe failed on $testdata_03"
21852
21853         # Verify only -n option
21854         local out1=$($LFS fid2path -n $DIR $fid01) ||
21855                 error "fid2path failed on $fid01"
21856         local out2=$($LFS fid2path -n $DIR $fid02) ||
21857                 error "fid2path failed on $fid02"
21858         local out3=$($LFS fid2path -n $DIR $fid03) ||
21859                 error "fid2path failed on $fid03"
21860
21861         [[ "$out1" == "$testresult_01" ]] ||
21862                 error "fid2path failed: Expected $testresult_01 got $out1"
21863         [[ "$out2" == "$testresult_02" ]] ||
21864                 error "fid2path failed: Expected $testresult_02 got $out2"
21865         [[ "$out3" == "$testresult_03" ]] ||
21866                 error "fid2path failed: Expected $testresult_03 got $out3"
21867
21868         # Verify with option -fn together
21869         out1=$($LFS fid2path -fn $DIR $fid01) ||
21870                 error "fid2path -fn failed on $fid01"
21871         out2=$($LFS fid2path -fn $DIR $fid02) ||
21872                 error "fid2path -fn failed on $fid02"
21873         out3=$($LFS fid2path -fn $DIR $fid03) ||
21874                 error "fid2path -fn failed on $fid03"
21875
21876         local tmpout=$(echo $out1 | cut -d" " -f2)
21877         [[ "$tmpout" == "$testresult_01" ]] ||
21878                 error "fid2path -fn failed: Expected $testresult_01 got $out1"
21879
21880         tmpout=$(echo $out2 | cut -d" " -f2)
21881         [[ "$tmpout" == "$testresult_02" ]] ||
21882                 error "fid2path -fn failed: Expected $testresult_02 got $out2"
21883
21884         tmpout=$(echo $out3 | cut -d" " -f2)
21885         [[ "$tmpout" == "$testresult_03" ]] ||
21886                 error "fid2path -fn failed: Expected $testresult_03 got $out3"
21887 }
21888 run_test 226d "verify fid2path with -n and -fn option"
21889
21890 test_226e () {
21891         (( $CLIENT_VERSION >= $(version_code 2.15.56) )) ||
21892                 skip "Need client at least version 2.15.56"
21893
21894         # Define filename with 'newline' and a space
21895         local testfile="Test"$'\n'"file 01"
21896         # Define link name with multiple 'newline' and a space
21897         local linkfile="Link"$'\n'"file "$'\n'"01"
21898         # Remove prior hard link
21899         rm -f $DIR/"$linkfile"
21900
21901         # Create file
21902         touch $DIR/"$testfile"
21903         # Create link
21904         ln $DIR/"$testfile" $DIR/"$linkfile"
21905
21906         local fid=$($LFS getstripe -F "$DIR/$testfile") ||
21907                 error "getstripe failed on $DIR/$testfile"
21908
21909         # Call with -0 option
21910         local out1=$($LFS fid2path -0 $DIR $fid | xargs --null -n1 \
21911                 echo "FILE:" | grep -c "FILE:")
21912
21913         # With -0 option the output should be exactly 2 lines.
21914         (( $out1 == 2 )) || error "fid2path -0 failed on $fid, $out1"
21915 }
21916 run_test 226e "Verify path2fid -0 option with newline and space"
21917
21918 # LU-1299 Executing or running ldd on a truncated executable does not
21919 # cause an out-of-memory condition.
21920 test_227() {
21921         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21922         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
21923
21924         dd if=$(which date) of=$MOUNT/date bs=1k count=1
21925         chmod +x $MOUNT/date
21926
21927         $MOUNT/date > /dev/null
21928         ldd $MOUNT/date > /dev/null
21929         rm -f $MOUNT/date
21930 }
21931 run_test 227 "running truncated executable does not cause OOM"
21932
21933 # LU-1512 try to reuse idle OI blocks
21934 test_228a() {
21935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21936         remote_mds_nodsh && skip "remote MDS with nodsh"
21937         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21938
21939         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21940         local myDIR=$DIR/$tdir
21941
21942         mkdir -p $myDIR
21943         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21944         $LCTL set_param fail_loc=0x80001002
21945         createmany -o $myDIR/t- 10000
21946         $LCTL set_param fail_loc=0
21947         # The guard is current the largest FID holder
21948         touch $myDIR/guard
21949         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21950                     tr -d '[')
21951         local IDX=$(($SEQ % 64))
21952
21953         do_facet $SINGLEMDS sync
21954         # Make sure journal flushed.
21955         sleep 6
21956         local blk1=$(do_facet $SINGLEMDS \
21957                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21958                      grep Blockcount | awk '{print $4}')
21959
21960         # Remove old files, some OI blocks will become idle.
21961         unlinkmany $myDIR/t- 10000
21962         # Create new files, idle OI blocks should be reused.
21963         createmany -o $myDIR/t- 2000
21964         do_facet $SINGLEMDS sync
21965         # Make sure journal flushed.
21966         sleep 6
21967         local blk2=$(do_facet $SINGLEMDS \
21968                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21969                      grep Blockcount | awk '{print $4}')
21970
21971         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21972 }
21973 run_test 228a "try to reuse idle OI blocks"
21974
21975 test_228b() {
21976         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21977         remote_mds_nodsh && skip "remote MDS with nodsh"
21978         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21979
21980         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21981         local myDIR=$DIR/$tdir
21982
21983         mkdir -p $myDIR
21984         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21985         $LCTL set_param fail_loc=0x80001002
21986         createmany -o $myDIR/t- 10000
21987         $LCTL set_param fail_loc=0
21988         # The guard is current the largest FID holder
21989         touch $myDIR/guard
21990         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21991                     tr -d '[')
21992         local IDX=$(($SEQ % 64))
21993
21994         do_facet $SINGLEMDS sync
21995         # Make sure journal flushed.
21996         sleep 6
21997         local blk1=$(do_facet $SINGLEMDS \
21998                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21999                      grep Blockcount | awk '{print $4}')
22000
22001         # Remove old files, some OI blocks will become idle.
22002         unlinkmany $myDIR/t- 10000
22003
22004         # stop the MDT
22005         stop $SINGLEMDS || error "Fail to stop MDT."
22006         # remount the MDT
22007         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
22008                 error "Fail to start MDT."
22009
22010         client_up || error "Fail to df."
22011         # Create new files, idle OI blocks should be reused.
22012         createmany -o $myDIR/t- 2000
22013         do_facet $SINGLEMDS sync
22014         # Make sure journal flushed.
22015         sleep 6
22016         local blk2=$(do_facet $SINGLEMDS \
22017                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
22018                      grep Blockcount | awk '{print $4}')
22019
22020         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
22021 }
22022 run_test 228b "idle OI blocks can be reused after MDT restart"
22023
22024 #LU-1881
22025 test_228c() {
22026         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22027         remote_mds_nodsh && skip "remote MDS with nodsh"
22028         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
22029
22030         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
22031         local myDIR=$DIR/$tdir
22032
22033         mkdir -p $myDIR
22034         #define OBD_FAIL_SEQ_EXHAUST             0x1002
22035         $LCTL set_param fail_loc=0x80001002
22036         # 20000 files can guarantee there are index nodes in the OI file
22037         createmany -o $myDIR/t- 20000
22038         $LCTL set_param fail_loc=0
22039         # The guard is current the largest FID holder
22040         touch $myDIR/guard
22041         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
22042                     tr -d '[')
22043         local IDX=$(($SEQ % 64))
22044
22045         do_facet $SINGLEMDS sync
22046         # Make sure journal flushed.
22047         sleep 6
22048         local blk1=$(do_facet $SINGLEMDS \
22049                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
22050                      grep Blockcount | awk '{print $4}')
22051
22052         # Remove old files, some OI blocks will become idle.
22053         unlinkmany $myDIR/t- 20000
22054         rm -f $myDIR/guard
22055         # The OI file should become empty now
22056
22057         # Create new files, idle OI blocks should be reused.
22058         createmany -o $myDIR/t- 2000
22059         do_facet $SINGLEMDS sync
22060         # Make sure journal flushed.
22061         sleep 6
22062         local blk2=$(do_facet $SINGLEMDS \
22063                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
22064                      grep Blockcount | awk '{print $4}')
22065
22066         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
22067 }
22068 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
22069
22070 test_229() { # LU-2482, LU-3448
22071         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22072         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
22073         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
22074                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
22075
22076         rm -f $DIR/$tfile
22077
22078         # Create a file with a released layout and stripe count 2.
22079         $MULTIOP $DIR/$tfile H2c ||
22080                 error "failed to create file with released layout"
22081
22082         $LFS getstripe -v $DIR/$tfile
22083
22084         local pattern=$($LFS getstripe -L $DIR/$tfile)
22085         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
22086
22087         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
22088                 error "getstripe"
22089         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
22090         stat $DIR/$tfile || error "failed to stat released file"
22091
22092         chown $RUNAS_ID $DIR/$tfile ||
22093                 error "chown $RUNAS_ID $DIR/$tfile failed"
22094
22095         chgrp $RUNAS_ID $DIR/$tfile ||
22096                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
22097
22098         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
22099         rm $DIR/$tfile || error "failed to remove released file"
22100 }
22101 run_test 229 "getstripe/stat/rm/attr changes work on released files"
22102
22103 test_230a() {
22104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22105         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22106         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22107                 skip "Need MDS version at least 2.11.52"
22108
22109         local MDTIDX=1
22110
22111         test_mkdir $DIR/$tdir
22112         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
22113         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
22114         [ $mdt_idx -ne 0 ] &&
22115                 error "create local directory on wrong MDT $mdt_idx"
22116
22117         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
22118                         error "create remote directory failed"
22119         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
22120         [ $mdt_idx -ne $MDTIDX ] &&
22121                 error "create remote directory on wrong MDT $mdt_idx"
22122
22123         createmany -o $DIR/$tdir/test_230/t- 10 ||
22124                 error "create files on remote directory failed"
22125         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
22126         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
22127         rm -r $DIR/$tdir || error "unlink remote directory failed"
22128 }
22129 run_test 230a "Create remote directory and files under the remote directory"
22130
22131 test_230b() {
22132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22133         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22134         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22135                 skip "Need MDS version at least 2.11.52"
22136
22137         local MDTIDX=1
22138         local mdt_index
22139         local i
22140         local file
22141         local pid
22142         local stripe_count
22143         local migrate_dir=$DIR/$tdir/migrate_dir
22144         local other_dir=$DIR/$tdir/other_dir
22145
22146         test_mkdir $DIR/$tdir
22147         test_mkdir -i0 -c1 $migrate_dir
22148         test_mkdir -i0 -c1 $other_dir
22149         for ((i=0; i<10; i++)); do
22150                 mkdir -p $migrate_dir/dir_${i}
22151                 createmany -o $migrate_dir/dir_${i}/f 10 ||
22152                         error "create files under remote dir failed $i"
22153         done
22154
22155         cp /etc/passwd $migrate_dir/$tfile
22156         cp /etc/passwd $other_dir/$tfile
22157         chattr +SAD $migrate_dir
22158         chattr +SAD $migrate_dir/$tfile
22159
22160         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
22161         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
22162         local old_dir_mode=$(stat -c%f $migrate_dir)
22163         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
22164
22165         mkdir -p $migrate_dir/dir_default_stripe2
22166         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
22167         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
22168
22169         mkdir -p $other_dir
22170         ln $migrate_dir/$tfile $other_dir/luna
22171         ln $migrate_dir/$tfile $migrate_dir/sofia
22172         ln $other_dir/$tfile $migrate_dir/david
22173         ln -s $migrate_dir/$tfile $other_dir/zachary
22174         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
22175         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
22176
22177         local len
22178         local lnktgt
22179
22180         # inline symlink
22181         for len in 58 59 60; do
22182                 lnktgt=$(str_repeat 'l' $len)
22183                 touch $migrate_dir/$lnktgt
22184                 ln -s $lnktgt $migrate_dir/${len}char_ln
22185         done
22186
22187         # PATH_MAX
22188         for len in 4094 4095; do
22189                 lnktgt=$(str_repeat 'l' $len)
22190                 ln -s $lnktgt $migrate_dir/${len}char_ln
22191         done
22192
22193         # NAME_MAX
22194         for len in 254 255; do
22195                 touch $migrate_dir/$(str_repeat 'l' $len)
22196         done
22197
22198         $LFS migrate -m $MDTIDX $migrate_dir ||
22199                 error "fails on migrating remote dir to MDT1"
22200
22201         echo "migratate to MDT1, then checking.."
22202         for ((i = 0; i < 10; i++)); do
22203                 for file in $(find $migrate_dir/dir_${i}); do
22204                         mdt_index=$($LFS getstripe -m $file)
22205                         # broken symlink getstripe will fail
22206                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
22207                                 error "$file is not on MDT${MDTIDX}"
22208                 done
22209         done
22210
22211         # the multiple link file should still in MDT0
22212         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
22213         [ $mdt_index == 0 ] ||
22214                 error "$file is not on MDT${MDTIDX}"
22215
22216         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
22217         [ "$old_dir_flag" = "$new_dir_flag" ] ||
22218                 error " expect $old_dir_flag get $new_dir_flag"
22219
22220         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
22221         [ "$old_file_flag" = "$new_file_flag" ] ||
22222                 error " expect $old_file_flag get $new_file_flag"
22223
22224         local new_dir_mode=$(stat -c%f $migrate_dir)
22225         [ "$old_dir_mode" = "$new_dir_mode" ] ||
22226                 error "expect mode $old_dir_mode get $new_dir_mode"
22227
22228         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
22229         [ "$old_file_mode" = "$new_file_mode" ] ||
22230                 error "expect mode $old_file_mode get $new_file_mode"
22231
22232         diff /etc/passwd $migrate_dir/$tfile ||
22233                 error "$tfile different after migration"
22234
22235         diff /etc/passwd $other_dir/luna ||
22236                 error "luna different after migration"
22237
22238         diff /etc/passwd $migrate_dir/sofia ||
22239                 error "sofia different after migration"
22240
22241         diff /etc/passwd $migrate_dir/david ||
22242                 error "david different after migration"
22243
22244         diff /etc/passwd $other_dir/zachary ||
22245                 error "zachary different after migration"
22246
22247         diff /etc/passwd $migrate_dir/${tfile}_ln ||
22248                 error "${tfile}_ln different after migration"
22249
22250         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
22251                 error "${tfile}_ln_other different after migration"
22252
22253         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
22254         [ $stripe_count = 2 ] ||
22255                 error "dir strpe_count $d != 2 after migration."
22256
22257         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
22258         [ $stripe_count = 2 ] ||
22259                 error "file strpe_count $d != 2 after migration."
22260
22261         #migrate back to MDT0
22262         MDTIDX=0
22263
22264         $LFS migrate -m $MDTIDX $migrate_dir ||
22265                 error "fails on migrating remote dir to MDT0"
22266
22267         echo "migrate back to MDT0, checking.."
22268         for file in $(find $migrate_dir); do
22269                 mdt_index=$($LFS getstripe -m $file)
22270                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
22271                         error "$file is not on MDT${MDTIDX}"
22272         done
22273
22274         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
22275         [ "$old_dir_flag" = "$new_dir_flag" ] ||
22276                 error " expect $old_dir_flag get $new_dir_flag"
22277
22278         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
22279         [ "$old_file_flag" = "$new_file_flag" ] ||
22280                 error " expect $old_file_flag get $new_file_flag"
22281
22282         local new_dir_mode=$(stat -c%f $migrate_dir)
22283         [ "$old_dir_mode" = "$new_dir_mode" ] ||
22284                 error "expect mode $old_dir_mode get $new_dir_mode"
22285
22286         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
22287         [ "$old_file_mode" = "$new_file_mode" ] ||
22288                 error "expect mode $old_file_mode get $new_file_mode"
22289
22290         diff /etc/passwd ${migrate_dir}/$tfile ||
22291                 error "$tfile different after migration"
22292
22293         diff /etc/passwd ${other_dir}/luna ||
22294                 error "luna different after migration"
22295
22296         diff /etc/passwd ${migrate_dir}/sofia ||
22297                 error "sofia different after migration"
22298
22299         diff /etc/passwd ${other_dir}/zachary ||
22300                 error "zachary different after migration"
22301
22302         diff /etc/passwd $migrate_dir/${tfile}_ln ||
22303                 error "${tfile}_ln different after migration"
22304
22305         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
22306                 error "${tfile}_ln_other different after migration"
22307
22308         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
22309         [ $stripe_count = 2 ] ||
22310                 error "dir strpe_count $d != 2 after migration."
22311
22312         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
22313         [ $stripe_count = 2 ] ||
22314                 error "file strpe_count $d != 2 after migration."
22315
22316         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22317 }
22318 run_test 230b "migrate directory"
22319
22320 test_230c() {
22321         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22322         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22323         remote_mds_nodsh && skip "remote MDS with nodsh"
22324         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22325                 skip "Need MDS version at least 2.11.52"
22326
22327         local MDTIDX=1
22328         local total=3
22329         local mdt_index
22330         local file
22331         local migrate_dir=$DIR/$tdir/migrate_dir
22332
22333         #If migrating directory fails in the middle, all entries of
22334         #the directory is still accessiable.
22335         test_mkdir $DIR/$tdir
22336         test_mkdir -i0 -c1 $migrate_dir
22337         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
22338         stat $migrate_dir
22339         createmany -o $migrate_dir/f $total ||
22340                 error "create files under ${migrate_dir} failed"
22341
22342         # fail after migrating top dir, and this will fail only once, so the
22343         # first sub file migration will fail (currently f3), others succeed.
22344         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
22345         do_facet mds1 lctl set_param fail_loc=0x1801
22346         local t=$(ls $migrate_dir | wc -l)
22347         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
22348                 error "migrate should fail"
22349         local u=$(ls $migrate_dir | wc -l)
22350         [ "$u" == "$t" ] || error "$u != $t during migration"
22351
22352         # add new dir/file should succeed
22353         mkdir $migrate_dir/dir ||
22354                 error "mkdir failed under migrating directory"
22355         touch $migrate_dir/file ||
22356                 error "create file failed under migrating directory"
22357
22358         # add file with existing name should fail
22359         for file in $migrate_dir/f*; do
22360                 stat $file > /dev/null || error "stat $file failed"
22361                 $OPENFILE -f O_CREAT:O_EXCL $file &&
22362                         error "open(O_CREAT|O_EXCL) $file should fail"
22363                 $MULTIOP $file m && error "create $file should fail"
22364                 touch $DIR/$tdir/remote_dir/$tfile ||
22365                         error "touch $tfile failed"
22366                 ln $DIR/$tdir/remote_dir/$tfile $file &&
22367                         error "link $file should fail"
22368                 mdt_index=$($LFS getstripe -m $file)
22369                 if [ $mdt_index == 0 ]; then
22370                         # file failed to migrate is not allowed to rename to
22371                         mv $DIR/$tdir/remote_dir/$tfile $file &&
22372                                 error "rename to $file should fail"
22373                 else
22374                         mv $DIR/$tdir/remote_dir/$tfile $file ||
22375                                 error "rename to $file failed"
22376                 fi
22377                 echo hello >> $file || error "write $file failed"
22378         done
22379
22380         # resume migration with different options should fail
22381         $LFS migrate -m 0 $migrate_dir &&
22382                 error "migrate -m 0 $migrate_dir should fail"
22383
22384         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
22385                 error "migrate -c 2 $migrate_dir should fail"
22386
22387         # resume migration should succeed
22388         $LFS migrate -m $MDTIDX $migrate_dir ||
22389                 error "migrate $migrate_dir failed"
22390
22391         echo "Finish migration, then checking.."
22392         for file in $(find $migrate_dir); do
22393                 mdt_index=$($LFS getstripe -m $file)
22394                 [ $mdt_index == $MDTIDX ] ||
22395                         error "$file is not on MDT${MDTIDX}"
22396         done
22397
22398         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22399 }
22400 run_test 230c "check directory accessiblity if migration failed"
22401
22402 test_230d() {
22403         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22404         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22405         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22406                 skip "Need MDS version at least 2.11.52"
22407         # LU-11235
22408         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
22409
22410         local migrate_dir=$DIR/$tdir/migrate_dir
22411         local old_index
22412         local new_index
22413         local old_count
22414         local new_count
22415         local new_hash
22416         local mdt_index
22417         local i
22418         local j
22419
22420         old_index=$((RANDOM % MDSCOUNT))
22421         old_count=$((MDSCOUNT - old_index))
22422         new_index=$((RANDOM % MDSCOUNT))
22423         new_count=$((MDSCOUNT - new_index))
22424         new_hash=1 # for all_char
22425
22426         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
22427         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
22428
22429         test_mkdir $DIR/$tdir
22430         test_mkdir -i $old_index -c $old_count $migrate_dir
22431
22432         for ((i=0; i<100; i++)); do
22433                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
22434                 createmany -o $migrate_dir/dir_${i}/f 100 ||
22435                         error "create files under remote dir failed $i"
22436         done
22437
22438         echo -n "Migrate from MDT$old_index "
22439         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
22440         echo -n "to MDT$new_index"
22441         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
22442         echo
22443
22444         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
22445         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
22446                 error "migrate remote dir error"
22447
22448         echo "Finish migration, then checking.."
22449         for file in $(find $migrate_dir -maxdepth 1); do
22450                 mdt_index=$($LFS getstripe -m $file)
22451                 if [ $mdt_index -lt $new_index ] ||
22452                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
22453                         error "$file is on MDT$mdt_index"
22454                 fi
22455         done
22456
22457         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22458 }
22459 run_test 230d "check migrate big directory"
22460
22461 test_230e() {
22462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22463         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22464         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22465                 skip "Need MDS version at least 2.11.52"
22466
22467         local i
22468         local j
22469         local a_fid
22470         local b_fid
22471
22472         mkdir_on_mdt0 $DIR/$tdir
22473         mkdir $DIR/$tdir/migrate_dir
22474         mkdir $DIR/$tdir/other_dir
22475         touch $DIR/$tdir/migrate_dir/a
22476         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
22477         ls $DIR/$tdir/other_dir
22478
22479         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22480                 error "migrate dir fails"
22481
22482         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
22483         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
22484
22485         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22486         [ $mdt_index == 0 ] || error "a is not on MDT0"
22487
22488         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
22489                 error "migrate dir fails"
22490
22491         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
22492         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
22493
22494         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22495         [ $mdt_index == 1 ] || error "a is not on MDT1"
22496
22497         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
22498         [ $mdt_index == 1 ] || error "b is not on MDT1"
22499
22500         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
22501         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
22502
22503         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
22504
22505         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22506 }
22507 run_test 230e "migrate mulitple local link files"
22508
22509 test_230f() {
22510         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22511         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22512         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22513                 skip "Need MDS version at least 2.11.52"
22514
22515         local a_fid
22516         local ln_fid
22517
22518         mkdir -p $DIR/$tdir
22519         mkdir $DIR/$tdir/migrate_dir
22520         $LFS mkdir -i1 $DIR/$tdir/other_dir
22521         touch $DIR/$tdir/migrate_dir/a
22522         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
22523         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
22524         ls $DIR/$tdir/other_dir
22525
22526         # a should be migrated to MDT1, since no other links on MDT0
22527         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22528                 error "#1 migrate dir fails"
22529         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
22530         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
22531         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22532         [ $mdt_index == 1 ] || error "a is not on MDT1"
22533
22534         # a should stay on MDT1, because it is a mulitple link file
22535         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22536                 error "#2 migrate dir fails"
22537         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22538         [ $mdt_index == 1 ] || error "a is not on MDT1"
22539
22540         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22541                 error "#3 migrate dir fails"
22542
22543         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
22544         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
22545         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
22546
22547         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
22548         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
22549
22550         # a should be migrated to MDT0, since no other links on MDT1
22551         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22552                 error "#4 migrate dir fails"
22553         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22554         [ $mdt_index == 0 ] || error "a is not on MDT0"
22555
22556         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22557 }
22558 run_test 230f "migrate mulitple remote link files"
22559
22560 test_230g() {
22561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22562         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22563         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22564                 skip "Need MDS version at least 2.11.52"
22565
22566         mkdir -p $DIR/$tdir/migrate_dir
22567
22568         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
22569                 error "migrating dir to non-exist MDT succeeds"
22570         true
22571 }
22572 run_test 230g "migrate dir to non-exist MDT"
22573
22574 test_230h() {
22575         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22576         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22577         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22578                 skip "Need MDS version at least 2.11.52"
22579
22580         local mdt_index
22581
22582         mkdir -p $DIR/$tdir/migrate_dir
22583
22584         $LFS migrate -m1 $DIR &&
22585                 error "migrating mountpoint1 should fail"
22586
22587         $LFS migrate -m1 $DIR/$tdir/.. &&
22588                 error "migrating mountpoint2 should fail"
22589
22590         # same as mv
22591         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
22592                 error "migrating $tdir/migrate_dir/.. should fail"
22593
22594         true
22595 }
22596 run_test 230h "migrate .. and root"
22597
22598 test_230i() {
22599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22600         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22601         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22602                 skip "Need MDS version at least 2.11.52"
22603
22604         mkdir -p $DIR/$tdir/migrate_dir
22605
22606         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
22607                 error "migration fails with a tailing slash"
22608
22609         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
22610                 error "migration fails with two tailing slashes"
22611 }
22612 run_test 230i "lfs migrate -m tolerates trailing slashes"
22613
22614 test_230j() {
22615         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22616         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
22617                 skip "Need MDS version at least 2.11.52"
22618
22619         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22620         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
22621                 error "create $tfile failed"
22622         cat /etc/passwd > $DIR/$tdir/$tfile
22623
22624         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22625
22626         cmp /etc/passwd $DIR/$tdir/$tfile ||
22627                 error "DoM file mismatch after migration"
22628 }
22629 run_test 230j "DoM file data not changed after dir migration"
22630
22631 test_230k() {
22632         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
22633         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22634                 skip "Need MDS version at least 2.11.56"
22635
22636         local total=20
22637         local files_on_starting_mdt=0
22638
22639         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
22640         $LFS getdirstripe $DIR/$tdir
22641         for i in $(seq $total); do
22642                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
22643                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22644                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22645         done
22646
22647         echo "$files_on_starting_mdt files on MDT0"
22648
22649         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
22650         $LFS getdirstripe $DIR/$tdir
22651
22652         files_on_starting_mdt=0
22653         for i in $(seq $total); do
22654                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22655                         error "file $tfile.$i mismatch after migration"
22656                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
22657                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22658         done
22659
22660         echo "$files_on_starting_mdt files on MDT1 after migration"
22661         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
22662
22663         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
22664         $LFS getdirstripe $DIR/$tdir
22665
22666         files_on_starting_mdt=0
22667         for i in $(seq $total); do
22668                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22669                         error "file $tfile.$i mismatch after 2nd migration"
22670                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22671                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22672         done
22673
22674         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
22675         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
22676
22677         true
22678 }
22679 run_test 230k "file data not changed after dir migration"
22680
22681 test_230l() {
22682         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22683         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22684                 skip "Need MDS version at least 2.11.56"
22685
22686         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
22687         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
22688                 error "create files under remote dir failed $i"
22689         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22690 }
22691 run_test 230l "readdir between MDTs won't crash"
22692
22693 test_230m() {
22694         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22695         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22696                 skip "Need MDS version at least 2.11.56"
22697
22698         local MDTIDX=1
22699         local mig_dir=$DIR/$tdir/migrate_dir
22700         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
22701         local shortstr="b"
22702         local val
22703
22704         echo "Creating files and dirs with xattrs"
22705         test_mkdir $DIR/$tdir
22706         test_mkdir -i0 -c1 $mig_dir
22707         mkdir $mig_dir/dir
22708         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
22709                 error "cannot set xattr attr1 on dir"
22710         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
22711                 error "cannot set xattr attr2 on dir"
22712         touch $mig_dir/dir/f0
22713         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
22714                 error "cannot set xattr attr1 on file"
22715         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
22716                 error "cannot set xattr attr2 on file"
22717         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22718         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22719         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
22720         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22721         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
22722         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22723         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
22724         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22725         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
22726
22727         echo "Migrating to MDT1"
22728         $LFS migrate -m $MDTIDX $mig_dir ||
22729                 error "fails on migrating dir to MDT1"
22730
22731         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22732         echo "Checking xattrs"
22733         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22734         [ "$val" = $longstr ] ||
22735                 error "expecting xattr1 $longstr on dir, found $val"
22736         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22737         [ "$val" = $shortstr ] ||
22738                 error "expecting xattr2 $shortstr on dir, found $val"
22739         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22740         [ "$val" = $longstr ] ||
22741                 error "expecting xattr1 $longstr on file, found $val"
22742         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22743         [ "$val" = $shortstr ] ||
22744                 error "expecting xattr2 $shortstr on file, found $val"
22745 }
22746 run_test 230m "xattrs not changed after dir migration"
22747
22748 test_230n() {
22749         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22750         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22751                 skip "Need MDS version at least 2.13.53"
22752
22753         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
22754         cat /etc/hosts > $DIR/$tdir/$tfile
22755         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
22756         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
22757
22758         cmp /etc/hosts $DIR/$tdir/$tfile ||
22759                 error "File data mismatch after migration"
22760 }
22761 run_test 230n "Dir migration with mirrored file"
22762
22763 test_230o() {
22764         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
22765         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22766                 skip "Need MDS version at least 2.13.52"
22767
22768         local mdts=$(comma_list $(mdts_nodes))
22769         local timeout=100
22770         local restripe_status
22771         local delta
22772         local i
22773
22774         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22775
22776         # in case "crush" hash type is not set
22777         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22778
22779         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22780                            mdt.*MDT0000.enable_dir_restripe)
22781         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22782         stack_trap "do_nodes $mdts $LCTL set_param \
22783                     mdt.*.enable_dir_restripe=$restripe_status"
22784
22785         mkdir $DIR/$tdir
22786         createmany -m $DIR/$tdir/f 100 ||
22787                 error "create files under remote dir failed $i"
22788         createmany -d $DIR/$tdir/d 100 ||
22789                 error "create dirs under remote dir failed $i"
22790
22791         for i in $(seq 2 $MDSCOUNT); do
22792                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22793                 $LFS setdirstripe -c $i $DIR/$tdir ||
22794                         error "split -c $i $tdir failed"
22795                 wait_update $HOSTNAME \
22796                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
22797                         error "dir split not finished"
22798                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22799                         awk '/migrate/ {sum += $2} END { print sum }')
22800                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
22801                 # delta is around total_files/stripe_count
22802                 (( $delta < 200 / (i - 1) + 4 )) ||
22803                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
22804         done
22805 }
22806 run_test 230o "dir split"
22807
22808 test_230p() {
22809         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22810         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22811                 skip "Need MDS version at least 2.13.52"
22812
22813         local mdts=$(comma_list $(mdts_nodes))
22814         local timeout=100
22815         local restripe_status
22816         local delta
22817         local c
22818
22819         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22820
22821         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22822
22823         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22824                            mdt.*MDT0000.enable_dir_restripe)
22825         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22826         stack_trap "do_nodes $mdts $LCTL set_param \
22827                     mdt.*.enable_dir_restripe=$restripe_status"
22828
22829         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
22830         createmany -m $DIR/$tdir/f 100 ||
22831                 error "create files under remote dir failed"
22832         createmany -d $DIR/$tdir/d 100 ||
22833                 error "create dirs under remote dir failed"
22834
22835         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
22836                 local mdt_hash="crush"
22837
22838                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22839                 $LFS setdirstripe -c $c $DIR/$tdir ||
22840                         error "split -c $c $tdir failed"
22841                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
22842                         mdt_hash="$mdt_hash,fixed"
22843                 elif [ $c -eq 1 ]; then
22844                         mdt_hash="none"
22845                 fi
22846                 wait_update $HOSTNAME \
22847                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
22848                         error "dir merge not finished"
22849                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22850                         awk '/migrate/ {sum += $2} END { print sum }')
22851                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
22852                 # delta is around total_files/stripe_count
22853                 (( delta < 200 / c + 4 )) ||
22854                         error "$delta files migrated >= $((200 / c + 4))"
22855         done
22856 }
22857 run_test 230p "dir merge"
22858
22859 test_230q() {
22860         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
22861         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22862                 skip "Need MDS version at least 2.13.52"
22863
22864         local mdts=$(comma_list $(mdts_nodes))
22865         local saved_threshold=$(do_facet mds1 \
22866                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
22867         local saved_delta=$(do_facet mds1 \
22868                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
22869         local threshold=100
22870         local delta=2
22871         local total=0
22872         local stripe_count=0
22873         local stripe_index
22874         local nr_files
22875         local create
22876
22877         # test with fewer files on ZFS
22878         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
22879
22880         stack_trap "do_nodes $mdts $LCTL set_param \
22881                     mdt.*.dir_split_count=$saved_threshold"
22882         stack_trap "do_nodes $mdts $LCTL set_param \
22883                     mdt.*.dir_split_delta=$saved_delta"
22884         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
22885         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
22886         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
22887         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
22888         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
22889         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22890
22891         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22892         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22893
22894         create=$((threshold * 3 / 2))
22895         while [ $stripe_count -lt $MDSCOUNT ]; do
22896                 createmany -m $DIR/$tdir/f $total $create ||
22897                         error "create sub files failed"
22898                 stat $DIR/$tdir > /dev/null
22899                 total=$((total + create))
22900                 stripe_count=$((stripe_count + delta))
22901                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
22902
22903                 wait_update $HOSTNAME \
22904                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
22905                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
22906
22907                 wait_update $HOSTNAME \
22908                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
22909                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
22910
22911                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
22912                 echo "$nr_files/$total files on MDT$stripe_index after split"
22913                 # allow 10% margin of imbalance with crush hash
22914                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
22915                         error "$nr_files files on MDT$stripe_index after split"
22916
22917                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
22918                 [ $nr_files -eq $total ] ||
22919                         error "total sub files $nr_files != $total"
22920         done
22921
22922         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
22923
22924         echo "fixed layout directory won't auto split"
22925         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
22926         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
22927                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
22928         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
22929                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
22930 }
22931 run_test 230q "dir auto split"
22932
22933 test_230r() {
22934         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
22935         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
22936         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
22937                 skip "Need MDS version at least 2.13.54"
22938
22939         # maximum amount of local locks:
22940         # parent striped dir - 2 locks
22941         # new stripe in parent to migrate to - 1 lock
22942         # source and target - 2 locks
22943         # Total 5 locks for regular file
22944         mkdir -p $DIR/$tdir
22945         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
22946         touch $DIR/$tdir/dir1/eee
22947
22948         # create 4 hardlink for 4 more locks
22949         # Total: 9 locks > RS_MAX_LOCKS (8)
22950         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
22951         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
22952         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
22953         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
22954         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
22955         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
22956         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
22957         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
22958
22959         cancel_lru_locks mdc
22960
22961         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
22962                 error "migrate dir fails"
22963
22964         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22965 }
22966 run_test 230r "migrate with too many local locks"
22967
22968 test_230s() {
22969         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
22970                 skip "Need MDS version at least 2.14.52"
22971
22972         local mdts=$(comma_list $(mdts_nodes))
22973         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
22974                                 mdt.*MDT0000.enable_dir_restripe)
22975
22976         stack_trap "do_nodes $mdts $LCTL set_param \
22977                     mdt.*.enable_dir_restripe=$restripe_status"
22978
22979         local st
22980         for st in 0 1; do
22981                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
22982                 test_mkdir $DIR/$tdir
22983                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
22984                         error "$LFS mkdir should return EEXIST if target exists"
22985                 rmdir $DIR/$tdir
22986         done
22987 }
22988 run_test 230s "lfs mkdir should return -EEXIST if target exists"
22989
22990 test_230t()
22991 {
22992         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
22993         (( $MDS1_VERSION >= $(version_code 2.14.50) )) ||
22994                 skip "Need MDS version at least 2.14.50"
22995
22996         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
22997         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
22998         $LFS project -p 1 -s $DIR/$tdir ||
22999                 error "set $tdir project id failed"
23000         $LFS project -p 2 -s $DIR/$tdir/subdir ||
23001                 error "set subdir project id failed"
23002         local pbefore="$($LFS project -d $DIR/$tdir)"
23003         local sbefore="$($LFS project -d $DIR/$tdir/subdir)"
23004         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
23005
23006         local pafter="$($LFS project -d $DIR/$tdir)"
23007         local safter="$($LFS project -d $DIR/$tdir/subdir)"
23008         [[ "$pbefore" == "$pafter" ]] || error "projid '$pbefore' != '$pafter'"
23009         [[ "$sbefore" == "$safter" ]] || error "projid '$sbefore' != '$safter'"
23010
23011         (( $MDS1_VERSION >= $(version_code 2.15.59.107) )) ||
23012                 { echo "Need MDS >= 2.15.59.107 for projid rename"; return 0; }
23013
23014         # check rename works, even if source parent projid differs (LU-17016)
23015         test_mkdir $DIR/$tdir.2 || error "mkdir $tdir.2 failed"
23016         local fid_before=$($LFS path2fid $DIR/$tdir/subdir)
23017
23018         $LFS project -p 2 -s $DIR/$tdir.2 || error "set $tdir.2 projid failed"
23019         mrename $DIR/$tdir/subdir $DIR/$tdir.2/subdir ||
23020                 error "subdir failed rename for different source parent projid"
23021         local fid_after=$($LFS path2fid $DIR/$tdir.2/subdir)
23022
23023         [[ "$fid_before" == "$fid_after" ]] ||
23024                 error "fid before '$fid_before' != after '$fid_after'"
23025 }
23026 run_test 230t "migrate directory with project ID set"
23027
23028 test_230u()
23029 {
23030         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
23031         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
23032                 skip "Need MDS version at least 2.14.53"
23033
23034         local count
23035
23036         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
23037         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
23038         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
23039         for i in $(seq 0 $((MDSCOUNT - 1))); do
23040                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
23041                 echo "$count dirs migrated to MDT$i"
23042         done
23043         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
23044         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
23045 }
23046 run_test 230u "migrate directory by QOS"
23047
23048 test_230v()
23049 {
23050         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
23051         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
23052                 skip "Need MDS version at least 2.14.53"
23053
23054         local count
23055
23056         mkdir $DIR/$tdir || error "mkdir $tdir failed"
23057         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
23058         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
23059         for i in $(seq 0 $((MDSCOUNT - 1))); do
23060                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
23061                 echo "$count subdirs migrated to MDT$i"
23062                 (( i == 3 )) && (( count > 0 )) &&
23063                         error "subdir shouldn't be migrated to MDT3"
23064         done
23065         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
23066         (( count == 3 )) || error "dirs migrated to $count MDTs"
23067 }
23068 run_test 230v "subdir migrated to the MDT where its parent is located"
23069
23070 test_230w() {
23071         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23072         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
23073                 skip "Need MDS version at least 2.15.0"
23074
23075         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
23076         createmany -o $DIR/$tdir/f 10 || error "create files failed"
23077         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
23078
23079         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
23080                 error "migrate failed"
23081
23082         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
23083                 error "$tdir stripe count mismatch"
23084
23085         for i in $(seq 0 9); do
23086                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
23087                         error "d$i is striped"
23088         done
23089 }
23090 run_test 230w "non-recursive mode dir migration"
23091
23092 test_230x() {
23093         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23094         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
23095                 skip "Need MDS version at least 2.15.0"
23096
23097         mkdir -p $DIR/$tdir || error "mkdir failed"
23098         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
23099
23100         local mdt_name=$(mdtname_from_index 0)
23101         local low=$(do_facet mds2 $LCTL get_param -n \
23102                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
23103         local high=$(do_facet mds2 $LCTL get_param -n \
23104                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
23105         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
23106         local maxage=$(do_facet mds2 $LCTL get_param -n \
23107                 osp.*$mdt_name-osp-MDT0001.maxage)
23108
23109         stack_trap "do_facet mds2 $LCTL set_param -n \
23110                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
23111                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
23112         stack_trap "do_facet mds2 $LCTL set_param -n \
23113                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
23114
23115         do_facet mds2 $LCTL set_param -n \
23116                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
23117         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
23118         sleep 4
23119         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
23120                 error "migrate $tdir should fail"
23121
23122         do_facet mds2 $LCTL set_param -n \
23123                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
23124         do_facet mds2 $LCTL set_param -n \
23125                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
23126         sleep 4
23127         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
23128                 error "migrate failed"
23129         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
23130                 error "$tdir stripe count mismatch"
23131 }
23132 run_test 230x "dir migration check space"
23133
23134 test_230y() {
23135         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23136         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
23137                 skip "Need MDS version at least 2.15.55.45"
23138
23139         local pid
23140
23141         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
23142         $LFS getdirstripe $DIR/$tdir
23143         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
23144         $LFS migrate -m 1 -c 2 $DIR/$tdir &
23145         pid=$!
23146         sleep 1
23147
23148         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
23149         do_facet mds2 lctl set_param fail_loc=0x1802
23150
23151         wait $pid
23152         do_facet mds2 lctl set_param fail_loc=0
23153         $LFS getdirstripe $DIR/$tdir
23154         unlinkmany -d $DIR/$tdir/d 100 || error "unlinkmany failed"
23155         rmdir $DIR/$tdir || error "rmdir $tdir failed"
23156 }
23157 run_test 230y "unlink dir with bad hash type"
23158
23159 test_230z() {
23160         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23161         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
23162                 skip "Need MDS version at least 2.15.55.45"
23163
23164         local pid
23165
23166         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
23167         $LFS getdirstripe $DIR/$tdir
23168         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
23169         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir &
23170         pid=$!
23171         sleep 1
23172
23173         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
23174         do_facet mds2 lctl set_param fail_loc=0x1802
23175
23176         wait $pid
23177         do_facet mds2 lctl set_param fail_loc=0
23178         $LFS getdirstripe $DIR/$tdir
23179
23180         # resume migration
23181         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir ||
23182                 error "resume migration failed"
23183         $LFS getdirstripe $DIR/$tdir
23184         [ $($LFS getdirstripe -H $DIR/$tdir) == "fnv_1a_64,fixed" ] ||
23185                 error "migration is not finished"
23186 }
23187 run_test 230z "resume dir migration with bad hash type"
23188
23189 test_231a()
23190 {
23191         # For simplicity this test assumes that max_pages_per_rpc
23192         # is the same across all OSCs
23193         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
23194         local bulk_size=$((max_pages * PAGE_SIZE))
23195         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
23196                                        head -n 1)
23197
23198         mkdir -p $DIR/$tdir
23199         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
23200                 error "failed to set stripe with -S ${brw_size}M option"
23201         stack_trap "rm -rf $DIR/$tdir"
23202
23203         # clear the OSC stats
23204         $LCTL set_param osc.*.stats=0 &>/dev/null
23205         stop_writeback
23206
23207         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
23208         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
23209                 oflag=direct &>/dev/null || error "dd failed"
23210
23211         sync; sleep 1; sync # just to be safe
23212         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
23213         if [ x$nrpcs != "x1" ]; then
23214                 $LCTL get_param osc.*.stats
23215                 error "found $nrpcs ost_write RPCs, not 1 as expected"
23216         fi
23217
23218         start_writeback
23219         # Drop the OSC cache, otherwise we will read from it
23220         cancel_lru_locks osc
23221
23222         # clear the OSC stats
23223         $LCTL set_param osc.*.stats=0 &>/dev/null
23224
23225         # Client reads $bulk_size.
23226         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
23227                 iflag=direct &>/dev/null || error "dd failed"
23228
23229         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
23230         if [ x$nrpcs != "x1" ]; then
23231                 $LCTL get_param osc.*.stats
23232                 error "found $nrpcs ost_read RPCs, not 1 as expected"
23233         fi
23234 }
23235 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
23236
23237 test_231b() {
23238         mkdir -p $DIR/$tdir
23239         stack_trap "rm -rf $DIR/$tdir"
23240         local i
23241         for i in {0..1023}; do
23242                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
23243                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
23244                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
23245         done
23246         sync
23247 }
23248 run_test 231b "must not assert on fully utilized OST request buffer"
23249
23250 test_232a() {
23251         mkdir -p $DIR/$tdir
23252         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
23253
23254         #define OBD_FAIL_LDLM_OST_LVB            0x31c
23255         do_facet ost1 $LCTL set_param fail_loc=0x31c
23256
23257         # ignore dd failure
23258         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
23259         stack_trap "rm -f $DIR/$tdir/$tfile"
23260
23261         do_facet ost1 $LCTL set_param fail_loc=0
23262         umount_client $MOUNT || error "umount failed"
23263         mount_client $MOUNT || error "mount failed"
23264         stop ost1 || error "cannot stop ost1"
23265         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23266 }
23267 run_test 232a "failed lock should not block umount"
23268
23269 test_232b() {
23270         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
23271                 skip "Need MDS version at least 2.10.58"
23272
23273         mkdir -p $DIR/$tdir
23274         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
23275         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
23276         stack_trap "rm -f $DIR/$tdir/$tfile"
23277         sync
23278         cancel_lru_locks osc
23279
23280         #define OBD_FAIL_LDLM_OST_LVB            0x31c
23281         do_facet ost1 $LCTL set_param fail_loc=0x31c
23282
23283         # ignore failure
23284         $LFS data_version $DIR/$tdir/$tfile || true
23285
23286         do_facet ost1 $LCTL set_param fail_loc=0
23287         umount_client $MOUNT || error "umount failed"
23288         mount_client $MOUNT || error "mount failed"
23289         stop ost1 || error "cannot stop ost1"
23290         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23291 }
23292 run_test 232b "failed data version lock should not block umount"
23293
23294 test_233a() {
23295         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
23296                 skip "Need MDS version at least 2.3.64"
23297         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
23298
23299         local fid=$($LFS path2fid $MOUNT)
23300
23301         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23302                 error "cannot access $MOUNT using its FID '$fid'"
23303 }
23304 run_test 233a "checking that OBF of the FS root succeeds"
23305
23306 test_233b() {
23307         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
23308                 skip "Need MDS version at least 2.5.90"
23309         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
23310
23311         local fid=$($LFS path2fid $MOUNT/.lustre)
23312
23313         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23314                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
23315
23316         fid=$($LFS path2fid $MOUNT/.lustre/fid)
23317         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23318                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
23319 }
23320 run_test 233b "checking that OBF of the FS .lustre succeeds"
23321
23322 test_234() {
23323         local p="$TMP/sanityN-$TESTNAME.parameters"
23324         save_lustre_params client "llite.*.xattr_cache" > $p
23325         lctl set_param llite.*.xattr_cache 1 ||
23326                 skip_env "xattr cache is not supported"
23327
23328         mkdir -p $DIR/$tdir || error "mkdir failed"
23329         touch $DIR/$tdir/$tfile || error "touch failed"
23330         # OBD_FAIL_LLITE_XATTR_ENOMEM
23331         $LCTL set_param fail_loc=0x1405
23332         getfattr -n user.attr $DIR/$tdir/$tfile &&
23333                 error "getfattr should have failed with ENOMEM"
23334         $LCTL set_param fail_loc=0x0
23335         rm -rf $DIR/$tdir
23336
23337         restore_lustre_params < $p
23338         rm -f $p
23339 }
23340 run_test 234 "xattr cache should not crash on ENOMEM"
23341
23342 test_235() {
23343         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
23344                 skip "Need MDS version at least 2.4.52"
23345
23346         flock_deadlock $DIR/$tfile
23347         local RC=$?
23348         case $RC in
23349                 0)
23350                 ;;
23351                 124) error "process hangs on a deadlock"
23352                 ;;
23353                 *) error "error executing flock_deadlock $DIR/$tfile"
23354                 ;;
23355         esac
23356 }
23357 run_test 235 "LU-1715: flock deadlock detection does not work properly"
23358
23359 #LU-2935
23360 test_236() {
23361         check_swap_layouts_support
23362
23363         local ref1=/etc/passwd
23364         local ref2=/etc/group
23365         local file1=$DIR/$tdir/f1
23366         local file2=$DIR/$tdir/f2
23367
23368         test_mkdir -c1 $DIR/$tdir
23369         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
23370         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
23371         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
23372         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
23373         local fd=$(free_fd)
23374         local cmd="exec $fd<>$file2"
23375         eval $cmd
23376         rm $file2
23377         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
23378                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
23379         cmd="exec $fd>&-"
23380         eval $cmd
23381         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
23382
23383         #cleanup
23384         rm -rf $DIR/$tdir
23385 }
23386 run_test 236 "Layout swap on open unlinked file"
23387
23388 # LU-4659 linkea consistency
23389 test_238() {
23390         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
23391                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
23392                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
23393                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
23394
23395         touch $DIR/$tfile
23396         ln $DIR/$tfile $DIR/$tfile.lnk
23397         touch $DIR/$tfile.new
23398         mv $DIR/$tfile.new $DIR/$tfile
23399         local fid1=$($LFS path2fid $DIR/$tfile)
23400         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
23401         local path1=$($LFS fid2path $FSNAME "$fid1")
23402         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
23403         local path2=$($LFS fid2path $FSNAME "$fid2")
23404         [ $tfile.lnk == $path2 ] ||
23405                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
23406         rm -f $DIR/$tfile*
23407 }
23408 run_test 238 "Verify linkea consistency"
23409
23410 test_239A() { # was test_239
23411         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
23412                 skip "Need MDS version at least 2.5.60"
23413
23414         local list=$(comma_list $(mdts_nodes))
23415
23416         mkdir -p $DIR/$tdir
23417         createmany -o $DIR/$tdir/f- 5000
23418         unlinkmany $DIR/$tdir/f- 5000
23419         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
23420                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
23421         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
23422                         osp.*MDT*.sync_in_flight" | calc_sum)
23423         [ "$changes" -eq 0 ] || error "$changes not synced"
23424 }
23425 run_test 239A "osp_sync test"
23426
23427 test_239a() { #LU-5297
23428         remote_mds_nodsh && skip "remote MDS with nodsh"
23429
23430         touch $DIR/$tfile
23431         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
23432         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
23433         chgrp $RUNAS_GID $DIR/$tfile
23434         wait_delete_completed
23435 }
23436 run_test 239a "process invalid osp sync record correctly"
23437
23438 test_239b() { #LU-5297
23439         remote_mds_nodsh && skip "remote MDS with nodsh"
23440
23441         touch $DIR/$tfile1
23442         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
23443         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
23444         chgrp $RUNAS_GID $DIR/$tfile1
23445         wait_delete_completed
23446         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
23447         touch $DIR/$tfile2
23448         chgrp $RUNAS_GID $DIR/$tfile2
23449         wait_delete_completed
23450 }
23451 run_test 239b "process osp sync record with ENOMEM error correctly"
23452
23453 test_240() {
23454         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23455         remote_mds_nodsh && skip "remote MDS with nodsh"
23456
23457         mkdir -p $DIR/$tdir
23458
23459         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
23460                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
23461         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
23462                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
23463
23464         umount_client $MOUNT || error "umount failed"
23465         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
23466         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
23467         mount_client $MOUNT || error "failed to mount client"
23468
23469         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
23470         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
23471 }
23472 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
23473
23474 test_241_bio() {
23475         local count=$1
23476         local bsize=$2
23477
23478         for LOOP in $(seq $count); do
23479                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
23480                 cancel_lru_locks $OSC || true
23481         done
23482 }
23483
23484 test_241_dio() {
23485         local count=$1
23486         local bsize=$2
23487
23488         for LOOP in $(seq $1); do
23489                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
23490                         2>/dev/null
23491         done
23492 }
23493
23494 test_241a() { # was test_241
23495         local bsize=$PAGE_SIZE
23496
23497         (( bsize < 40960 )) && bsize=40960
23498         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
23499         ls -la $DIR/$tfile
23500         cancel_lru_locks $OSC
23501         test_241_bio 1000 $bsize &
23502         PID=$!
23503         test_241_dio 1000 $bsize
23504         wait $PID
23505 }
23506 run_test 241a "bio vs dio"
23507
23508 test_241b() {
23509         local bsize=$PAGE_SIZE
23510
23511         (( bsize < 40960 )) && bsize=40960
23512         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
23513         ls -la $DIR/$tfile
23514         test_241_dio 1000 $bsize &
23515         PID=$!
23516         test_241_dio 1000 $bsize
23517         wait $PID
23518 }
23519 run_test 241b "dio vs dio"
23520
23521 test_242() {
23522         remote_mds_nodsh && skip "remote MDS with nodsh"
23523
23524         mkdir_on_mdt0 $DIR/$tdir
23525         touch $DIR/$tdir/$tfile
23526
23527         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
23528         do_facet mds1 lctl set_param fail_loc=0x105
23529         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
23530
23531         do_facet mds1 lctl set_param fail_loc=0
23532         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
23533 }
23534 run_test 242 "mdt_readpage failure should not cause directory unreadable"
23535
23536 test_243()
23537 {
23538         test_mkdir $DIR/$tdir
23539         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
23540 }
23541 run_test 243 "various group lock tests"
23542
23543 test_244a()
23544 {
23545         test_mkdir $DIR/$tdir
23546         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
23547         sendfile_grouplock $DIR/$tdir/$tfile || \
23548                 error "sendfile+grouplock failed"
23549         rm -rf $DIR/$tdir
23550 }
23551 run_test 244a "sendfile with group lock tests"
23552
23553 test_244b()
23554 {
23555         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23556
23557         local threads=50
23558         local size=$((1024*1024))
23559
23560         test_mkdir $DIR/$tdir
23561         for i in $(seq 1 $threads); do
23562                 local file=$DIR/$tdir/file_$((i / 10))
23563                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
23564                 local pids[$i]=$!
23565         done
23566         for i in $(seq 1 $threads); do
23567                 wait ${pids[$i]}
23568         done
23569 }
23570 run_test 244b "multi-threaded write with group lock"
23571
23572 test_245a() {
23573         local flagname="multi_mod_rpcs"
23574         local connect_data_name="max_mod_rpcs"
23575         local out
23576
23577         # check if multiple modify RPCs flag is set
23578         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
23579                 grep "connect_flags:")
23580         echo "$out"
23581
23582         echo "$out" | grep -qw $flagname
23583         if [ $? -ne 0 ]; then
23584                 echo "connect flag $flagname is not set"
23585                 return
23586         fi
23587
23588         # check if multiple modify RPCs data is set
23589         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
23590         echo "$out"
23591
23592         echo "$out" | grep -qw $connect_data_name ||
23593                 error "import should have connect data $connect_data_name"
23594 }
23595 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
23596
23597 test_245b() {
23598         local flagname="multi_mod_rpcs"
23599         local connect_data_name="max_mod_rpcs"
23600         local out
23601
23602         remote_mds_nodsh && skip "remote MDS with nodsh"
23603         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
23604
23605         # check if multiple modify RPCs flag is set
23606         out=$(do_facet mds1 \
23607               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
23608               grep "connect_flags:")
23609         echo "$out"
23610
23611         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
23612
23613         # check if multiple modify RPCs data is set
23614         out=$(do_facet mds1 \
23615               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
23616
23617         [[ "$out" =~ $connect_data_name ]] ||
23618                 {
23619                         echo "$out"
23620                         error "missing connect data $connect_data_name"
23621                 }
23622 }
23623 run_test 245b "check osp connection flag/data: multiple modify RPCs"
23624
23625 cleanup_247() {
23626         local submount=$1
23627
23628         trap 0
23629         umount_client $submount
23630         rmdir $submount
23631 }
23632
23633 test_247a() {
23634         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23635                 grep -q subtree ||
23636                 skip_env "Fileset feature is not supported"
23637
23638         local submount=${MOUNT}_$tdir
23639
23640         mkdir $MOUNT/$tdir
23641         mkdir -p $submount || error "mkdir $submount failed"
23642         FILESET="$FILESET/$tdir" mount_client $submount ||
23643                 error "mount $submount failed"
23644         trap "cleanup_247 $submount" EXIT
23645         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
23646         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
23647                 error "read $MOUNT/$tdir/$tfile failed"
23648         cleanup_247 $submount
23649 }
23650 run_test 247a "mount subdir as fileset"
23651
23652 test_247b() {
23653         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23654                 skip_env "Fileset feature is not supported"
23655
23656         local submount=${MOUNT}_$tdir
23657
23658         rm -rf $MOUNT/$tdir
23659         mkdir -p $submount || error "mkdir $submount failed"
23660         SKIP_FILESET=1
23661         FILESET="$FILESET/$tdir" mount_client $submount &&
23662                 error "mount $submount should fail"
23663         rmdir $submount
23664 }
23665 run_test 247b "mount subdir that dose not exist"
23666
23667 test_247c() {
23668         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23669                 skip_env "Fileset feature is not supported"
23670
23671         local submount=${MOUNT}_$tdir
23672
23673         mkdir -p $MOUNT/$tdir/dir1
23674         mkdir -p $submount || error "mkdir $submount failed"
23675         trap "cleanup_247 $submount" EXIT
23676         FILESET="$FILESET/$tdir" mount_client $submount ||
23677                 error "mount $submount failed"
23678         local fid=$($LFS path2fid $MOUNT/)
23679         $LFS fid2path $submount $fid && error "fid2path should fail"
23680         cleanup_247 $submount
23681 }
23682 run_test 247c "running fid2path outside subdirectory root"
23683
23684 test_247d() {
23685         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23686                 skip "Fileset feature is not supported"
23687
23688         local submount=${MOUNT}_$tdir
23689
23690         mkdir -p $MOUNT/$tdir/dir1
23691         mkdir -p $submount || error "mkdir $submount failed"
23692         FILESET="$FILESET/$tdir" mount_client $submount ||
23693                 error "mount $submount failed"
23694         trap "cleanup_247 $submount" EXIT
23695
23696         local td=$submount/dir1
23697         local fid=$($LFS path2fid $td)
23698         [ -z "$fid" ] && error "path2fid unable to get $td FID"
23699
23700         # check that we get the same pathname back
23701         local rootpath
23702         local found
23703         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
23704                 echo "$rootpath $fid"
23705                 found=$($LFS fid2path $rootpath "$fid")
23706                 [ -n "$found" ] || error "fid2path should succeed"
23707                 [ "$found" == "$td" ] || error "fid2path $found != $td"
23708         done
23709         # check wrong root path format
23710         rootpath=$submount"_wrong"
23711         found=$($LFS fid2path $rootpath "$fid")
23712         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
23713
23714         cleanup_247 $submount
23715 }
23716 run_test 247d "running fid2path inside subdirectory root"
23717
23718 # LU-8037
23719 test_247e() {
23720         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23721                 grep -q subtree ||
23722                 skip "Fileset feature is not supported"
23723
23724         local submount=${MOUNT}_$tdir
23725
23726         mkdir $MOUNT/$tdir
23727         mkdir -p $submount || error "mkdir $submount failed"
23728         FILESET="$FILESET/.." mount_client $submount &&
23729                 error "mount $submount should fail"
23730         rmdir $submount
23731 }
23732 run_test 247e "mount .. as fileset"
23733
23734 test_247f() {
23735         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
23736         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
23737                 skip "Need at least version 2.14.50.162"
23738         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23739                 skip "Fileset feature is not supported"
23740
23741         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
23742         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
23743                 error "mkdir remote failed"
23744         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
23745                 error "mkdir remote/subdir failed"
23746         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
23747                 error "mkdir striped failed"
23748         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
23749
23750         local submount=${MOUNT}_$tdir
23751
23752         mkdir -p $submount || error "mkdir $submount failed"
23753         stack_trap "rmdir $submount"
23754
23755         local dir
23756         local fileset=$FILESET
23757         local mdts=$(comma_list $(mdts_nodes))
23758
23759         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
23760         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
23761                 $tdir/striped/subdir $tdir/striped/.; do
23762                 FILESET="$fileset/$dir" mount_client $submount ||
23763                         error "mount $dir failed"
23764                 umount_client $submount
23765         done
23766 }
23767 run_test 247f "mount striped or remote directory as fileset"
23768
23769 test_subdir_mount_lock()
23770 {
23771         local testdir=$1
23772         local submount=${MOUNT}_$(basename $testdir)
23773
23774         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
23775
23776         mkdir -p $submount || error "mkdir $submount failed"
23777         stack_trap "rmdir $submount"
23778
23779         FILESET="$fileset/$testdir" mount_client $submount ||
23780                 error "mount $FILESET failed"
23781         stack_trap "umount $submount"
23782
23783         local mdts=$(comma_list $(mdts_nodes))
23784
23785         local nrpcs
23786
23787         stat $submount > /dev/null || error "stat $submount failed"
23788         cancel_lru_locks $MDC
23789         stat $submount > /dev/null || error "stat $submount failed"
23790         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23791         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
23792         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23793         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
23794                 awk '/getattr/ {sum += $2} END {print sum}')
23795
23796         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
23797 }
23798
23799 test_247g() {
23800         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23801
23802         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
23803                 error "mkdir $tdir failed"
23804         test_subdir_mount_lock $tdir
23805 }
23806 run_test 247g "striped directory submount revalidate ROOT from cache"
23807
23808 test_247h() {
23809         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23810         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
23811                 skip "Need MDS version at least 2.15.51"
23812
23813         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23814         test_subdir_mount_lock $tdir
23815         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
23816         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
23817                 error "mkdir $tdir.1 failed"
23818         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
23819 }
23820 run_test 247h "remote directory submount revalidate ROOT from cache"
23821
23822 test_248a() {
23823         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
23824         [ -z "$fast_read_sav" ] && skip "no fast read support"
23825
23826         # create a large file for fast read verification
23827         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
23828
23829         # make sure the file is created correctly
23830         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
23831                 { rm -f $DIR/$tfile; skip "file creation error"; }
23832
23833         echo "Test 1: verify that fast read is 4 times faster on cache read"
23834
23835         # small read with fast read enabled
23836         $LCTL set_param -n llite.*.fast_read=1
23837         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23838                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23839                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23840         # small read with fast read disabled
23841         $LCTL set_param -n llite.*.fast_read=0
23842         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23843                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23844                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23845
23846         # verify that fast read is 4 times faster for cache read
23847         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
23848                 error_not_in_vm "fast read was not 4 times faster: " \
23849                            "$t_fast vs $t_slow"
23850
23851         echo "Test 2: verify the performance between big and small read"
23852         $LCTL set_param -n llite.*.fast_read=1
23853
23854         # 1k non-cache read
23855         cancel_lru_locks osc
23856         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23857                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23858                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23859
23860         # 1M non-cache read
23861         cancel_lru_locks osc
23862         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23863                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23864                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23865
23866         # verify that big IO is not 4 times faster than small IO
23867         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
23868                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
23869
23870         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
23871         rm -f $DIR/$tfile
23872 }
23873 run_test 248a "fast read verification"
23874
23875 test_248b() {
23876         # Default short_io_bytes=16384, try both smaller and larger sizes.
23877         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
23878         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
23879         echo "bs=53248 count=113 normal buffered write"
23880         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
23881                 error "dd of initial data file failed"
23882         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
23883
23884         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
23885         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
23886                 error "dd with sync normal writes failed"
23887         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
23888
23889         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
23890         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
23891                 error "dd with sync small writes failed"
23892         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
23893
23894         cancel_lru_locks osc
23895
23896         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
23897         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
23898         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
23899         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
23900                 iflag=direct || error "dd with O_DIRECT small read failed"
23901         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
23902         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
23903                 error "compare $TMP/$tfile.1 failed"
23904
23905         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
23906         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
23907
23908         # just to see what the maximum tunable value is, and test parsing
23909         echo "test invalid parameter 2MB"
23910         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
23911                 error "too-large short_io_bytes allowed"
23912         echo "test maximum parameter 512KB"
23913         # if we can set a larger short_io_bytes, run test regardless of version
23914         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
23915                 # older clients may not allow setting it this large, that's OK
23916                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
23917                         skip "Need at least client version 2.13.50"
23918                 error "medium short_io_bytes failed"
23919         fi
23920         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23921         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
23922
23923         echo "test large parameter 64KB"
23924         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
23925         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23926
23927         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
23928         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
23929                 error "dd with sync large writes failed"
23930         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
23931
23932         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
23933         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
23934         num=$((113 * 4096 / PAGE_SIZE))
23935         echo "bs=$size count=$num oflag=direct large write $tfile.3"
23936         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
23937                 error "dd with O_DIRECT large writes failed"
23938         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
23939                 error "compare $DIR/$tfile.3 failed"
23940
23941         cancel_lru_locks osc
23942
23943         echo "bs=$size count=$num iflag=direct large read $tfile.2"
23944         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
23945                 error "dd with O_DIRECT large read failed"
23946         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
23947                 error "compare $TMP/$tfile.2 failed"
23948
23949         echo "bs=$size count=$num iflag=direct large read $tfile.3"
23950         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
23951                 error "dd with O_DIRECT large read failed"
23952         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
23953                 error "compare $TMP/$tfile.3 failed"
23954 }
23955 run_test 248b "test short_io read and write for both small and large sizes"
23956
23957 test_248c() {
23958         $LCTL set_param llite.*.read_ahead_stats=c
23959         # This test compares whole file readahead to non-whole file readahead
23960         # The performance should be consistently slightly faster for whole file,
23961         # and the bug caused whole file readahead to be 80-100x slower, but to
23962         # account for possible test system lag, we require whole file to be
23963         # <= 1.5xnon-whole file, and require 3 failures in a row to fail the
23964         # test
23965         local time1
23966         local time2
23967         local whole_mb=$($LCTL get_param -n llite.*.max_read_ahead_whole_mb)
23968         stack_trap "$LCTL set_param llite.*.max_read_ahead_whole_mb=$whole_mb" EXIT
23969         counter=0
23970
23971         while [ $counter -lt 3 ]; do
23972                 # Increment the counter
23973                 ((counter++))
23974
23975                 $LCTL set_param llite.*.max_read_ahead_whole_mb=64
23976                 rm -f $DIR/$tfile
23977                 touch $DIR/$tfile || error "(0) failed to create file"
23978                 # 64 MiB
23979                 $TRUNCATE $DIR/$tfile 67108864 || error "(1) failed to truncate file"
23980                 time1=$(dd if=$DIR/$tfile bs=4K of=/dev/null 2>&1 | awk '/bytes/ {print $8}')
23981                 echo "whole file readahead of 64 MiB took $time1 seconds"
23982                 $LCTL get_param llite.*.read_ahead_stats
23983
23984                 $LCTL set_param llite.*.read_ahead_stats=c
23985                 $LCTL set_param llite.*.max_read_ahead_whole_mb=8
23986                 rm -f $DIR/$tfile
23987                 touch $DIR/$tfile || error "(2) failed to create file"
23988                 # 64 MiB
23989                 $TRUNCATE $DIR/$tfile 67108864 || error "(3) failed to create file"
23990                 time2=$(dd if=$DIR/$tfile bs=4K of=/dev/null 2>&1 | awk '/bytes/ {print $8}')
23991                 echo "non-whole file readahead of 64 MiB took $time2 seconds"
23992                 $LCTL get_param llite.*.read_ahead_stats
23993
23994                 # Check if time1 is not more than 1.5 times2
23995                 timecheck=$(echo "$time1 <= (1.5 * $time2)" | bc -l)
23996
23997                 if [[ $timecheck -eq 1 ]]; then
23998                         echo "Test passed on attempt $counter"
23999                         # Exit the loop
24000                         counter=4
24001                 else
24002                         echo "Attempt $counter failed: whole file readahead took: $time1, greater than non: $time2"
24003                 fi
24004         done
24005         if [ $counter -eq 3 ]; then
24006                 error "whole file readahead check failed 3 times in a row, probably not just VM lag"
24007         fi
24008
24009 }
24010 run_test 248c "verify whole file read behavior"
24011
24012 test_249() { # LU-7890
24013         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
24014                 skip "Need at least version 2.8.54"
24015
24016         rm -f $DIR/$tfile
24017         $LFS setstripe -c 1 $DIR/$tfile
24018         # Offset 2T == 4k * 512M
24019         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
24020                 error "dd to 2T offset failed"
24021 }
24022 run_test 249 "Write above 2T file size"
24023
24024 test_250() {
24025         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
24026          && skip "no 16TB file size limit on ZFS"
24027
24028         $LFS setstripe -c 1 $DIR/$tfile
24029         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
24030         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
24031         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
24032         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
24033                 conv=notrunc,fsync && error "append succeeded"
24034         return 0
24035 }
24036 run_test 250 "Write above 16T limit"
24037
24038 test_251a() {
24039         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
24040
24041         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
24042         #Skip once - writing the first stripe will succeed
24043         $LCTL set_param fail_loc=0xa0001407 fail_val=1
24044         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
24045                 error "short write happened"
24046
24047         $LCTL set_param fail_loc=0xa0001407 fail_val=1
24048         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
24049                 error "short read happened"
24050
24051         rm -f $DIR/$tfile
24052 }
24053 run_test 251a "Handling short read and write correctly"
24054
24055 test_251b() {
24056         dd if=/dev/zero of=$DIR/$tfile bs=1k count=4 ||
24057                 error "write $tfile failed"
24058
24059         sleep 2 && echo 12345 >> $DIR/$tfile &
24060
24061         #define OBD_FAIL_LLITE_READ_PAUSE 0x1431
24062         $LCTL set_param fail_loc=0x1431 fail_val=5
24063         # seek to 4096, 2 seconds later, file size expand to 4102, and after
24064         # 5 seconds, read 10 bytes, the short read should
24065         # report:
24066         #                start ->+ read_len -> offset_after_read read_count
24067         #     short read: 4096 ->+ 10 -> 4096 0
24068         # not:
24069         #     short read: 4096 ->+ 10 -> 4102 0
24070         local off=$($MULTIOP $DIR/$tfile oO_RDONLY:z4096r10c 2>&1 | \
24071                         awk '/short read/ { print $7 }')
24072         (( off == 4096 )) ||
24073                 error "short read should set offset at 4096, not $off"
24074 }
24075 run_test 251b "short read restore offset correctly"
24076
24077 test_252() {
24078         remote_mds_nodsh && skip "remote MDS with nodsh"
24079         remote_ost_nodsh && skip "remote OST with nodsh"
24080         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
24081                 skip_env "ldiskfs only test"
24082         fi
24083
24084         local tgt
24085         local dev
24086         local out
24087         local uuid
24088         local num
24089         local gen
24090
24091         # check lr_reader on OST0000
24092         tgt=ost1
24093         dev=$(facet_device $tgt)
24094         out=$(do_facet $tgt $LR_READER $dev)
24095         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
24096         echo "$out"
24097         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
24098         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
24099                 error "Invalid uuid returned by $LR_READER on target $tgt"
24100         echo -e "uuid returned by $LR_READER is '$uuid'\n"
24101
24102         # check lr_reader -c on MDT0000
24103         tgt=mds1
24104         dev=$(facet_device $tgt)
24105         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
24106                 skip "$LR_READER does not support additional options"
24107         fi
24108         out=$(do_facet $tgt $LR_READER -c $dev)
24109         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
24110         echo "$out"
24111         num=$(echo "$out" | grep -c "mdtlov")
24112         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
24113                 error "Invalid number of mdtlov clients returned by $LR_READER"
24114         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
24115
24116         # check lr_reader -cr on MDT0000
24117         out=$(do_facet $tgt $LR_READER -cr $dev)
24118         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
24119         echo "$out"
24120         echo "$out" | grep -q "^reply_data:$" ||
24121                 error "$LR_READER should have returned 'reply_data' section"
24122         num=$(echo "$out" | grep -c "client_generation")
24123         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
24124 }
24125 run_test 252 "check lr_reader tool"
24126
24127 test_253() {
24128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24129         remote_mds_nodsh && skip "remote MDS with nodsh"
24130         remote_mgs_nodsh && skip "remote MGS with nodsh"
24131         check_set_fallocate_or_skip
24132
24133         local ostidx=0
24134         local rc=0
24135         local ost_name=$(ostname_from_index $ostidx)
24136
24137         # on the mdt's osc
24138         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
24139         do_facet $SINGLEMDS $LCTL get_param -n \
24140                 osp.$mdtosc_proc1.reserved_mb_high ||
24141                 skip  "remote MDS does not support reserved_mb_high"
24142
24143         rm -rf $DIR/$tdir
24144         wait_mds_ost_sync
24145         wait_delete_completed
24146         mkdir $DIR/$tdir
24147         stack_trap "rm -rf $DIR/$tdir"
24148
24149         pool_add $TESTNAME || error "Pool creation failed"
24150         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
24151
24152         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
24153                 error "Setstripe failed"
24154
24155         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
24156
24157         local wms=$(ost_watermarks_get $ostidx)
24158
24159         ost_watermarks_set $ostidx 60 50
24160         stack_trap "ost_watermarks_set $ostidx $wms"
24161
24162         local free_kb=$($LFS df $MOUNT | awk "/$ost_name/ { print \$4 }")
24163         local size=$((free_kb * 1024))
24164
24165         fallocate -l $size $DIR/$tdir/fill_ost$ostidx ||
24166                 error "fallocate failed"
24167         sleep_maxage
24168
24169         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
24170                         osp.$mdtosc_proc1.prealloc_status)
24171         echo "prealloc_status $oa_status"
24172
24173         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
24174                 error "File creation should fail"
24175
24176         #object allocation was stopped, but we still able to append files
24177         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
24178                 oflag=append || error "Append failed"
24179
24180         rm -f $DIR/$tdir/$tfile.0
24181         rm -f $DIR/$tdir/fill_ost$ostidx
24182
24183         wait_delete_completed
24184         sleep_maxage
24185
24186         for i in $(seq 10 12); do
24187                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
24188                         2>/dev/null || error "File creation failed after rm"
24189         done
24190
24191         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
24192                         osp.$mdtosc_proc1.prealloc_status)
24193         echo "prealloc_status $oa_status"
24194
24195         if (( oa_status != 0 )); then
24196                 error "Object allocation still disable after rm"
24197         fi
24198 }
24199 run_test 253 "Check object allocation limit"
24200
24201 test_254() {
24202         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24203         remote_mds_nodsh && skip "remote MDS with nodsh"
24204
24205         local mdt=$(facet_svc $SINGLEMDS)
24206
24207         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
24208                 skip "MDS does not support changelog_size"
24209
24210         local cl_user
24211
24212         changelog_register || error "changelog_register failed"
24213
24214         changelog_clear 0 || error "changelog_clear failed"
24215
24216         local size1=$(do_facet $SINGLEMDS \
24217                       $LCTL get_param -n mdd.$mdt.changelog_size)
24218         echo "Changelog size $size1"
24219
24220         rm -rf $DIR/$tdir
24221         $LFS mkdir -i 0 $DIR/$tdir
24222         # change something
24223         mkdir -p $DIR/$tdir/pics/2008/zachy
24224         touch $DIR/$tdir/pics/2008/zachy/timestamp
24225         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
24226         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
24227         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
24228         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
24229         rm $DIR/$tdir/pics/desktop.jpg
24230
24231         local size2=$(do_facet $SINGLEMDS \
24232                       $LCTL get_param -n mdd.$mdt.changelog_size)
24233         echo "Changelog size after work $size2"
24234
24235         (( $size2 > $size1 )) ||
24236                 error "new Changelog size=$size2 less than old size=$size1"
24237 }
24238 run_test 254 "Check changelog size"
24239
24240 ladvise_no_type()
24241 {
24242         local type=$1
24243         local file=$2
24244
24245         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
24246                 awk -F: '{print $2}' | grep $type > /dev/null
24247         if [ $? -ne 0 ]; then
24248                 return 0
24249         fi
24250         return 1
24251 }
24252
24253 ladvise_no_ioctl()
24254 {
24255         local file=$1
24256
24257         lfs ladvise -a willread $file > /dev/null 2>&1
24258         if [ $? -eq 0 ]; then
24259                 return 1
24260         fi
24261
24262         lfs ladvise -a willread $file 2>&1 |
24263                 grep "Inappropriate ioctl for device" > /dev/null
24264         if [ $? -eq 0 ]; then
24265                 return 0
24266         fi
24267         return 1
24268 }
24269
24270 percent() {
24271         bc <<<"scale=2; ($1 - $2) * 100 / $2"
24272 }
24273
24274 # run a random read IO workload
24275 # usage: random_read_iops <filename> <filesize> <iosize>
24276 random_read_iops() {
24277         local file=$1
24278         local fsize=$2
24279         local iosize=${3:-4096}
24280
24281         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
24282                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
24283 }
24284
24285 drop_file_oss_cache() {
24286         local file="$1"
24287         local nodes="$2"
24288
24289         $LFS ladvise -a dontneed $file 2>/dev/null ||
24290                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
24291 }
24292
24293 ladvise_willread_performance()
24294 {
24295         local repeat=10
24296         local average_origin=0
24297         local average_cache=0
24298         local average_ladvise=0
24299
24300         for ((i = 1; i <= $repeat; i++)); do
24301                 echo "Iter $i/$repeat: reading without willread hint"
24302                 cancel_lru_locks osc
24303                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
24304                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
24305                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
24306                 average_origin=$(bc <<<"$average_origin + $speed_origin")
24307
24308                 cancel_lru_locks osc
24309                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
24310                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
24311                 average_cache=$(bc <<<"$average_cache + $speed_cache")
24312
24313                 cancel_lru_locks osc
24314                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
24315                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
24316                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
24317                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
24318                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
24319         done
24320         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
24321         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
24322         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
24323
24324         speedup_cache=$(percent $average_cache $average_origin)
24325         speedup_ladvise=$(percent $average_ladvise $average_origin)
24326
24327         echo "Average uncached read: $average_origin"
24328         echo "Average speedup with OSS cached read:" \
24329                 "$average_cache = +$speedup_cache%"
24330         echo "Average speedup with ladvise willread:" \
24331                 "$average_ladvise = +$speedup_ladvise%"
24332
24333         local lowest_speedup=20
24334         if (( ${speedup_cache%.*} < $lowest_speedup )); then
24335                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
24336                      "got $speedup_cache%. Skipping ladvise willread check."
24337                 return 0
24338         fi
24339
24340         # the test won't work on ZFS until it supports 'ladvise dontneed', but
24341         # it is still good to run until then to exercise 'ladvise willread'
24342         ! $LFS ladvise -a dontneed $DIR/$tfile &&
24343                 [ "$ost1_FSTYPE" = "zfs" ] &&
24344                 echo "osd-zfs does not support dontneed or drop_caches" &&
24345                 return 0
24346
24347         lowest_speedup=$(bc <<<"scale=2; $speedup_cache / 2")
24348         (( ${speedup_ladvise%.*} > ${lowest_speedup%.*} )) ||
24349                 error_not_in_vm "Speedup with willread is less than " \
24350                         "$lowest_speedup%, got $speedup_ladvise%"
24351 }
24352
24353 test_255a() {
24354         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
24355                 skip "lustre < 2.8.54 does not support ladvise "
24356         remote_ost_nodsh && skip "remote OST with nodsh"
24357
24358         stack_trap "rm -f $DIR/$tfile"
24359         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
24360
24361         ladvise_no_type willread $DIR/$tfile &&
24362                 skip "willread ladvise is not supported"
24363
24364         ladvise_no_ioctl $DIR/$tfile &&
24365                 skip "ladvise ioctl is not supported"
24366
24367         local size_mb=100
24368         local size=$((size_mb * 1048576))
24369         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
24370                 error "dd to $DIR/$tfile failed"
24371
24372         lfs ladvise -a willread $DIR/$tfile ||
24373                 error "Ladvise failed with no range argument"
24374
24375         lfs ladvise -a willread -s 0 $DIR/$tfile ||
24376                 error "Ladvise failed with no -l or -e argument"
24377
24378         lfs ladvise -a willread -e 1 $DIR/$tfile ||
24379                 error "Ladvise failed with only -e argument"
24380
24381         lfs ladvise -a willread -l 1 $DIR/$tfile ||
24382                 error "Ladvise failed with only -l argument"
24383
24384         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
24385                 error "End offset should not be smaller than start offset"
24386
24387         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
24388                 error "End offset should not be equal to start offset"
24389
24390         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
24391                 error "Ladvise failed with overflowing -s argument"
24392
24393         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
24394                 error "Ladvise failed with overflowing -e argument"
24395
24396         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
24397                 error "Ladvise failed with overflowing -l argument"
24398
24399         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
24400                 error "Ladvise succeeded with conflicting -l and -e arguments"
24401
24402         echo "Synchronous ladvise should wait"
24403         local delay=8
24404 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
24405         do_nodes $(comma_list $(osts_nodes)) \
24406                 $LCTL set_param fail_val=$delay fail_loc=0x237
24407         stack_trap "do_nodes $(comma_list $(osts_nodes)) \
24408                 $LCTL set_param fail_loc=0"
24409
24410         local start_ts=$SECONDS
24411         lfs ladvise -a willread $DIR/$tfile ||
24412                 error "Ladvise failed with no range argument"
24413         local end_ts=$SECONDS
24414         local inteval_ts=$((end_ts - start_ts))
24415
24416         if [ $inteval_ts -lt $(($delay - 1)) ]; then
24417                 error "Synchronous advice didn't wait reply"
24418         fi
24419
24420         echo "Asynchronous ladvise shouldn't wait"
24421         local start_ts=$SECONDS
24422         lfs ladvise -a willread -b $DIR/$tfile ||
24423                 error "Ladvise failed with no range argument"
24424         local end_ts=$SECONDS
24425         local inteval_ts=$((end_ts - start_ts))
24426
24427         if [ $inteval_ts -gt $(($delay / 2)) ]; then
24428                 error "Asynchronous advice blocked"
24429         fi
24430
24431         ladvise_willread_performance
24432 }
24433 run_test 255a "check 'lfs ladvise -a willread'"
24434
24435 facet_meminfo() {
24436         local facet=$1
24437         local info=$2
24438
24439         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
24440 }
24441
24442 test_255b() {
24443         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
24444                 skip "lustre < 2.8.54 does not support ladvise "
24445         remote_ost_nodsh && skip "remote OST with nodsh"
24446
24447         stack_trap "rm -f $DIR/$tfile"
24448         lfs setstripe -c 1 -i 0 $DIR/$tfile
24449
24450         ladvise_no_type dontneed $DIR/$tfile &&
24451                 skip "dontneed ladvise is not supported"
24452
24453         ladvise_no_ioctl $DIR/$tfile &&
24454                 skip "ladvise ioctl is not supported"
24455
24456         ! $LFS ladvise -a dontneed $DIR/$tfile &&
24457                 [ "$ost1_FSTYPE" = "zfs" ] &&
24458                 skip "zfs-osd does not support 'ladvise dontneed'"
24459
24460         local size_mb=100
24461         local size=$((size_mb * 1048576))
24462         # In order to prevent disturbance of other processes, only check 3/4
24463         # of the memory usage
24464         local kibibytes=$((size_mb * 1024 * 3 / 4))
24465
24466         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
24467                 error "dd to $DIR/$tfile failed"
24468
24469         #force write to complete before dropping OST cache & checking memory
24470         sync
24471
24472         local total=$(facet_meminfo ost1 MemTotal)
24473         echo "Total memory: $total KiB"
24474
24475         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
24476         local before_read=$(facet_meminfo ost1 Cached)
24477         echo "Cache used before read: $before_read KiB"
24478
24479         lfs ladvise -a willread $DIR/$tfile ||
24480                 error "Ladvise willread failed"
24481         local after_read=$(facet_meminfo ost1 Cached)
24482         echo "Cache used after read: $after_read KiB"
24483
24484         lfs ladvise -a dontneed $DIR/$tfile ||
24485                 error "Ladvise dontneed again failed"
24486         local no_read=$(facet_meminfo ost1 Cached)
24487         echo "Cache used after dontneed ladvise: $no_read KiB"
24488
24489         if [ $total -lt $((before_read + kibibytes)) ]; then
24490                 echo "Memory is too small, abort checking"
24491                 return 0
24492         fi
24493
24494         if [ $((before_read + kibibytes)) -gt $after_read ]; then
24495                 error "Ladvise willread should use more memory" \
24496                         "than $kibibytes KiB"
24497         fi
24498
24499         if [ $((no_read + kibibytes)) -gt $after_read ]; then
24500                 error "Ladvise dontneed should release more memory" \
24501                         "than $kibibytes KiB"
24502         fi
24503 }
24504 run_test 255b "check 'lfs ladvise -a dontneed'"
24505
24506 test_255c() {
24507         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
24508                 skip "lustre < 2.10.50 does not support lockahead"
24509
24510         local ost1_imp=$(get_osc_import_name client ost1)
24511         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24512                          cut -d'.' -f2)
24513         local count
24514         local new_count
24515         local difference
24516         local i
24517         local rc
24518
24519         test_mkdir -p $DIR/$tdir
24520         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24521
24522         #test 10 returns only success/failure
24523         i=10
24524         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24525         rc=$?
24526         if [ $rc -eq 255 ]; then
24527                 error "Ladvise test${i} failed, ${rc}"
24528         fi
24529
24530         #test 11 counts lock enqueue requests, all others count new locks
24531         i=11
24532         count=$(do_facet ost1 \
24533                 $LCTL get_param -n ost.OSS.ost.stats)
24534         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
24535
24536         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24537         rc=$?
24538         if [ $rc -eq 255 ]; then
24539                 error "Ladvise test${i} failed, ${rc}"
24540         fi
24541
24542         new_count=$(do_facet ost1 \
24543                 $LCTL get_param -n ost.OSS.ost.stats)
24544         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
24545                    awk '{ print $2 }')
24546
24547         difference="$((new_count - count))"
24548         if [ $difference -ne $rc ]; then
24549                 error "Ladvise test${i}, bad enqueue count, returned " \
24550                       "${rc}, actual ${difference}"
24551         fi
24552
24553         for i in $(seq 12 21); do
24554                 # If we do not do this, we run the risk of having too many
24555                 # locks and starting lock cancellation while we are checking
24556                 # lock counts.
24557                 cancel_lru_locks osc
24558
24559                 count=$($LCTL get_param -n \
24560                        ldlm.namespaces.$imp_name.lock_unused_count)
24561
24562                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
24563                 rc=$?
24564                 if [ $rc -eq 255 ]; then
24565                         error "Ladvise test ${i} failed, ${rc}"
24566                 fi
24567
24568                 new_count=$($LCTL get_param -n \
24569                        ldlm.namespaces.$imp_name.lock_unused_count)
24570                 difference="$((new_count - count))"
24571
24572                 # Test 15 output is divided by 100 to map down to valid return
24573                 if [ $i -eq 15 ]; then
24574                         rc="$((rc * 100))"
24575                 fi
24576
24577                 if [ $difference -ne $rc ]; then
24578                         error "Ladvise test ${i}, bad lock count, returned " \
24579                               "${rc}, actual ${difference}"
24580                 fi
24581         done
24582
24583         #test 22 returns only success/failure
24584         i=22
24585         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24586         rc=$?
24587         if [ $rc -eq 255 ]; then
24588                 error "Ladvise test${i} failed, ${rc}"
24589         fi
24590 }
24591 run_test 255c "suite of ladvise lockahead tests"
24592
24593 test_256() {
24594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24595         remote_mds_nodsh && skip "remote MDS with nodsh"
24596         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
24597         changelog_users $SINGLEMDS | grep "^cl" &&
24598                 skip "active changelog user"
24599
24600         local cl_user
24601         local cat_sl
24602         local mdt_dev
24603
24604         mdt_dev=$(facet_device $SINGLEMDS)
24605         echo $mdt_dev
24606
24607         changelog_register || error "changelog_register failed"
24608
24609         rm -rf $DIR/$tdir
24610         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
24611
24612         changelog_clear 0 || error "changelog_clear failed"
24613
24614         # change something
24615         touch $DIR/$tdir/{1..10}
24616
24617         # stop the MDT
24618         stop $SINGLEMDS || error "Fail to stop MDT"
24619
24620         # remount the MDT
24621         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
24622                 error "Fail to start MDT"
24623
24624         #after mount new plainllog is used
24625         touch $DIR/$tdir/{11..19}
24626         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
24627         stack_trap "rm -f $tmpfile"
24628         cat_sl=$(do_facet $SINGLEMDS "sync; \
24629                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24630                  llog_reader $tmpfile | grep -c type=1064553b")
24631         do_facet $SINGLEMDS llog_reader $tmpfile
24632
24633         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
24634
24635         changelog_clear 0 || error "changelog_clear failed"
24636
24637         cat_sl=$(do_facet $SINGLEMDS "sync; \
24638                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24639                  llog_reader $tmpfile | grep -c type=1064553b")
24640
24641         if (( cat_sl == 2 )); then
24642                 error "Empty plain llog was not deleted from changelog catalog"
24643         elif (( cat_sl != 1 )); then
24644                 error "Active plain llog shouldn't be deleted from catalog"
24645         fi
24646 }
24647 run_test 256 "Check llog delete for empty and not full state"
24648
24649 test_257() {
24650         remote_mds_nodsh && skip "remote MDS with nodsh"
24651         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
24652                 skip "Need MDS version at least 2.8.55"
24653
24654         test_mkdir $DIR/$tdir
24655
24656         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
24657                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
24658         stat $DIR/$tdir
24659
24660 #define OBD_FAIL_MDS_XATTR_REP                  0x161
24661         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
24662         local facet=mds$((mdtidx + 1))
24663         set_nodes_failloc $(facet_active_host $facet) 0x80000161
24664         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
24665
24666         stop $facet || error "stop MDS failed"
24667         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
24668                 error "start MDS fail"
24669         wait_recovery_complete $facet
24670 }
24671 run_test 257 "xattr locks are not lost"
24672
24673 # Verify we take the i_mutex when security requires it
24674 test_258a() {
24675 #define OBD_FAIL_IMUTEX_SEC 0x141c
24676         $LCTL set_param fail_loc=0x141c
24677         touch $DIR/$tfile
24678         chmod u+s $DIR/$tfile
24679         chmod a+rwx $DIR/$tfile
24680         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24681         RC=$?
24682         if [ $RC -ne 0 ]; then
24683                 error "error, failed to take i_mutex, rc=$?"
24684         fi
24685         rm -f $DIR/$tfile
24686 }
24687 run_test 258a "verify i_mutex security behavior when suid attributes is set"
24688
24689 # Verify we do NOT take the i_mutex in the normal case
24690 test_258b() {
24691 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
24692         $LCTL set_param fail_loc=0x141d
24693         touch $DIR/$tfile
24694         chmod a+rwx $DIR
24695         chmod a+rw $DIR/$tfile
24696         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24697         RC=$?
24698         if [ $RC -ne 0 ]; then
24699                 error "error, took i_mutex unnecessarily, rc=$?"
24700         fi
24701         rm -f $DIR/$tfile
24702
24703 }
24704 run_test 258b "verify i_mutex security behavior"
24705
24706 test_259() {
24707         local file=$DIR/$tfile
24708         local before
24709         local after
24710
24711         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
24712
24713         stack_trap "rm -f $file" EXIT
24714
24715         wait_delete_completed
24716         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24717         echo "before: $before"
24718
24719         $LFS setstripe -i 0 -c 1 $file
24720         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
24721         sync_all_data
24722         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24723         echo "after write: $after"
24724
24725 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
24726         do_facet ost1 $LCTL set_param fail_loc=0x2301
24727         $TRUNCATE $file 0
24728         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24729         echo "after truncate: $after"
24730
24731         stop ost1
24732         do_facet ost1 $LCTL set_param fail_loc=0
24733         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
24734         sleep 2
24735         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24736         echo "after restart: $after"
24737         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
24738                 error "missing truncate?"
24739
24740         return 0
24741 }
24742 run_test 259 "crash at delayed truncate"
24743
24744 test_260() {
24745 #define OBD_FAIL_MDC_CLOSE               0x806
24746         $LCTL set_param fail_loc=0x80000806
24747         touch $DIR/$tfile
24748
24749 }
24750 run_test 260 "Check mdc_close fail"
24751
24752 ### Data-on-MDT sanity tests ###
24753 test_270a() {
24754         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24755                 skip "Need MDS version at least 2.10.55 for DoM"
24756
24757         # create DoM file
24758         local dom=$DIR/$tdir/dom_file
24759         local tmp=$DIR/$tdir/tmp_file
24760
24761         mkdir_on_mdt0 $DIR/$tdir
24762
24763         # basic checks for DoM component creation
24764         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
24765                 error "Can set MDT layout to non-first entry"
24766
24767         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
24768                 error "Can define multiple entries as MDT layout"
24769
24770         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
24771
24772         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
24773         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
24774         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
24775
24776         local mdtidx=$($LFS getstripe -m $dom)
24777         local mdtname=MDT$(printf %04x $mdtidx)
24778         local facet=mds$((mdtidx + 1))
24779         local space_check=1
24780
24781         # Skip free space checks with ZFS
24782         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
24783
24784         # write
24785         sync
24786         local size_tmp=$((65536 * 3))
24787         local mdtfree1=$(do_facet $facet \
24788                          lctl get_param -n osd*.*$mdtname.kbytesfree)
24789
24790         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24791         # check also direct IO along write
24792         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
24793         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24794         sync
24795         cmp $tmp $dom || error "file data is different"
24796         [ $(stat -c%s $dom) == $size_tmp ] ||
24797                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24798         if [ $space_check == 1 ]; then
24799                 local mdtfree2=$(do_facet $facet \
24800                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
24801
24802                 # increase in usage from by $size_tmp
24803                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24804                         error "MDT free space wrong after write: " \
24805                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24806         fi
24807
24808         # truncate
24809         local size_dom=10000
24810
24811         $TRUNCATE $dom $size_dom
24812         [ $(stat -c%s $dom) == $size_dom ] ||
24813                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
24814         if [ $space_check == 1 ]; then
24815                 mdtfree1=$(do_facet $facet \
24816                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24817                 # decrease in usage from $size_tmp to new $size_dom
24818                 [ $(($mdtfree1 - $mdtfree2)) -ge \
24819                   $(((size_tmp - size_dom) / 1024)) ] ||
24820                         error "MDT free space is wrong after truncate: " \
24821                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
24822         fi
24823
24824         # append
24825         cat $tmp >> $dom
24826         sync
24827         size_dom=$((size_dom + size_tmp))
24828         [ $(stat -c%s $dom) == $size_dom ] ||
24829                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
24830         if [ $space_check == 1 ]; then
24831                 mdtfree2=$(do_facet $facet \
24832                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24833                 # increase in usage by $size_tmp from previous
24834                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24835                         error "MDT free space is wrong after append: " \
24836                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24837         fi
24838
24839         # delete
24840         rm $dom
24841         if [ $space_check == 1 ]; then
24842                 mdtfree1=$(do_facet $facet \
24843                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24844                 # decrease in usage by $size_dom from previous
24845                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
24846                         error "MDT free space is wrong after removal: " \
24847                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
24848         fi
24849
24850         # combined striping
24851         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
24852                 error "Can't create DoM + OST striping"
24853
24854         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
24855         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24856         # check also direct IO along write
24857         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24858         sync
24859         cmp $tmp $dom || error "file data is different"
24860         [ $(stat -c%s $dom) == $size_tmp ] ||
24861                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24862         rm $dom $tmp
24863
24864         return 0
24865 }
24866 run_test 270a "DoM: basic functionality tests"
24867
24868 test_270b() {
24869         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24870                 skip "Need MDS version at least 2.10.55"
24871
24872         local dom=$DIR/$tdir/dom_file
24873         local max_size=1048576
24874
24875         mkdir -p $DIR/$tdir
24876         $LFS setstripe -E $max_size -L mdt $dom
24877
24878         # truncate over the limit
24879         $TRUNCATE $dom $(($max_size + 1)) &&
24880                 error "successful truncate over the maximum size"
24881         # write over the limit
24882         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
24883                 error "successful write over the maximum size"
24884         # append over the limit
24885         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
24886         echo "12345" >> $dom && error "successful append over the maximum size"
24887         rm $dom
24888
24889         return 0
24890 }
24891 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
24892
24893 test_270c() {
24894         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24895                 skip "Need MDS version at least 2.10.55"
24896
24897         mkdir -p $DIR/$tdir
24898         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24899
24900         # check files inherit DoM EA
24901         touch $DIR/$tdir/first
24902         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
24903                 error "bad pattern"
24904         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
24905                 error "bad stripe count"
24906         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
24907                 error "bad stripe size"
24908
24909         # check directory inherits DoM EA and uses it as default
24910         mkdir $DIR/$tdir/subdir
24911         touch $DIR/$tdir/subdir/second
24912         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
24913                 error "bad pattern in sub-directory"
24914         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
24915                 error "bad stripe count in sub-directory"
24916         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
24917                 error "bad stripe size in sub-directory"
24918         return 0
24919 }
24920 run_test 270c "DoM: DoM EA inheritance tests"
24921
24922 test_270d() {
24923         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24924                 skip "Need MDS version at least 2.10.55"
24925
24926         mkdir -p $DIR/$tdir
24927         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24928
24929         # inherit default DoM striping
24930         mkdir $DIR/$tdir/subdir
24931         touch $DIR/$tdir/subdir/f1
24932
24933         # change default directory striping
24934         $LFS setstripe -c 1 $DIR/$tdir/subdir
24935         touch $DIR/$tdir/subdir/f2
24936         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
24937                 error "wrong default striping in file 2"
24938         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
24939                 error "bad pattern in file 2"
24940         return 0
24941 }
24942 run_test 270d "DoM: change striping from DoM to RAID0"
24943
24944 test_270e() {
24945         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24946                 skip "Need MDS version at least 2.10.55"
24947
24948         mkdir -p $DIR/$tdir/dom
24949         mkdir -p $DIR/$tdir/norm
24950         DOMFILES=20
24951         NORMFILES=10
24952         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
24953         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
24954
24955         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
24956         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
24957
24958         # find DoM files by layout
24959         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
24960         [ $NUM -eq  $DOMFILES ] ||
24961                 error "lfs find -L: found $NUM, expected $DOMFILES"
24962         echo "Test 1: lfs find 20 DOM files by layout: OK"
24963
24964         # there should be 1 dir with default DOM striping
24965         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
24966         [ $NUM -eq  1 ] ||
24967                 error "lfs find -L: found $NUM, expected 1 dir"
24968         echo "Test 2: lfs find 1 DOM dir by layout: OK"
24969
24970         # find DoM files by stripe size
24971         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
24972         [ $NUM -eq  $DOMFILES ] ||
24973                 error "lfs find -S: found $NUM, expected $DOMFILES"
24974         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
24975
24976         # find files by stripe offset except DoM files
24977         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
24978         [ $NUM -eq  $NORMFILES ] ||
24979                 error "lfs find -i: found $NUM, expected $NORMFILES"
24980         echo "Test 5: lfs find no DOM files by stripe index: OK"
24981         return 0
24982 }
24983 run_test 270e "DoM: lfs find with DoM files test"
24984
24985 test_270f() {
24986         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24987                 skip "Need MDS version at least 2.10.55"
24988
24989         local mdtname=${FSNAME}-MDT0000-mdtlov
24990         local dom=$DIR/$tdir/dom_file
24991         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
24992                                                 lod.$mdtname.dom_stripesize)
24993         local dom_limit=131072
24994
24995         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
24996         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24997                                                 lod.$mdtname.dom_stripesize)
24998         [ ${dom_limit} -eq ${dom_current} ] ||
24999                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
25000
25001         $LFS mkdir -i 0 -c 1 $DIR/$tdir
25002         $LFS setstripe -d $DIR/$tdir
25003         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
25004                 error "Can't set directory default striping"
25005
25006         # exceed maximum stripe size
25007         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
25008                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
25009         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
25010                 error "Able to create DoM component size more than LOD limit"
25011
25012         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
25013         dom_current=$(do_facet mds1 $LCTL get_param -n \
25014                                                 lod.$mdtname.dom_stripesize)
25015         [ 0 -eq ${dom_current} ] ||
25016                 error "Can't set zero DoM stripe limit"
25017         rm $dom
25018
25019         # attempt to create DoM file on server with disabled DoM should
25020         # remove DoM entry from layout and be succeed
25021         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
25022                 error "Can't create DoM file (DoM is disabled)"
25023         [ $($LFS getstripe -L $dom) == "mdt" ] &&
25024                 error "File has DoM component while DoM is disabled"
25025         rm $dom
25026
25027         # attempt to create DoM file with only DoM stripe should return error
25028         $LFS setstripe -E $dom_limit -L mdt $dom &&
25029                 error "Able to create DoM-only file while DoM is disabled"
25030
25031         # too low values to be aligned with smallest stripe size 64K
25032         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
25033         dom_current=$(do_facet mds1 $LCTL get_param -n \
25034                                                 lod.$mdtname.dom_stripesize)
25035         [ 30000 -eq ${dom_current} ] &&
25036                 error "Can set too small DoM stripe limit"
25037
25038         # 64K is a minimal stripe size in Lustre, expect limit of that size
25039         [ 65536 -eq ${dom_current} ] ||
25040                 error "Limit is not set to 64K but ${dom_current}"
25041
25042         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
25043         dom_current=$(do_facet mds1 $LCTL get_param -n \
25044                                                 lod.$mdtname.dom_stripesize)
25045         echo $dom_current
25046         [ 2147483648 -eq ${dom_current} ] &&
25047                 error "Can set too large DoM stripe limit"
25048
25049         do_facet mds1 $LCTL set_param -n \
25050                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
25051         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
25052                 error "Can't create DoM component size after limit change"
25053         do_facet mds1 $LCTL set_param -n \
25054                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
25055         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
25056                 error "Can't create DoM file after limit decrease"
25057         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
25058                 error "Can create big DoM component after limit decrease"
25059         touch ${dom}_def ||
25060                 error "Can't create file with old default layout"
25061
25062         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
25063         return 0
25064 }
25065 run_test 270f "DoM: maximum DoM stripe size checks"
25066
25067 test_270g() {
25068         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
25069                 skip "Need MDS version at least 2.13.52"
25070         local dom=$DIR/$tdir/$tfile
25071
25072         $LFS mkdir -i 0 -c 1 $DIR/$tdir
25073         local lodname=${FSNAME}-MDT0000-mdtlov
25074
25075         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25076         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
25077         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
25078         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25079
25080         local dom_limit=1024
25081         local dom_threshold="50%"
25082
25083         $LFS setstripe -d $DIR/$tdir
25084         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
25085                 error "Can't set directory default striping"
25086
25087         do_facet mds1 $LCTL set_param -n \
25088                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
25089         # set 0 threshold and create DOM file to change tunable stripesize
25090         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
25091         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
25092                 error "Failed to create $dom file"
25093         # now tunable dom_cur_stripesize should reach maximum
25094         local dom_current=$(do_facet mds1 $LCTL get_param -n \
25095                                         lod.${lodname}.dom_stripesize_cur_kb)
25096         [[ $dom_current == $dom_limit ]] ||
25097                 error "Current DOM stripesize is not maximum"
25098         rm $dom
25099
25100         # set threshold for further tests
25101         do_facet mds1 $LCTL set_param -n \
25102                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
25103         echo "DOM threshold is $dom_threshold free space"
25104         local dom_def
25105         local dom_set
25106         # Spoof bfree to exceed threshold
25107         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
25108         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
25109         for spfree in 40 20 0 15 30 55; do
25110                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
25111                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
25112                         error "Failed to create $dom file"
25113                 dom_def=$(do_facet mds1 $LCTL get_param -n \
25114                                         lod.${lodname}.dom_stripesize_cur_kb)
25115                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
25116                 [[ $dom_def != $dom_current ]] ||
25117                         error "Default stripe size was not changed"
25118                 if (( spfree > 0 )) ; then
25119                         dom_set=$($LFS getstripe -S $dom)
25120                         (( dom_set == dom_def * 1024 )) ||
25121                                 error "DOM component size is still old"
25122                 else
25123                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
25124                                 error "DoM component is set with no free space"
25125                 fi
25126                 rm $dom
25127                 dom_current=$dom_def
25128         done
25129 }
25130 run_test 270g "DoM: default DoM stripe size depends on free space"
25131
25132 test_270h() {
25133         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
25134                 skip "Need MDS version at least 2.13.53"
25135
25136         local mdtname=${FSNAME}-MDT0000-mdtlov
25137         local dom=$DIR/$tdir/$tfile
25138         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25139
25140         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
25141         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25142
25143         $LFS mkdir -i 0 -c 1 $DIR/$tdir
25144         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
25145                 error "can't create OST file"
25146         # mirrored file with DOM entry in the second mirror
25147         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
25148                 error "can't create mirror with DoM component"
25149
25150         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
25151
25152         # DOM component in the middle and has other enries in the same mirror,
25153         # should succeed but lost DoM component
25154         $LFS setstripe --copy=${dom}_1 $dom ||
25155                 error "Can't create file from OST|DOM mirror layout"
25156         # check new file has no DoM layout after all
25157         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
25158                 error "File has DoM component while DoM is disabled"
25159 }
25160 run_test 270h "DoM: DoM stripe removal when disabled on server"
25161
25162 test_270i() {
25163         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
25164                 skip "Need MDS version at least 2.14.54"
25165
25166         mkdir $DIR/$tdir
25167         # DoM with plain layout
25168         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
25169                 error "default plain layout with DoM must fail"
25170         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
25171                 error "setstripe plain file layout with DoM must fail"
25172         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
25173                 error "default DoM layout with bad striping must fail"
25174         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
25175                 error "setstripe to DoM layout with bad striping must fail"
25176         return 0
25177 }
25178 run_test 270i "DoM: setting invalid DoM striping should fail"
25179
25180 test_270j() {
25181         (( $MDS1_VERSION >= $(version_code 2.15.55.203) )) ||
25182                 skip "Need MDS version at least 2.15.55.203"
25183
25184         local dom=$DIR/$tdir/$tfile
25185         local odv
25186         local ndv
25187
25188         mkdir -p $DIR/$tdir
25189
25190         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25191
25192         odv=$($LFS data_version $dom)
25193         chmod 666 $dom
25194         mv $dom ${dom}_moved
25195         link ${dom}_moved $dom
25196         setfattr -n user.attrx -v "some_attr" $dom
25197         ndv=$($LFS data_version $dom)
25198         (( $ndv == $odv )) ||
25199                 error "data version was changed by metadata operations"
25200
25201         dd if=/dev/urandom of=$dom bs=1M count=1 ||
25202                 error "failed to write data into $dom"
25203         cancel_lru_locks mdc
25204         ndv=$($LFS data_version $dom)
25205         (( $ndv != $odv )) ||
25206                 error "data version wasn't changed on write"
25207
25208         odv=$ndv
25209         $TRUNCATE $dom 1000 || error "failed to truncate $dom"
25210         ndv=$($LFS data_version $dom)
25211         (( $ndv != $odv )) ||
25212                 error "data version wasn't changed on truncate down"
25213
25214         odv=$ndv
25215         $TRUNCATE $dom 25000
25216         ndv=$($LFS data_version $dom)
25217         (( $ndv != $odv )) ||
25218                 error "data version wasn't changed on truncate up"
25219
25220         # check also fallocate for ldiskfs
25221         if [[ "$mds1_FSTYPE" == ldiskfs ]]; then
25222                 odv=$ndv
25223                 fallocate -l 1048576 $dom
25224                 ndv=$($LFS data_version $dom)
25225                 (( $ndv != $odv )) ||
25226                         error "data version wasn't changed on fallocate"
25227
25228                 odv=$ndv
25229                 fallocate -p --offset 4096 -l 4096 $dom
25230                 ndv=$($LFS data_version $dom)
25231                 (( $ndv != $odv )) ||
25232                         error "data version wasn't changed on fallocate punch"
25233         fi
25234 }
25235 run_test 270j "DoM migration: DOM file to the OST-striped file (plain)"
25236
25237 test_271a() {
25238         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25239                 skip "Need MDS version at least 2.10.55"
25240
25241         local dom=$DIR/$tdir/dom
25242
25243         mkdir -p $DIR/$tdir
25244
25245         $LFS setstripe -E 1024K -L mdt $dom
25246
25247         lctl set_param -n mdc.*.stats=clear
25248         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
25249         cat $dom > /dev/null
25250         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
25251         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
25252         ls $dom
25253         rm -f $dom
25254 }
25255 run_test 271a "DoM: data is cached for read after write"
25256
25257 test_271b() {
25258         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25259                 skip "Need MDS version at least 2.10.55"
25260
25261         local dom=$DIR/$tdir/dom
25262
25263         mkdir -p $DIR/$tdir
25264
25265         $LFS setstripe -E 1024K -L mdt -E EOF $dom
25266
25267         lctl set_param -n mdc.*.stats=clear
25268         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
25269         cancel_lru_locks mdc
25270         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
25271         # second stat to check size is cached on client
25272         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
25273         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
25274         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
25275         rm -f $dom
25276 }
25277 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
25278
25279 test_271ba() {
25280         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25281                 skip "Need MDS version at least 2.10.55"
25282
25283         local dom=$DIR/$tdir/dom
25284
25285         mkdir -p $DIR/$tdir
25286
25287         $LFS setstripe -E 1024K -L mdt -E EOF $dom
25288
25289         lctl set_param -n mdc.*.stats=clear
25290         lctl set_param -n osc.*.stats=clear
25291         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
25292         cancel_lru_locks mdc
25293         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
25294         # second stat to check size is cached on client
25295         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
25296         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
25297         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
25298         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
25299         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
25300         rm -f $dom
25301 }
25302 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
25303
25304
25305 get_mdc_stats() {
25306         local mdtidx=$1
25307         local param=$2
25308         local mdt=MDT$(printf %04x $mdtidx)
25309
25310         if [ -z $param ]; then
25311                 lctl get_param -n mdc.*$mdt*.stats
25312         else
25313                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
25314         fi
25315 }
25316
25317 test_271c() {
25318         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25319                 skip "Need MDS version at least 2.10.55"
25320
25321         local dom=$DIR/$tdir/dom
25322
25323         mkdir -p $DIR/$tdir
25324
25325         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25326
25327         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
25328         local facet=mds$((mdtidx + 1))
25329
25330         cancel_lru_locks mdc
25331         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
25332         createmany -o $dom 1000
25333         lctl set_param -n mdc.*.stats=clear
25334         smalliomany -w $dom 1000 200
25335         get_mdc_stats $mdtidx
25336         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
25337         # Each file has 1 open, 1 IO enqueues, total 2000
25338         # but now we have also +1 getxattr for security.capability, total 3000
25339         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
25340         unlinkmany $dom 1000
25341
25342         cancel_lru_locks mdc
25343         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
25344         createmany -o $dom 1000
25345         lctl set_param -n mdc.*.stats=clear
25346         smalliomany -w $dom 1000 200
25347         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
25348         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
25349         # for OPEN and IO lock.
25350         [ $((enq - enq_2)) -ge 1000 ] ||
25351                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
25352         unlinkmany $dom 1000
25353         return 0
25354 }
25355 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
25356
25357 cleanup_271def_tests() {
25358         trap 0
25359         rm -f $1
25360 }
25361
25362 test_271d() {
25363         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
25364                 skip "Need MDS version at least 2.10.57"
25365
25366         local dom=$DIR/$tdir/dom
25367         local tmp=$TMP/$tfile
25368         trap "cleanup_271def_tests $tmp" EXIT
25369
25370         mkdir -p $DIR/$tdir
25371
25372         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25373
25374         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
25375
25376         cancel_lru_locks mdc
25377         dd if=/dev/urandom of=$tmp bs=1000 count=1
25378         dd if=$tmp of=$dom bs=1000 count=1
25379         cancel_lru_locks mdc
25380
25381         cat /etc/hosts >> $tmp
25382         lctl set_param -n mdc.*.stats=clear
25383
25384         # append data to the same file it should update local page
25385         echo "Append to the same page"
25386         cat /etc/hosts >> $dom
25387         local num=$(get_mdc_stats $mdtidx ost_read)
25388         local ra=$(get_mdc_stats $mdtidx req_active)
25389         local rw=$(get_mdc_stats $mdtidx req_waittime)
25390
25391         [ -z $num ] || error "$num READ RPC occured"
25392         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25393         echo "... DONE"
25394
25395         # compare content
25396         cmp $tmp $dom || error "file miscompare"
25397
25398         cancel_lru_locks mdc
25399         lctl set_param -n mdc.*.stats=clear
25400
25401         echo "Open and read file"
25402         cat $dom > /dev/null
25403         local num=$(get_mdc_stats $mdtidx ost_read)
25404         local ra=$(get_mdc_stats $mdtidx req_active)
25405         local rw=$(get_mdc_stats $mdtidx req_waittime)
25406
25407         [ -z $num ] || error "$num READ RPC occured"
25408         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25409         echo "... DONE"
25410
25411         # compare content
25412         cmp $tmp $dom || error "file miscompare"
25413
25414         return 0
25415 }
25416 run_test 271d "DoM: read on open (1K file in reply buffer)"
25417
25418 test_271f() {
25419         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
25420                 skip "Need MDS version at least 2.10.57"
25421
25422         local dom=$DIR/$tdir/dom
25423         local tmp=$TMP/$tfile
25424         trap "cleanup_271def_tests $tmp" EXIT
25425
25426         mkdir -p $DIR/$tdir
25427
25428         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25429
25430         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
25431
25432         cancel_lru_locks mdc
25433         dd if=/dev/urandom of=$tmp bs=265000 count=1
25434         dd if=$tmp of=$dom bs=265000 count=1
25435         cancel_lru_locks mdc
25436         cat /etc/hosts >> $tmp
25437         lctl set_param -n mdc.*.stats=clear
25438
25439         echo "Append to the same page"
25440         cat /etc/hosts >> $dom
25441         local num=$(get_mdc_stats $mdtidx ost_read)
25442         local ra=$(get_mdc_stats $mdtidx req_active)
25443         local rw=$(get_mdc_stats $mdtidx req_waittime)
25444
25445         [ -z $num ] || error "$num READ RPC occured"
25446         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25447         echo "... DONE"
25448
25449         # compare content
25450         cmp $tmp $dom || error "file miscompare"
25451
25452         cancel_lru_locks mdc
25453         lctl set_param -n mdc.*.stats=clear
25454
25455         echo "Open and read file"
25456         cat $dom > /dev/null
25457         local num=$(get_mdc_stats $mdtidx ost_read)
25458         local ra=$(get_mdc_stats $mdtidx req_active)
25459         local rw=$(get_mdc_stats $mdtidx req_waittime)
25460
25461         [ -z $num ] && num=0
25462         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
25463         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25464         echo "... DONE"
25465
25466         # compare content
25467         cmp $tmp $dom || error "file miscompare"
25468
25469         return 0
25470 }
25471 run_test 271f "DoM: read on open (200K file and read tail)"
25472
25473 test_271g() {
25474         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
25475                 skip "Skipping due to old client or server version"
25476
25477         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
25478         # to get layout
25479         $CHECKSTAT -t file $DIR1/$tfile
25480
25481         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
25482         MULTIOP_PID=$!
25483         sleep 1
25484         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
25485         $LCTL set_param fail_loc=0x80000314
25486         rm $DIR1/$tfile || error "Unlink fails"
25487         RC=$?
25488         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
25489         [ $RC -eq 0 ] || error "Failed write to stale object"
25490 }
25491 run_test 271g "Discard DoM data vs client flush race"
25492
25493 test_272a() {
25494         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25495                 skip "Need MDS version at least 2.11.50"
25496
25497         local dom=$DIR/$tdir/dom
25498         mkdir -p $DIR/$tdir
25499
25500         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
25501         dd if=/dev/urandom of=$dom bs=512K count=1 ||
25502                 error "failed to write data into $dom"
25503         local old_md5=$(md5sum $dom)
25504
25505         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
25506                 error "failed to migrate to the same DoM component"
25507
25508         local new_md5=$(md5sum $dom)
25509
25510         [ "$old_md5" == "$new_md5" ] ||
25511                 error "md5sum differ: $old_md5, $new_md5"
25512
25513         [ $($LFS getstripe -c $dom) -eq 2 ] ||
25514                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
25515 }
25516 run_test 272a "DoM migration: new layout with the same DOM component"
25517
25518 test_272b() {
25519         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25520                 skip "Need MDS version at least 2.11.50"
25521
25522         local dom=$DIR/$tdir/dom
25523         mkdir -p $DIR/$tdir
25524         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25525         stack_trap "rm -rf $DIR/$tdir"
25526
25527         local mdtidx=$($LFS getstripe -m $dom)
25528         local mdtname=MDT$(printf %04x $mdtidx)
25529         local facet=mds$((mdtidx + 1))
25530
25531         local mdtfree1=$(do_facet $facet \
25532                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25533         dd if=/dev/urandom of=$dom bs=2M count=1 ||
25534                 error "failed to write data into $dom"
25535         local old_md5=$(md5sum $dom)
25536         cancel_lru_locks mdc
25537         local mdtfree1=$(do_facet $facet \
25538                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25539
25540         $LFS migrate -c2 $dom ||
25541                 error "failed to migrate to the new composite layout"
25542         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
25543                 error "MDT stripe was not removed"
25544         ! getfattr -n trusted.dataver $dom &> /dev/null ||
25545                 error "$dir1 shouldn't have DATAVER EA"
25546
25547         cancel_lru_locks mdc
25548         local new_md5=$(md5sum $dom)
25549         [ "$old_md5" == "$new_md5" ] ||
25550                 error "$old_md5 != $new_md5"
25551
25552         # Skip free space checks with ZFS
25553         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25554                 local mdtfree2=$(do_facet $facet \
25555                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25556                 [ $mdtfree2 -gt $mdtfree1 ] ||
25557                         error "MDT space is not freed after migration"
25558         fi
25559         return 0
25560 }
25561 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
25562
25563 test_272c() {
25564         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25565                 skip "Need MDS version at least 2.11.50"
25566
25567         local dom=$DIR/$tdir/$tfile
25568         mkdir -p $DIR/$tdir
25569         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25570         stack_trap "rm -rf $DIR/$tdir"
25571
25572         local mdtidx=$($LFS getstripe -m $dom)
25573         local mdtname=MDT$(printf %04x $mdtidx)
25574         local facet=mds$((mdtidx + 1))
25575
25576         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25577                 error "failed to write data into $dom"
25578         local old_md5=$(md5sum $dom)
25579         cancel_lru_locks mdc
25580         local mdtfree1=$(do_facet $facet \
25581                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25582
25583         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
25584                 error "failed to migrate to the new composite layout"
25585         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
25586                 error "MDT stripe was not removed"
25587
25588         cancel_lru_locks mdc
25589         local new_md5=$(md5sum $dom)
25590         [ "$old_md5" == "$new_md5" ] ||
25591                 error "$old_md5 != $new_md5"
25592
25593         # Skip free space checks with ZFS
25594         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25595                 local mdtfree2=$(do_facet $facet \
25596                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25597                 [ $mdtfree2 -gt $mdtfree1 ] ||
25598                         error "MDS space is not freed after migration"
25599         fi
25600         return 0
25601 }
25602 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
25603
25604 test_272d() {
25605         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25606                 skip "Need MDS version at least 2.12.55"
25607
25608         local dom=$DIR/$tdir/$tfile
25609         mkdir -p $DIR/$tdir
25610         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25611
25612         local mdtidx=$($LFS getstripe -m $dom)
25613         local mdtname=MDT$(printf %04x $mdtidx)
25614         local facet=mds$((mdtidx + 1))
25615
25616         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25617                 error "failed to write data into $dom"
25618         local old_md5=$(md5sum $dom)
25619         cancel_lru_locks mdc
25620         local mdtfree1=$(do_facet $facet \
25621                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25622
25623         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
25624                 error "failed mirroring to the new composite layout"
25625         $LFS mirror resync $dom ||
25626                 error "failed mirror resync"
25627         $LFS mirror split --mirror-id 1 -d $dom ||
25628                 error "failed mirror split"
25629
25630         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
25631                 error "MDT stripe was not removed"
25632
25633         cancel_lru_locks mdc
25634         local new_md5=$(md5sum $dom)
25635         [ "$old_md5" == "$new_md5" ] ||
25636                 error "$old_md5 != $new_md5"
25637
25638         # Skip free space checks with ZFS
25639         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25640                 local mdtfree2=$(do_facet $facet \
25641                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25642                 [ $mdtfree2 -gt $mdtfree1 ] ||
25643                         error "MDS space is not freed after DOM mirror deletion"
25644         fi
25645         return 0
25646 }
25647 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
25648
25649 test_272e() {
25650         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25651                 skip "Need MDS version at least 2.12.55"
25652
25653         local dom=$DIR/$tdir/$tfile
25654         mkdir -p $DIR/$tdir
25655         $LFS setstripe -c 2 $dom
25656
25657         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25658                 error "failed to write data into $dom"
25659         local old_md5=$(md5sum $dom)
25660         cancel_lru_locks
25661
25662         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
25663                 error "failed mirroring to the DOM layout"
25664         $LFS mirror resync $dom ||
25665                 error "failed mirror resync"
25666         $LFS mirror split --mirror-id 1 -d $dom ||
25667                 error "failed mirror split"
25668
25669         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25670                 error "MDT stripe wasn't set"
25671
25672         cancel_lru_locks
25673         local new_md5=$(md5sum $dom)
25674         [ "$old_md5" == "$new_md5" ] ||
25675                 error "$old_md5 != $new_md5"
25676
25677         return 0
25678 }
25679 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
25680
25681 test_272f() {
25682         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25683                 skip "Need MDS version at least 2.12.55"
25684
25685         local dom=$DIR/$tdir/$tfile
25686         mkdir -p $DIR/$tdir
25687         $LFS setstripe -c 2 $dom
25688
25689         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25690                 error "failed to write data into $dom"
25691         local old_md5=$(md5sum $dom)
25692         cancel_lru_locks
25693
25694         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
25695                 error "failed migrating to the DOM file"
25696
25697         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25698                 error "MDT stripe wasn't set"
25699
25700         cancel_lru_locks
25701         local new_md5=$(md5sum $dom)
25702         [ "$old_md5" != "$new_md5" ] &&
25703                 error "$old_md5 != $new_md5"
25704
25705         return 0
25706 }
25707 run_test 272f "DoM migration: OST-striped file to DOM file"
25708
25709 test_273a() {
25710         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25711                 skip "Need MDS version at least 2.11.50"
25712
25713         # Layout swap cannot be done if either file has DOM component,
25714         # this will never be supported, migration should be used instead
25715
25716         local dom=$DIR/$tdir/$tfile
25717         mkdir -p $DIR/$tdir
25718
25719         $LFS setstripe -c2 ${dom}_plain
25720         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
25721         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
25722                 error "can swap layout with DoM component"
25723         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
25724                 error "can swap layout with DoM component"
25725
25726         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
25727         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
25728                 error "can swap layout with DoM component"
25729         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
25730                 error "can swap layout with DoM component"
25731         return 0
25732 }
25733 run_test 273a "DoM: layout swapping should fail with DOM"
25734
25735 test_273b() {
25736         mkdir -p $DIR/$tdir
25737         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
25738
25739 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
25740         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
25741
25742         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25743 }
25744 run_test 273b "DoM: race writeback and object destroy"
25745
25746 test_273c() {
25747         mkdir -p $DIR/$tdir
25748         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
25749
25750         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
25751         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
25752
25753         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25754 }
25755 run_test 273c "race writeback and object destroy"
25756
25757 test_275() {
25758         remote_ost_nodsh && skip "remote OST with nodsh"
25759         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
25760                 skip "Need OST version >= 2.10.57"
25761
25762         local file=$DIR/$tfile
25763         local oss
25764
25765         oss=$(comma_list $(osts_nodes))
25766
25767         dd if=/dev/urandom of=$file bs=1M count=2 ||
25768                 error "failed to create a file"
25769         stack_trap "rm -f $file"
25770         cancel_lru_locks osc
25771
25772         #lock 1
25773         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25774                 error "failed to read a file"
25775
25776 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
25777         $LCTL set_param fail_loc=0x8000031f
25778
25779         cancel_lru_locks osc &
25780         sleep 1
25781
25782 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
25783         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
25784         #IO takes another lock, but matches the PENDING one
25785         #and places it to the IO RPC
25786         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25787                 error "failed to read a file with PENDING lock"
25788 }
25789 run_test 275 "Read on a canceled duplicate lock"
25790
25791 test_276() {
25792         remote_ost_nodsh && skip "remote OST with nodsh"
25793         local pid
25794
25795         do_facet ost1 "(while true; do \
25796                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
25797                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
25798         pid=$!
25799
25800         for LOOP in $(seq 20); do
25801                 stop ost1
25802                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
25803         done
25804         kill -9 $pid
25805         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
25806                 rm $TMP/sanity_276_pid"
25807 }
25808 run_test 276 "Race between mount and obd_statfs"
25809
25810 test_277() {
25811         $LCTL set_param ldlm.namespaces.*.lru_size=0
25812         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25813         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25814                           awk '/^used_mb/ { print $2 }')
25815         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
25816         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
25817                 oflag=direct conv=notrunc
25818         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25819                     awk '/^used_mb/ { print $2 }')
25820         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
25821 }
25822 run_test 277 "Direct IO shall drop page cache"
25823
25824 test_278() {
25825         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
25826         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25827         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
25828                 skip "needs the same host for mdt1 mdt2" && return
25829
25830         local pid1
25831         local pid2
25832
25833 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
25834         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
25835         stop mds2 &
25836         pid2=$!
25837
25838         stop mds1
25839
25840         echo "Starting MDTs"
25841         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
25842         wait $pid2
25843 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
25844 #will return NULL
25845         do_facet mds2 $LCTL set_param fail_loc=0
25846
25847         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
25848         wait_recovery_complete mds2
25849 }
25850 run_test 278 "Race starting MDS between MDTs stop/start"
25851
25852 test_280() {
25853         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
25854                 skip "Need MGS version at least 2.13.52"
25855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25856         combined_mgs_mds || skip "needs combined MGS/MDT"
25857
25858         umount_client $MOUNT
25859 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
25860         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
25861
25862         mount_client $MOUNT &
25863         sleep 1
25864         stop mgs || error "stop mgs failed"
25865         #for a race mgs would crash
25866         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
25867         # make sure we unmount client before remounting
25868         wait
25869         umount_client $MOUNT
25870         mount_client $MOUNT || error "mount client failed"
25871 }
25872 run_test 280 "Race between MGS umount and client llog processing"
25873
25874 cleanup_test_300() {
25875         trap 0
25876         umask $SAVE_UMASK
25877 }
25878
25879 test_striped_dir() {
25880         local mdt_index=$1
25881         local stripe_count=$2
25882         local overstriping=$3
25883         local stripe_index
25884         local getstripe_count
25885
25886         mkdir -p $DIR/$tdir
25887
25888         SAVE_UMASK=$(umask)
25889         trap cleanup_test_300 RETURN EXIT
25890
25891         if [ -z $overstriping ]; then
25892                 $LFS setdirstripe -i $mdt_index -c $stripe_count -H all_char \
25893                                         -o 755 $DIR/$tdir/striped_dir ||
25894                         error "set striped dir error"
25895         else
25896                 $LFS setdirstripe -i $mdt_index -C $stripe_count -H all_char \
25897                                         -o 755 $DIR/$tdir/striped_dir ||
25898                         error "set striped dir error"
25899         fi
25900
25901         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
25902         [ "$mode" = "755" ] || error "expect 755 got $mode"
25903
25904         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
25905                 error "getdirstripe failed"
25906         getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
25907         if [ "$getstripe_count" != "$stripe_count" ]; then
25908                 error "1:stripe_count is $getstripe_count, expect $stripe_count"
25909         fi
25910         getstripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
25911         if [ "$getstripe_count" != "$stripe_count" ]; then
25912                 error "2:stripe_count is $getstripe_count, expect $stripe_count"
25913         fi
25914
25915         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
25916         if [ "$stripe_index" != "$mdt_index" ]; then
25917                 error "stripe_index is $stripe_index, expect $mdt_index"
25918         fi
25919
25920         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25921                 error "nlink error after create striped dir"
25922
25923         mkdir $DIR/$tdir/striped_dir/a
25924         mkdir $DIR/$tdir/striped_dir/b
25925
25926         stat $DIR/$tdir/striped_dir/a ||
25927                 error "create dir under striped dir failed"
25928         stat $DIR/$tdir/striped_dir/b ||
25929                 error "create dir under striped dir failed"
25930
25931         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
25932                 error "nlink error after mkdir"
25933
25934         rmdir $DIR/$tdir/striped_dir/a
25935         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
25936                 error "nlink error after rmdir"
25937
25938         rmdir $DIR/$tdir/striped_dir/b
25939         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25940                 error "nlink error after rmdir"
25941
25942         chattr +i $DIR/$tdir/striped_dir
25943         createmany -o $DIR/$tdir/striped_dir/f 10 &&
25944                 error "immutable flags not working under striped dir!"
25945         chattr -i $DIR/$tdir/striped_dir
25946
25947         rmdir $DIR/$tdir/striped_dir ||
25948                 error "rmdir striped dir error"
25949
25950         cleanup_test_300
25951
25952         true
25953 }
25954
25955 test_300a() {
25956         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25957                 skip "skipped for lustre < 2.7.0"
25958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25959         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25960
25961         test_striped_dir 0 2 || error "failed on striped dir on MDT0"
25962         test_striped_dir 1 2 || error "failed on striped dir on MDT0"
25963 }
25964 run_test 300a "basic striped dir sanity test"
25965
25966 test_300b() {
25967         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25968                 skip "skipped for lustre < 2.7.0"
25969         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25970         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25971
25972         local i
25973         local mtime1
25974         local mtime2
25975         local mtime3
25976
25977         test_mkdir $DIR/$tdir || error "mkdir fail"
25978         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25979                 error "set striped dir error"
25980         for i in {0..9}; do
25981                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
25982                 sleep 1
25983                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
25984                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
25985                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
25986                 sleep 1
25987                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
25988                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
25989                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
25990         done
25991         true
25992 }
25993 run_test 300b "check ctime/mtime for striped dir"
25994
25995 test_300c() {
25996         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25997                 skip "skipped for lustre < 2.7.0"
25998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25999         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26000
26001         local file_count
26002
26003         mkdir_on_mdt0 $DIR/$tdir
26004         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
26005                 error "set striped dir error"
26006
26007         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
26008                 error "chown striped dir failed"
26009
26010         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
26011                 error "create 5k files failed"
26012
26013         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
26014
26015         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
26016
26017         rm -rf $DIR/$tdir
26018 }
26019 run_test 300c "chown && check ls under striped directory"
26020
26021 test_300d() {
26022         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
26023                 skip "skipped for lustre < 2.7.0"
26024         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26025         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26026
26027         local stripe_count
26028         local file
26029
26030         mkdir -p $DIR/$tdir
26031         $LFS setstripe -c 2 $DIR/$tdir
26032
26033         #local striped directory
26034         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
26035                 error "set striped dir error"
26036         #look at the directories for debug purposes
26037         ls -l $DIR/$tdir
26038         $LFS getdirstripe $DIR/$tdir
26039         ls -l $DIR/$tdir/striped_dir
26040         $LFS getdirstripe $DIR/$tdir/striped_dir
26041         createmany -o $DIR/$tdir/striped_dir/f 10 ||
26042                 error "create 10 files failed"
26043
26044         #remote striped directory
26045         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
26046                 error "set striped dir error"
26047         #look at the directories for debug purposes
26048         ls -l $DIR/$tdir
26049         $LFS getdirstripe $DIR/$tdir
26050         ls -l $DIR/$tdir/remote_striped_dir
26051         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
26052         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
26053                 error "create 10 files failed"
26054
26055         for file in $(find $DIR/$tdir); do
26056                 stripe_count=$($LFS getstripe -c $file)
26057                 [ $stripe_count -eq 2 ] ||
26058                         error "wrong stripe $stripe_count for $file"
26059         done
26060
26061         rm -rf $DIR/$tdir
26062 }
26063 run_test 300d "check default stripe under striped directory"
26064
26065 test_300e() {
26066         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26067                 skip "Need MDS version at least 2.7.55"
26068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26069         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26070
26071         local stripe_count
26072         local file
26073
26074         mkdir -p $DIR/$tdir
26075
26076         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
26077                 error "set striped dir error"
26078
26079         touch $DIR/$tdir/striped_dir/a
26080         touch $DIR/$tdir/striped_dir/b
26081         touch $DIR/$tdir/striped_dir/c
26082
26083         mkdir $DIR/$tdir/striped_dir/dir_a
26084         mkdir $DIR/$tdir/striped_dir/dir_b
26085         mkdir $DIR/$tdir/striped_dir/dir_c
26086
26087         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
26088                 error "set striped adir under striped dir error"
26089
26090         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
26091                 error "set striped bdir under striped dir error"
26092
26093         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
26094                 error "set striped cdir under striped dir error"
26095
26096         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
26097                 error "rename dir under striped dir fails"
26098
26099         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
26100                 error "rename dir under different stripes fails"
26101
26102         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
26103                 error "rename file under striped dir should succeed"
26104
26105         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
26106                 error "rename dir under striped dir should succeed"
26107
26108         rm -rf $DIR/$tdir
26109 }
26110 run_test 300e "check rename under striped directory"
26111
26112 test_300f() {
26113         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26114         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26115         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26116                 skip "Need MDS version at least 2.7.55"
26117
26118         local stripe_count
26119         local file
26120
26121         rm -rf $DIR/$tdir
26122         mkdir -p $DIR/$tdir
26123
26124         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
26125                 error "set striped dir error"
26126
26127         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
26128                 error "set striped dir error"
26129
26130         touch $DIR/$tdir/striped_dir/a
26131         mkdir $DIR/$tdir/striped_dir/dir_a
26132         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
26133                 error "create striped dir under striped dir fails"
26134
26135         touch $DIR/$tdir/striped_dir1/b
26136         mkdir $DIR/$tdir/striped_dir1/dir_b
26137         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
26138                 error "create striped dir under striped dir fails"
26139
26140         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
26141                 error "rename dir under different striped dir should fail"
26142
26143         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
26144                 error "rename striped dir under diff striped dir should fail"
26145
26146         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
26147                 error "rename file under diff striped dirs fails"
26148
26149         rm -rf $DIR/$tdir
26150 }
26151 run_test 300f "check rename cross striped directory"
26152
26153 test_300_check_default_striped_dir()
26154 {
26155         local dirname=$1
26156         local default_count=$2
26157         local default_index=$3
26158         local stripe_count
26159         local stripe_index
26160         local dir_stripe_index
26161         local dir
26162
26163         echo "checking $dirname $default_count $default_index"
26164         $LFS setdirstripe -D -c $default_count -i $default_index \
26165                                 -H all_char $DIR/$tdir/$dirname ||
26166                 error "set default stripe on striped dir error"
26167         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
26168         [ $stripe_count -eq $default_count ] ||
26169                 error "expect $default_count get $stripe_count for $dirname"
26170
26171         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
26172         [ $stripe_index -eq $default_index ] ||
26173                 error "expect $default_index get $stripe_index for $dirname"
26174
26175         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
26176                                                 error "create dirs failed"
26177
26178         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
26179         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
26180         for dir in $(find $DIR/$tdir/$dirname/*); do
26181                 stripe_count=$($LFS getdirstripe -c $dir)
26182                 (( $stripe_count == $default_count )) ||
26183                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
26184                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
26185                 error "stripe count $default_count != $stripe_count for $dir"
26186
26187                 stripe_index=$($LFS getdirstripe -i $dir)
26188                 [ $default_index -eq -1 ] ||
26189                         [ $stripe_index -eq $default_index ] ||
26190                         error "$stripe_index != $default_index for $dir"
26191
26192                 #check default stripe
26193                 stripe_count=$($LFS getdirstripe -D -c $dir)
26194                 [ $stripe_count -eq $default_count ] ||
26195                 error "default count $default_count != $stripe_count for $dir"
26196
26197                 stripe_index=$($LFS getdirstripe -D -i $dir)
26198                 [ $stripe_index -eq $default_index ] ||
26199                 error "default index $default_index != $stripe_index for $dir"
26200         done
26201         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
26202 }
26203
26204 test_300g() {
26205         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26206         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26207                 skip "Need MDS version at least 2.7.55"
26208
26209         local dir
26210         local stripe_count
26211         local stripe_index
26212
26213         mkdir_on_mdt0 $DIR/$tdir
26214         mkdir $DIR/$tdir/normal_dir
26215
26216         #Checking when client cache stripe index
26217         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26218         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
26219                 error "create striped_dir failed"
26220
26221         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
26222                 error "create dir0 fails"
26223         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
26224         [ $stripe_index -eq 0 ] ||
26225                 error "dir0 expect index 0 got $stripe_index"
26226
26227         mkdir $DIR/$tdir/striped_dir/dir1 ||
26228                 error "create dir1 fails"
26229         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
26230         [ $stripe_index -eq 1 ] ||
26231                 error "dir1 expect index 1 got $stripe_index"
26232
26233         #check default stripe count/stripe index
26234         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
26235         test_300_check_default_striped_dir normal_dir 1 0
26236         test_300_check_default_striped_dir normal_dir -1 1
26237         test_300_check_default_striped_dir normal_dir 2 -1
26238
26239         #delete default stripe information
26240         echo "delete default stripeEA"
26241         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
26242                 error "set default stripe on striped dir error"
26243
26244         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
26245         for dir in $(find $DIR/$tdir/normal_dir/*); do
26246                 stripe_count=$($LFS getdirstripe -c $dir)
26247                 [ $stripe_count -eq 0 ] ||
26248                         error "expect 1 get $stripe_count for $dir"
26249         done
26250 }
26251 run_test 300g "check default striped directory for normal directory"
26252
26253 test_300h() {
26254         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26255         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26256                 skip "Need MDS version at least 2.7.55"
26257
26258         local dir
26259         local stripe_count
26260
26261         mkdir $DIR/$tdir
26262         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
26263                 error "set striped dir error"
26264
26265         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
26266         test_300_check_default_striped_dir striped_dir 1 0
26267         test_300_check_default_striped_dir striped_dir -1 1
26268         test_300_check_default_striped_dir striped_dir 2 -1
26269
26270         #delete default stripe information
26271         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
26272                 error "set default stripe on striped dir error"
26273
26274         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
26275         for dir in $(find $DIR/$tdir/striped_dir/*); do
26276                 stripe_count=$($LFS getdirstripe -c $dir)
26277                 [ $stripe_count -eq 0 ] ||
26278                         error "expect 1 get $stripe_count for $dir"
26279         done
26280 }
26281 run_test 300h "check default striped directory for striped directory"
26282
26283 test_300i() {
26284         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
26285         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
26286         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
26287                 skip "Need MDS version at least 2.7.55"
26288
26289         local stripe_count
26290         local file
26291
26292         mkdir $DIR/$tdir
26293
26294         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
26295                 error "set striped dir error"
26296
26297         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
26298                 error "create files under striped dir failed"
26299
26300         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
26301                 error "set striped hashdir error"
26302
26303         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
26304                 error "create dir0 under hash dir failed"
26305         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
26306                 error "create dir1 under hash dir failed"
26307         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
26308                 error "create dir2 under hash dir failed"
26309
26310         # unfortunately, we need to umount to clear dir layout cache for now
26311         # once we fully implement dir layout, we can drop this
26312         umount_client $MOUNT || error "umount failed"
26313         mount_client $MOUNT || error "mount failed"
26314
26315         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
26316         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
26317         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
26318
26319         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
26320                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
26321                         error "create crush2 dir $tdir/hashdir/d3 failed"
26322                 $LFS find -H crush2 $DIR/$tdir/hashdir
26323                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
26324                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
26325
26326                 # mkdir with an invalid hash type (hash=fail_val) from client
26327                 # should be replaced on MDS with a valid (default) hash type
26328                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
26329                 $LCTL set_param fail_loc=0x1901 fail_val=99
26330                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
26331
26332                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
26333                 local expect=$(do_facet mds1 \
26334                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
26335                 [[ $hash == $expect ]] ||
26336                         error "d99 hash '$hash' != expected hash '$expect'"
26337         fi
26338
26339         #set the stripe to be unknown hash type on read
26340         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
26341         $LCTL set_param fail_loc=0x1901 fail_val=99
26342         for ((i = 0; i < 10; i++)); do
26343                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
26344                         error "stat f-$i failed"
26345                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
26346         done
26347
26348         touch $DIR/$tdir/striped_dir/f0 &&
26349                 error "create under striped dir with unknown hash should fail"
26350
26351         $LCTL set_param fail_loc=0
26352
26353         umount_client $MOUNT || error "umount failed"
26354         mount_client $MOUNT || error "mount failed"
26355
26356         return 0
26357 }
26358 run_test 300i "client handle unknown hash type striped directory"
26359
26360 test_300j() {
26361         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26363         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26364                 skip "Need MDS version at least 2.7.55"
26365
26366         local stripe_count
26367         local file
26368
26369         mkdir $DIR/$tdir
26370
26371         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
26372         $LCTL set_param fail_loc=0x1702
26373         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
26374                 error "set striped dir error"
26375
26376         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
26377                 error "create files under striped dir failed"
26378
26379         $LCTL set_param fail_loc=0
26380
26381         rm -rf $DIR/$tdir || error "unlink striped dir fails"
26382
26383         return 0
26384 }
26385 run_test 300j "test large update record"
26386
26387 test_300k() {
26388         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26389         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26390         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26391                 skip "Need MDS version at least 2.7.55"
26392
26393         # this test needs a huge transaction
26394         local kb
26395         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
26396              osd*.$FSNAME-MDT0000.kbytestotal")
26397         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
26398
26399         local stripe_count
26400         local file
26401
26402         mkdir $DIR/$tdir
26403
26404         #define OBD_FAIL_LARGE_STRIPE   0x1703
26405         $LCTL set_param fail_loc=0x1703
26406         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
26407                 error "set striped dir error"
26408         $LCTL set_param fail_loc=0
26409
26410         $LFS getdirstripe $DIR/$tdir/striped_dir ||
26411                 error "getstripeddir fails"
26412         rm -rf $DIR/$tdir/striped_dir ||
26413                 error "unlink striped dir fails"
26414
26415         return 0
26416 }
26417 run_test 300k "test large striped directory"
26418
26419 test_300l() {
26420         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26421         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26422         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26423                 skip "Need MDS version at least 2.7.55"
26424
26425         local stripe_index
26426
26427         test_mkdir -p $DIR/$tdir/striped_dir
26428         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
26429                         error "chown $RUNAS_ID failed"
26430         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
26431                 error "set default striped dir failed"
26432
26433         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
26434         $LCTL set_param fail_loc=0x80000158
26435         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
26436
26437         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
26438         [ $stripe_index -eq 1 ] ||
26439                 error "expect 1 get $stripe_index for $dir"
26440 }
26441 run_test 300l "non-root user to create dir under striped dir with stale layout"
26442
26443 test_300m() {
26444         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26445         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
26446         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26447                 skip "Need MDS version at least 2.7.55"
26448
26449         mkdir -p $DIR/$tdir/striped_dir
26450         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
26451                 error "set default stripes dir error"
26452
26453         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
26454
26455         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
26456         [ $stripe_count -eq 0 ] ||
26457                         error "expect 0 get $stripe_count for a"
26458
26459         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
26460                 error "set default stripes dir error"
26461
26462         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
26463
26464         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
26465         [ $stripe_count -eq 0 ] ||
26466                         error "expect 0 get $stripe_count for b"
26467
26468         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
26469                 error "set default stripes dir error"
26470
26471         mkdir $DIR/$tdir/striped_dir/c &&
26472                 error "default stripe_index is invalid, mkdir c should fails"
26473
26474         rm -rf $DIR/$tdir || error "rmdir fails"
26475 }
26476 run_test 300m "setstriped directory on single MDT FS"
26477
26478 cleanup_300n() {
26479         local list=$(comma_list $(mdts_nodes))
26480
26481         trap 0
26482         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26483 }
26484
26485 test_300n() {
26486         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26487         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26488         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26489                 skip "Need MDS version at least 2.7.55"
26490         remote_mds_nodsh && skip "remote MDS with nodsh"
26491
26492         local stripe_index
26493         local list=$(comma_list $(mdts_nodes))
26494
26495         trap cleanup_300n RETURN EXIT
26496         mkdir -p $DIR/$tdir
26497         chmod 777 $DIR/$tdir
26498         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
26499                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
26500                 error "create striped dir succeeds with gid=0"
26501
26502         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
26503         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
26504                 error "create striped dir fails with gid=-1"
26505
26506         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26507         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
26508                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
26509                 error "set default striped dir succeeds with gid=0"
26510
26511
26512         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
26513         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
26514                 error "set default striped dir fails with gid=-1"
26515
26516
26517         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26518         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
26519                                         error "create test_dir fails"
26520         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
26521                                         error "create test_dir1 fails"
26522         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
26523                                         error "create test_dir2 fails"
26524         cleanup_300n
26525 }
26526 run_test 300n "non-root user to create dir under striped dir with default EA"
26527
26528 test_300o() {
26529         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26530         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26531         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26532                 skip "Need MDS version at least 2.7.55"
26533
26534         local numfree1
26535         local numfree2
26536
26537         mkdir -p $DIR/$tdir
26538
26539         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
26540         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
26541         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
26542                 skip "not enough free inodes $numfree1 $numfree2"
26543         fi
26544
26545         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
26546         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
26547         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
26548                 skip "not enough free space $numfree1 $numfree2"
26549         fi
26550
26551         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
26552                 error "setdirstripe fails"
26553
26554         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
26555                 error "create dirs fails"
26556
26557         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
26558         ls $DIR/$tdir/striped_dir > /dev/null ||
26559                 error "ls striped dir fails"
26560         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
26561                 error "unlink big striped dir fails"
26562 }
26563 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
26564
26565 test_300p() {
26566         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26567         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26568         remote_mds_nodsh && skip "remote MDS with nodsh"
26569
26570         mkdir_on_mdt0 $DIR/$tdir
26571
26572         #define OBD_FAIL_OUT_ENOSPC     0x1704
26573         do_facet mds2 lctl set_param fail_loc=0x80001704
26574         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
26575                  && error "create striped directory should fail"
26576
26577         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
26578
26579         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
26580         true
26581 }
26582 run_test 300p "create striped directory without space"
26583
26584 test_300q() {
26585         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26586         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26587
26588         local fd=$(free_fd)
26589         local cmd="exec $fd<$tdir"
26590         cd $DIR
26591         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
26592         eval $cmd
26593         cmd="exec $fd<&-"
26594         trap "eval $cmd" EXIT
26595         cd $tdir || error "cd $tdir fails"
26596         rmdir  ../$tdir || error "rmdir $tdir fails"
26597         mkdir local_dir && error "create dir succeeds"
26598         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
26599         eval $cmd
26600         return 0
26601 }
26602 run_test 300q "create remote directory under orphan directory"
26603
26604 test_300r() {
26605         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26606                 skip "Need MDS version at least 2.7.55" && return
26607         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
26608
26609         mkdir $DIR/$tdir
26610
26611         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
26612                 error "set striped dir error"
26613
26614         $LFS getdirstripe $DIR/$tdir/striped_dir ||
26615                 error "getstripeddir fails"
26616
26617         local stripe_count
26618         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
26619                       awk '/lmv_stripe_count:/ { print $2 }')
26620
26621         [ $MDSCOUNT -ne $stripe_count ] &&
26622                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
26623
26624         rm -rf $DIR/$tdir/striped_dir ||
26625                 error "unlink striped dir fails"
26626 }
26627 run_test 300r "test -1 striped directory"
26628
26629 test_300s_helper() {
26630         local count=$1
26631
26632         local stripe_dir=$DIR/$tdir/striped_dir.$count
26633
26634         $LFS mkdir -c $count $stripe_dir ||
26635                 error "lfs mkdir -c error"
26636
26637         $LFS getdirstripe $stripe_dir ||
26638                 error "lfs getdirstripe fails"
26639
26640         local stripe_count
26641         stripe_count=$($LFS getdirstripe $stripe_dir |
26642                       awk '/lmv_stripe_count:/ { print $2 }')
26643
26644         [ $count -ne $stripe_count ] &&
26645                 error_noexit "bad stripe count $stripe_count expected $count"
26646
26647         local dupe_stripes
26648         dupe_stripes=$($LFS getdirstripe $stripe_dir |
26649                 awk '/0x/ {count[$1] += 1}; END {
26650                         for (idx in count) {
26651                                 if (count[idx]>1) {
26652                                         print "index " idx " count " count[idx]
26653                                 }
26654                         }
26655                 }')
26656
26657         if [[ -n "$dupe_stripes" ]] ; then
26658                 lfs getdirstripe $stripe_dir
26659                 error_noexit "Dupe MDT above: $dupe_stripes "
26660         fi
26661
26662         rm -rf $stripe_dir ||
26663                 error_noexit "unlink $stripe_dir fails"
26664 }
26665
26666 test_300s() {
26667         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26668                 skip "Need MDS version at least 2.7.55" && return
26669         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
26670
26671         mkdir $DIR/$tdir
26672         for count in $(seq 2 $MDSCOUNT); do
26673                 test_300s_helper $count
26674         done
26675 }
26676 run_test 300s "test lfs mkdir -c without -i"
26677
26678 test_300t() {
26679         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
26680                 skip "need MDS 2.14.55 or later"
26681         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
26682
26683         local testdir="$DIR/$tdir/striped_dir"
26684         local dir1=$testdir/dir1
26685         local dir2=$testdir/dir2
26686
26687         mkdir -p $testdir
26688
26689         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
26690                 error "failed to set default stripe count for $testdir"
26691
26692         mkdir $dir1
26693         local stripe_count=$($LFS getdirstripe -c $dir1)
26694
26695         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
26696
26697         local max_count=$((MDSCOUNT - 1))
26698         local mdts=$(comma_list $(mdts_nodes))
26699
26700         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
26701         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
26702
26703         mkdir $dir2
26704         stripe_count=$($LFS getdirstripe -c $dir2)
26705
26706         (( $stripe_count == $max_count )) || error "wrong stripe count"
26707 }
26708 run_test 300t "test max_mdt_stripecount"
26709
26710 MDT_OVSTRP_VER="2.15.60"
26711 # 300u family tests MDT overstriping
26712 test_300ua() {
26713         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26714
26715         local setcount=$((MDSCOUNT * 2))
26716
26717         local expected_count
26718
26719         mkdir $DIR/$tdir
26720         $LFS setdirstripe -C $setcount $DIR/$tdir/${tdir}.0 ||
26721                 error "(0) failed basic overstriped dir creation test"
26722         local getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.0)
26723
26724         # This does a basic interop test - if the MDS does not support mdt
26725         # overstriping, we should get stripes == number of MDTs
26726         if (( $MDS1_VERSION < $(version_code $MDT_OVSTRP_VER) )); then
26727                 expected_count=$MDSCOUNT
26728         else
26729                 expected_count=$setcount
26730         fi
26731         (( getstripe_count == expected_count )) ||
26732                 error "(1) incorrect stripe count for simple overstriped dir"
26733
26734         rm -rf $DIR/$tdir/${tdir}.0 ||
26735                 error "(2) unable to rm overstriped dir"
26736
26737         # Tests after this require overstriping support
26738         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26739                 { echo "skipped for MDS < $MDT_OVSTRP_VER"; return 0; }
26740
26741         test_striped_dir 0 $setcount true ||
26742                 error "(3)failed on overstriped dir"
26743         test_striped_dir 1 $setcount true ||
26744                 error "(4)failed on overstriped dir"
26745
26746         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26747
26748         test_striped_dir 0 $setcount true ||
26749                 error "(5)failed on overstriped dir"
26750 }
26751 run_test 300ua "basic overstriped dir sanity test"
26752
26753 test_300ub() {
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         echo "Testing invalid stripe count, failure expected"
26761         local setcount=$((MDSCOUNT * 2))
26762
26763         $LFS setdirstripe -c $setcount $DIR/$tdir/${tdir}.0
26764         local getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.0)
26765
26766         (( getstripe_count <= MDSCOUNT )) ||
26767                 error "(0)stripe count ($setcount) > MDT count ($MDSCOUNT) succeeded with -c"
26768
26769         # When a user requests > LMV_MAX_STRIPES_PER_MDT, we reduce to that
26770         setcount=$((MDSCOUNT * 2 * LMV_MAX_STRIPES_PER_MDT))
26771         $LFS setdirstripe -C $setcount $DIR/$tdir/${tdir}.1
26772
26773         local maxcount=$((MDSCOUNT * LMV_MAX_STRIPES_PER_MDT))
26774
26775         getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.1)
26776         (( getstripe_count == maxcount )) ||
26777                 error "(1)stripe_count is $getstripe_count, expect $maxcount"
26778
26779         # Test specific striping with -i
26780         $LFS setdirstripe -i 0,0,0,0 $DIR/$tdir/${tdir}.2
26781
26782         getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.2)
26783         (( getstripe_count == 4 )) ||
26784                 error "(2)stripe_count is $getstripe_count, expect 4"
26785
26786         local nonzeroindices=$($LFS getdirstripe $DIR/$tdir/${tdir}.2 | grep "\[" | \
26787                                grep -v mdtidx | awk '{print $1}' | grep -c -v 0)
26788
26789         [[ -n "$nonzeroindices" ]] ||
26790                 error "(3) stripes indices not all 0: $nonzeroindices"
26791
26792         # Test specific striping with too many stripes on one MDT
26793         echo "Testing invalid striping, failure expected"
26794         $LFS setdirstripe -i 0,1,0,1,0,1,0,1,0,1,0 $DIR/$tdir/${tdir}.3
26795         $LFS getdirstripe $DIR/$tdir/${tdir}.3
26796         getstripe_count=$($LFS getdirstripe $DIR/$tdir/${tdir}.3 | grep "\[" | \
26797                           grep -v mdtidx | awk '{print $1}' | grep -c '0')
26798         echo "stripes on MDT0: $getstripe_count"
26799         (( getstripe_count <= LMV_MAX_STRIPES_PER_MDT )) ||
26800                 error "(4) setstripe with too many stripes on MDT0 succeeded"
26801
26802         setcount=$((MDSCOUNT * 2))
26803         $LFS setdirstripe -C $setcount -H all_char $DIR/${tdir}.4 ||
26804                 error "(5) can't setdirstripe with manually set hash function"
26805
26806         getstripe_count=$($LFS getdirstripe -c $DIR/${tdir}.4)
26807         (( getstripe_count == setcount )) ||
26808                 error "(6)stripe_count is $getstripe_count, expect $setcount"
26809
26810         setcount=$((MDSCOUNT * 2))
26811         mkdir $DIR/${tdir}.5
26812         $LFS setdirstripe -C $setcount -D -H crush $DIR/${tdir}.5 ||
26813                 error "(7) can't setdirstripe with manually set hash function"
26814         mkdir $DIR/${tdir}.5/${tdir}.6
26815
26816         getstripe_count=$($LFS getdirstripe -c $DIR/${tdir}.5/${tdir}.6)
26817         (( getstripe_count == setcount )) ||
26818                 error "(8)stripe_count is $getstripe_count, expect $setcount"
26819 }
26820 run_test 300ub "test MDT overstriping interface & limits"
26821
26822 test_300uc() {
26823         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26824                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26825         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26826
26827         mkdir $DIR/$tdir
26828
26829         local setcount=$((MDSCOUNT * 2))
26830
26831         $LFS setdirstripe -D -C $setcount $DIR/$tdir
26832
26833         mkdir $DIR/$tdir/${tdir}.1
26834
26835         local getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.1)
26836
26837         (( getstripe_count == setcount )) ||
26838                 error "(0)stripe_count is $getstripe_count, expect $setcount"
26839
26840         mkdir $DIR/$tdir/${tdir}.1/${tdir}.2
26841
26842         local getstripe_count=$($LFS getdirstripe -c \
26843                                 $DIR/$tdir/${tdir}.1/${tdir}.2)
26844
26845         (( getstripe_count == setcount )) ||
26846                 error "(1)stripe_count is $getstripe_count, expect $setcount"
26847 }
26848 run_test 300uc "test MDT overstriping as default & inheritance"
26849
26850 test_300ud() {
26851         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26852                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26853         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26854
26855         local mdts=$(comma_list $(mdts_nodes))
26856         local timeout=100
26857
26858         local restripe_status
26859         local delta
26860         local i
26861
26862         [[ $mds1_FSTYPE == zfs ]] && timeout=300
26863
26864         # in case "crush" hash type is not set
26865         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
26866
26867         restripe_status=$(do_facet mds1 $LCTL get_param -n \
26868                            mdt.*MDT0000.enable_dir_restripe)
26869         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
26870         stack_trap "do_nodes $mdts $LCTL set_param \
26871                     mdt.*.enable_dir_restripe=$restripe_status"
26872
26873         mkdir $DIR/$tdir
26874         createmany -m $DIR/$tdir/f $((50 * MDSCOUNT)) ||
26875                 error "create files under remote dir failed $i"
26876         createmany -d $DIR/$tdir/d $((50 * MDSCOUNT)) ||
26877                 error "create dirs under remote dir failed $i"
26878
26879         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26880
26881         (( setcount < 13 )) || setcount=12
26882         for i in $(seq 2 $setcount); do
26883                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
26884                 $LFS setdirstripe -C $i $DIR/$tdir ||
26885                         error "split -C $i $tdir failed"
26886                 wait_update $HOSTNAME \
26887                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
26888                         error "dir split not finished"
26889                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
26890                         awk '/migrate/ {sum += $2} END { print sum }')
26891                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
26892                 # delta is around total_files/stripe_count, deviation 3%
26893                 (( delta < 100 * MDSCOUNT / i + 3 * MDSCOUNT )) ||
26894                         error "$delta files migrated >= $((100 * MDSCOUNT / i + 3 * MDSCOUNT))"
26895         done
26896 }
26897 run_test 300ud "dir split"
26898
26899 test_300ue() {
26900         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26901                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26902         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26903
26904         local mdts=$(comma_list $(mdts_nodes))
26905         local timeout=100
26906
26907         local restripe_status
26908         local delta
26909         local c
26910
26911         [[ $mds1_FSTYPE == zfs ]] && timeout=300
26912
26913         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
26914
26915         restripe_status=$(do_facet mds1 $LCTL get_param -n \
26916                            mdt.*MDT0000.enable_dir_restripe)
26917         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
26918         stack_trap "do_nodes $mdts $LCTL set_param \
26919                     mdt.*.enable_dir_restripe=$restripe_status"
26920
26921         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26922
26923         (( setcount < 13 )) || setcount=12
26924         test_mkdir -C $setcount -H crush $DIR/$tdir
26925         createmany -m $DIR/$tdir/f $((50 * MDSCOUNT)) ||
26926                 error "create files under remote dir failed"
26927         createmany -d $DIR/$tdir/d $((50 * MDSCOUNT)) ||
26928                 error "create dirs under remote dir failed"
26929
26930         for c in $(seq $((setcount - 1)) -1 1); do
26931                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
26932                 $LFS setdirstripe -C $c $DIR/$tdir ||
26933                         error "split -C $c $tdir failed"
26934                 wait_update $HOSTNAME \
26935                         "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" $timeout ||
26936                         error "dir merge not finished"
26937                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
26938                         awk '/migrate/ {sum += $2} END { print sum }')
26939                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
26940                 # delta is around total_files/stripe_count, deviation 3%
26941                 (( delta < 100 * MDSCOUNT / c + 3 * MDSCOUNT )) ||
26942                         error "$delta files migrated >= $((100 * MDSCOUNT / c + 3 * MDSCOUNT))"
26943         done
26944 }
26945 run_test 300ue "dir merge"
26946
26947 test_300uf() {
26948         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26949                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26950         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26951
26952         # maximum amount of local locks:
26953         # parent striped dir - 2 locks
26954         # new stripe in parent to migrate to - 1 lock
26955         # source and target - 2 locks
26956         # Total 5 locks for regular file
26957         #
26958         # NB: Overstriping should add several extra local locks
26959         # FIXME: Remove this once understood
26960         #lctl set_param *debug=-1 debug_mb=10000
26961         lctl clear
26962         lctl mark "touch/create"
26963         mkdir -p $DIR/$tdir
26964         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26965         local setcount=$((MDSCOUNT * 5))
26966
26967         $LFS mkdir -i1 -C $setcount $DIR/$tdir/dir1
26968         touch $DIR/$tdir/dir1/eee
26969
26970         lctl mark "hardlinks"
26971         # create 4 hardlink for 4 more locks
26972         # Total: 9 locks > RS_MAX_LOCKS (8)
26973         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
26974         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
26975         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
26976         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
26977         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
26978         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
26979         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
26980         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
26981
26982         lctl mark "cancel lru"
26983         cancel_lru_locks mdc
26984
26985         lctl mark "migrate"
26986         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
26987                 error "migrate dir fails"
26988
26989         rm -rf $DIR/$tdir || error "rm dir failed after migration"
26990 }
26991 run_test 300uf "migrate with too many local locks"
26992
26993 test_300ug() {
26994         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26995                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26996         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26997
26998         mkdir -p $DIR/$tdir
26999         local migrate_dir=$DIR/$tdir/migrate_dir
27000         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
27001         local setcount2=$((setcount - 2))
27002
27003         $LFS setdirstripe -c 2 $migrate_dir ||
27004                 error "(0) failed to create striped directory"
27005
27006         $LFS migrate -m 0 -C $setcount $migrate_dir ||
27007                 error "(1)failed to migrate to overstriped directory"
27008         local getstripe_count=$($LFS getdirstripe -c $migrate_dir)
27009
27010         (( getstripe_count == setcount )) ||
27011                 error "(2)stripe_count is $getstripe_count, expect $setcount"
27012         touch $DIR/$tdir/migrate_dir/$tfile ||
27013                 error "(3)failed to create file in overstriped directory"
27014         $LFS migrate -m 0 -C $setcount2 $migrate_dir ||
27015                 error "(4)failed to migrate overstriped directory"
27016         # Check stripe count after migration
27017         $LFS getdirstripe $migrate_dir
27018         getstripe_count=$($LFS getdirstripe -c $migrate_dir)
27019         (( getstripe_count == setcount2 )) ||
27020                 error "(5)stripe_count is $getstripe_count, expect $setcount2"
27021
27022         rm -rf $migrate_dir || error "(6) unable to rm overstriped dir"
27023 }
27024 run_test 300ug "migrate overstriped dirs"
27025
27026 prepare_remote_file() {
27027         mkdir $DIR/$tdir/src_dir ||
27028                 error "create remote source failed"
27029
27030         cp /etc/hosts $DIR/$tdir/src_dir/a ||
27031                  error "cp to remote source failed"
27032         touch $DIR/$tdir/src_dir/a
27033
27034         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
27035                 error "create remote target dir failed"
27036
27037         touch $DIR/$tdir/tgt_dir/b
27038
27039         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
27040                 error "rename dir cross MDT failed!"
27041
27042         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
27043                 error "src_child still exists after rename"
27044
27045         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
27046                 error "missing file(a) after rename"
27047
27048         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
27049                 error "diff after rename"
27050 }
27051
27052 test_310a() {
27053         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
27054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27055
27056         local remote_file=$DIR/$tdir/tgt_dir/b
27057
27058         mkdir -p $DIR/$tdir
27059
27060         prepare_remote_file || error "prepare remote file failed"
27061
27062         #open-unlink file
27063         $OPENUNLINK $remote_file $remote_file ||
27064                 error "openunlink $remote_file failed"
27065         $CHECKSTAT -a $remote_file || error "$remote_file exists"
27066 }
27067 run_test 310a "open unlink remote file"
27068
27069 test_310b() {
27070         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
27071         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27072
27073         local remote_file=$DIR/$tdir/tgt_dir/b
27074
27075         mkdir -p $DIR/$tdir
27076
27077         prepare_remote_file || error "prepare remote file failed"
27078
27079         ln $remote_file $DIR/$tfile || error "link failed for remote file"
27080         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
27081         $CHECKSTAT -t file $remote_file || error "check file failed"
27082 }
27083 run_test 310b "unlink remote file with multiple links while open"
27084
27085 test_310c() {
27086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27087         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
27088
27089         local remote_file=$DIR/$tdir/tgt_dir/b
27090
27091         mkdir -p $DIR/$tdir
27092
27093         prepare_remote_file || error "prepare remote file failed"
27094
27095         ln $remote_file $DIR/$tfile || error "link failed for remote file"
27096         multiop_bg_pause $remote_file O_uc ||
27097                         error "mulitop failed for remote file"
27098         MULTIPID=$!
27099         $MULTIOP $DIR/$tfile Ouc
27100         kill -USR1 $MULTIPID
27101         wait $MULTIPID
27102 }
27103 run_test 310c "open-unlink remote file with multiple links"
27104
27105 #LU-4825
27106 test_311() {
27107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27108         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
27109         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
27110                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
27111         remote_mds_nodsh && skip "remote MDS with nodsh"
27112
27113         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
27114         local mdts=$(comma_list $(mdts_nodes))
27115
27116         mkdir -p $DIR/$tdir
27117         $LFS setstripe -i 0 -c 1 $DIR/$tdir
27118         createmany -o $DIR/$tdir/$tfile. 1000
27119
27120         # statfs data is not real time, let's just calculate it
27121         old_iused=$((old_iused + 1000))
27122
27123         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27124                         osp.*OST0000*MDT0000.create_count")
27125         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27126                                 osp.*OST0000*MDT0000.max_create_count")
27127         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
27128
27129         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
27130         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
27131         [ $index -ne 0 ] || error "$tfile stripe index is 0"
27132
27133         unlinkmany $DIR/$tdir/$tfile. 1000
27134
27135         do_nodes $mdts "$LCTL set_param -n \
27136                         osp.*OST0000*.max_create_count=$max_count"
27137         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
27138                 do_nodes $mdts "$LCTL set_param -n \
27139                                 osp.*OST0000*.create_count=$count"
27140         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
27141                         grep "=0" && error "create_count is zero"
27142
27143         local new_iused
27144         for i in $(seq 120); do
27145                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
27146                 # system may be too busy to destroy all objs in time, use
27147                 # a somewhat small value to not fail autotest
27148                 [ $((old_iused - new_iused)) -gt 400 ] && break
27149                 sleep 1
27150         done
27151
27152         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
27153         [ $((old_iused - new_iused)) -gt 400 ] ||
27154                 error "objs not destroyed after unlink"
27155 }
27156 run_test 311 "disable OSP precreate, and unlink should destroy objs"
27157
27158 zfs_get_objid()
27159 {
27160         local ost=$1
27161         local tf=$2
27162         local fid=($($LFS getstripe $tf | grep 0x))
27163         local seq=${fid[3]#0x}
27164         local objid=${fid[1]}
27165
27166         local vdevdir=$(dirname $(facet_vdevice $ost))
27167         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
27168         local zfs_zapid=$(do_facet $ost $cmd |
27169                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
27170                           awk '/Object/{getline; print $1}')
27171         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
27172                           awk "/$objid = /"'{printf $3}')
27173
27174         echo $zfs_objid
27175 }
27176
27177 zfs_object_blksz() {
27178         local ost=$1
27179         local objid=$2
27180
27181         local vdevdir=$(dirname $(facet_vdevice $ost))
27182         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
27183         local blksz=$(do_facet $ost $cmd $objid |
27184                       awk '/dblk/{getline; printf $4}')
27185
27186         case "${blksz: -1}" in
27187                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
27188                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
27189                 *) ;;
27190         esac
27191
27192         echo $blksz
27193 }
27194
27195 test_312() { # LU-4856
27196         remote_ost_nodsh && skip "remote OST with nodsh"
27197         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
27198
27199         local max_blksz=$(do_facet ost1 \
27200                           $ZFS get -p recordsize $(facet_device ost1) |
27201                           awk '!/VALUE/{print $3}')
27202         local tf=$DIR/$tfile
27203
27204         $LFS setstripe -c1 $tf
27205         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
27206
27207         # Get ZFS object id
27208         local zfs_objid=$(zfs_get_objid $facet $tf)
27209         # block size change by sequential overwrite
27210         local bs
27211
27212         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
27213                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
27214
27215                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
27216                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
27217         done
27218         rm -f $tf
27219
27220         $LFS setstripe -c1 $tf
27221         facet="ost$(($($LFS getstripe -i $tf) + 1))"
27222
27223         # block size change by sequential append write
27224         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
27225         zfs_objid=$(zfs_get_objid $facet $tf)
27226         local count
27227
27228         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
27229                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
27230                         oflag=sync conv=notrunc
27231
27232                 blksz=$(zfs_object_blksz $facet $zfs_objid)
27233                 (( $blksz == 2 * count * PAGE_SIZE )) ||
27234                         error "blksz error, actual $blksz, " \
27235                                 "expected: 2 * $count * $PAGE_SIZE"
27236         done
27237         rm -f $tf
27238
27239         # random write
27240         $LFS setstripe -c1 $tf
27241         facet="ost$(($($LFS getstripe -i $tf) + 1))"
27242         zfs_objid=$(zfs_get_objid $facet $tf)
27243
27244         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
27245         blksz=$(zfs_object_blksz $facet $zfs_objid)
27246         (( blksz == PAGE_SIZE )) ||
27247                 error "blksz error: $blksz, expected: $PAGE_SIZE"
27248
27249         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
27250         blksz=$(zfs_object_blksz $facet $zfs_objid)
27251         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
27252
27253         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
27254         blksz=$(zfs_object_blksz $facet $zfs_objid)
27255         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
27256 }
27257 run_test 312 "make sure ZFS adjusts its block size by write pattern"
27258
27259 test_313() {
27260         remote_ost_nodsh && skip "remote OST with nodsh"
27261
27262         local file=$DIR/$tfile
27263
27264         rm -f $file
27265         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
27266
27267         # define OBD_FAIL_TGT_RCVD_EIO           0x720
27268         do_facet ost1 "$LCTL set_param fail_loc=0x720"
27269         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
27270                 error "write should failed"
27271         do_facet ost1 "$LCTL set_param fail_loc=0"
27272         rm -f $file
27273 }
27274 run_test 313 "io should fail after last_rcvd update fail"
27275
27276 test_314() {
27277         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
27278
27279         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
27280         do_facet ost1 "$LCTL set_param fail_loc=0x720"
27281         rm -f $DIR/$tfile
27282         wait_delete_completed
27283         do_facet ost1 "$LCTL set_param fail_loc=0"
27284 }
27285 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
27286
27287 test_315() { # LU-618
27288         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
27289
27290         local file=$DIR/$tfile
27291         rm -f $file
27292
27293         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
27294                 error "multiop file write failed"
27295         $MULTIOP $file oO_RDONLY:r4063232_c &
27296         PID=$!
27297
27298         sleep 2
27299
27300         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
27301         kill -USR1 $PID
27302
27303         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
27304         rm -f $file
27305 }
27306 run_test 315 "read should be accounted"
27307
27308 test_316() {
27309         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
27310         large_xattr_enabled || skip "ea_inode feature disabled"
27311
27312         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27313         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
27314         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
27315         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
27316
27317         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
27318 }
27319 run_test 316 "lfs migrate of file with large_xattr enabled"
27320
27321 test_317() {
27322         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
27323                 skip "Need MDS version at least 2.11.53"
27324         if [ "$ost1_FSTYPE" == "zfs" ]; then
27325                 skip "LU-10370: no implementation for ZFS"
27326         fi
27327
27328         local trunc_sz
27329         local grant_blk_size
27330
27331         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
27332                         awk '/grant_block_size:/ { print $2; exit; }')
27333         #
27334         # Create File of size 5M. Truncate it to below size's and verify
27335         # blocks count.
27336         #
27337         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
27338                 error "Create file $DIR/$tfile failed"
27339         stack_trap "rm -f $DIR/$tfile" EXIT
27340
27341         for trunc_sz in 2097152 4097 4000 509 0; do
27342                 $TRUNCATE $DIR/$tfile $trunc_sz ||
27343                         error "truncate $tfile to $trunc_sz failed"
27344                 local sz=$(stat --format=%s $DIR/$tfile)
27345                 local blk=$(stat --format=%b $DIR/$tfile)
27346                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
27347                                      grant_blk_size) * 8))
27348
27349                 if [[ $blk -ne $trunc_blk ]]; then
27350                         $(which stat) $DIR/$tfile
27351                         error "Expected Block $trunc_blk got $blk for $tfile"
27352                 fi
27353
27354                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
27355                         error "Expected Size $trunc_sz got $sz for $tfile"
27356         done
27357
27358         #
27359         # sparse file test
27360         # Create file with a hole and write actual 65536 bytes which aligned
27361         # with 4K and 64K PAGE_SIZE. Block count must be 128.
27362         #
27363         local bs=65536
27364         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
27365                 error "Create file : $DIR/$tfile"
27366
27367         #
27368         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
27369         # blocks. The block count must drop to 8.
27370         #
27371         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
27372                 ((bs - grant_blk_size) + 1)))
27373         $TRUNCATE $DIR/$tfile $trunc_sz ||
27374                 error "truncate $tfile to $trunc_sz failed"
27375
27376         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
27377         sz=$(stat --format=%s $DIR/$tfile)
27378         blk=$(stat --format=%b $DIR/$tfile)
27379
27380         if [[ $blk -ne $trunc_bsz ]]; then
27381                 $(which stat) $DIR/$tfile
27382                 error "Expected Block $trunc_bsz got $blk for $tfile"
27383         fi
27384
27385         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
27386                 error "Expected Size $trunc_sz got $sz for $tfile"
27387 }
27388 run_test 317 "Verify blocks get correctly update after truncate"
27389
27390 test_318() {
27391         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
27392         local old_max_active=$($LCTL get_param -n \
27393                             ${llite_name}.max_read_ahead_async_active \
27394                             2>/dev/null)
27395
27396         $LCTL set_param llite.*.max_read_ahead_async_active=256
27397         local max_active=$($LCTL get_param -n \
27398                            ${llite_name}.max_read_ahead_async_active \
27399                            2>/dev/null)
27400         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
27401
27402         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
27403                 error "set max_read_ahead_async_active should succeed"
27404
27405         $LCTL set_param llite.*.max_read_ahead_async_active=512
27406         max_active=$($LCTL get_param -n \
27407                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
27408         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
27409
27410         # restore @max_active
27411         [ $old_max_active -ne 0 ] && $LCTL set_param \
27412                 llite.*.max_read_ahead_async_active=$old_max_active
27413
27414         local old_threshold=$($LCTL get_param -n \
27415                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
27416         local max_per_file_mb=$($LCTL get_param -n \
27417                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
27418
27419         local invalid=$(($max_per_file_mb + 1))
27420         $LCTL set_param \
27421                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
27422                         && error "set $invalid should fail"
27423
27424         local valid=$(($invalid - 1))
27425         $LCTL set_param \
27426                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
27427                         error "set $valid should succeed"
27428         local threshold=$($LCTL get_param -n \
27429                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
27430         [ $threshold -eq $valid ] || error \
27431                 "expect threshold $valid got $threshold"
27432         $LCTL set_param \
27433                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
27434 }
27435 run_test 318 "Verify async readahead tunables"
27436
27437 test_319() {
27438         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
27439
27440         local before=$(date +%s)
27441         local evict
27442         local mdir=$DIR/$tdir
27443         local file=$mdir/xxx
27444
27445         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
27446         touch $file
27447
27448 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
27449         $LCTL set_param fail_val=5 fail_loc=0x8000032c
27450         $LFS migrate -m1 $mdir &
27451
27452         sleep 1
27453         dd if=$file of=/dev/null
27454         wait
27455         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
27456           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
27457
27458         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
27459 }
27460 run_test 319 "lost lease lock on migrate error"
27461
27462 test_350() {
27463         local mdts=$(comma_list $(mdts_nodes))
27464
27465         mkdir $DIR/$tdir || error "mkdir $DIR/$tdir failed"
27466         stack_trap "rm -r $DIR/$tdir"
27467
27468         #force 1/100 of replies to take "NID mismatch" codepath
27469         #define CFS_FAIL_MATCH_MD_NID 0xe001  CFS_FAIL_SOME 0x10000000
27470         do_nodes $mdts $LCTL set_param fail_loc=0x1000e001 fail_val=100
27471
27472         while ls -lR $DIR/$tdir > /dev/null; do :; done &
27473         stack_trap "killall -9 ls || killall -9 ls"
27474
27475         cp -a /etc $DIR/$tdir || error "cp failed"
27476 }
27477 run_test 350 "force NID mismatch path to be exercised"
27478
27479 test_360() {
27480         (( $OST1_VERSION >= $(version_code 2.15.58.96) )) ||
27481                 skip "Need OST version at least 2.15.58.96"
27482         [[ "$ost1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
27483
27484         check_set_fallocate_or_skip
27485         local param="osd-ldiskfs.delayed_unlink_mb"
27486         local old=($(do_facet ost1 "$LCTL get_param -n $param"))
27487
27488         do_facet ost1 "$LCTL set_param $param=1MiB"
27489         stack_trap "do_facet ost1 $LCTL set_param $param=${old[0]}"
27490
27491         mkdir $DIR/$tdir/
27492         do_facet ost1 $LCTL set_param debug=+inode
27493         do_facet ost1 $LCTL clear
27494         local files=100
27495
27496         for ((i = 0; i < $files; i++)); do
27497                 fallocate -l 1280k $DIR/$tdir/$tfile.$i ||
27498                         error "fallocate 1280k $DIR/$tdir/$tfile.$i failed"
27499         done
27500         local min=$(($($LFS find $DIR/$tdir --ost 0 | wc -l) / 2))
27501
27502         for ((i = 0; i < $files; i++)); do
27503                 unlink $DIR/$tdir/$tfile.$i ||
27504                         error "unlink $DIR/$tdir/$tfile.$i failed"
27505         done
27506
27507         local count=0
27508         local loop
27509
27510         for (( loop = 0; loop < 30 && count < min; loop++)); do
27511                 sleep 1
27512                 (( count += $(do_facet ost1 $LCTL dk | grep -c "delayed iput")))
27513                 echo "Count[$loop]: $count"
27514         done
27515         (( count >= min )) || error "$count < $min delayed iput after $loop s"
27516 }
27517 run_test 360 "ldiskfs unlink in a separate thread"
27518
27519 test_398a() { # LU-4198
27520         local ost1_imp=$(get_osc_import_name client ost1)
27521         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27522                          cut -d'.' -f2)
27523
27524         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27525         stack_trap "rm -f $DIR/$tfile"
27526         $LCTL set_param ldlm.namespaces.*.lru_size=clear
27527
27528         # request a new lock on client
27529         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27530
27531         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
27532         local lock_count=$($LCTL get_param -n \
27533                            ldlm.namespaces.$imp_name.lru_size)
27534         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
27535
27536         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
27537
27538         # no lock cached, should use lockless DIO and not enqueue new lock
27539         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
27540         lock_count=$($LCTL get_param -n \
27541                      ldlm.namespaces.$imp_name.lru_size)
27542         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
27543
27544         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
27545
27546         # no lock cached, should use locked DIO append
27547         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
27548                 conv=notrunc || error "DIO append failed"
27549         lock_count=$($LCTL get_param -n \
27550                      ldlm.namespaces.$imp_name.lru_size)
27551         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
27552 }
27553 run_test 398a "direct IO should cancel lock otherwise lockless"
27554
27555 test_398b() { # LU-4198
27556         local before=$(date +%s)
27557         local njobs=4
27558         local size=48
27559
27560         which fio || skip_env "no fio installed"
27561         $LFS setstripe -c -1 -S 1M $DIR/$tfile
27562         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
27563
27564         # Single page, multiple pages, stripe size, 4*stripe size
27565         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
27566                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
27567                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
27568                         --numjobs=$njobs --fallocate=none \
27569                         --iodepth=16 --allow_file_create=0 \
27570                         --size=$((size/njobs))M \
27571                         --filename=$DIR/$tfile &
27572                 bg_pid=$!
27573
27574                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
27575                 fio --name=rand-rw --rw=randrw --bs=$bsize \
27576                         --numjobs=$njobs --fallocate=none \
27577                         --iodepth=16 --allow_file_create=0 \
27578                         --size=$((size/njobs))M \
27579                         --filename=$DIR/$tfile || true
27580                 wait $bg_pid
27581         done
27582
27583         evict=$(do_facet client $LCTL get_param \
27584                 osc.$FSNAME-OST*-osc-*/state |
27585             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
27586
27587         [ -z "$evict" ] || [[ $evict -le $before ]] ||
27588                 (do_facet client $LCTL get_param \
27589                         osc.$FSNAME-OST*-osc-*/state;
27590                     error "eviction happened: $evict before:$before")
27591
27592         rm -f $DIR/$tfile
27593 }
27594 run_test 398b "DIO and buffer IO race"
27595
27596 test_398c() { # LU-4198
27597         local ost1_imp=$(get_osc_import_name client ost1)
27598         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27599                          cut -d'.' -f2)
27600
27601         which fio || skip_env "no fio installed"
27602
27603         saved_debug=$($LCTL get_param -n debug)
27604         $LCTL set_param debug=0
27605
27606         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
27607         ((size /= 1024)) # by megabytes
27608         ((size /= 2)) # write half of the OST at most
27609         [ $size -gt 40 ] && size=40 #reduce test time anyway
27610
27611         $LFS setstripe -c 1 $DIR/$tfile
27612
27613         # it seems like ldiskfs reserves more space than necessary if the
27614         # writing blocks are not mapped, so it extends the file firstly
27615         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
27616         cancel_lru_locks osc
27617
27618         # clear and verify rpc_stats later
27619         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
27620
27621         local njobs=4
27622         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
27623         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
27624                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
27625                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
27626                 --filename=$DIR/$tfile
27627         [ $? -eq 0 ] || error "fio write error"
27628
27629         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
27630                 error "Locks were requested while doing AIO"
27631
27632         # get the percentage of 1-page I/O
27633         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
27634                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
27635                 awk '{print $7}')
27636         (( $pct <= 50 )) || {
27637                 $LCTL get_param osc.${imp_name}.rpc_stats
27638                 error "$pct% of I/O are 1-page"
27639         }
27640
27641         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
27642         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
27643                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
27644                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
27645                 --filename=$DIR/$tfile
27646         [ $? -eq 0 ] || error "fio mixed read write error"
27647
27648         echo "AIO with large block size ${size}M"
27649         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
27650                 --numjobs=1 --fallocate=none --ioengine=libaio \
27651                 --iodepth=16 --allow_file_create=0 --size=${size}M \
27652                 --filename=$DIR/$tfile
27653         [ $? -eq 0 ] || error "fio large block size failed"
27654
27655         rm -f $DIR/$tfile
27656         $LCTL set_param debug="$saved_debug"
27657 }
27658 run_test 398c "run fio to test AIO"
27659
27660 test_398d() { #  LU-13846
27661         which aiocp || skip_env "no aiocp installed"
27662         local aio_file=$DIR/$tfile.aio
27663
27664         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
27665
27666         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
27667         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
27668         stack_trap "rm -f $DIR/$tfile $aio_file"
27669
27670         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
27671
27672         # test memory unaligned aio
27673         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file ||
27674                 error "unaligned aio failed"
27675         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
27676
27677         rm -f $DIR/$tfile $aio_file
27678 }
27679 run_test 398d "run aiocp to verify block size > stripe size"
27680
27681 test_398e() {
27682         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
27683         touch $DIR/$tfile.new
27684         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
27685 }
27686 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
27687
27688 test_398f() { #  LU-14687
27689         which aiocp || skip_env "no aiocp installed"
27690         local aio_file=$DIR/$tfile.aio
27691
27692         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
27693
27694         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
27695         stack_trap "rm -f $DIR/$tfile $aio_file"
27696
27697         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
27698         $LCTL set_param fail_loc=0x1418
27699         # make sure we don't crash and fail properly
27700         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
27701                 error "aio with page allocation failure succeeded"
27702         $LCTL set_param fail_loc=0
27703         diff $DIR/$tfile $aio_file
27704         [[ $? != 0 ]] || error "no diff after failed aiocp"
27705 }
27706 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
27707
27708 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
27709 # stripe and i/o size must be > stripe size
27710 # Old style synchronous DIO waits after submitting each chunk, resulting in a
27711 # single RPC in flight.  This test shows async DIO submission is working by
27712 # showing multiple RPCs in flight.
27713 test_398g() { #  LU-13798
27714         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
27715
27716         # We need to do some i/o first to acquire enough grant to put our RPCs
27717         # in flight; otherwise a new connection may not have enough grant
27718         # available
27719         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27720                 error "parallel dio failed"
27721         stack_trap "rm -f $DIR/$tfile"
27722
27723         # Reduce RPC size to 1M to avoid combination in to larger RPCs
27724         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
27725         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
27726         stack_trap "$LCTL set_param -n $pages_per_rpc"
27727
27728         # Recreate file so it's empty
27729         rm -f $DIR/$tfile
27730         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
27731         #Pause rpc completion to guarantee we see multiple rpcs in flight
27732         #define OBD_FAIL_OST_BRW_PAUSE_BULK
27733         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
27734         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
27735
27736         # Clear rpc stats
27737         $LCTL set_param osc.*.rpc_stats=c
27738
27739         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27740                 error "parallel dio failed"
27741         stack_trap "rm -f $DIR/$tfile"
27742
27743         $LCTL get_param osc.*-OST0000-*.rpc_stats
27744         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
27745                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
27746                 grep "8:" | awk '{print $8}')
27747         # We look at the "8 rpcs in flight" field, and verify A) it is present
27748         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
27749         # as expected for an 8M DIO to a file with 1M stripes.
27750         # NB: There is occasionally a mystery extra write RPC to a different
27751         # file.  I can't identify why that's happening, so we set up a margin
27752         # of 1 RPC here, ie, 8/9 RPCs at this size, or ~88%
27753         [ $pct -gt 87 ] || error "we should see 8 RPCs in flight"
27754
27755         # Verify turning off parallel dio works as expected
27756         # Clear rpc stats
27757         $LCTL set_param osc.*.rpc_stats=c
27758         $LCTL set_param llite.*.parallel_dio=0
27759         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
27760
27761         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27762                 error "dio with parallel dio disabled failed"
27763
27764         # Ideally, we would see only one RPC in flight here, but there is an
27765         # unavoidable race between i/o completion and RPC in flight counting,
27766         # so while only 1 i/o is in flight at a time, the RPC in flight counter
27767         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
27768         # So instead we just verify it's always < 8.
27769         $LCTL get_param osc.*-OST0000-*.rpc_stats
27770         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
27771                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
27772                 grep '^$' -B1 | grep . | awk '{print $1}')
27773         [ $ret != "8:" ] ||
27774                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
27775 }
27776 run_test 398g "verify parallel dio async RPC submission"
27777
27778 test_398h() { #  LU-13798
27779         local dio_file=$DIR/$tfile.dio
27780
27781         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
27782
27783         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27784         stack_trap "rm -f $DIR/$tfile $dio_file"
27785
27786         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
27787                 error "parallel dio failed"
27788         diff $DIR/$tfile $dio_file
27789         [[ $? == 0 ]] || error "file diff after aiocp"
27790 }
27791 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
27792
27793 test_398i() { #  LU-13798
27794         local dio_file=$DIR/$tfile.dio
27795
27796         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
27797
27798         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27799         stack_trap "rm -f $DIR/$tfile $dio_file"
27800
27801         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
27802         $LCTL set_param fail_loc=0x1418
27803         # make sure we don't crash and fail properly
27804         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
27805                 error "parallel dio page allocation failure succeeded"
27806         diff $DIR/$tfile $dio_file
27807         [[ $? != 0 ]] || error "no diff after failed aiocp"
27808 }
27809 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
27810
27811 test_398j() { #  LU-13798
27812         # Stripe size > RPC size but less than i/o size tests split across
27813         # stripes and RPCs for individual i/o op
27814         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
27815
27816         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
27817         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
27818         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
27819         stack_trap "$LCTL set_param -n $pages_per_rpc"
27820
27821         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27822                 error "parallel dio write failed"
27823         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
27824
27825         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
27826                 error "parallel dio read failed"
27827         diff $DIR/$tfile $DIR/$tfile.2
27828         [[ $? == 0 ]] || error "file diff after parallel dio read"
27829 }
27830 run_test 398j "test parallel dio where stripe size > rpc_size"
27831
27832 test_398k() { #  LU-13798
27833         wait_delete_completed
27834         wait_mds_ost_sync
27835
27836         # 4 stripe file; we will cause out of space on OST0
27837         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
27838
27839         # Fill OST0 (if it's not too large)
27840         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
27841                    head -n1)
27842         if [[ $ORIGFREE -gt $MAXFREE ]]; then
27843                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
27844         fi
27845         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
27846         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
27847                 error "dd should fill OST0"
27848         stack_trap "rm -f $DIR/$tfile.1"
27849
27850         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27851         err=$?
27852
27853         ls -la $DIR/$tfile
27854         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
27855                 error "file is not 0 bytes in size"
27856
27857         # dd above should not succeed, but don't error until here so we can
27858         # get debug info above
27859         [[ $err != 0 ]] ||
27860                 error "parallel dio write with enospc succeeded"
27861         stack_trap "rm -f $DIR/$tfile"
27862 }
27863 run_test 398k "test enospc on first stripe"
27864
27865 test_398l() { #  LU-13798
27866         wait_delete_completed
27867         wait_mds_ost_sync
27868
27869         # 4 stripe file; we will cause out of space on OST0
27870         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
27871         # happens on the second i/o chunk we issue
27872         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
27873
27874         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
27875         stack_trap "rm -f $DIR/$tfile"
27876
27877         # Fill OST0 (if it's not too large)
27878         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
27879                    head -n1)
27880         if [[ $ORIGFREE -gt $MAXFREE ]]; then
27881                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
27882         fi
27883         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
27884         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
27885                 error "dd should fill OST0"
27886         stack_trap "rm -f $DIR/$tfile.1"
27887
27888         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
27889         err=$?
27890         stack_trap "rm -f $DIR/$tfile.2"
27891
27892         # Check that short write completed as expected
27893         ls -la $DIR/$tfile.2
27894         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
27895                 error "file is not 1M in size"
27896
27897         # dd above should not succeed, but don't error until here so we can
27898         # get debug info above
27899         [[ $err != 0 ]] ||
27900                 error "parallel dio write with enospc succeeded"
27901
27902         # Truncate source file to same length as output file and diff them
27903         $TRUNCATE $DIR/$tfile 1048576
27904         diff $DIR/$tfile $DIR/$tfile.2
27905         [[ $? == 0 ]] || error "data incorrect after short write"
27906 }
27907 run_test 398l "test enospc on intermediate stripe/RPC"
27908
27909 test_398m() { #  LU-13798
27910         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
27911
27912         # Set up failure on OST0, the first stripe:
27913         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
27914         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
27915         # OST0 is on ost1, OST1 is on ost2.
27916         # So this fail_val specifies OST0
27917         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
27918         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
27919
27920         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
27921                 error "parallel dio write with failure on first stripe succeeded"
27922         stack_trap "rm -f $DIR/$tfile"
27923         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
27924
27925         # Place data in file for read
27926         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27927                 error "parallel dio write failed"
27928
27929         # Fail read on OST0, first stripe
27930         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
27931         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
27932         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
27933                 error "parallel dio read with error on first stripe succeeded"
27934         rm -f $DIR/$tfile.2
27935         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
27936
27937         # Switch to testing on OST1, second stripe
27938         # Clear file contents, maintain striping
27939         echo > $DIR/$tfile
27940         # Set up failure on OST1, second stripe:
27941         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
27942         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
27943
27944         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
27945                 error "parallel dio write with failure on second stripe succeeded"
27946         stack_trap "rm -f $DIR/$tfile"
27947         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
27948
27949         # Place data in file for read
27950         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27951                 error "parallel dio write failed"
27952
27953         # Fail read on OST1, second stripe
27954         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
27955         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
27956         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
27957                 error "parallel dio read with error on second stripe succeeded"
27958         rm -f $DIR/$tfile.2
27959         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
27960 }
27961 run_test 398m "test RPC failures with parallel dio"
27962
27963 # Parallel submission of DIO should not cause problems for append, but it's
27964 # important to verify.
27965 test_398n() { #  LU-13798
27966         $LFS setstripe -C 2 -S 1M $DIR/$tfile
27967
27968         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
27969                 error "dd to create source file failed"
27970         stack_trap "rm -f $DIR/$tfile"
27971
27972         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
27973                 error "parallel dio write with failure on second stripe succeeded"
27974         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
27975         diff $DIR/$tfile $DIR/$tfile.1
27976         [[ $? == 0 ]] || error "data incorrect after append"
27977
27978 }
27979 run_test 398n "test append with parallel DIO"
27980
27981 test_398o() {
27982         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
27983 }
27984 run_test 398o "right kms with DIO"
27985
27986 test_398p()
27987 {
27988         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
27989         which aiocp || skip_env "no aiocp installed"
27990
27991         local stripe_size=$((1024 * 1024)) #1 MiB
27992         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
27993         local file_size=$((25 * stripe_size))
27994
27995         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
27996         stack_trap "rm -f $DIR/$tfile*"
27997         # Just a bit bigger than the largest size in the test set below
27998         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
27999                 error "buffered i/o to create file failed"
28000
28001         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
28002                 $((stripe_size * 4)); do
28003
28004                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
28005
28006                 echo "bs: $bs, file_size $file_size"
28007                 aiocp -a $PAGE_SIZE -b $bs -s $file_size -f O_DIRECT \
28008                         $DIR/$tfile.1 $DIR/$tfile.2 &
28009                 pid_dio1=$!
28010                 # Buffered I/O with similar but not the same block size
28011                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
28012                         conv=notrunc &
28013                 pid_bio2=$!
28014                 wait $pid_dio1
28015                 rc1=$?
28016                 wait $pid_bio2
28017                 rc2=$?
28018                 if (( rc1 != 0 )); then
28019                         error "aio copy 1 w/bsize $bs failed: $rc1"
28020                 fi
28021                 if (( rc2 != 0 )); then
28022                         error "buffered copy 2 w/bsize $bs failed: $rc2"
28023                 fi
28024
28025                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
28026                         error "size incorrect"
28027                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
28028                         error "files differ, bsize $bs"
28029                 rm -f $DIR/$tfile.2
28030         done
28031 }
28032 run_test 398p "race aio with buffered i/o"
28033
28034 test_398q()
28035 {
28036         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
28037
28038         local stripe_size=$((1024 * 1024)) #1 MiB
28039         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
28040         local file_size=$((25 * stripe_size))
28041
28042         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
28043         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
28044
28045         # Just a bit bigger than the largest size in the test set below
28046         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
28047                 error "buffered i/o to create file failed"
28048
28049         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
28050                 $((stripe_size * 4)); do
28051
28052                 echo "bs: $bs, file_size $file_size"
28053                 dd if=$DIR/$tfile.1 bs=$((bs *2 )) of=$DIR/$tfile.2 \
28054                         conv=notrunc oflag=direct iflag=direct &
28055                 pid_dio1=$!
28056                 # Buffered I/O with similar but not the same block size
28057                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
28058                         conv=notrunc &
28059                 pid_bio2=$!
28060                 wait $pid_dio1
28061                 rc1=$?
28062                 wait $pid_bio2
28063                 rc2=$?
28064                 if (( rc1 != 0 )); then
28065                         error "dio copy 1 w/bsize $bs failed: $rc1"
28066                 fi
28067                 if (( rc2 != 0 )); then
28068                         error "buffered copy 2 w/bsize $bs failed: $rc2"
28069                 fi
28070
28071                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
28072                         error "size incorrect"
28073                 diff $DIR/$tfile.1 $DIR/$tfile.2 ||
28074                         error "files differ, bsize $bs"
28075         done
28076
28077         rm -f $DIR/$tfile*
28078 }
28079 run_test 398q "race dio with buffered i/o"
28080
28081 test_398r() {
28082         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
28083         echo "hello, world" > $DIR/$tfile
28084
28085         cancel_lru_locks osc
28086
28087 #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
28088         do_facet ost1 $LCTL set_param fail_loc=0x20f
28089         cat $DIR/$tfile > /dev/null && error "cat should fail"
28090         return 0
28091 }
28092 run_test 398r "i/o error on file read"
28093
28094 test_398s() {
28095         [[ $OSTCOUNT -ge 2 && "$ost1_HOST" = "$ost2_HOST" ]] ||
28096                 skip "remote OST"
28097
28098         $LFS mirror create -N -i 0 -c 1 -N -i 1 -c 1 $DIR/$tfile ||
28099                 error "mirror create failed"
28100
28101         echo "hello, world" > $DIR/$tfile
28102         $LFS mirror resync $DIR/$tfile || error "mirror resync failed"
28103
28104         cancel_lru_locks osc
28105
28106 #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
28107         do_facet ost1 $LCTL set_param fail_loc=0x20f
28108         cat $DIR/$tfile > /dev/null && error "cat should fail"
28109         return 0
28110 }
28111 run_test 398s "i/o error on mirror file read"
28112
28113 test_fake_rw() {
28114         local read_write=$1
28115         if [ "$read_write" = "write" ]; then
28116                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
28117         elif [ "$read_write" = "read" ]; then
28118                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
28119         else
28120                 error "argument error"
28121         fi
28122
28123         # turn off debug for performance testing
28124         local saved_debug=$($LCTL get_param -n debug)
28125         $LCTL set_param debug=0
28126
28127         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28128
28129         # get ost1 size - $FSNAME-OST0000
28130         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
28131         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
28132         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
28133
28134         if [ "$read_write" = "read" ]; then
28135                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
28136         fi
28137
28138         local start_time=$(date +%s.%N)
28139         $dd_cmd bs=1M count=$blocks oflag=sync ||
28140                 error "real dd $read_write error"
28141         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
28142
28143         if [ "$read_write" = "write" ]; then
28144                 rm -f $DIR/$tfile
28145         fi
28146
28147         # define OBD_FAIL_OST_FAKE_RW           0x238
28148         do_facet ost1 $LCTL set_param fail_loc=0x238
28149
28150         local start_time=$(date +%s.%N)
28151         $dd_cmd bs=1M count=$blocks oflag=sync ||
28152                 error "fake dd $read_write error"
28153         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
28154
28155         if [ "$read_write" = "write" ]; then
28156                 # verify file size
28157                 cancel_lru_locks osc
28158                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
28159                         error "$tfile size not $blocks MB"
28160         fi
28161         do_facet ost1 $LCTL set_param fail_loc=0
28162
28163         echo "fake $read_write $duration_fake vs. normal $read_write" \
28164                 "$duration in seconds"
28165         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
28166                 error_not_in_vm "fake write is slower"
28167
28168         $LCTL set_param -n debug="$saved_debug"
28169         rm -f $DIR/$tfile
28170 }
28171 test_399a() { # LU-7655 for OST fake write
28172         remote_ost_nodsh && skip "remote OST with nodsh"
28173
28174         test_fake_rw write
28175 }
28176 run_test 399a "fake write should not be slower than normal write"
28177
28178 test_399b() { # LU-8726 for OST fake read
28179         remote_ost_nodsh && skip "remote OST with nodsh"
28180         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
28181                 skip_env "ldiskfs only test"
28182         fi
28183
28184         test_fake_rw read
28185 }
28186 run_test 399b "fake read should not be slower than normal read"
28187
28188 test_400a() { # LU-1606, was conf-sanity test_74
28189         if ! which $CC > /dev/null 2>&1; then
28190                 skip_env "$CC is not installed"
28191         fi
28192
28193         local extra_flags=''
28194         local out=$TMP/$tfile
28195         local prefix=/usr/include/lustre
28196         local prog
28197
28198         # Oleg removes .c files in his test rig so test if any c files exist
28199         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
28200                 skip_env "Needed .c test files are missing"
28201
28202         if ! [[ -d $prefix ]]; then
28203                 # Assume we're running in tree and fixup the include path.
28204                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
28205                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
28206                 extra_flags+=" -L$LUSTRE/utils/.libs"
28207         fi
28208
28209         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
28210                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
28211                         error "client api broken"
28212         done
28213         rm -f $out
28214 }
28215 run_test 400a "Lustre client api program can compile and link"
28216
28217 test_400b() { # LU-1606, LU-5011
28218         local header
28219         local out=$TMP/$tfile
28220         local prefix=/usr/include/linux/lustre
28221
28222         # We use a hard coded prefix so that this test will not fail
28223         # when run in tree. There are headers in lustre/include/lustre/
28224         # that are not packaged (like lustre_idl.h) and have more
28225         # complicated include dependencies (like config.h and lnet/types.h).
28226         # Since this test about correct packaging we just skip them when
28227         # they don't exist (see below) rather than try to fixup cppflags.
28228
28229         if ! which $CC > /dev/null 2>&1; then
28230                 skip_env "$CC is not installed"
28231         fi
28232
28233         for header in $prefix/*.h; do
28234                 if ! [[ -f "$header" ]]; then
28235                         continue
28236                 fi
28237
28238                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
28239                         continue # lustre_ioctl.h is internal header
28240                 fi
28241
28242                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
28243                         error "cannot compile '$header'"
28244         done
28245         rm -f $out
28246 }
28247 run_test 400b "packaged headers can be compiled"
28248
28249 test_401a() { #LU-7437
28250         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
28251         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
28252
28253         #count the number of parameters by "list_param -R"
28254         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
28255         #count the number of parameters by listing proc files
28256         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
28257         echo "proc_dirs='$proc_dirs'"
28258         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
28259         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
28260                       sort -u | wc -l)
28261
28262         [ $params -eq $procs ] ||
28263                 error "found $params parameters vs. $procs proc files"
28264
28265         # test the list_param -D option only returns directories
28266         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
28267         #count the number of parameters by listing proc directories
28268         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
28269                 sort -u | wc -l)
28270
28271         [ $params -eq $procs ] ||
28272                 error "found $params parameters vs. $procs proc files"
28273 }
28274 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
28275
28276 test_401b() {
28277         # jobid_var may not allow arbitrary values, so use jobid_name
28278         # if available
28279         if $LCTL list_param jobid_name > /dev/null 2>&1; then
28280                 local testname=jobid_name tmp='testing%p'
28281         else
28282                 local testname=jobid_var tmp=testing
28283         fi
28284
28285         local save=$($LCTL get_param -n $testname)
28286
28287         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
28288                 error "no error returned when setting bad parameters"
28289
28290         local jobid_new=$($LCTL get_param -n foe $testname baz)
28291         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
28292
28293         $LCTL set_param -n fog=bam $testname=$save bat=fog
28294         local jobid_old=$($LCTL get_param -n foe $testname bag)
28295         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
28296 }
28297 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
28298
28299 test_401c() {
28300         # jobid_var may not allow arbitrary values, so use jobid_name
28301         # if available
28302         if $LCTL list_param jobid_name > /dev/null 2>&1; then
28303                 local testname=jobid_name
28304         else
28305                 local testname=jobid_var
28306         fi
28307
28308         local jobid_var_old=$($LCTL get_param -n $testname)
28309         local jobid_var_new
28310
28311         $LCTL set_param $testname= &&
28312                 error "no error returned for 'set_param a='"
28313
28314         jobid_var_new=$($LCTL get_param -n $testname)
28315         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
28316                 error "$testname was changed by setting without value"
28317
28318         $LCTL set_param $testname &&
28319                 error "no error returned for 'set_param a'"
28320
28321         jobid_var_new=$($LCTL get_param -n $testname)
28322         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
28323                 error "$testname was changed by setting without value"
28324 }
28325 run_test 401c "Verify 'lctl set_param' without value fails in either format."
28326
28327 test_401d() {
28328         # jobid_var may not allow arbitrary values, so use jobid_name
28329         # if available
28330         if $LCTL list_param jobid_name > /dev/null 2>&1; then
28331                 local testname=jobid_name new_value='foo=bar%p'
28332         else
28333                 local testname=jobid_var new_valuie=foo=bar
28334         fi
28335
28336         local jobid_var_old=$($LCTL get_param -n $testname)
28337         local jobid_var_new
28338
28339         $LCTL set_param $testname=$new_value ||
28340                 error "'set_param a=b' did not accept a value containing '='"
28341
28342         jobid_var_new=$($LCTL get_param -n $testname)
28343         [[ "$jobid_var_new" == "$new_value" ]] ||
28344                 error "'set_param a=b' failed on a value containing '='"
28345
28346         # Reset the $testname to test the other format
28347         $LCTL set_param $testname=$jobid_var_old
28348         jobid_var_new=$($LCTL get_param -n $testname)
28349         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
28350                 error "failed to reset $testname"
28351
28352         $LCTL set_param $testname $new_value ||
28353                 error "'set_param a b' did not accept a value containing '='"
28354
28355         jobid_var_new=$($LCTL get_param -n $testname)
28356         [[ "$jobid_var_new" == "$new_value" ]] ||
28357                 error "'set_param a b' failed on a value containing '='"
28358
28359         $LCTL set_param $testname $jobid_var_old
28360         jobid_var_new=$($LCTL get_param -n $testname)
28361         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
28362                 error "failed to reset $testname"
28363 }
28364 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
28365
28366 test_401e() { # LU-14779
28367         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
28368                 error "lctl list_param MGC* failed"
28369         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
28370         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
28371                 error "lctl get_param lru_size failed"
28372 }
28373 run_test 401e "verify 'lctl get_param' works with NID in parameter"
28374
28375 test_402() {
28376         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
28377         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
28378                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
28379         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
28380                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
28381                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
28382         remote_mds_nodsh && skip "remote MDS with nodsh"
28383
28384         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
28385 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
28386         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
28387         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
28388                 echo "Touch failed - OK"
28389 }
28390 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
28391
28392 test_403() {
28393         local file1=$DIR/$tfile.1
28394         local file2=$DIR/$tfile.2
28395         local tfile=$TMP/$tfile
28396
28397         rm -f $file1 $file2 $tfile
28398
28399         touch $file1
28400         ln $file1 $file2
28401
28402         # 30 sec OBD_TIMEOUT in ll_getattr()
28403         # right before populating st_nlink
28404         $LCTL set_param fail_loc=0x80001409
28405         stat -c %h $file1 > $tfile &
28406
28407         # create an alias, drop all locks and reclaim the dentry
28408         < $file2
28409         cancel_lru_locks mdc
28410         cancel_lru_locks osc
28411         sysctl -w vm.drop_caches=2
28412
28413         wait
28414
28415         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
28416
28417         rm -f $tfile $file1 $file2
28418 }
28419 run_test 403 "i_nlink should not drop to zero due to aliasing"
28420
28421 test_404() { # LU-6601
28422         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
28423                 skip "Need server version newer than 2.8.52"
28424         remote_mds_nodsh && skip "remote MDS with nodsh"
28425
28426         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
28427                 awk '/osp .*-osc-MDT/ { print $4}')
28428
28429         local osp
28430         for osp in $mosps; do
28431                 echo "Deactivate: " $osp
28432                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
28433                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
28434                         awk -vp=$osp '$4 == p { print $2 }')
28435                 [ $stat = IN ] || {
28436                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
28437                         error "deactivate error"
28438                 }
28439                 echo "Activate: " $osp
28440                 do_facet $SINGLEMDS $LCTL --device %$osp activate
28441                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
28442                         awk -vp=$osp '$4 == p { print $2 }')
28443                 [ $stat = UP ] || {
28444                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
28445                         error "activate error"
28446                 }
28447         done
28448 }
28449 run_test 404 "validate manual {de}activated works properly for OSPs"
28450
28451 test_405() {
28452         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
28453         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
28454                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
28455                         skip "Layout swap lock is not supported"
28456
28457         check_swap_layouts_support
28458         check_swap_layout_no_dom $DIR
28459
28460         test_mkdir $DIR/$tdir
28461         swap_lock_test -d $DIR/$tdir ||
28462                 error "One layout swap locked test failed"
28463 }
28464 run_test 405 "Various layout swap lock tests"
28465
28466 test_406() {
28467         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
28468         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
28469         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
28470         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28471         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
28472                 skip "Need MDS version at least 2.8.50"
28473
28474         local def_stripe_size=$($LFS getstripe -S $MOUNT)
28475         local test_pool=$TESTNAME
28476
28477         pool_add $test_pool || error "pool_add failed"
28478         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
28479                 error "pool_add_targets failed"
28480
28481         save_layout_restore_at_exit $MOUNT
28482
28483         # parent set default stripe count only, child will stripe from both
28484         # parent and fs default
28485         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
28486                 error "setstripe $MOUNT failed"
28487         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
28488         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
28489         for i in $(seq 10); do
28490                 local f=$DIR/$tdir/$tfile.$i
28491                 touch $f || error "touch failed"
28492                 local count=$($LFS getstripe -c $f)
28493                 [ $count -eq $OSTCOUNT ] ||
28494                         error "$f stripe count $count != $OSTCOUNT"
28495                 local offset=$($LFS getstripe -i $f)
28496                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
28497                 local size=$($LFS getstripe -S $f)
28498                 [ $size -eq $((def_stripe_size * 2)) ] ||
28499                         error "$f stripe size $size != $((def_stripe_size * 2))"
28500                 local pool=$($LFS getstripe -p $f)
28501                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
28502         done
28503
28504         # change fs default striping, delete parent default striping, now child
28505         # will stripe from new fs default striping only
28506         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
28507                 error "change $MOUNT default stripe failed"
28508         $LFS setstripe -c 0 $DIR/$tdir ||
28509                 error "delete $tdir default stripe failed"
28510         for i in $(seq 11 20); do
28511                 local f=$DIR/$tdir/$tfile.$i
28512                 touch $f || error "touch $f failed"
28513                 local count=$($LFS getstripe -c $f)
28514                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
28515                 local offset=$($LFS getstripe -i $f)
28516                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
28517                 local size=$($LFS getstripe -S $f)
28518                 [ $size -eq $def_stripe_size ] ||
28519                         error "$f stripe size $size != $def_stripe_size"
28520                 local pool=$($LFS getstripe -p $f)
28521                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
28522         done
28523
28524         unlinkmany $DIR/$tdir/$tfile. 1 20
28525
28526         local f=$DIR/$tdir/$tfile
28527         pool_remove_all_targets $test_pool $f
28528         pool_remove $test_pool $f
28529 }
28530 run_test 406 "DNE support fs default striping"
28531
28532 test_407() {
28533         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
28534         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
28535                 skip "Need MDS version at least 2.8.55"
28536         remote_mds_nodsh && skip "remote MDS with nodsh"
28537
28538         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
28539                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
28540         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
28541                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
28542         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
28543
28544         #define OBD_FAIL_DT_TXN_STOP    0x2019
28545         for idx in $(seq $MDSCOUNT); do
28546                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
28547         done
28548         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
28549         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
28550                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
28551         true
28552 }
28553 run_test 407 "transaction fail should cause operation fail"
28554
28555 test_408() {
28556         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
28557
28558         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
28559         lctl set_param fail_loc=0x8000040a
28560         # let ll_prepare_partial_page() fail
28561         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
28562
28563         rm -f $DIR/$tfile
28564
28565         # create at least 100 unused inodes so that
28566         # shrink_icache_memory(0) should not return 0
28567         touch $DIR/$tfile-{0..100}
28568         rm -f $DIR/$tfile-{0..100}
28569         sync
28570
28571         echo 2 > /proc/sys/vm/drop_caches
28572 }
28573 run_test 408 "drop_caches should not hang due to page leaks"
28574
28575 test_409()
28576 {
28577         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28578
28579         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
28580         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
28581         touch $DIR/$tdir/guard || error "(2) Fail to create"
28582
28583         local PREFIX=$(str_repeat 'A' 128)
28584         echo "Create 1K hard links start at $(date)"
28585         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
28586                 error "(3) Fail to hard link"
28587
28588         echo "Links count should be right although linkEA overflow"
28589         stat $DIR/$tdir/guard || error "(4) Fail to stat"
28590         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
28591         [ $linkcount -eq 1001 ] ||
28592                 error "(5) Unexpected hard links count: $linkcount"
28593
28594         echo "List all links start at $(date)"
28595         ls -l $DIR/$tdir/foo > /dev/null ||
28596                 error "(6) Fail to list $DIR/$tdir/foo"
28597
28598         echo "Unlink hard links start at $(date)"
28599         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
28600                 error "(7) Fail to unlink"
28601         echo "Unlink hard links finished at $(date)"
28602 }
28603 run_test 409 "Large amount of cross-MDTs hard links on the same file"
28604
28605 test_410()
28606 {
28607         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
28608                 skip "Need client version at least 2.9.59"
28609
28610         # Create a file, and stat it from the kernel
28611         local testfile=$DIR/$tfile
28612         touch $testfile
28613
28614         local run_id=$RANDOM
28615         local my_ino=$(stat --format "%i" $testfile)
28616
28617         # Try to insert the module.
28618         load_module kunit/kinode run_id=$run_id fname=$testfile ||
28619                 error "load_module failed"
28620
28621         # Anything but success is a test failure
28622         dmesg | grep -q \
28623             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
28624             error "no inode match"
28625
28626         # Remove the test module
28627         rmmod -v kinode ||
28628                 error "rmmod failed (may trigger a failure in a later test)"
28629 }
28630 run_test 410 "Test inode number returned from kernel thread"
28631
28632 cleanup_test411_cgroup() {
28633         trap 0
28634         cat $1/memory.stat
28635         rmdir "$1"
28636 }
28637
28638 test_411a() {
28639         local cg_basedir=/sys/fs/cgroup/memory
28640         # LU-9966
28641         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
28642                 skip "no setup for cgroup"
28643
28644         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
28645                 error "test file creation failed"
28646         cancel_lru_locks osc
28647
28648         # Create a very small memory cgroup to force a slab allocation error
28649         local cgdir=$cg_basedir/osc_slab_alloc
28650         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
28651         trap "cleanup_test411_cgroup $cgdir" EXIT
28652         echo 2M > $cgdir/memory.kmem.limit_in_bytes
28653         echo 1M > $cgdir/memory.limit_in_bytes
28654
28655         # Should not LBUG, just be killed by oom-killer
28656         # dd will return 0 even allocation failure in some environment.
28657         # So don't check return value
28658         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
28659         cleanup_test411_cgroup $cgdir
28660
28661         return 0
28662 }
28663 run_test 411a "Slab allocation error with cgroup does not LBUG"
28664
28665 test_411b() {
28666         local cg_basedir=/sys/fs/cgroup/memory
28667         # LU-9966
28668         [ -e "$cg_basedir/memory.kmem.limit_in_bytes" ] ||
28669                 skip "no setup for cgroup"
28670         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
28671         # (x86) testing suggests we can't reliably avoid OOM with a 64M-256M
28672         # limit, so we have 384M in cgroup
28673         # (arm) this seems to hit OOM more often than x86, so 1024M
28674         if [[ $(uname -m) = aarch64 ]]; then
28675                 local memlimit_mb=1024
28676         else
28677                 local memlimit_mb=384
28678         fi
28679
28680         # Create a cgroup and set memory limit
28681         # (tfile is used as an easy way to get a recognizable cgroup name)
28682         local cgdir=$cg_basedir/$tfile
28683         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
28684         stack_trap "cleanup_test411_cgroup $cgdir" EXIT
28685         echo $((memlimit_mb * 1024 * 1024)) > $cgdir/memory.limit_in_bytes
28686
28687         echo "writing first file"
28688         # Write a file 4x the memory limit in size
28689         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=1M count=$((memlimit_mb * 4))" ||
28690                 error "(1) failed to write successfully"
28691
28692         sync
28693         cancel_lru_locks osc
28694
28695         rm -f $DIR/$tfile
28696         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
28697
28698         # Try writing at a larger block size
28699         # NB: if block size is >= 1/2 cgroup size, we sometimes get OOM killed
28700         # so test with 1/4 cgroup size (this seems reasonable to me - we do
28701         # need *some* memory to do IO in)
28702         echo "writing at larger block size"
28703         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=64M count=$((memlimit_mb * 4 / 128))" ||
28704                 error "(3) failed to write successfully"
28705
28706         sync
28707         cancel_lru_locks osc
28708         rm -f $DIR/$tfile
28709         $LFS setstripe -c 2 $DIR/$tfile.{1..4} || error "unable to setstripe"
28710
28711         # Try writing multiple files at once
28712         echo "writing multiple files"
28713         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.1 bs=32M count=$((memlimit_mb * 4 / 64))" &
28714         local pid1=$!
28715         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.2 bs=32M count=$((memlimit_mb * 4 / 64))" &
28716         local pid2=$!
28717         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.3 bs=32M count=$((memlimit_mb * 4 / 64))" &
28718         local pid3=$!
28719         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.4 bs=32M count=$((memlimit_mb * 4 / 64))" &
28720         local pid4=$!
28721
28722         wait $pid1
28723         local rc1=$?
28724         wait $pid2
28725         local rc2=$?
28726         wait $pid3
28727         local rc3=$?
28728         wait $pid4
28729         local rc4=$?
28730         if (( rc1 != 0)); then
28731                 error "error $rc1 writing to file from $pid1"
28732         fi
28733         if (( rc2 != 0)); then
28734                 error "error $rc2 writing to file from $pid2"
28735         fi
28736         if (( rc3 != 0)); then
28737                 error "error $rc3 writing to file from $pid3"
28738         fi
28739         if (( rc4 != 0)); then
28740                 error "error $rc4 writing to file from $pid4"
28741         fi
28742
28743         sync
28744         cancel_lru_locks osc
28745
28746         # These files can be large-ish (~1 GiB total), so delete them rather
28747         # than leave for later cleanup
28748         rm -f $DIR/$tfile.*
28749         return 0
28750 }
28751 run_test 411b "confirm Lustre can avoid OOM with reasonable cgroups limits"
28752
28753 test_412() {
28754         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
28755         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
28756                 skip "Need server version at least 2.10.55"
28757
28758         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
28759                 error "mkdir failed"
28760         $LFS getdirstripe $DIR/$tdir
28761         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
28762         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
28763                 error "expect $((MDSCOUT - 1)) get $stripe_index"
28764         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
28765         [ $stripe_count -eq 2 ] ||
28766                 error "expect 2 get $stripe_count"
28767
28768         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
28769
28770         local index
28771         local index2
28772
28773         # subdirs should be on the same MDT as parent
28774         for i in $(seq 0 $((MDSCOUNT - 1))); do
28775                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
28776                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
28777                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
28778                 (( index == i )) || error "mdt$i/sub on MDT$index"
28779         done
28780
28781         # stripe offset -1, ditto
28782         for i in {1..10}; do
28783                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
28784                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
28785                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
28786                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
28787                 (( index == index2 )) ||
28788                         error "qos$i on MDT$index, sub on MDT$index2"
28789         done
28790
28791         local testdir=$DIR/$tdir/inherit
28792
28793         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
28794         # inherit 2 levels
28795         for i in 1 2; do
28796                 testdir=$testdir/s$i
28797                 mkdir $testdir || error "mkdir $testdir failed"
28798                 index=$($LFS getstripe -m $testdir)
28799                 (( index == 1 )) ||
28800                         error "$testdir on MDT$index"
28801         done
28802
28803         # not inherit any more
28804         testdir=$testdir/s3
28805         mkdir $testdir || error "mkdir $testdir failed"
28806         getfattr -d -m dmv $testdir | grep dmv &&
28807                 error "default LMV set on $testdir" || true
28808 }
28809 run_test 412 "mkdir on specific MDTs"
28810
28811 TEST413_COUNT=${TEST413_COUNT:-200}
28812
28813 #
28814 # set_maxage() is used by test_413 only.
28815 # This is a helper function to set maxage. Does not return any value.
28816 # Input: maxage to set
28817 #
28818 set_maxage() {
28819         local lmv_qos_maxage
28820         local lod_qos_maxage
28821         local new_maxage=$1
28822
28823         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
28824         $LCTL set_param lmv.*.qos_maxage=$new_maxage
28825         stack_trap "$LCTL set_param \
28826                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
28827         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
28828                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
28829         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28830                 lod.*.mdt_qos_maxage=$new_maxage
28831         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28832                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
28833 }
28834
28835 generate_uneven_mdts() {
28836         local threshold=$1
28837         local ffree
28838         local bavail
28839         local max
28840         local min
28841         local max_index
28842         local min_index
28843         local tmp
28844         local i
28845
28846         echo
28847         echo "Check for uneven MDTs: "
28848
28849         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28850         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28851         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28852
28853         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28854         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28855         max_index=0
28856         min_index=0
28857         for ((i = 1; i < ${#ffree[@]}; i++)); do
28858                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28859                 if [ $tmp -gt $max ]; then
28860                         max=$tmp
28861                         max_index=$i
28862                 fi
28863                 if [ $tmp -lt $min ]; then
28864                         min=$tmp
28865                         min_index=$i
28866                 fi
28867         done
28868
28869         (( min > 0 )) || skip "low space on MDT$min_index"
28870         (( ${ffree[min_index]} > 0 )) ||
28871                 skip "no free files on MDT$min_index"
28872         (( ${ffree[min_index]} < 10000000 )) ||
28873                 skip "too many free files on MDT$min_index"
28874
28875         # Check if we need to generate uneven MDTs
28876         local diff=$(((max - min) * 100 / min))
28877         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
28878         local testdir # individual folder within $testdirp
28879         local start
28880         local cmd
28881
28882         # fallocate is faster to consume space on MDT, if available
28883         if check_fallocate_supported mds$((min_index + 1)); then
28884                 cmd="fallocate -l 128K "
28885         else
28886                 cmd="dd if=/dev/zero bs=128K count=1 of="
28887         fi
28888
28889         echo "using cmd $cmd"
28890         for (( i = 0; diff < threshold; i++ )); do
28891                 testdir=${testdirp}/$i
28892                 [ -d $testdir ] && continue
28893
28894                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
28895
28896                 mkdir -p $testdirp
28897                 # generate uneven MDTs, create till $threshold% diff
28898                 echo -n "weight diff=$diff% must be > $threshold% ..."
28899                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
28900                 $LFS mkdir -i $min_index $testdir ||
28901                         error "mkdir $testdir failed"
28902                 $LFS setstripe -E 1M -L mdt $testdir ||
28903                         error "setstripe $testdir failed"
28904                 start=$SECONDS
28905                 for (( f = 0; f < TEST413_COUNT; f++ )); do
28906                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
28907                 done
28908                 sync; sleep 1; sync
28909
28910                 # wait for QOS to update
28911                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
28912
28913                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
28914                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
28915                 max=$(((${ffree[max_index]} >> 8) *
28916                         (${bavail[max_index]} * bsize >> 16)))
28917                 min=$(((${ffree[min_index]} >> 8) *
28918                         (${bavail[min_index]} * bsize >> 16)))
28919                 (( min > 0 )) || skip "low space on MDT$min_index"
28920                 diff=$(((max - min) * 100 / min))
28921         done
28922
28923         echo "MDT filesfree available: ${ffree[*]}"
28924         echo "MDT blocks available: ${bavail[*]}"
28925         echo "weight diff=$diff%"
28926 }
28927
28928 test_qos_mkdir() {
28929         local mkdir_cmd=$1
28930         local stripe_count=$2
28931         local mdts=$(comma_list $(mdts_nodes))
28932
28933         local testdir
28934         local lmv_qos_prio_free
28935         local lmv_qos_threshold_rr
28936         local lod_qos_prio_free
28937         local lod_qos_threshold_rr
28938         local total
28939         local count
28940         local i
28941
28942         # @total is total directories created if it's testing plain
28943         # directories, otherwise it's total stripe object count for
28944         # striped directories test.
28945         # remote/striped directory unlinking is slow on zfs and may
28946         # timeout, test with fewer directories
28947         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
28948
28949         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
28950         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
28951         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
28952                 head -n1)
28953         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
28954         stack_trap "$LCTL set_param \
28955                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
28956         stack_trap "$LCTL set_param \
28957                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
28958
28959         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
28960                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
28961         lod_qos_prio_free=${lod_qos_prio_free%%%}
28962         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
28963                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
28964         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
28965         stack_trap "do_nodes $mdts $LCTL set_param \
28966                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
28967         stack_trap "do_nodes $mdts $LCTL set_param \
28968                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
28969
28970         # decrease statfs age, so that it can be updated in time
28971         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
28972         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
28973
28974         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
28975         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
28976
28977         testdir=$DIR/$tdir-s$stripe_count/rr
28978
28979         local stripe_index=$($LFS getstripe -m $testdir)
28980         local test_mkdir_rr=true
28981
28982         getfattr -d -m dmv -e hex $testdir | grep dmv
28983         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
28984                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
28985                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
28986                         test_mkdir_rr=false
28987         fi
28988
28989         echo
28990         $test_mkdir_rr &&
28991                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
28992                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
28993
28994         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
28995         for (( i = 0; i < total / stripe_count; i++ )); do
28996                 eval $mkdir_cmd $testdir/subdir$i ||
28997                         error "$mkdir_cmd subdir$i failed"
28998         done
28999
29000         for (( i = 0; i < $MDSCOUNT; i++ )); do
29001                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
29002                 echo "$count directories created on MDT$i"
29003                 if $test_mkdir_rr; then
29004                         (( count == total / stripe_count / MDSCOUNT )) ||
29005                                 error "subdirs are not evenly distributed"
29006                 elif (( i == stripe_index )); then
29007                         (( count == total / stripe_count )) ||
29008                                 error "$count subdirs created on MDT$i"
29009                 else
29010                         (( count == 0 )) ||
29011                                 error "$count subdirs created on MDT$i"
29012                 fi
29013
29014                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
29015                         count=$($LFS getdirstripe $testdir/* |
29016                                 grep -c -P "^\s+$i\t")
29017                         echo "$count stripes created on MDT$i"
29018                         # deviation should < 5% of average
29019                         delta=$((count - total / MDSCOUNT))
29020                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
29021                                 error "stripes are not evenly distributed"
29022                 fi
29023         done
29024
29025         echo
29026         echo "Check for uneven MDTs: "
29027
29028         local ffree
29029         local bavail
29030         local max
29031         local min
29032         local max_index
29033         local min_index
29034         local tmp
29035
29036         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
29037         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
29038         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
29039
29040         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
29041         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
29042         max_index=0
29043         min_index=0
29044         for ((i = 1; i < ${#ffree[@]}; i++)); do
29045                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
29046                 if [ $tmp -gt $max ]; then
29047                         max=$tmp
29048                         max_index=$i
29049                 fi
29050                 if [ $tmp -lt $min ]; then
29051                         min=$tmp
29052                         min_index=$i
29053                 fi
29054         done
29055         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
29056
29057         (( min > 0 )) || skip "low space on MDT$min_index"
29058         (( ${ffree[min_index]} < 10000000 )) ||
29059                 skip "too many free files on MDT$min_index"
29060
29061         generate_uneven_mdts 120
29062
29063         echo "MDT filesfree available: ${ffree[*]}"
29064         echo "MDT blocks available: ${bavail[*]}"
29065         echo "weight diff=$(((max - min) * 100 / min))%"
29066         echo
29067         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
29068
29069         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
29070         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
29071         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
29072         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
29073
29074         sleep 1
29075
29076         testdir=$DIR/$tdir-s$stripe_count/qos
29077
29078         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
29079         for (( i = 0; i < total / stripe_count; i++ )); do
29080                 eval $mkdir_cmd $testdir/subdir$i ||
29081                         error "$mkdir_cmd subdir$i failed"
29082         done
29083
29084         max=0
29085         for (( i = 0; i < $MDSCOUNT; i++ )); do
29086                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
29087                 (( count > max )) && max=$count
29088                 echo "$count directories created on MDT$i : curmax=$max"
29089         done
29090
29091         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
29092
29093         # D-value should > 10% of average
29094         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
29095                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
29096
29097         # ditto for stripes
29098         if (( stripe_count > 1 )); then
29099                 max=0
29100                 for (( i = 0; i < $MDSCOUNT; i++ )); do
29101                         count=$($LFS getdirstripe $testdir/* |
29102                                 grep -c -P "^\s+$i\t")
29103                         (( count > max )) && max=$count
29104                         echo "$count stripes created on MDT$i"
29105                 done
29106
29107                 min=$($LFS getdirstripe $testdir/* |
29108                         grep -c -P "^\s+$min_index\t")
29109                 (( max - min > total / MDSCOUNT / 10 )) ||
29110                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
29111         fi
29112 }
29113
29114 most_full_mdt() {
29115         local ffree
29116         local bavail
29117         local bsize
29118         local min
29119         local min_index
29120         local tmp
29121
29122         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
29123         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
29124         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
29125
29126         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
29127         min_index=0
29128         for ((i = 1; i < ${#ffree[@]}; i++)); do
29129                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
29130                 (( tmp < min )) && min=$tmp && min_index=$i
29131         done
29132
29133         echo -n $min_index
29134 }
29135
29136 test_413a() {
29137         [ $MDSCOUNT -lt 2 ] &&
29138                 skip "We need at least 2 MDTs for this test"
29139
29140         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
29141                 skip "Need server version at least 2.12.52"
29142
29143         local stripe_max=$((MDSCOUNT - 1))
29144         local stripe_count
29145
29146         # let caller set maxage for latest result
29147         set_maxage 1
29148
29149         # fill MDT unevenly
29150         generate_uneven_mdts 120
29151
29152         # test 4-stripe directory at most, otherwise it's too slow
29153         # We are being very defensive. Although Autotest uses 4 MDTs.
29154         # We make sure stripe_max does not go over 4.
29155         (( stripe_max > 4 )) && stripe_max=4
29156         # unlinking striped directory is slow on zfs, and may timeout, only test
29157         # plain directory
29158         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
29159         for stripe_count in $(seq 1 $stripe_max); do
29160                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
29161                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
29162                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
29163                         error "mkdir failed"
29164                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
29165         done
29166 }
29167 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
29168
29169 test_413b() {
29170         [ $MDSCOUNT -lt 2 ] &&
29171                 skip "We need at least 2 MDTs for this test"
29172
29173         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
29174                 skip "Need server version at least 2.12.52"
29175
29176         local stripe_max=$((MDSCOUNT - 1))
29177         local testdir
29178         local stripe_count
29179
29180         # let caller set maxage for latest result
29181         set_maxage 1
29182
29183         # fill MDT unevenly
29184         generate_uneven_mdts 120
29185
29186         # test 4-stripe directory at most, otherwise it's too slow
29187         # We are being very defensive. Although Autotest uses 4 MDTs.
29188         # We make sure stripe_max does not go over 4.
29189         (( stripe_max > 4 )) && stripe_max=4
29190         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
29191         for stripe_count in $(seq 1 $stripe_max); do
29192                 testdir=$DIR/$tdir-s$stripe_count
29193                 mkdir $testdir || error "mkdir $testdir failed"
29194                 mkdir $testdir/rr || error "mkdir rr failed"
29195                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
29196                         error "mkdir qos failed"
29197                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
29198                         $testdir/rr || error "setdirstripe rr failed"
29199                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
29200                         error "setdirstripe failed"
29201                 test_qos_mkdir "mkdir" $stripe_count
29202         done
29203 }
29204 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
29205
29206 test_413c() {
29207         (( $MDSCOUNT >= 2 )) ||
29208                 skip "We need at least 2 MDTs for this test"
29209
29210         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
29211                 skip "Need server version at least 2.14.51"
29212
29213         local testdir
29214         local inherit
29215         local inherit_rr
29216         local lmv_qos_maxage
29217         local lod_qos_maxage
29218
29219         # let caller set maxage for latest result
29220         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
29221         $LCTL set_param lmv.*.qos_maxage=1
29222         stack_trap "$LCTL set_param \
29223                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
29224         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
29225                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
29226         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
29227                 lod.*.mdt_qos_maxage=1
29228         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
29229                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
29230
29231         # fill MDT unevenly
29232         generate_uneven_mdts 120
29233
29234         testdir=$DIR/${tdir}-s1
29235         mkdir $testdir || error "mkdir $testdir failed"
29236         mkdir $testdir/rr || error "mkdir rr failed"
29237         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
29238         # default max_inherit is -1, default max_inherit_rr is 0
29239         $LFS setdirstripe -D -c 1 $testdir/rr ||
29240                 error "setdirstripe rr failed"
29241         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
29242                 error "setdirstripe qos failed"
29243         test_qos_mkdir "mkdir" 1
29244
29245         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
29246         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
29247         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
29248         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
29249         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
29250
29251         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
29252         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
29253         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
29254         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
29255         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
29256         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
29257         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
29258                 error "level2 shouldn't have default LMV" || true
29259 }
29260 run_test 413c "mkdir with default LMV max inherit rr"
29261
29262 test_413d() {
29263         (( MDSCOUNT >= 2 )) ||
29264                 skip "We need at least 2 MDTs for this test"
29265
29266         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
29267                 skip "Need server version at least 2.14.51"
29268
29269         local lmv_qos_threshold_rr
29270
29271         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
29272                 head -n1)
29273         stack_trap "$LCTL set_param \
29274                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
29275
29276         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
29277         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
29278         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
29279                 error "$tdir shouldn't have default LMV"
29280         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
29281                 error "mkdir sub failed"
29282
29283         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
29284
29285         (( count == 100 )) || error "$count subdirs on MDT0"
29286 }
29287 run_test 413d "inherit ROOT default LMV"
29288
29289 test_413e() {
29290         (( MDSCOUNT >= 2 )) ||
29291                 skip "We need at least 2 MDTs for this test"
29292         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
29293                 skip "Need server version at least 2.14.55"
29294
29295         local testdir=$DIR/$tdir
29296         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
29297         local max_inherit
29298         local sub_max_inherit
29299
29300         mkdir -p $testdir || error "failed to create $testdir"
29301
29302         # set default max-inherit to -1 if stripe count is 0 or 1
29303         $LFS setdirstripe -D -c 1 $testdir ||
29304                 error "failed to set default LMV"
29305         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
29306         (( max_inherit == -1 )) ||
29307                 error "wrong max_inherit value $max_inherit"
29308
29309         # set default max_inherit to a fixed value if stripe count is not 0 or 1
29310         $LFS setdirstripe -D -c -1 $testdir ||
29311                 error "failed to set default LMV"
29312         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
29313         (( max_inherit > 0 )) ||
29314                 error "wrong max_inherit value $max_inherit"
29315
29316         # and the subdir will decrease the max_inherit by 1
29317         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
29318         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
29319         (( sub_max_inherit == max_inherit - 1)) ||
29320                 error "wrong max-inherit of subdir $sub_max_inherit"
29321
29322         # check specified --max-inherit and warning message
29323         stack_trap "rm -f $tmpfile"
29324         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
29325                 error "failed to set default LMV"
29326         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
29327         (( max_inherit == -1 )) ||
29328                 error "wrong max_inherit value $max_inherit"
29329
29330         # check the warning messages
29331         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
29332                 error "failed to detect warning string"
29333         fi
29334 }
29335 run_test 413e "check default max-inherit value"
29336
29337 test_fs_dmv_inherit()
29338 {
29339         local testdir=$DIR/$tdir
29340
29341         local count
29342         local inherit
29343         local inherit_rr
29344
29345         for i in 1 2; do
29346                 mkdir $testdir || error "mkdir $testdir failed"
29347                 count=$($LFS getdirstripe -D -c $testdir)
29348                 (( count == 1 )) ||
29349                         error "$testdir default LMV count mismatch $count != 1"
29350                 inherit=$($LFS getdirstripe -D -X $testdir)
29351                 (( inherit == 3 - i )) ||
29352                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
29353                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
29354                 (( inherit_rr == 3 - i )) ||
29355                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
29356                 testdir=$testdir/sub
29357         done
29358
29359         mkdir $testdir || error "mkdir $testdir failed"
29360         count=$($LFS getdirstripe -D -c $testdir)
29361         (( count == 0 )) ||
29362                 error "$testdir default LMV count not zero: $count"
29363 }
29364
29365 test_413f() {
29366         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
29367
29368         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
29369                 skip "Need server version at least 2.14.55"
29370
29371         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
29372                 error "dump $DIR default LMV failed"
29373         stack_trap "setfattr --restore=$TMP/dmv.ea"
29374
29375         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
29376                 error "set $DIR default LMV failed"
29377
29378         test_fs_dmv_inherit
29379 }
29380 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
29381
29382 test_413g() {
29383         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
29384
29385         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
29386         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
29387                 error "dump $DIR default LMV failed"
29388         stack_trap "setfattr --restore=$TMP/dmv.ea"
29389
29390         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
29391                 error "set $DIR default LMV failed"
29392
29393         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
29394                 error "mount $MOUNT2 failed"
29395         stack_trap "umount_client $MOUNT2"
29396
29397         local saved_DIR=$DIR
29398
29399         export DIR=$MOUNT2
29400
29401         stack_trap "export DIR=$saved_DIR"
29402
29403         # first check filesystem-wide default LMV inheritance
29404         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
29405
29406         # then check subdirs are spread to all MDTs
29407         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
29408
29409         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
29410
29411         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
29412 }
29413 run_test 413g "enforce ROOT default LMV on subdir mount"
29414
29415 test_413h() {
29416         (( MDSCOUNT >= 2 )) ||
29417                 skip "We need at least 2 MDTs for this test"
29418
29419         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
29420                 skip "Need server version at least 2.15.50.6"
29421
29422         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
29423
29424         stack_trap "$LCTL set_param \
29425                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
29426         $LCTL set_param lmv.*.qos_maxage=1
29427
29428         local depth=5
29429         local rr_depth=4
29430         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
29431         local count=$((MDSCOUNT * 20))
29432
29433         generate_uneven_mdts 50
29434
29435         mkdir -p $dir || error "mkdir $dir failed"
29436         stack_trap "rm -rf $dir"
29437         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
29438                 --max-inherit-rr=$rr_depth $dir
29439
29440         for ((d=0; d < depth + 2; d++)); do
29441                 log "dir=$dir:"
29442                 for ((sub=0; sub < count; sub++)); do
29443                         mkdir $dir/d$sub
29444                 done
29445                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
29446                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
29447                 # subdirs within $rr_depth should be created round-robin
29448                 if (( d < rr_depth )); then
29449                         (( ${num[0]} != count )) ||
29450                                 error "all objects created on MDT ${num[1]}"
29451                 fi
29452
29453                 dir=$dir/d0
29454         done
29455 }
29456 run_test 413h "don't stick to parent for round-robin dirs"
29457
29458 test_413i() {
29459         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
29460
29461         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
29462                 skip "Need server version at least 2.14.55"
29463
29464         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
29465                 error "dump $DIR default LMV failed"
29466         stack_trap "setfattr --restore=$TMP/dmv.ea"
29467
29468         local testdir=$DIR/$tdir
29469         local def_max_rr=1
29470         local def_max=3
29471         local count
29472
29473         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
29474                 --max-inherit-rr=$def_max_rr $DIR ||
29475                 error "set $DIR default LMV failed"
29476
29477         for i in $(seq 2 3); do
29478                 def_max=$((def_max - 1))
29479                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
29480
29481                 mkdir $testdir
29482                 # RR is decremented and keeps zeroed once exhausted
29483                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
29484                 (( count == def_max_rr )) ||
29485                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
29486
29487                 # max-inherit is decremented
29488                 count=$($LFS getdirstripe -D --max-inherit $testdir)
29489                 (( count == def_max )) ||
29490                         error_noexit "$testdir: max-inherit $count != $def_max"
29491
29492                 testdir=$testdir/d$i
29493         done
29494
29495         # d3 is the last inherited from ROOT, no inheritance anymore
29496         # i.e. no the default layout anymore
29497         mkdir -p $testdir/d4/d5
29498         count=$($LFS getdirstripe -D --max-inherit $testdir)
29499         (( count == -1 )) ||
29500                 error_noexit "$testdir: max-inherit $count != -1"
29501
29502         local p_count=$($LFS getdirstripe -i $testdir)
29503
29504         for i in $(seq 4 5); do
29505                 testdir=$testdir/d$i
29506
29507                 # the root default layout is not applied once exhausted
29508                 count=$($LFS getdirstripe -i $testdir)
29509                 (( count == p_count )) ||
29510                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
29511         done
29512
29513         $LFS setdirstripe -i 0 $DIR/d2
29514         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
29515         (( count == -1 )) ||
29516                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
29517 }
29518 run_test 413i "check default layout inheritance"
29519
29520 test_413j()
29521 {
29522         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
29523
29524         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
29525         $LFS setdirstripe -D -c2 --max-inherit=2 $DIR/$tdir ||
29526                 error "setdirstripe $tdir failed"
29527
29528         local value=$(getfattr -n trusted.dmv $DIR/$tdir | \
29529                       grep "trusted.dmv" |sed -e 's/[^=]\+=//')
29530
29531         mkdir -p $DIR/$tdir/sub || error "mkdir sub failed"
29532         # setfattr dmv calls setdirstripe -D
29533         setfattr -n trusted.dmv -v $value $DIR/$tdir/sub ||
29534                 error "setfattr sub failed"
29535         local value2=$(getfattr -n trusted.dmv $DIR/$tdir/sub | \
29536                        grep "trusted.dmv" |sed -e 's/[^=]\+=//')
29537
29538         [ $value == $value2 ] || error "dmv mismatch"
29539
29540         (( MDS1_VERSION >= $(version_code 2.15.58) )) || return 0
29541
29542         # do not allow remove dmv by setfattr -x
29543         do_nodes $(comma_list $(mdts_nodes)) \
29544                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=0"
29545         setfattr -x trusted.dmv $DIR/$tdir/sub || error "setfattr sub failed"
29546         getfattr -n trusted.dmv $DIR/$tdir/sub || error "default LMV deleted"
29547
29548         # allow remove dmv by setfattr -x
29549         do_nodes $(comma_list $(mdts_nodes)) \
29550                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=1"
29551         setfattr -x trusted.dmv $DIR/$tdir/sub || error "setfattr sub failed"
29552         getfattr -n trusted.dmv $DIR/$tdir/sub && error "default LMV exists"
29553         do_nodes $(comma_list $(mdts_nodes)) \
29554                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=0"
29555 }
29556 run_test 413j "set default LMV by setxattr"
29557
29558 test_413k() {
29559         (( $MDS1_VERSION >= $(version_code 2.15.60) )) ||
29560                 skip "Need server version at least 2.15.60"
29561
29562         local index1
29563         local index2
29564         local old=$($LCTL get_param -n lmv.*.qos_exclude_prefixes)
29565         local count=$($LCTL get_param -n lmv.*.qos_exclude_prefixes | wc -l)
29566         local prefixes="abc:123:foo bar"
29567
29568         # add prefixes
29569         stack_trap "$LCTL set_param lmv.*.qos_exclude_prefixes=\"$old\""
29570         $LCTL set_param lmv.*.qos_exclude_prefixes="+$prefixes"
29571
29572         mkdir $DIR/$tdir || error "mkdir $tdir failed"
29573         index1=$($LFS getstripe -m $DIR/$tdir)
29574         for dname in _temporary _temporary.XXXXXX abc 123 "foo bar"; do
29575                 mkdir "$DIR/$tdir/$dname" || error "mkdir $dname failed"
29576                 index2=$($LFS getstripe -m "$DIR/$tdir/$dname")
29577                 ((index1 == index2)) ||
29578                         error "$tdir on MDT$index1, $dname on MDT$index2"
29579         done
29580
29581         # remove prefixes
29582         $LCTL set_param lmv.*.qos_exclude_prefixes="-$prefixes"
29583
29584         # total prefixes length > PAGE_SIZE can be printed correctly
29585         for c in {a..z}; do
29586                 prefixes=$(str_repeat $c 255)
29587                 $LCTL set_param lmv.*.qos_exclude_prefixes="+$prefixes" >/dev/null
29588         done
29589         local count2=$($LCTL get_param -n lmv.*.qos_exclude_prefixes | wc -l)
29590         ((count2 == count + 26)) ||
29591                 error "prefixes count $count2 != $((count + 26))"
29592 }
29593 run_test 413k "QoS mkdir exclude prefixes"
29594
29595 test_413z() {
29596         local pids=""
29597         local subdir
29598         local pid
29599
29600         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
29601                 unlinkmany $subdir/f. $TEST413_COUNT &
29602                 pids="$pids $!"
29603         done
29604
29605         for pid in $pids; do
29606                 wait $pid
29607         done
29608
29609         true
29610 }
29611 run_test 413z "413 test cleanup"
29612
29613 test_414() {
29614 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
29615         $LCTL set_param fail_loc=0x80000521
29616         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
29617         rm -f $DIR/$tfile
29618         # This error path has sometimes left inflight requests dangling, so
29619         # test for this by remounting the client (umount will hang if there's
29620         # a dangling request)
29621         umount_client $MOUNT
29622         mount_client $MOUNT
29623 }
29624 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
29625
29626 test_415() {
29627         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
29628         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
29629                 skip "Need server version at least 2.11.52"
29630
29631         # LU-11102
29632         local total=500
29633         local max=120
29634
29635         # this test may be slow on ZFS
29636         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
29637
29638         # though this test is designed for striped directory, let's test normal
29639         # directory too since lock is always saved as CoS lock.
29640         test_mkdir $DIR/$tdir || error "mkdir $tdir"
29641         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
29642         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
29643         # if looping with ONLY_REPEAT, wait for previous deletions to finish
29644         wait_delete_completed_mds
29645
29646         # run a loop without concurrent touch to measure rename duration.
29647         # only for test debug/robustness, NOT part of COS functional test.
29648         local start_time=$SECONDS
29649         for ((i = 0; i < total; i++)); do
29650                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
29651                         > /dev/null
29652         done
29653         local baseline=$((SECONDS - start_time))
29654         echo "rename $total files without 'touch' took $baseline sec"
29655
29656         (
29657                 while true; do
29658                         touch $DIR/$tdir
29659                 done
29660         ) &
29661         local setattr_pid=$!
29662
29663         # rename files back to original name so unlinkmany works
29664         start_time=$SECONDS
29665         for ((i = 0; i < total; i++)); do
29666                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
29667                         > /dev/null
29668         done
29669         local duration=$((SECONDS - start_time))
29670
29671         kill -9 $setattr_pid
29672
29673         echo "rename $total files with 'touch' took $duration sec"
29674         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
29675         (( duration <= max )) ||
29676                 error_not_in_vm "rename took $duration > $max sec"
29677 }
29678 run_test 415 "lock revoke is not missing"
29679
29680 test_416() {
29681         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
29682                 skip "Need server version at least 2.11.55"
29683
29684         # define OBD_FAIL_OSD_TXN_START    0x19a
29685         do_facet mds1 lctl set_param fail_loc=0x19a
29686
29687         lfs mkdir -c $MDSCOUNT $DIR/$tdir
29688
29689         true
29690 }
29691 run_test 416 "transaction start failure won't cause system hung"
29692
29693 cleanup_417() {
29694         trap 0
29695         do_nodes $(comma_list $(mdts_nodes)) \
29696                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
29697         do_nodes $(comma_list $(mdts_nodes)) \
29698                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
29699         do_nodes $(comma_list $(mdts_nodes)) \
29700                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
29701 }
29702
29703 test_417() {
29704         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
29705         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
29706                 skip "Need MDS version at least 2.11.56"
29707
29708         trap cleanup_417 RETURN EXIT
29709
29710         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
29711         do_nodes $(comma_list $(mdts_nodes)) \
29712                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
29713         $LFS migrate -m 0 $DIR/$tdir.1 &&
29714                 error "migrate dir $tdir.1 should fail"
29715
29716         do_nodes $(comma_list $(mdts_nodes)) \
29717                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
29718         $LFS mkdir -i 1 $DIR/$tdir.2 &&
29719                 error "create remote dir $tdir.2 should fail"
29720
29721         do_nodes $(comma_list $(mdts_nodes)) \
29722                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
29723         $LFS mkdir -c 2 $DIR/$tdir.3 &&
29724                 error "create striped dir $tdir.3 should fail"
29725         true
29726 }
29727 run_test 417 "disable remote dir, striped dir and dir migration"
29728
29729 # Checks that the outputs of df [-i] and lfs df [-i] match
29730 #
29731 # usage: check_lfs_df <blocks | inodes> <mountpoint>
29732 check_lfs_df() {
29733         local dir=$2
29734         local inodes
29735         local df_out
29736         local lfs_df_out
29737         local count
29738         local passed=false
29739
29740         # blocks or inodes
29741         [ "$1" == "blocks" ] && inodes= || inodes="-i"
29742
29743         for count in {1..100}; do
29744                 do_nodes "$CLIENTS" \
29745                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
29746                 sync; sleep 0.2
29747
29748                 # read the lines of interest
29749                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
29750                         error "df $inodes $dir | tail -n +2 failed"
29751                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
29752                         error "lfs df $inodes $dir | grep summary: failed"
29753
29754                 # skip first substrings of each output as they are different
29755                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
29756                 # compare the two outputs
29757                 passed=true
29758                 #  skip "available" on MDT until LU-13997 is fixed.
29759                 #for i in {1..5}; do
29760                 for i in 1 2 4 5; do
29761                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
29762                 done
29763                 $passed && break
29764         done
29765
29766         if ! $passed; then
29767                 df -P $inodes $dir
29768                 echo
29769                 lfs df $inodes $dir
29770                 error "df and lfs df $1 output mismatch: "      \
29771                       "df ${inodes}: ${df_out[*]}, "            \
29772                       "lfs df ${inodes}: ${lfs_df_out[*]}"
29773         fi
29774 }
29775
29776 test_418() {
29777         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29778
29779         local dir=$DIR/$tdir
29780         local numfiles=$((RANDOM % 4096 + 2))
29781         local numblocks=$((RANDOM % 256 + 1))
29782
29783         wait_delete_completed
29784         test_mkdir $dir
29785
29786         # check block output
29787         check_lfs_df blocks $dir
29788         # check inode output
29789         check_lfs_df inodes $dir
29790
29791         # create a single file and retest
29792         echo "Creating a single file and testing"
29793         createmany -o $dir/$tfile- 1 &>/dev/null ||
29794                 error "creating 1 file in $dir failed"
29795         check_lfs_df blocks $dir
29796         check_lfs_df inodes $dir
29797
29798         # create a random number of files
29799         echo "Creating $((numfiles - 1)) files and testing"
29800         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
29801                 error "creating $((numfiles - 1)) files in $dir failed"
29802
29803         # write a random number of blocks to the first test file
29804         echo "Writing $numblocks 4K blocks and testing"
29805         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
29806                 count=$numblocks &>/dev/null ||
29807                 error "dd to $dir/${tfile}-0 failed"
29808
29809         # retest
29810         check_lfs_df blocks $dir
29811         check_lfs_df inodes $dir
29812
29813         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
29814                 error "unlinking $numfiles files in $dir failed"
29815 }
29816 run_test 418 "df and lfs df outputs match"
29817
29818 test_419()
29819 {
29820         local dir=$DIR/$tdir
29821
29822         mkdir -p $dir
29823         touch $dir/file
29824
29825         cancel_lru_locks mdc
29826
29827         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
29828         $LCTL set_param fail_loc=0x1410
29829         cat $dir/file
29830         $LCTL set_param fail_loc=0
29831         rm -rf $dir
29832 }
29833 run_test 419 "Verify open file by name doesn't crash kernel"
29834
29835 test_420()
29836 {
29837         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
29838                 skip "Need MDS version at least 2.12.53"
29839
29840         local SAVE_UMASK=$(umask)
29841         local dir=$DIR/$tdir
29842         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
29843
29844         mkdir -p $dir
29845         umask 0000
29846         mkdir -m03777 $dir/testdir
29847         ls -dn $dir/testdir
29848         # Need to remove trailing '.' when SELinux is enabled
29849         local dirperms=$(ls -dn $dir/testdir |
29850                          awk '{ sub(/\.$/, "", $1); print $1}')
29851         [ $dirperms == "drwxrwsrwt" ] ||
29852                 error "incorrect perms on $dir/testdir"
29853
29854         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
29855                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
29856         ls -n $dir/testdir/testfile
29857         local fileperms=$(ls -n $dir/testdir/testfile |
29858                           awk '{ sub(/\.$/, "", $1); print $1}')
29859         [ $fileperms == "-rwxr-xr-x" ] ||
29860                 error "incorrect perms on $dir/testdir/testfile"
29861
29862         umask $SAVE_UMASK
29863 }
29864 run_test 420 "clear SGID bit on non-directories for non-members"
29865
29866 test_421a() {
29867         local cnt
29868         local fid1
29869         local fid2
29870
29871         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29872                 skip "Need MDS version at least 2.12.54"
29873
29874         test_mkdir $DIR/$tdir
29875         createmany -o $DIR/$tdir/f 3
29876         cnt=$(ls -1 $DIR/$tdir | wc -l)
29877         [ $cnt != 3 ] && error "unexpected #files: $cnt"
29878
29879         fid1=$(lfs path2fid $DIR/$tdir/f1)
29880         fid2=$(lfs path2fid $DIR/$tdir/f2)
29881         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
29882
29883         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
29884         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
29885
29886         cnt=$(ls -1 $DIR/$tdir | wc -l)
29887         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
29888
29889         rm -f $DIR/$tdir/f3 || error "can't remove f3"
29890         createmany -o $DIR/$tdir/f 3
29891         cnt=$(ls -1 $DIR/$tdir | wc -l)
29892         [ $cnt != 3 ] && error "unexpected #files: $cnt"
29893
29894         fid1=$(lfs path2fid $DIR/$tdir/f1)
29895         fid2=$(lfs path2fid $DIR/$tdir/f2)
29896         echo "remove using fsname $FSNAME"
29897         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
29898
29899         cnt=$(ls -1 $DIR/$tdir | wc -l)
29900         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
29901 }
29902 run_test 421a "simple rm by fid"
29903
29904 test_421b() {
29905         local cnt
29906         local FID1
29907         local FID2
29908
29909         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29910                 skip "Need MDS version at least 2.12.54"
29911
29912         test_mkdir $DIR/$tdir
29913         createmany -o $DIR/$tdir/f 3
29914         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
29915         MULTIPID=$!
29916
29917         FID1=$(lfs path2fid $DIR/$tdir/f1)
29918         FID2=$(lfs path2fid $DIR/$tdir/f2)
29919         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
29920
29921         kill -USR1 $MULTIPID
29922         wait
29923
29924         cnt=$(ls $DIR/$tdir | wc -l)
29925         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
29926 }
29927 run_test 421b "rm by fid on open file"
29928
29929 test_421c() {
29930         local cnt
29931         local FIDS
29932
29933         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29934                 skip "Need MDS version at least 2.12.54"
29935
29936         test_mkdir $DIR/$tdir
29937         createmany -o $DIR/$tdir/f 3
29938         touch $DIR/$tdir/$tfile
29939         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
29940         cnt=$(ls -1 $DIR/$tdir | wc -l)
29941         [ $cnt != 184 ] && error "unexpected #files: $cnt"
29942
29943         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
29944         $LFS rmfid $DIR $FID1 || error "rmfid failed"
29945
29946         cnt=$(ls $DIR/$tdir | wc -l)
29947         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
29948 }
29949 run_test 421c "rm by fid against hardlinked files"
29950
29951 test_421d() {
29952         local cnt
29953         local FIDS
29954
29955         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29956                 skip "Need MDS version at least 2.12.54"
29957
29958         test_mkdir $DIR/$tdir
29959         createmany -o $DIR/$tdir/f 4097
29960         cnt=$(ls -1 $DIR/$tdir | wc -l)
29961         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
29962
29963         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
29964         $LFS rmfid $DIR $FIDS || error "rmfid failed"
29965
29966         cnt=$(ls $DIR/$tdir | wc -l)
29967         rm -rf $DIR/$tdir
29968         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
29969 }
29970 run_test 421d "rmfid en masse"
29971
29972 test_421e() {
29973         local cnt
29974         local FID
29975
29976         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
29977         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29978                 skip "Need MDS version at least 2.12.54"
29979
29980         mkdir -p $DIR/$tdir
29981         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
29982         createmany -o $DIR/$tdir/striped_dir/f 512
29983         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
29984         [ $cnt != 512 ] && error "unexpected #files: $cnt"
29985
29986         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
29987                 sed "s/[/][^:]*://g")
29988         $LFS rmfid $DIR $FIDS || error "rmfid failed"
29989
29990         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
29991         rm -rf $DIR/$tdir
29992         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
29993 }
29994 run_test 421e "rmfid in DNE"
29995
29996 test_421f() {
29997         local cnt
29998         local FID
29999
30000         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
30001                 skip "Need MDS version at least 2.12.54"
30002
30003         test_mkdir $DIR/$tdir
30004         touch $DIR/$tdir/f
30005         cnt=$(ls -1 $DIR/$tdir | wc -l)
30006         [ $cnt != 1 ] && error "unexpected #files: $cnt"
30007
30008         FID=$(lfs path2fid $DIR/$tdir/f)
30009         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
30010         # rmfid should fail
30011         cnt=$(ls -1 $DIR/$tdir | wc -l)
30012         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
30013
30014         chmod a+rw $DIR/$tdir
30015         ls -la $DIR/$tdir
30016         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
30017         # rmfid should fail
30018         cnt=$(ls -1 $DIR/$tdir | wc -l)
30019         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
30020
30021         rm -f $DIR/$tdir/f
30022         $RUNAS touch $DIR/$tdir/f
30023         FID=$(lfs path2fid $DIR/$tdir/f)
30024         echo "rmfid as root"
30025         $LFS rmfid $DIR $FID || error "rmfid as root failed"
30026         cnt=$(ls -1 $DIR/$tdir | wc -l)
30027         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
30028
30029         rm -f $DIR/$tdir/f
30030         $RUNAS touch $DIR/$tdir/f
30031         cnt=$(ls -1 $DIR/$tdir | wc -l)
30032         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
30033         FID=$(lfs path2fid $DIR/$tdir/f)
30034         # rmfid w/o user_fid2path mount option should fail
30035         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
30036         cnt=$(ls -1 $DIR/$tdir | wc -l)
30037         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
30038
30039         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
30040         stack_trap "rmdir $tmpdir"
30041         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
30042                 error "failed to mount client'"
30043         stack_trap "umount_client $tmpdir"
30044
30045         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
30046         # rmfid should succeed
30047         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
30048         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
30049
30050         # rmfid shouldn't allow to remove files due to dir's permission
30051         chmod a+rwx $tmpdir/$tdir
30052         touch $tmpdir/$tdir/f
30053         ls -la $tmpdir/$tdir
30054         FID=$(lfs path2fid $tmpdir/$tdir/f)
30055         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
30056         return 0
30057 }
30058 run_test 421f "rmfid checks permissions"
30059
30060 test_421g() {
30061         local cnt
30062         local FIDS
30063
30064         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
30065         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
30066                 skip "Need MDS version at least 2.12.54"
30067
30068         mkdir -p $DIR/$tdir
30069         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
30070         createmany -o $DIR/$tdir/striped_dir/f 512
30071         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
30072         [ $cnt != 512 ] && error "unexpected #files: $cnt"
30073
30074         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
30075                 sed "s/[/][^:]*://g")
30076
30077         rm -f $DIR/$tdir/striped_dir/f1*
30078         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
30079         removed=$((512 - cnt))
30080
30081         # few files have been just removed, so we expect
30082         # rmfid to fail on their fids
30083         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
30084         [ $removed != $errors ] && error "$errors != $removed"
30085
30086         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
30087         rm -rf $DIR/$tdir
30088         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
30089 }
30090 run_test 421g "rmfid to return errors properly"
30091
30092 test_421h() {
30093         local mount_other
30094         local mount_ret
30095         local rmfid_ret
30096         local old_fid
30097         local fidA
30098         local fidB
30099         local fidC
30100         local fidD
30101
30102         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
30103                 skip "Need MDS version at least 2.15.53"
30104
30105         test_mkdir $DIR/$tdir
30106         test_mkdir $DIR/$tdir/subdir
30107         touch $DIR/$tdir/subdir/file0
30108         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
30109         echo File $DIR/$tdir/subdir/file0 FID $old_fid
30110         rm -f $DIR/$tdir/subdir/file0
30111         touch $DIR/$tdir/subdir/fileA
30112         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
30113         echo File $DIR/$tdir/subdir/fileA FID $fidA
30114         touch $DIR/$tdir/subdir/fileB
30115         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
30116         echo File $DIR/$tdir/subdir/fileB FID $fidB
30117         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
30118         touch $DIR/$tdir/subdir/fileC
30119         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
30120         echo File $DIR/$tdir/subdir/fileC FID $fidC
30121         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
30122         touch $DIR/$tdir/fileD
30123         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
30124         echo File $DIR/$tdir/fileD FID $fidD
30125
30126         # mount another client mount point with subdirectory mount
30127         export FILESET=/$tdir/subdir
30128         mount_other=${MOUNT}_other
30129         mount_client $mount_other ${MOUNT_OPTS}
30130         mount_ret=$?
30131         export FILESET=""
30132         (( mount_ret == 0 )) || error "mount $mount_other failed"
30133
30134         echo Removing FIDs:
30135         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
30136         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
30137         rmfid_ret=$?
30138
30139         umount_client $mount_other || error "umount $mount_other failed"
30140
30141         (( rmfid_ret != 0 )) || error "rmfid should have failed"
30142
30143         # fileA should have been deleted
30144         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
30145
30146         # fileB should have been deleted
30147         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
30148
30149         # fileC should not have been deleted, fid also exists outside of fileset
30150         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
30151
30152         # fileD should not have been deleted, it exists outside of fileset
30153         stat $DIR/$tdir/fileD || error "fileD deleted"
30154 }
30155 run_test 421h "rmfid with fileset mount"
30156
30157 test_422() {
30158         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
30159         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
30160         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
30161         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
30162         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
30163
30164         local amc=$(at_max_get client)
30165         local amo=$(at_max_get mds1)
30166         local timeout=`lctl get_param -n timeout`
30167
30168         at_max_set 0 client
30169         at_max_set 0 mds1
30170
30171 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
30172         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
30173                         fail_val=$(((2*timeout + 10)*1000))
30174         touch $DIR/$tdir/d3/file &
30175         sleep 2
30176 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
30177         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
30178                         fail_val=$((2*timeout + 5))
30179         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
30180         local pid=$!
30181         sleep 1
30182         kill -9 $pid
30183         sleep $((2 * timeout))
30184         echo kill $pid
30185         kill -9 $pid
30186         lctl mark touch
30187         touch $DIR/$tdir/d2/file3
30188         touch $DIR/$tdir/d2/file4
30189         touch $DIR/$tdir/d2/file5
30190
30191         wait
30192         at_max_set $amc client
30193         at_max_set $amo mds1
30194
30195         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
30196         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
30197                 error "Watchdog is always throttled"
30198 }
30199 run_test 422 "kill a process with RPC in progress"
30200
30201 stat_test() {
30202     df -h $MOUNT &
30203     df -h $MOUNT &
30204     df -h $MOUNT &
30205     df -h $MOUNT &
30206     df -h $MOUNT &
30207     df -h $MOUNT &
30208 }
30209
30210 test_423() {
30211     local _stats
30212     # ensure statfs cache is expired
30213     sleep 2;
30214
30215     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
30216     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
30217
30218     return 0
30219 }
30220 run_test 423 "statfs should return a right data"
30221
30222 test_424() {
30223 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | CFS_FAIL_ONCE
30224         $LCTL set_param fail_loc=0x80000522
30225         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
30226         rm -f $DIR/$tfile
30227 }
30228 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
30229
30230 test_425() {
30231         test_mkdir -c -1 $DIR/$tdir
30232         $LFS setstripe -c -1 $DIR/$tdir
30233
30234         lru_resize_disable "" 100
30235         stack_trap "lru_resize_enable" EXIT
30236
30237         sleep 5
30238
30239         for i in $(seq $((MDSCOUNT * 125))); do
30240                 local t=$DIR/$tdir/$tfile_$i
30241
30242                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
30243                         error_noexit "Create file $t"
30244         done
30245         stack_trap "rm -rf $DIR/$tdir" EXIT
30246
30247         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
30248                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
30249                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
30250
30251                 [ $lock_count -le $lru_size ] ||
30252                         error "osc lock count $lock_count > lru size $lru_size"
30253         done
30254
30255         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
30256                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
30257                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
30258
30259                 [ $lock_count -le $lru_size ] ||
30260                         error "mdc lock count $lock_count > lru size $lru_size"
30261         done
30262 }
30263 run_test 425 "lock count should not exceed lru size"
30264
30265 test_426() {
30266         splice-test -r $DIR/$tfile
30267         splice-test -rd $DIR/$tfile
30268         splice-test $DIR/$tfile
30269         splice-test -d $DIR/$tfile
30270 }
30271 run_test 426 "splice test on Lustre"
30272
30273 test_427() {
30274         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
30275         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
30276                 skip "Need MDS version at least 2.12.4"
30277         local log
30278
30279         mkdir $DIR/$tdir
30280         mkdir $DIR/$tdir/1
30281         mkdir $DIR/$tdir/2
30282         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
30283         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
30284
30285         $LFS getdirstripe $DIR/$tdir/1/dir
30286
30287         #first setfattr for creating updatelog
30288         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
30289
30290 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
30291         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
30292         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
30293         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
30294
30295         sleep 2
30296         fail mds2
30297         wait_recovery_complete mds2 $((2*TIMEOUT))
30298
30299         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
30300         echo $log | grep "get update log failed" &&
30301                 error "update log corruption is detected" || true
30302 }
30303 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
30304
30305 test_428() {
30306         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30307         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
30308                               awk '/^max_cached_mb/ { print $2 }')
30309         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
30310
30311         $LCTL set_param -n llite.*.max_cached_mb=64
30312
30313         mkdir $DIR/$tdir
30314         $LFS setstripe -c 1 $DIR/$tdir
30315         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
30316         stack_trap "rm -f $DIR/$tdir/$tfile.*"
30317         #test write
30318         for f in $(seq 4); do
30319                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
30320         done
30321         wait
30322
30323         cancel_lru_locks osc
30324         # Test read
30325         for f in $(seq 4); do
30326                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
30327         done
30328         wait
30329 }
30330 run_test 428 "large block size IO should not hang"
30331
30332 test_429() { # LU-7915 / LU-10948
30333         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
30334         local testfile=$DIR/$tfile
30335         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
30336         local new_flag=1
30337         local first_rpc
30338         local second_rpc
30339         local third_rpc
30340
30341         $LCTL get_param $ll_opencache_threshold_count ||
30342                 skip "client does not have opencache parameter"
30343
30344         set_opencache $new_flag
30345         stack_trap "restore_opencache"
30346         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
30347                 error "enable opencache failed"
30348         touch $testfile
30349         # drop MDC DLM locks
30350         cancel_lru_locks mdc
30351         # clear MDC RPC stats counters
30352         $LCTL set_param $mdc_rpcstats=clear
30353
30354         # According to the current implementation, we need to run 3 times
30355         # open & close file to verify if opencache is enabled correctly.
30356         # 1st, RPCs are sent for lookup/open and open handle is released on
30357         #      close finally.
30358         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
30359         #      so open handle won't be released thereafter.
30360         # 3rd, No RPC is sent out.
30361         $MULTIOP $testfile oc || error "multiop failed"
30362         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
30363         echo "1st: $first_rpc RPCs in flight"
30364
30365         $MULTIOP $testfile oc || error "multiop failed"
30366         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
30367         echo "2nd: $second_rpc RPCs in flight"
30368
30369         $MULTIOP $testfile oc || error "multiop failed"
30370         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
30371         echo "3rd: $third_rpc RPCs in flight"
30372
30373         #verify no MDC RPC is sent
30374         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
30375 }
30376 run_test 429 "verify if opencache flag on client side does work"
30377
30378 lseek_test_430() {
30379         local offset
30380         local file=$1
30381
30382         # data at [200K, 400K)
30383         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
30384                 error "256K->512K dd fails"
30385         # data at [2M, 3M)
30386         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
30387                 error "2M->3M dd fails"
30388         # data at [4M, 5M)
30389         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
30390                 error "4M->5M dd fails"
30391         echo "Data at 256K...512K, 2M...3M and 4M...5M"
30392         # start at first component hole #1
30393         printf "Seeking hole from 1000 ... "
30394         offset=$(lseek_test -l 1000 $file)
30395         echo $offset
30396         [[ $offset == 1000 ]] || error "offset $offset != 1000"
30397         printf "Seeking data from 1000 ... "
30398         offset=$(lseek_test -d 1000 $file)
30399         echo $offset
30400         [[ $offset == 262144 ]] || error "offset $offset != 262144"
30401
30402         # start at first component data block
30403         printf "Seeking hole from 300000 ... "
30404         offset=$(lseek_test -l 300000 $file)
30405         echo $offset
30406         [[ $offset == 524288 ]] || error "offset $offset != 524288"
30407         printf "Seeking data from 300000 ... "
30408         offset=$(lseek_test -d 300000 $file)
30409         echo $offset
30410         [[ $offset == 300000 ]] || error "offset $offset != 300000"
30411
30412         # start at the first component but beyond end of object size
30413         printf "Seeking hole from 1000000 ... "
30414         offset=$(lseek_test -l 1000000 $file)
30415         echo $offset
30416         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
30417         printf "Seeking data from 1000000 ... "
30418         offset=$(lseek_test -d 1000000 $file)
30419         echo $offset
30420         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
30421
30422         # start at second component stripe 2 (empty file)
30423         printf "Seeking hole from 1500000 ... "
30424         offset=$(lseek_test -l 1500000 $file)
30425         echo $offset
30426         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
30427         printf "Seeking data from 1500000 ... "
30428         offset=$(lseek_test -d 1500000 $file)
30429         echo $offset
30430         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
30431
30432         # start at second component stripe 1 (all data)
30433         printf "Seeking hole from 3000000 ... "
30434         offset=$(lseek_test -l 3000000 $file)
30435         echo $offset
30436         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
30437         printf "Seeking data from 3000000 ... "
30438         offset=$(lseek_test -d 3000000 $file)
30439         echo $offset
30440         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
30441
30442         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
30443                 error "2nd dd fails"
30444         echo "Add data block at 640K...1280K"
30445
30446         # start at before new data block, in hole
30447         printf "Seeking hole from 600000 ... "
30448         offset=$(lseek_test -l 600000 $file)
30449         echo $offset
30450         [[ $offset == 600000 ]] || error "offset $offset != 600000"
30451         printf "Seeking data from 600000 ... "
30452         offset=$(lseek_test -d 600000 $file)
30453         echo $offset
30454         [[ $offset == 655360 ]] || error "offset $offset != 655360"
30455
30456         # start at the first component new data block
30457         printf "Seeking hole from 1000000 ... "
30458         offset=$(lseek_test -l 1000000 $file)
30459         echo $offset
30460         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
30461         printf "Seeking data from 1000000 ... "
30462         offset=$(lseek_test -d 1000000 $file)
30463         echo $offset
30464         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
30465
30466         # start at second component stripe 2, new data
30467         printf "Seeking hole from 1200000 ... "
30468         offset=$(lseek_test -l 1200000 $file)
30469         echo $offset
30470         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
30471         printf "Seeking data from 1200000 ... "
30472         offset=$(lseek_test -d 1200000 $file)
30473         echo $offset
30474         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
30475
30476         # start beyond file end
30477         printf "Using offset > filesize ... "
30478         lseek_test -l 4000000 $file && error "lseek should fail"
30479         printf "Using offset > filesize ... "
30480         lseek_test -d 4000000 $file && error "lseek should fail"
30481
30482         printf "Done\n\n"
30483 }
30484
30485 test_430a() {
30486         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
30487                 skip "MDT does not support SEEK_HOLE"
30488
30489         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
30490                 skip "OST does not support SEEK_HOLE"
30491
30492         local file=$DIR/$tdir/$tfile
30493
30494         mkdir -p $DIR/$tdir
30495
30496         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
30497         # OST stripe #1 will have continuous data at [1M, 3M)
30498         # OST stripe #2 is empty
30499         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
30500         lseek_test_430 $file
30501         rm $file
30502         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
30503         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
30504         lseek_test_430 $file
30505         rm $file
30506         $LFS setstripe -c2 -S 512K $file
30507         echo "Two stripes, stripe size 512K"
30508         lseek_test_430 $file
30509         rm $file
30510         # FLR with stale mirror
30511         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
30512                        -N -c2 -S 1M $file
30513         echo "Mirrored file:"
30514         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
30515         echo "Plain 2 stripes 1M"
30516         lseek_test_430 $file
30517         rm $file
30518 }
30519 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
30520
30521 test_430b() {
30522         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
30523                 skip "OST does not support SEEK_HOLE"
30524
30525         local offset
30526         local file=$DIR/$tdir/$tfile
30527
30528         mkdir -p $DIR/$tdir
30529         # Empty layout lseek should fail
30530         $MCREATE $file
30531         # seek from 0
30532         printf "Seeking hole from 0 ... "
30533         lseek_test -l 0 $file && error "lseek should fail"
30534         printf "Seeking data from 0 ... "
30535         lseek_test -d 0 $file && error "lseek should fail"
30536         rm $file
30537
30538         # 1M-hole file
30539         $LFS setstripe -E 1M -c2 -E eof $file
30540         $TRUNCATE $file 1048576
30541         printf "Seeking hole from 1000000 ... "
30542         offset=$(lseek_test -l 1000000 $file)
30543         echo $offset
30544         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
30545         printf "Seeking data from 1000000 ... "
30546         lseek_test -d 1000000 $file && error "lseek should fail"
30547         rm $file
30548
30549         # full component followed by non-inited one
30550         $LFS setstripe -E 1M -c2 -E eof $file
30551         dd if=/dev/urandom of=$file bs=1M count=1
30552         printf "Seeking hole from 1000000 ... "
30553         offset=$(lseek_test -l 1000000 $file)
30554         echo $offset
30555         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
30556         printf "Seeking hole from 1048576 ... "
30557         lseek_test -l 1048576 $file && error "lseek should fail"
30558         # init second component and truncate back
30559         echo "123" >> $file
30560         $TRUNCATE $file 1048576
30561         printf "Seeking hole from 1000000 ... "
30562         offset=$(lseek_test -l 1000000 $file)
30563         echo $offset
30564         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
30565         printf "Seeking hole from 1048576 ... "
30566         lseek_test -l 1048576 $file && error "lseek should fail"
30567         # boundary checks for big values
30568         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
30569         offset=$(lseek_test -d 0 $file.10g)
30570         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
30571         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
30572         offset=$(lseek_test -d 0 $file.100g)
30573         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
30574         return 0
30575 }
30576 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
30577
30578 test_430c() {
30579         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
30580                 skip "OST does not support SEEK_HOLE"
30581
30582         local file=$DIR/$tdir/$tfile
30583         local start
30584
30585         mkdir -p $DIR/$tdir
30586         stack_trap "rm -f $file $file.tmp"
30587         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M || error "dd failed"
30588
30589         # cp version 8.33+ prefers lseek over fiemap
30590         local ver=$(cp --version | awk '{ print $4; exit; }')
30591
30592         echo "cp $ver installed"
30593         if (( $(version_code $ver) >= $(version_code 8.33) )); then
30594                 start=$SECONDS
30595                 time cp -v $file $file.tmp || error "cp $file failed"
30596                 (( SECONDS - start < 5 )) || {
30597                         strace cp $file $file.tmp |&
30598                                 grep -E "open|read|seek|FIEMAP" |
30599                                 grep -A 100 $file
30600                         error "cp: too long runtime $((SECONDS - start))"
30601                 }
30602         else
30603                 echo "cp test skipped due to $ver < 8.33"
30604         fi
30605
30606         # tar version 1.29+ supports SEEK_HOLE/DATA
30607         ver=$(tar --version | awk '{ print $4; exit; }')
30608         echo "tar $ver installed"
30609         if (( $(version_code $ver) >= $(version_code 1.29) )); then
30610                 start=$SECONDS
30611                 time tar cvf $file.tmp --sparse $file || error "tar $file error"
30612                 (( SECONDS - start < 5 )) || {
30613                         strace tar cf $file.tmp --sparse $file |&
30614                                 grep -E "open|read|seek|FIEMAP" |
30615                                 grep -A 100 $file
30616                         error "tar: too long runtime $((SECONDS - start))"
30617                 }
30618         else
30619                 echo "tar test skipped due to $ver < 1.29"
30620         fi
30621 }
30622 run_test 430c "lseek: external tools check"
30623
30624 test_431() { # LU-14187
30625         local file=$DIR/$tdir/$tfile
30626
30627         mkdir -p $DIR/$tdir
30628         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
30629         dd if=/dev/urandom of=$file bs=4k count=1
30630         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
30631         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
30632         #define OBD_FAIL_OST_RESTART_IO 0x251
30633         do_facet ost1 "$LCTL set_param fail_loc=0x251"
30634         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
30635         cp $file $file.0
30636         cancel_lru_locks
30637         sync_all_data
30638         echo 3 > /proc/sys/vm/drop_caches
30639         diff  $file $file.0 || error "data diff"
30640 }
30641 run_test 431 "Restart transaction for IO"
30642
30643 cleanup_test_432() {
30644         do_facet mgs $LCTL nodemap_activate 0
30645         wait_nm_sync active
30646 }
30647
30648 test_432() {
30649         local tmpdir=$TMP/dir432
30650
30651         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
30652                 skip "Need MDS version at least 2.14.52"
30653
30654         stack_trap cleanup_test_432 EXIT
30655         mkdir $DIR/$tdir
30656         mkdir $tmpdir
30657
30658         do_facet mgs $LCTL nodemap_activate 1
30659         wait_nm_sync active
30660         do_facet mgs $LCTL nodemap_modify --name default \
30661                 --property admin --value 1
30662         do_facet mgs $LCTL nodemap_modify --name default \
30663                 --property trusted --value 1
30664         cancel_lru_locks mdc
30665         wait_nm_sync default admin_nodemap
30666         wait_nm_sync default trusted_nodemap
30667
30668         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
30669                grep -ci "Operation not permitted") -ne 0 ]; then
30670                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
30671         fi
30672 }
30673 run_test 432 "mv dir from outside Lustre"
30674
30675 test_433() {
30676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30677
30678         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
30679                 skip "inode cache not supported"
30680
30681         $LCTL set_param llite.*.inode_cache=0
30682         stack_trap "$LCTL set_param llite.*.inode_cache=1"
30683
30684         local count=256
30685         local before
30686         local after
30687
30688         cancel_lru_locks mdc
30689         test_mkdir $DIR/$tdir || error "mkdir $tdir"
30690         createmany -m $DIR/$tdir/f $count
30691         createmany -d $DIR/$tdir/d $count
30692         ls -l $DIR/$tdir > /dev/null
30693         stack_trap "rm -rf $DIR/$tdir"
30694
30695         before=$(num_objects)
30696         cancel_lru_locks mdc
30697         after=$(num_objects)
30698
30699         # sometimes even @before is less than 2 * count
30700         while (( before - after < count )); do
30701                 sleep 1
30702                 after=$(num_objects)
30703                 wait=$((wait + 1))
30704                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
30705                 if (( wait > 60 )); then
30706                         error "inode slab grew from $before to $after"
30707                 fi
30708         done
30709
30710         echo "lustre_inode_cache $before objs before lock cancel, $after after"
30711 }
30712 run_test 433 "ldlm lock cancel releases dentries and inodes"
30713
30714 test_434() {
30715         local file
30716         local getxattr_count
30717         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
30718         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30719
30720         [[ $(getenforce) == "Disabled" ]] ||
30721                 skip "lsm selinux module have to be disabled for this test"
30722
30723         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
30724                 error "fail to create $DIR/$tdir/ on MDT0000"
30725
30726         touch $DIR/$tdir/$tfile-{001..100}
30727
30728         # disable the xattr cache
30729         save_lustre_params client "llite.*.xattr_cache" > $p
30730         lctl set_param llite.*.xattr_cache=0
30731         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
30732
30733         # clear clients mdc stats
30734         clear_stats $mdc_stat_param ||
30735                 error "fail to clear stats on mdc MDT0000"
30736
30737         for file in $DIR/$tdir/$tfile-{001..100}; do
30738                 getfattr -n security.selinux $file |&
30739                         grep -q "Operation not supported" ||
30740                         error "getxattr on security.selinux should return EOPNOTSUPP"
30741         done
30742
30743         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
30744         (( getxattr_count < 100 )) ||
30745                 error "client sent $getxattr_count getxattr RPCs to the MDS"
30746 }
30747 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
30748
30749 test_440() {
30750         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
30751                 source $LUSTRE/scripts/bash-completion/lustre
30752         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
30753                 source /usr/share/bash-completion/completions/lustre
30754         else
30755                 skip "bash completion scripts not found"
30756         fi
30757
30758         local lctl_completions
30759         local lfs_completions
30760
30761         lctl_completions=$(_lustre_cmds lctl)
30762         if [[ ! $lctl_completions =~ "get_param" ]]; then
30763                 error "lctl bash completion failed"
30764         fi
30765
30766         lfs_completions=$(_lustre_cmds lfs)
30767         if [[ ! $lfs_completions =~ "setstripe" ]]; then
30768                 error "lfs bash completion failed"
30769         fi
30770 }
30771 run_test 440 "bash completion for lfs, lctl"
30772
30773 test_442() {
30774         local pid1
30775         local pid2
30776         mkdir -p $DIR/$tdir
30777         multiop $DIR/$tdir/$tfile.1 O_w1 & pid1=$!
30778         multiop $DIR/$tdir/$tfile.1 O_w1 & pid2=$!
30779         sleep 1
30780         touch $DIR/$tdir/$tfile.2
30781         $LFS swap_layouts -n $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
30782         $LCTL set_param fail_loc=0x1430
30783         kill -USR1 $pid1
30784         sleep 1
30785         kill -USR1 $pid2
30786         wait
30787 }
30788 run_test 442 "truncate vs read/write should not panic"
30789
30790 test_460d() {
30791         verify_yaml_available || skip_env "YAML verification not installed"
30792         $LCTL get_param -n sptlrpc.page_pools
30793         $LCTL get_param -n sptlrpc.page_pools | verify_yaml ||
30794                 error "The output of encrypt_page_pools is not an valid YAML"
30795 }
30796 run_test 460d "Check encrypt pools output"
30797
30798 prep_801() {
30799         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
30800         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
30801                 skip "Need server version at least 2.9.55"
30802
30803         start_full_debug_logging
30804 }
30805
30806 post_801() {
30807         stop_full_debug_logging
30808 }
30809
30810 barrier_stat() {
30811         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
30812                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
30813                            awk '/The barrier for/ { print $7 }')
30814                 echo $st
30815         else
30816                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
30817                 echo \'$st\'
30818         fi
30819 }
30820
30821 barrier_expired() {
30822         local expired
30823
30824         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
30825                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
30826                           awk '/will be expired/ { print $7 }')
30827         else
30828                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
30829         fi
30830
30831         echo $expired
30832 }
30833
30834 test_801a() {
30835         prep_801
30836
30837         echo "Start barrier_freeze at: $(date)"
30838         #define OBD_FAIL_BARRIER_DELAY          0x2202
30839         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
30840         # Do not reduce barrier time - See LU-11873
30841         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
30842
30843         sleep 2
30844         local b_status=$(barrier_stat)
30845         echo "Got barrier status at: $(date)"
30846         [ "$b_status" = "'freezing_p1'" ] ||
30847                 error "(1) unexpected barrier status $b_status"
30848
30849         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
30850         wait
30851         b_status=$(barrier_stat)
30852         [ "$b_status" = "'frozen'" ] ||
30853                 error "(2) unexpected barrier status $b_status"
30854
30855         local expired=$(barrier_expired)
30856         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
30857         sleep $((expired + 3))
30858
30859         b_status=$(barrier_stat)
30860         [ "$b_status" = "'expired'" ] ||
30861                 error "(3) unexpected barrier status $b_status"
30862
30863         # Do not reduce barrier time - See LU-11873
30864         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
30865                 error "(4) fail to freeze barrier"
30866
30867         b_status=$(barrier_stat)
30868         [ "$b_status" = "'frozen'" ] ||
30869                 error "(5) unexpected barrier status $b_status"
30870
30871         echo "Start barrier_thaw at: $(date)"
30872         #define OBD_FAIL_BARRIER_DELAY          0x2202
30873         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
30874         do_facet mgs $LCTL barrier_thaw $FSNAME &
30875
30876         sleep 2
30877         b_status=$(barrier_stat)
30878         echo "Got barrier status at: $(date)"
30879         [ "$b_status" = "'thawing'" ] ||
30880                 error "(6) unexpected barrier status $b_status"
30881
30882         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
30883         wait
30884         b_status=$(barrier_stat)
30885         [ "$b_status" = "'thawed'" ] ||
30886                 error "(7) unexpected barrier status $b_status"
30887
30888         #define OBD_FAIL_BARRIER_FAILURE        0x2203
30889         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
30890         do_facet mgs $LCTL barrier_freeze $FSNAME
30891
30892         b_status=$(barrier_stat)
30893         [ "$b_status" = "'failed'" ] ||
30894                 error "(8) unexpected barrier status $b_status"
30895
30896         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
30897         do_facet mgs $LCTL barrier_thaw $FSNAME
30898
30899         post_801
30900 }
30901 run_test 801a "write barrier user interfaces and stat machine"
30902
30903 test_801b() {
30904         prep_801
30905
30906         mkdir $DIR/$tdir || error "(1) fail to mkdir"
30907         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
30908         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
30909         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
30910         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
30911
30912         cancel_lru_locks mdc
30913
30914         # 180 seconds should be long enough
30915         do_facet mgs $LCTL barrier_freeze $FSNAME 180
30916
30917         local b_status=$(barrier_stat)
30918         [ "$b_status" = "'frozen'" ] ||
30919                 error "(6) unexpected barrier status $b_status"
30920
30921         mkdir $DIR/$tdir/d0/d10 &
30922         mkdir_pid=$!
30923
30924         touch $DIR/$tdir/d1/f13 &
30925         touch_pid=$!
30926
30927         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
30928         ln_pid=$!
30929
30930         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
30931         mv_pid=$!
30932
30933         rm -f $DIR/$tdir/d4/f12 &
30934         rm_pid=$!
30935
30936         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
30937
30938         # To guarantee taht the 'stat' is not blocked
30939         b_status=$(barrier_stat)
30940         [ "$b_status" = "'frozen'" ] ||
30941                 error "(8) unexpected barrier status $b_status"
30942
30943         # let above commands to run at background
30944         sleep 5
30945
30946         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
30947         ps -p $touch_pid || error "(10) touch should be blocked"
30948         ps -p $ln_pid || error "(11) link should be blocked"
30949         ps -p $mv_pid || error "(12) rename should be blocked"
30950         ps -p $rm_pid || error "(13) unlink should be blocked"
30951
30952         b_status=$(barrier_stat)
30953         [ "$b_status" = "'frozen'" ] ||
30954                 error "(14) unexpected barrier status $b_status"
30955
30956         do_facet mgs $LCTL barrier_thaw $FSNAME
30957         b_status=$(barrier_stat)
30958         [ "$b_status" = "'thawed'" ] ||
30959                 error "(15) unexpected barrier status $b_status"
30960
30961         wait $mkdir_pid || error "(16) mkdir should succeed"
30962         wait $touch_pid || error "(17) touch should succeed"
30963         wait $ln_pid || error "(18) link should succeed"
30964         wait $mv_pid || error "(19) rename should succeed"
30965         wait $rm_pid || error "(20) unlink should succeed"
30966
30967         post_801
30968 }
30969 run_test 801b "modification will be blocked by write barrier"
30970
30971 test_801c() {
30972         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30973
30974         prep_801
30975
30976         stop mds2 || error "(1) Fail to stop mds2"
30977
30978         do_facet mgs $LCTL barrier_freeze $FSNAME 30
30979
30980         local b_status=$(barrier_stat)
30981         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
30982                 do_facet mgs $LCTL barrier_thaw $FSNAME
30983                 error "(2) unexpected barrier status $b_status"
30984         }
30985
30986         do_facet mgs $LCTL barrier_rescan $FSNAME ||
30987                 error "(3) Fail to rescan barrier bitmap"
30988
30989         # Do not reduce barrier time - See LU-11873
30990         do_facet mgs $LCTL barrier_freeze $FSNAME 20
30991
30992         b_status=$(barrier_stat)
30993         [ "$b_status" = "'frozen'" ] ||
30994                 error "(4) unexpected barrier status $b_status"
30995
30996         do_facet mgs $LCTL barrier_thaw $FSNAME
30997         b_status=$(barrier_stat)
30998         [ "$b_status" = "'thawed'" ] ||
30999                 error "(5) unexpected barrier status $b_status"
31000
31001         local devname=$(mdsdevname 2)
31002
31003         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
31004
31005         do_facet mgs $LCTL barrier_rescan $FSNAME ||
31006                 error "(7) Fail to rescan barrier bitmap"
31007
31008         post_801
31009 }
31010 run_test 801c "rescan barrier bitmap"
31011
31012 test_802b() {
31013         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31014         remote_mds_nodsh && skip "remote MDS with nodsh"
31015
31016         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
31017                 skip "readonly option not available"
31018
31019         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
31020
31021         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
31022                 error "(2) Fail to copy"
31023
31024         # write back all cached data before setting MDT to readonly
31025         cancel_lru_locks
31026         sync_all_data
31027
31028         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
31029         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
31030
31031         echo "Modify should be refused"
31032         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
31033
31034         echo "Read should be allowed"
31035         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
31036                 error "(7) Read should succeed under ro mode"
31037
31038         # disable readonly
31039         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
31040 }
31041 run_test 802b "be able to set MDTs to readonly"
31042
31043 test_803a() {
31044         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
31045         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
31046                 skip "MDS needs to be newer than 2.10.54"
31047
31048         mkdir_on_mdt0 $DIR/$tdir
31049         # Create some objects on all MDTs to trigger related logs objects
31050         for idx in $(seq $MDSCOUNT); do
31051                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
31052                         $DIR/$tdir/dir${idx} ||
31053                         error "Fail to create $DIR/$tdir/dir${idx}"
31054         done
31055
31056         wait_delete_completed # ensure old test cleanups are finished
31057         sleep 3
31058         echo "before create:"
31059         $LFS df -i $MOUNT
31060         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
31061
31062         for i in {1..10}; do
31063                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
31064                         error "Fail to create $DIR/$tdir/foo$i"
31065         done
31066
31067         # sync ZFS-on-MDS to refresh statfs data
31068         wait_zfs_commit mds1
31069         sleep 3
31070         echo "after create:"
31071         $LFS df -i $MOUNT
31072         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
31073
31074         # allow for an llog to be cleaned up during the test
31075         [ $after_used -ge $((before_used + 10 - 1)) ] ||
31076                 error "before ($before_used) + 10 > after ($after_used)"
31077
31078         for i in {1..10}; do
31079                 rm -rf $DIR/$tdir/foo$i ||
31080                         error "Fail to remove $DIR/$tdir/foo$i"
31081         done
31082
31083         # sync ZFS-on-MDS to refresh statfs data
31084         wait_zfs_commit mds1
31085         wait_delete_completed
31086         sleep 3 # avoid MDT return cached statfs
31087         echo "after unlink:"
31088         $LFS df -i $MOUNT
31089         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
31090
31091         # allow for an llog to be created during the test
31092         [ $after_used -le $((before_used + 1)) ] ||
31093                 error "after ($after_used) > before ($before_used) + 1"
31094 }
31095 run_test 803a "verify agent object for remote object"
31096
31097 test_803b() {
31098         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
31099         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
31100                 skip "MDS needs to be newer than 2.13.56"
31101         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31102
31103         for i in $(seq 0 $((MDSCOUNT - 1))); do
31104                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
31105         done
31106
31107         local before=0
31108         local after=0
31109
31110         local tmp
31111
31112         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
31113         for i in $(seq 0 $((MDSCOUNT - 1))); do
31114                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
31115                         awk '/getattr/ { print $2 }')
31116                 before=$((before + tmp))
31117         done
31118         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
31119         for i in $(seq 0 $((MDSCOUNT - 1))); do
31120                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
31121                         awk '/getattr/ { print $2 }')
31122                 after=$((after + tmp))
31123         done
31124
31125         [ $before -eq $after ] || error "getattr count $before != $after"
31126 }
31127 run_test 803b "remote object can getattr from cache"
31128
31129 test_804() {
31130         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
31131         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
31132                 skip "MDS needs to be newer than 2.10.54"
31133         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
31134
31135         mkdir -p $DIR/$tdir
31136         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
31137                 error "Fail to create $DIR/$tdir/dir0"
31138
31139         local fid=$($LFS path2fid $DIR/$tdir/dir0)
31140         local dev=$(mdsdevname 2)
31141
31142         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
31143                 grep ${fid} || error "NOT found agent entry for dir0"
31144
31145         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
31146                 error "Fail to create $DIR/$tdir/dir1"
31147
31148         touch $DIR/$tdir/dir1/foo0 ||
31149                 error "Fail to create $DIR/$tdir/dir1/foo0"
31150         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
31151         local rc=0
31152
31153         for idx in $(seq $MDSCOUNT); do
31154                 dev=$(mdsdevname $idx)
31155                 do_facet mds${idx} \
31156                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
31157                         grep ${fid} && rc=$idx
31158         done
31159
31160         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
31161                 error "Fail to rename foo0 to foo1"
31162         if [ $rc -eq 0 ]; then
31163                 for idx in $(seq $MDSCOUNT); do
31164                         dev=$(mdsdevname $idx)
31165                         do_facet mds${idx} \
31166                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
31167                         grep ${fid} && rc=$idx
31168                 done
31169         fi
31170
31171         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
31172                 error "Fail to rename foo1 to foo2"
31173         if [ $rc -eq 0 ]; then
31174                 for idx in $(seq $MDSCOUNT); do
31175                         dev=$(mdsdevname $idx)
31176                         do_facet mds${idx} \
31177                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
31178                         grep ${fid} && rc=$idx
31179                 done
31180         fi
31181
31182         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
31183
31184         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
31185                 error "Fail to link to $DIR/$tdir/dir1/foo2"
31186         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
31187                 error "Fail to rename foo2 to foo0"
31188         unlink $DIR/$tdir/dir1/foo0 ||
31189                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
31190         rm -rf $DIR/$tdir/dir0 ||
31191                 error "Fail to rm $DIR/$tdir/dir0"
31192
31193         for idx in $(seq $MDSCOUNT); do
31194                 rc=0
31195
31196                 stop mds${idx}
31197                 dev=$(mdsdevname $idx)
31198                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
31199                         rc=$?
31200                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
31201                         error "mount mds$idx failed"
31202                 df $MOUNT > /dev/null 2>&1
31203
31204                 # e2fsck should not return error
31205                 [ $rc -eq 0 ] ||
31206                         error "e2fsck detected error on MDT${idx}: rc=$rc"
31207         done
31208 }
31209 run_test 804 "verify agent entry for remote entry"
31210
31211 cleanup_805() {
31212         do_facet $SINGLEMDS zfs set quota=$old $fsset
31213         unlinkmany $DIR/$tdir/f- 1000000
31214         trap 0
31215 }
31216
31217 test_805() {
31218         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
31219         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
31220         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
31221                 skip "netfree not implemented before 0.7"
31222         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
31223                 skip "Need MDS version at least 2.10.57"
31224
31225         local fsset
31226         local freekb
31227         local usedkb
31228         local old
31229         local quota
31230         local pref="osd-zfs.$FSNAME-MDT0000."
31231
31232         # limit available space on MDS dataset to meet nospace issue
31233         # quickly. then ZFS 0.7.2 can use reserved space if asked
31234         # properly (using netfree flag in osd_declare_destroy()
31235         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
31236         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
31237                 gawk '{print $3}')
31238         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
31239         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
31240         let "usedkb=usedkb-freekb"
31241         let "freekb=freekb/2"
31242         if let "freekb > 5000"; then
31243                 let "freekb=5000"
31244         fi
31245         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
31246         trap cleanup_805 EXIT
31247         mkdir_on_mdt0 $DIR/$tdir
31248         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
31249                 error "Can't set PFL layout"
31250         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
31251         rm -rf $DIR/$tdir || error "not able to remove"
31252         do_facet $SINGLEMDS zfs set quota=$old $fsset
31253         trap 0
31254 }
31255 run_test 805 "ZFS can remove from full fs"
31256
31257 # Size-on-MDS test
31258 check_lsom_data()
31259 {
31260         local file=$1
31261         local expect=$(stat -c %s $file)
31262         local msg=$2
31263
31264         check_lsom_size $1 $expect $msg
31265
31266         local blocks=$($LFS getsom -b $file)
31267         expect=$(stat -c %b $file)
31268         [[ $blocks == $expect ]] ||
31269                 error "$msg $file expected blocks: $expect, got: $blocks"
31270 }
31271
31272 check_lsom_size()
31273 {
31274         local size
31275         local expect=$2
31276         local msg=$3
31277
31278         cancel_lru_locks mdc
31279
31280         size=$($LFS getsom -s $1)
31281         [[ $size == $expect ]] ||
31282                 error "$msg $file expected size: $expect, got: $size"
31283 }
31284
31285 test_806() {
31286         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
31287                 skip "Need MDS version at least 2.11.52"
31288
31289         local bs=1048576
31290
31291         $LFS setstripe -c-1 $DIR/$tfile || error "setstripe $tfile failed"
31292
31293         disable_opencache
31294         stack_trap "restore_opencache"
31295
31296         # single-threaded write
31297         echo "Test SOM for single-threaded write"
31298         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
31299                 error "write $tfile failed"
31300         check_lsom_size $DIR/$tfile $bs "(0)"
31301         # Test SOM with DIO write (dd truncates to 0)
31302         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 oflag=direct ||
31303                 error "write $tfile failed"
31304         check_lsom_size $DIR/$tfile $bs "(1)"
31305
31306         local num=32
31307         local size=$(($num * $bs))
31308         local offset=0
31309         local i
31310
31311         echo "Test SOM for single client multi-threaded($num) write"
31312         $TRUNCATE $DIR/$tfile 0
31313         for ((i = 0; i < $num; i++)); do
31314                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31315                 local pids[$i]=$!
31316                 offset=$((offset + $bs))
31317         done
31318         for (( i=0; i < $num; i++ )); do
31319                 wait ${pids[$i]}
31320         done
31321         check_lsom_size $DIR/$tfile $size "(2)"
31322
31323         $TRUNCATE $DIR/$tfile 0
31324         for ((i = 0; i < $num; i++)); do
31325                 offset=$((offset - $bs))
31326                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31327                 local pids[$i]=$!
31328         done
31329         for (( i=0; i < $num; i++ )); do
31330                 wait ${pids[$i]}
31331         done
31332         check_lsom_size $DIR/$tfile $size "(3)"
31333
31334         # multi-client writes
31335         num=$(get_node_count ${CLIENTS//,/ })
31336         size=$(($num * $bs))
31337         offset=0
31338         i=0
31339
31340         echo "Test SOM for multi-client ($num) writes"
31341         $TRUNCATE $DIR/$tfile 0
31342         for client in ${CLIENTS//,/ }; do
31343                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31344                 local pids[$i]=$!
31345                 i=$((i + 1))
31346                 offset=$((offset + $bs))
31347         done
31348         for (( i=0; i < $num; i++ )); do
31349                 wait ${pids[$i]}
31350         done
31351         check_lsom_size $DIR/$tfile $offset "(4)"
31352
31353         i=0
31354         $TRUNCATE $DIR/$tfile 0
31355         for client in ${CLIENTS//,/ }; do
31356                 offset=$((offset - $bs))
31357                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31358                 local pids[$i]=$!
31359                 i=$((i + 1))
31360         done
31361         for (( i=0; i < $num; i++ )); do
31362                 wait ${pids[$i]}
31363         done
31364         check_lsom_size $DIR/$tfile $size "(5)"
31365
31366         # verify SOM blocks count
31367         echo "Verify SOM block count"
31368         $TRUNCATE $DIR/$tfile 0
31369         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs))YSc ||
31370                 error "failed to write file $tfile with fdatasync and fstat"
31371         check_lsom_data $DIR/$tfile "(6)"
31372
31373         $TRUNCATE $DIR/$tfile 0
31374         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs * 2))Yc ||
31375                 error "failed to write file $tfile with fdatasync"
31376         check_lsom_data $DIR/$tfile "(7)"
31377
31378         $TRUNCATE $DIR/$tfile 0
31379         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:O_SYNC:w$((bs * 3))c ||
31380                 error "failed to write file $tfile with sync IO"
31381         check_lsom_data $DIR/$tfile "(8)"
31382
31383         # verify truncate
31384         echo "Test SOM for truncate"
31385         # use ftruncate to sync blocks on close request
31386         $MULTIOP $DIR/$tfile oO_WRONLY:T16384c
31387         check_lsom_size $DIR/$tfile 16384 "(9)"
31388         check_lsom_data $DIR/$tfile "(10)"
31389
31390         $TRUNCATE $DIR/$tfile 1234
31391         check_lsom_size $DIR/$tfile 1234 "(11)"
31392         # sync blocks on the MDT
31393         $MULTIOP $DIR/$tfile oc
31394         check_lsom_data $DIR/$tfile "(12)"
31395 }
31396 run_test 806 "Verify Lazy Size on MDS"
31397
31398 test_807() {
31399         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
31400         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
31401                 skip "Need MDS version at least 2.11.52"
31402
31403         # Registration step
31404         changelog_register || error "changelog_register failed"
31405         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
31406         changelog_users $SINGLEMDS | grep -q $cl_user ||
31407                 error "User $cl_user not found in changelog_users"
31408
31409         rm -rf $DIR/$tdir || error "rm $tdir failed"
31410         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
31411         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
31412         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
31413         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
31414                 error "truncate $tdir/trunc failed"
31415
31416         local bs=1048576
31417         echo "Test SOM for single-threaded write with fsync"
31418         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
31419                 error "write $tfile failed"
31420         sync;sync;sync
31421
31422         # multi-client wirtes
31423         local num=$(get_node_count ${CLIENTS//,/ })
31424         local offset=0
31425         local i=0
31426
31427         echo "Test SOM for multi-client ($num) writes"
31428         touch $DIR/$tfile || error "touch $tfile failed"
31429         $TRUNCATE $DIR/$tfile 0
31430         for client in ${CLIENTS//,/ }; do
31431                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31432                 local pids[$i]=$!
31433                 i=$((i + 1))
31434                 offset=$((offset + $bs))
31435         done
31436         for (( i=0; i < $num; i++ )); do
31437                 wait ${pids[$i]}
31438         done
31439
31440         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
31441         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
31442         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
31443         check_lsom_data $DIR/$tdir/trunc "(0)"
31444         check_lsom_data $DIR/$tdir/single_dd "(1)"
31445         check_lsom_data $DIR/$tfile "(2)"
31446
31447         rm -rf $DIR/$tdir
31448         # Deregistration step
31449         changelog_deregister || error "changelog_deregister failed"
31450 }
31451 run_test 807 "verify LSOM syncing tool"
31452
31453 check_som_nologged()
31454 {
31455         local lines=$($LFS changelog $FSNAME-MDT0000 |
31456                 grep 'x=trusted.som' | wc -l)
31457         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
31458 }
31459
31460 test_808() {
31461         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
31462                 skip "Need MDS version at least 2.11.55"
31463
31464         # Registration step
31465         changelog_register || error "changelog_register failed"
31466
31467         touch $DIR/$tfile || error "touch $tfile failed"
31468         check_som_nologged
31469
31470         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
31471                 error "write $tfile failed"
31472         check_som_nologged
31473
31474         $TRUNCATE $DIR/$tfile 1234
31475         check_som_nologged
31476
31477         $TRUNCATE $DIR/$tfile 1048576
31478         check_som_nologged
31479
31480         # Deregistration step
31481         changelog_deregister || error "changelog_deregister failed"
31482 }
31483 run_test 808 "Check trusted.som xattr not logged in Changelogs"
31484
31485 check_som_nodata()
31486 {
31487         $LFS getsom $1
31488         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
31489 }
31490
31491 test_809() {
31492         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
31493                 skip "Need MDS version at least 2.11.56"
31494
31495         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
31496                 error "failed to create DoM-only file $DIR/$tfile"
31497         touch $DIR/$tfile || error "touch $tfile failed"
31498         check_som_nodata $DIR/$tfile
31499
31500         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
31501                 error "write $tfile failed"
31502         check_som_nodata $DIR/$tfile
31503
31504         $TRUNCATE $DIR/$tfile 1234
31505         check_som_nodata $DIR/$tfile
31506
31507         $TRUNCATE $DIR/$tfile 4097
31508         check_som_nodata $DIR/$file
31509 }
31510 run_test 809 "Verify no SOM xattr store for DoM-only files"
31511
31512 test_810() {
31513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31514         $GSS && skip_env "could not run with gss"
31515         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
31516                 skip "OST < 2.12.58 doesn't align checksum"
31517
31518         set_checksums 1
31519         stack_trap "set_checksums $ORIG_CSUM" EXIT
31520         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
31521
31522         local csum
31523         local before
31524         local after
31525         for csum in $CKSUM_TYPES; do
31526                 #define OBD_FAIL_OSC_NO_GRANT   0x411
31527                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
31528                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
31529                         eval set -- $i
31530                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
31531                         before=$(md5sum $DIR/$tfile)
31532                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
31533                         after=$(md5sum $DIR/$tfile)
31534                         [ "$before" == "$after" ] ||
31535                                 error "$csum: $before != $after bs=$1 seek=$2"
31536                 done
31537         done
31538 }
31539 run_test 810 "partial page writes on ZFS (LU-11663)"
31540
31541 test_812a() {
31542         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
31543                 skip "OST < 2.12.51 doesn't support this fail_loc"
31544         local old
31545
31546         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
31547         $LCTL set_param osc.*.idle_timeout=10
31548         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
31549
31550         $LFS setstripe -c 1 -i 0 $DIR/$tfile
31551         # ensure ost1 is connected
31552         stat $DIR/$tfile >/dev/null || error "can't stat"
31553         wait_osc_import_state client ost1 FULL
31554         # no locks, no reqs to let the connection idle
31555         cancel_lru_locks osc
31556
31557         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
31558 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
31559         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
31560         wait_osc_import_state client ost1 CONNECTING
31561         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
31562
31563         stat $DIR/$tfile >/dev/null || error "can't stat file"
31564 }
31565 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
31566
31567 test_812b() { # LU-12378
31568         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
31569                 skip "OST < 2.12.51 doesn't support this fail_loc"
31570         local old
31571
31572         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
31573         $LCTL set_param osc.*.idle_timeout=10
31574         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
31575
31576         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
31577         # ensure ost1 is connected
31578         stat $DIR/$tfile >/dev/null || error "can't stat"
31579         wait_osc_import_state client ost1 FULL
31580         # no locks, no reqs to let the connection idle
31581         cancel_lru_locks osc
31582
31583         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
31584 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
31585         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
31586         wait_osc_import_state client ost1 CONNECTING
31587         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
31588
31589         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
31590         wait_osc_import_state client ost1 IDLE
31591 }
31592 run_test 812b "do not drop no resend request for idle connect"
31593
31594 test_812c() {
31595         local old
31596
31597         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
31598
31599         $LFS setstripe -c 1 -o 0 $DIR/$tfile
31600         $LFS getstripe $DIR/$tfile
31601         $LCTL set_param osc.*.idle_timeout=10
31602         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
31603         # ensure ost1 is connected
31604         stat $DIR/$tfile >/dev/null || error "can't stat"
31605         wait_osc_import_state client ost1 FULL
31606         # no locks, no reqs to let the connection idle
31607         cancel_lru_locks osc
31608
31609 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
31610         $LCTL set_param fail_loc=0x80000533
31611         sleep 15
31612         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
31613 }
31614 run_test 812c "idle import vs lock enqueue race"
31615
31616 test_813() {
31617         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
31618         [ -z "$file_heat_sav" ] && skip "no file heat support"
31619
31620         local readsample
31621         local writesample
31622         local readbyte
31623         local writebyte
31624         local readsample1
31625         local writesample1
31626         local readbyte1
31627         local writebyte1
31628
31629         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
31630         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
31631
31632         $LCTL set_param -n llite.*.file_heat=1
31633         echo "Turn on file heat"
31634         echo "Period second: $period_second, Decay percentage: $decay_pct"
31635
31636         echo "QQQQ" > $DIR/$tfile
31637         echo "QQQQ" > $DIR/$tfile
31638         echo "QQQQ" > $DIR/$tfile
31639         cat $DIR/$tfile > /dev/null
31640         cat $DIR/$tfile > /dev/null
31641         cat $DIR/$tfile > /dev/null
31642         cat $DIR/$tfile > /dev/null
31643
31644         local out=$($LFS heat_get $DIR/$tfile)
31645
31646         $LFS heat_get $DIR/$tfile
31647         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31648         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31649         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31650         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31651
31652         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
31653         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
31654         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
31655         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
31656
31657         sleep $((period_second + 3))
31658         echo "Sleep $((period_second + 3)) seconds..."
31659         # The recursion formula to calculate the heat of the file f is as
31660         # follow:
31661         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
31662         # Where Hi is the heat value in the period between time points i*I and
31663         # (i+1)*I; Ci is the access count in the period; the symbol P refers
31664         # to the weight of Ci.
31665         out=$($LFS heat_get $DIR/$tfile)
31666         $LFS heat_get $DIR/$tfile
31667         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31668         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31669         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31670         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31671
31672         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
31673                 error "read sample ($readsample) is wrong"
31674         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
31675                 error "write sample ($writesample) is wrong"
31676         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
31677                 error "read bytes ($readbyte) is wrong"
31678         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
31679                 error "write bytes ($writebyte) is wrong"
31680
31681         echo "QQQQ" > $DIR/$tfile
31682         echo "QQQQ" > $DIR/$tfile
31683         echo "QQQQ" > $DIR/$tfile
31684         cat $DIR/$tfile > /dev/null
31685         cat $DIR/$tfile > /dev/null
31686         cat $DIR/$tfile > /dev/null
31687         cat $DIR/$tfile > /dev/null
31688
31689         sleep $((period_second + 3))
31690         echo "Sleep $((period_second + 3)) seconds..."
31691
31692         out=$($LFS heat_get $DIR/$tfile)
31693         $LFS heat_get $DIR/$tfile
31694         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31695         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31696         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31697         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31698
31699         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
31700                 4 * $decay_pct) / 100") -eq 1 ] ||
31701                 error "read sample ($readsample1) is wrong"
31702         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
31703                 3 * $decay_pct) / 100") -eq 1 ] ||
31704                 error "write sample ($writesample1) is wrong"
31705         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
31706                 20 * $decay_pct) / 100") -eq 1 ] ||
31707                 error "read bytes ($readbyte1) is wrong"
31708         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
31709                 15 * $decay_pct) / 100") -eq 1 ] ||
31710                 error "write bytes ($writebyte1) is wrong"
31711
31712         echo "Turn off file heat for the file $DIR/$tfile"
31713         $LFS heat_set -o $DIR/$tfile
31714
31715         echo "QQQQ" > $DIR/$tfile
31716         echo "QQQQ" > $DIR/$tfile
31717         echo "QQQQ" > $DIR/$tfile
31718         cat $DIR/$tfile > /dev/null
31719         cat $DIR/$tfile > /dev/null
31720         cat $DIR/$tfile > /dev/null
31721         cat $DIR/$tfile > /dev/null
31722
31723         out=$($LFS heat_get $DIR/$tfile)
31724         $LFS heat_get $DIR/$tfile
31725         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31726         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31727         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31728         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31729
31730         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
31731         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
31732         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
31733         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
31734
31735         echo "Trun on file heat for the file $DIR/$tfile"
31736         $LFS heat_set -O $DIR/$tfile
31737
31738         echo "QQQQ" > $DIR/$tfile
31739         echo "QQQQ" > $DIR/$tfile
31740         echo "QQQQ" > $DIR/$tfile
31741         cat $DIR/$tfile > /dev/null
31742         cat $DIR/$tfile > /dev/null
31743         cat $DIR/$tfile > /dev/null
31744         cat $DIR/$tfile > /dev/null
31745
31746         out=$($LFS heat_get $DIR/$tfile)
31747         $LFS heat_get $DIR/$tfile
31748         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31749         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31750         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31751         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31752
31753         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
31754         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
31755         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
31756         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
31757
31758         $LFS heat_set -c $DIR/$tfile
31759         $LCTL set_param -n llite.*.file_heat=0
31760         echo "Turn off file heat support for the Lustre filesystem"
31761
31762         echo "QQQQ" > $DIR/$tfile
31763         echo "QQQQ" > $DIR/$tfile
31764         echo "QQQQ" > $DIR/$tfile
31765         cat $DIR/$tfile > /dev/null
31766         cat $DIR/$tfile > /dev/null
31767         cat $DIR/$tfile > /dev/null
31768         cat $DIR/$tfile > /dev/null
31769
31770         out=$($LFS heat_get $DIR/$tfile)
31771         $LFS heat_get $DIR/$tfile
31772         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31773         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31774         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31775         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31776
31777         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
31778         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
31779         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
31780         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
31781
31782         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
31783         rm -f $DIR/$tfile
31784 }
31785 run_test 813 "File heat verfication"
31786
31787 test_814()
31788 {
31789         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
31790         echo -n y >> $DIR/$tfile
31791         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
31792         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
31793 }
31794 run_test 814 "sparse cp works as expected (LU-12361)"
31795
31796 test_815()
31797 {
31798         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
31799         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
31800 }
31801 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
31802
31803 test_816() {
31804         local ost1_imp=$(get_osc_import_name client ost1)
31805         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
31806                          cut -d'.' -f2)
31807         local old
31808
31809         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
31810         $LCTL set_param osc.*.idle_timeout=10
31811         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
31812
31813         $LFS setstripe -c 1 -i 0 $DIR/$tfile
31814         # ensure ost1 is connected
31815
31816         stat $DIR/$tfile >/dev/null || error "can't stat"
31817         wait_osc_import_state client ost1 FULL
31818         # no locks, no reqs to let the connection idle
31819         cancel_lru_locks osc
31820         lru_resize_disable osc
31821         local before
31822         local now
31823         before=$($LCTL get_param -n \
31824                  ldlm.namespaces.$imp_name.lru_size)
31825
31826         wait_osc_import_state client ost1 IDLE
31827         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
31828         now=$($LCTL get_param -n \
31829               ldlm.namespaces.$imp_name.lru_size)
31830         [ $before == $now ] || error "lru_size changed $before != $now"
31831 }
31832 run_test 816 "do not reset lru_resize on idle reconnect"
31833
31834 cleanup_817() {
31835         umount $tmpdir
31836         exportfs -u localhost:$DIR/nfsexp
31837         rm -rf $DIR/nfsexp
31838 }
31839
31840 test_817() {
31841         systemctl restart nfs-server.service || skip "failed to restart nfsd"
31842
31843         mkdir -p $DIR/nfsexp
31844         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
31845                 error "failed to export nfs"
31846
31847         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
31848         stack_trap cleanup_817 EXIT
31849
31850         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
31851                 error "failed to mount nfs to $tmpdir"
31852
31853         cp /bin/true $tmpdir
31854         $DIR/nfsexp/true || error "failed to execute 'true' command"
31855 }
31856 run_test 817 "nfsd won't cache write lock for exec file"
31857
31858 test_818() {
31859         test_mkdir -i0 -c1 $DIR/$tdir
31860         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
31861         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
31862         stop $SINGLEMDS
31863
31864         # restore osp-syn threads
31865         stack_trap "fail $SINGLEMDS"
31866
31867         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
31868         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
31869         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
31870                 error "start $SINGLEMDS failed"
31871         rm -rf $DIR/$tdir
31872
31873         local testid=$(echo $TESTNAME | tr '_' ' ')
31874
31875         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
31876                 grep "run LFSCK" || error "run LFSCK is not suggested"
31877 }
31878 run_test 818 "unlink with failed llog"
31879
31880 test_819a() {
31881         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
31882         cancel_lru_locks osc
31883         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
31884         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
31885         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
31886         rm -f $TDIR/$tfile
31887 }
31888 run_test 819a "too big niobuf in read"
31889
31890 test_819b() {
31891         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
31892         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
31893         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
31894         cancel_lru_locks osc
31895         sleep 1
31896         rm -f $TDIR/$tfile
31897 }
31898 run_test 819b "too big niobuf in write"
31899
31900
31901 function test_820_start_ost() {
31902         sleep 5
31903
31904         for num in $(seq $OSTCOUNT); do
31905                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
31906         done
31907 }
31908
31909 test_820() {
31910         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
31911
31912         mkdir $DIR/$tdir
31913         umount_client $MOUNT || error "umount failed"
31914         for num in $(seq $OSTCOUNT); do
31915                 stop ost$num
31916         done
31917
31918         # mount client with no active OSTs
31919         # so that the client can't initialize max LOV EA size
31920         # from OSC notifications
31921         mount_client $MOUNT || error "mount failed"
31922         # delay OST starting to keep this 0 max EA size for a while
31923         test_820_start_ost &
31924
31925         # create a directory on MDS2
31926         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
31927                 error "Failed to create directory"
31928         # open intent should update default EA size
31929         # see mdc_update_max_ea_from_body()
31930         # notice this is the very first RPC to MDS2
31931         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
31932         ret=$?
31933         echo $out
31934         # With SSK, this situation can lead to -EPERM being returned.
31935         # In that case, simply retry.
31936         if [ $ret -ne 0 ] && $SHARED_KEY; then
31937                 if echo "$out" | grep -q "not permitted"; then
31938                         cp /etc/services $DIR/$tdir/mds2
31939                         ret=$?
31940                 fi
31941         fi
31942         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
31943 }
31944 run_test 820 "update max EA from open intent"
31945
31946 test_823() {
31947         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
31948         local OST_MAX_PRECREATE=20000
31949
31950         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
31951                 skip "Need MDS version at least 2.14.56"
31952
31953         save_lustre_params mds1 \
31954                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
31955         do_facet $SINGLEMDS "$LCTL set_param -n \
31956                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
31957         do_facet $SINGLEMDS "$LCTL set_param -n \
31958                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
31959
31960         stack_trap "restore_lustre_params < $p; rm $p"
31961
31962         do_facet $SINGLEMDS "$LCTL set_param -n \
31963                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
31964
31965         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
31966                       osp.$FSNAME-OST0000*MDT0000.create_count")
31967         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
31968                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
31969         local expect_count=$(((($max/2)/256) * 256))
31970
31971         log "setting create_count to 100200:"
31972         log " -result- count: $count with max: $max, expecting: $expect_count"
31973
31974         [[ $count -eq expect_count ]] ||
31975                 error "Create count not set to max precreate."
31976 }
31977 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
31978
31979 test_831() {
31980         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
31981                 skip "Need MDS version 2.14.56"
31982
31983         local sync_changes=$(do_facet $SINGLEMDS \
31984                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
31985
31986         [ "$sync_changes" -gt 100 ] &&
31987                 skip "Sync changes $sync_changes > 100 already"
31988
31989         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
31990
31991         $LFS mkdir -i 0 $DIR/$tdir
31992         $LFS setstripe -c 1 -i 0 $DIR/$tdir
31993
31994         save_lustre_params mds1 \
31995                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
31996         save_lustre_params mds1 \
31997                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
31998
31999         do_facet mds1 "$LCTL set_param -n \
32000                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
32001                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
32002         stack_trap "restore_lustre_params < $p" EXIT
32003
32004         createmany -o $DIR/$tdir/f- 1000
32005         unlinkmany $DIR/$tdir/f- 1000 &
32006         local UNLINK_PID=$!
32007
32008         while sleep 1; do
32009                 sync_changes=$(do_facet mds1 \
32010                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
32011                 # the check in the code is racy, fail the test
32012                 # if the value above the limit by 10.
32013                 [ $sync_changes -gt 110 ] && {
32014                         kill -2 $UNLINK_PID
32015                         wait
32016                         error "osp changes throttling failed, $sync_changes>110"
32017                 }
32018                 kill -0 $UNLINK_PID 2> /dev/null || break
32019         done
32020         wait
32021 }
32022 run_test 831 "throttling unlink/setattr queuing on OSP"
32023
32024 test_832() {
32025         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
32026         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
32027                 skip "Need MDS version 2.15.52+"
32028         is_rmentry_supported || skip "rm_entry not supported"
32029
32030         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
32031         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
32032         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
32033                 error "mkdir remote_dir failed"
32034         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
32035                 error "mkdir striped_dir failed"
32036         touch $DIR/$tdir/file || error "touch file failed"
32037         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
32038         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
32039 }
32040 run_test 832 "lfs rm_entry"
32041
32042 test_833() {
32043         local file=$DIR/$tfile
32044
32045         stack_trap "rm -f $file" EXIT
32046         dd if=/dev/zero of=$file bs=1M count=50 || error "Write $file failed"
32047
32048         local wpid
32049         local rpid
32050         local rpid2
32051
32052         # Buffered I/O write
32053         (
32054                 while [ ! -e $DIR/sanity.833.lck ]; do
32055                         dd if=/dev/zero of=$file bs=1M count=50 conv=notrunc ||
32056                                 error "failed to write $file"
32057                         sleep 0.$((RANDOM % 4 + 1))
32058                 done
32059         )&
32060         wpid=$!
32061
32062         # Buffered I/O read
32063         (
32064                 while [ ! -e $DIR/sanity.833.lck ]; do
32065                         dd if=$file of=/dev/null bs=1M count=50 ||
32066                                 error "failed to read $file"
32067                         sleep 0.$((RANDOM % 4 + 1))
32068                 done
32069         )&
32070         rpid=$!
32071
32072         # Direct I/O read
32073         (
32074                 while [ ! -e $DIR/sanity.833.lck ]; do
32075                         dd if=$file of=/dev/null bs=1M count=50 iflag=direct ||
32076                                 error "failed to read $file in direct I/O mode"
32077                         sleep 0.$((RANDOM % 4 + 1))
32078                 done
32079         )&
32080         rpid2=$!
32081
32082         sleep 30
32083         touch $DIR/sanity.833.lck
32084         wait $wpid || error "$?: buffered write failed"
32085         wait $rpid || error "$?: buffered read failed"
32086         wait $rpid2 || error "$?: direct read failed"
32087 }
32088 run_test 833 "Mixed buffered/direct read and write should not return -EIO"
32089
32090 test_842() {
32091         local oss1=$(facet_host ost1)
32092
32093         # Try to insert the module.  This will leave results in dmesg
32094         now=$(date +%s)
32095         log "STAMP $now" > /dev/kmsg
32096         do_rpc_nodes $oss1 load_module kunit/ldlm_extent ||
32097                 error "$oss1 load_module ldlm_extent failed"
32098
32099         do_node $oss1 dmesg | sed -n -e "1,/STAMP $now/d" -e '/ldlm_extent:/p'
32100         do_node $oss1 rmmod -v ldlm_extent ||
32101                 error "rmmod failed (may trigger a failure in a later test)"
32102 }
32103 run_test 842 "Measure ldlm_extent performance"
32104
32105 test_850() {
32106         local dir=$DIR/$tdir
32107         local file=$dir/$tfile
32108         local statsfile=$dir/all_job_stats.txt
32109
32110         test_mkdir -p $dir || error "failed to create dir $dir"
32111         echo "abcdefg" > $file || error "failed to create file $file"
32112
32113         # read job_stats in the living system
32114         lljobstat -n 1 ||
32115                 error "failed to run lljobstat on living system"
32116
32117         $LCTL get_param *.*.job_stats > $statsfile
32118         lljobstat --statsfile=$statsfile ||
32119                 error "failed to run lljobstat on file $statsfile"
32120 }
32121 run_test 850 "lljobstat can parse living and aggregated job_stats"
32122
32123 test_851() {
32124         local dir=$DIR/$tdir
32125         local file=$dir/f_test_851_$$
32126         local report=/tmp/report_test_851_$$
32127         local fanotify_prog=monitor_lustrefs
32128         local pid
32129
32130         test_mkdir $dir || error "failed to create dir $dir"
32131
32132         $fanotify_prog $DIR > $report &
32133         pid=$!
32134
32135         sleep 1
32136         if ! kill -0 $pid; then
32137                 error "failed to start $fanoify_prog"
32138         fi
32139
32140         stack_trap "kill $pid"
32141         stack_trap "rm -f $report"
32142
32143         echo "1234567890" > $file
32144         wait_update_cond localhost "stat -c %s $report" "-gt" "0" 30 ||
32145                 error "fanotify did not report anything after 30 seconds"
32146         grep -a -E "open.*:$file:" $report ||
32147                 error "no open event for writing $file"
32148         grep -a -E "write.*:$file:" $report ||
32149                 error "no write event for writing $file"
32150         grep -a -E "close.*:$file:" $report ||
32151                 error "no close event for writing $file"
32152
32153         > $report
32154         cat $file
32155         wait_update_cond localhost "stat -c %s $report" "-gt" "0" 30 ||
32156                 error "fanotify did not report anything after 30 seconds"
32157         grep -a -E "open.*:$file:" $report ||
32158                 error "no open event for reading $file"
32159         grep -a -E "read.*:$file:" $report ||
32160                 error "no write event for reading $file"
32161         grep -a -E "close.*:$file:" $report ||
32162                 error "no close event for reading $file"
32163 }
32164 run_test 851 "fanotify can monitor open/read/write/close events for lustre fs"
32165
32166 #
32167 # tests that do cleanup/setup should be run at the end
32168 #
32169
32170 test_900() {
32171         [ $PARALLEL == "yes" ] && skip "skip parallel run"
32172         local ls
32173
32174         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
32175         $LCTL set_param fail_loc=0x903
32176
32177         cancel_lru_locks MGC
32178
32179         FAIL_ON_ERROR=true cleanup
32180         FAIL_ON_ERROR=true setup
32181 }
32182 run_test 900 "umount should not race with any mgc requeue thread"
32183
32184 # LUS-6253/LU-11185
32185 test_901() {
32186         local old
32187         local count
32188         local oldc
32189         local newc
32190         local olds
32191         local news
32192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
32193
32194         # some get_param have a bug to handle dot in param name
32195         cancel_lru_locks MGC
32196         old=$(mount -t lustre | wc -l)
32197         # 1 config+sptlrpc
32198         # 2 params
32199         # 3 nodemap
32200         # 4 IR
32201         old=$((old * 4))
32202         oldc=0
32203         count=0
32204         while [ $old -ne $oldc ]; do
32205                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
32206                 sleep 1
32207                 ((count++))
32208                 if [ $count -ge $TIMEOUT ]; then
32209                         error "too large timeout"
32210                 fi
32211         done
32212         umount_client $MOUNT || error "umount failed"
32213         mount_client $MOUNT || error "mount failed"
32214         cancel_lru_locks MGC
32215         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
32216
32217         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
32218
32219         return 0
32220 }
32221 run_test 901 "don't leak a mgc lock on client umount"
32222
32223 # LU-13377
32224 test_902() {
32225         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
32226                 skip "client does not have LU-13377 fix"
32227         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
32228         $LCTL set_param fail_loc=0x1415
32229         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
32230         cancel_lru_locks osc
32231         rm -f $DIR/$tfile
32232 }
32233 run_test 902 "test short write doesn't hang lustre"
32234
32235 # LU-14711
32236 test_903() {
32237         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
32238         echo "blah" > $DIR/${tfile}-2
32239         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
32240         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
32241         $LCTL set_param fail_loc=0x417 fail_val=20
32242
32243         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
32244         sleep 1 # To start the destroy
32245         wait_destroy_complete 150 || error "Destroy taking too long"
32246         cat $DIR/$tfile > /dev/null || error "Evicted"
32247 }
32248 run_test 903 "Test long page discard does not cause evictions"
32249
32250 test_904() {
32251         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
32252         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
32253                 grep -q project || skip "skip project quota not supported"
32254
32255         local testfile="$DIR/$tdir/$tfile"
32256         local xattr="trusted.projid"
32257         local projid
32258         local mdts=$(comma_list $(mdts_nodes))
32259         local saved=$(do_facet mds1 $LCTL get_param -n \
32260                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
32261
32262         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
32263         stack_trap "do_nodes $mdts $LCTL set_param \
32264                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
32265
32266         mkdir -p $DIR/$tdir
32267         touch $testfile
32268         #hide projid xattr on server
32269         $LFS project -p 1 $testfile ||
32270                 error "set $testfile project id failed"
32271         getfattr -m - $testfile | grep $xattr &&
32272                 error "do not show trusted.projid when disabled on server"
32273         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
32274         #should be hidden when projid is 0
32275         $LFS project -p 0 $testfile ||
32276                 error "set $testfile project id failed"
32277         getfattr -m - $testfile | grep $xattr &&
32278                 error "do not show trusted.projid with project ID 0"
32279
32280         #still can getxattr explicitly
32281         projid=$(getfattr -n $xattr $testfile |
32282                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
32283         [ $projid == "0" ] ||
32284                 error "projid expected 0 not $projid"
32285
32286         #set the projid via setxattr
32287         setfattr -n $xattr -v "1000" $testfile ||
32288                 error "setattr failed with $?"
32289         projid=($($LFS project $testfile))
32290         [ ${projid[0]} == "1000" ] ||
32291                 error "projid expected 1000 not $projid"
32292
32293         #check the new projid via getxattr
32294         $LFS project -p 1001 $testfile ||
32295                 error "set $testfile project id failed"
32296         getfattr -m - $testfile | grep $xattr ||
32297                 error "should show trusted.projid when project ID != 0"
32298         projid=$(getfattr -n $xattr $testfile |
32299                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
32300         [ $projid == "1001" ] ||
32301                 error "projid expected 1001 not $projid"
32302
32303         #try to set invalid projid
32304         setfattr -n $xattr -v "4294967295" $testfile &&
32305                 error "set invalid projid should fail"
32306
32307         #remove the xattr means setting projid to 0
32308         setfattr -x $xattr $testfile ||
32309                 error "setfattr failed with $?"
32310         projid=($($LFS project $testfile))
32311         [ ${projid[0]} == "0" ] ||
32312                 error "projid expected 0 not $projid"
32313
32314         #should be hidden when parent has inherit flag and same projid
32315         $LFS project -srp 1002 $DIR/$tdir ||
32316                 error "set $tdir project id failed"
32317         getfattr -m - $testfile | grep $xattr &&
32318                 error "do not show trusted.projid with inherit flag"
32319
32320         #still can getxattr explicitly
32321         projid=$(getfattr -n $xattr $testfile |
32322                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
32323         [ $projid == "1002" ] ||
32324                 error "projid expected 1002 not $projid"
32325 }
32326 run_test 904 "virtual project ID xattr"
32327
32328 # LU-8582
32329 test_905() {
32330         (( $OST1_VERSION >= $(version_code 2.15.50.220) )) ||
32331                 skip "need OST version >= 2.15.50.220 for fail_loc"
32332
32333         remote_ost_nodsh && skip "remote OST with nodsh"
32334         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
32335
32336         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
32337
32338         #define OBD_FAIL_OST_OPCODE 0x253
32339         # OST_LADVISE = 21
32340         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
32341         $LFS ladvise -a willread $DIR/$tfile &&
32342                 error "unexpected success of ladvise with fault injection"
32343         $LFS ladvise -a willread $DIR/$tfile |&
32344                 grep -q "Operation not supported"
32345         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
32346 }
32347 run_test 905 "bad or new opcode should not stuck client"
32348
32349 test_906() {
32350         grep -q io_uring_setup /proc/kallsyms ||
32351                 skip "Client OS does not support io_uring I/O engine"
32352         io_uring_probe || skip "kernel does not support io_uring fully"
32353         which fio || skip_env "no fio installed"
32354         fio --enghelp | grep -q io_uring ||
32355                 skip_env "fio does not support io_uring I/O engine"
32356
32357         local file=$DIR/$tfile
32358         local ioengine="io_uring"
32359         local numjobs=2
32360         local size=50M
32361
32362         fio --name=seqwrite --ioengine=$ioengine        \
32363                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
32364                 --iodepth=64 --size=$size --filename=$file --rw=write ||
32365                 error "fio seqwrite $file failed"
32366
32367         fio --name=seqread --ioengine=$ioengine \
32368                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
32369                 --iodepth=64 --size=$size --filename=$file --rw=read ||
32370                 error "fio seqread $file failed"
32371
32372         rm -f $file || error "rm -f $file failed"
32373 }
32374 run_test 906 "Simple test for io_uring I/O engine via fio"
32375
32376 test_907() {
32377         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
32378
32379         # set stripe size to max rpc size
32380         $LFS setstripe -i 0 -c 2 -S $((max_pages * PAGE_SIZE)) $DIR/$tfile
32381         $LFS getstripe $DIR/$tfile
32382 #define OBD_FAIL_OST_EROFS               0x216
32383         do_facet ost1 "$LCTL set_param fail_val=3 fail_loc=0x80000216"
32384
32385         local bs=$((max_pages * PAGE_SIZE / 16))
32386
32387         # write full one stripe and one block
32388         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=17 || error "dd failed"
32389
32390         rm $DIR/$tfile || error "rm failed"
32391 }
32392 run_test 907 "write rpc error during unlink"
32393
32394 complete_test $SECONDS
32395 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
32396 check_and_cleanup_lustre
32397 if [ "$I_MOUNTED" != "yes" ]; then
32398         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
32399 fi
32400 exit_status