Whamcloud - gitweb
LU-15274 llite: whole file read fixes
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 SOCKETSERVER=${SOCKETSERVER:-socketserver}
23 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
24 MEMHOG=${MEMHOG:-memhog}
25 DIRECTIO=${DIRECTIO:-directio}
26 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
27 DEF_STRIPE_COUNT=-1
28 CHECK_GRANT=${CHECK_GRANT:-"yes"}
29 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
30
31 TRACE=${TRACE:-""}
32 LUSTRE=${LUSTRE:-$(dirname $0)/..}
33 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
34 . $LUSTRE/tests/test-framework.sh
35 init_test_env "$@"
36
37 init_logging
38
39 ALWAYS_EXCEPT="$SANITY_EXCEPT "
40 always_except LU-9693  42a 42c
41 always_except LU-6493  42b
42 always_except LU-16515 118c 118d
43 always_except LU-8411  407
44
45 if $SHARED_KEY; then
46         always_except LU-14181 64e 64f
47         always_except LU-17127 39o
48 fi
49
50 # skip the grant tests for ARM until they are fixed
51 if [[ $(uname -m) = aarch64 ]]; then
52         always_except LU-11671 45
53 fi
54
55 # skip nfs tests on kernels >= 4.12.0 until they are fixed
56 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
57         always_except LU-12661 817
58 fi
59 # skip cgroup tests on RHEL8.1 kernels until they are fixed
60 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
61       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
62         always_except LU-13063 411a
63 fi
64
65 # skip cgroup tests for kernels < v4.18.0
66 if (( $LINUX_VERSION_CODE < $(version_code 4.18.0) )); then
67         always_except LU-13063 411b
68 fi
69
70 #                                  5              12     8   12  15   (min)"
71 [[ "$SLOW" = "no" ]] && EXCEPT_SLOW="27m 60i 64b 68 71 135 136 230d 300o"
72
73 if [[ "$mds1_FSTYPE" == "zfs" ]]; then
74         #                                               13    (min)"
75         [[ "$SLOW" == "no" ]] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
76 fi
77
78 if [[ "$ost1_FSTYPE" = "zfs" ]]; then
79         always_except LU-1941 130b 130c 130d 130e 130f 130g
80         always_except LU-9054 312
81 fi
82
83 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
84
85 # Get the SLES distro version
86 #
87 # Returns a version string that should only be used in comparing
88 # strings returned by version_code()
89 sles_version_code()
90 {
91         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
92
93         # All SuSE Linux versions have one decimal. version_code expects two
94         local sles_version=$version.0
95         version_code $sles_version
96 }
97
98 # Check if we are running on Ubuntu or SLES so we can make decisions on
99 # what tests to run
100 if [ -r /etc/SuSE-release ] || [ -r /etc/SUSE-brand ]; then
101         sles_version=$(sles_version_code)
102         (( $sles_version >= $(version_code 11.4.0) )) ||
103                 always_except LU-4341 170
104
105         (( $sles_version >= $(version_code 12.0.0) )) ||
106                 always_except LU-3703 234
107 elif [ -r /etc/redhat-release ]; then
108         rhel_version=$(cat /etc/redhat-release |
109                 sed -e 's/^[^0-9.]*//g' | sed -e 's/[ ].*//')
110         if (( $(version_code $rhel_version) >= $(version_code 9.3.0) )); then
111                 # disable test_906 temporarily until rhel9.3 solves the
112                 # failure on fio io_uring I/O engine.
113                 always_except LU-17289 906
114         fi
115 fi
116
117 build_test_filter
118 FAIL_ON_ERROR=false
119
120 cleanup() {
121         echo -n "cln.."
122         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
123         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
124 }
125 setup() {
126         echo -n "mnt.."
127         load_modules
128         setupall || exit 10
129         echo "done"
130 }
131
132 check_swap_layouts_support()
133 {
134         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
135                 skip "Does not support layout lock."
136 }
137
138 check_swap_layout_no_dom()
139 {
140         local FOLDER=$1
141         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
142         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
143 }
144
145 check_and_setup_lustre
146 DIR=${DIR:-$MOUNT}
147 assert_DIR
148
149 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
150
151 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
152 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
153 rm -rf $DIR/[Rdfs][0-9]*
154
155 # $RUNAS_ID may get set incorrectly somewhere else
156 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
157         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
158
159 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
160
161 if [ "${ONLY}" = "MOUNT" ] ; then
162         echo "Lustre is up, please go on"
163         exit
164 fi
165
166 echo "preparing for tests involving mounts"
167 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
168 touch $EXT2_DEV
169 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
170 echo # add a newline after mke2fs.
171
172 umask 077
173
174 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
175
176 # ensure all internal functions know we want full debug
177 export PTLDEBUG=all
178 lctl set_param debug=$PTLDEBUG 2> /dev/null || true
179
180 test_0a() {
181         touch $DIR/$tfile
182         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
183         rm $DIR/$tfile
184         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
185 }
186 run_test 0a "touch; rm ====================="
187
188 test_0b() {
189         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
190         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
191 }
192 run_test 0b "chmod 0755 $DIR ============================="
193
194 test_0c() {
195         $LCTL get_param mdc.*.import | grep "state: FULL" ||
196                 error "import not FULL"
197         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
198                 error "bad target"
199 }
200 run_test 0c "check import proc"
201
202 test_0d() { # LU-3397
203         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
204                 skip "proc exports not supported before 2.10.57"
205
206         local mgs_exp="mgs.MGS.exports"
207         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
208         local exp_client_nid
209         local exp_client_version
210         local exp_val
211         local imp_val
212         local temp_imp=$DIR/$tfile.import
213         local temp_exp=$DIR/$tfile.export
214
215         # save mgc import file to $temp_imp
216         $LCTL get_param mgc.*.import | tee $temp_imp
217         # Check if client uuid is found in MGS export
218         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
219                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
220                         $client_uuid ] &&
221                         break;
222         done
223         # save mgs export file to $temp_exp
224         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
225
226         # Compare the value of field "connect_flags"
227         imp_val=$(grep "connect_flags" $temp_imp)
228         exp_val=$(grep "connect_flags" $temp_exp)
229         [ "$exp_val" == "$imp_val" ] ||
230                 error "export flags '$exp_val' != import flags '$imp_val'"
231
232         # Compare client versions.  Only compare top-3 fields for compatibility
233         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
234         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
235         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
236         [ "$exp_val" == "$imp_val" ] ||
237                 error "exp version '$exp_client_version'($exp_val) != " \
238                         "'$(lustre_build_version client)'($imp_val)"
239 }
240 run_test 0d "check export proc ============================="
241
242 test_0e() { # LU-13417
243         (( $MDSCOUNT > 1 )) ||
244                 skip "We need at least 2 MDTs for this test"
245
246         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
247                 skip "Need server version at least 2.14.51"
248
249         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
250         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
251
252         [ $default_lmv_count -eq 1 ] ||
253                 error "$MOUNT default stripe count $default_lmv_count"
254
255         [ $default_lmv_index -eq -1 ] ||
256                 error "$MOUNT default stripe index $default_lmv_index"
257
258         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
259         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
260
261         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
262         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
263
264         [ $mdt_index1 -eq $mdt_index2 ] &&
265                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
266
267         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
268 }
269 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
270
271 test_0f() { # LU-17471
272         (( $MDS1_VERSION < $(version_code 2.17.53) )) ||
273                 skip "MDS >= 2.17.53 removes /proc/.../brw_stats symlink"
274         (( $MDS1_VERSION < $(version_code 2.14.55-100-g8a84c7f9c7) ||
275            $MDS1_VERSION > $(version_code 2.15.60-25) )) ||
276                 skip "MDS was missing /proc/.../brw_stats value"
277
278         local path="lustre/osd-$FSTYPE/$FSNAME-MDT0000/brw_stats"
279         local out_proc=$(do_facet mds1 grep snapshot_time /proc/fs/$path)
280
281         [[ -n "$out_proc" ]] || error "brw_stats /proc/fs/$path not found"
282 }
283 run_test 0f "Symlink to /sys/kernel/debug/*/*/brw_stats should work properly"
284
285 test_1() {
286         test_mkdir $DIR/$tdir
287         test_mkdir $DIR/$tdir/d2
288         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
289         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
290         rmdir $DIR/$tdir/d2
291         rmdir $DIR/$tdir
292         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
293 }
294 run_test 1 "mkdir; remkdir; rmdir"
295
296 test_2() {
297         test_mkdir $DIR/$tdir
298         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
299         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
300         rm -r $DIR/$tdir
301         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
302 }
303 run_test 2 "mkdir; touch; rmdir; check file"
304
305 test_3() {
306         test_mkdir $DIR/$tdir
307         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
308         touch $DIR/$tdir/$tfile
309         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
310         rm -r $DIR/$tdir
311         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
312 }
313 run_test 3 "mkdir; touch; rmdir; check dir"
314
315 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
316 test_4() {
317         test_mkdir -i 1 $DIR/$tdir
318
319         touch $DIR/$tdir/$tfile ||
320                 error "Create file under remote directory failed"
321
322         rmdir $DIR/$tdir &&
323                 error "Expect error removing in-use dir $DIR/$tdir"
324
325         test -d $DIR/$tdir || error "Remote directory disappeared"
326
327         rm -rf $DIR/$tdir || error "remove remote dir error"
328 }
329 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
330
331 test_5() {
332         test_mkdir $DIR/$tdir
333         test_mkdir $DIR/$tdir/d2
334         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
335         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
336         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
337 }
338 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
339
340 test_6a() {
341         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
342         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
343         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
344                 error "$tfile does not have perm 0666 or UID $UID"
345         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
346         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
347                 error "$tfile should be 0666 and owned by UID $UID"
348 }
349 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
350
351 test_6c() {
352         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
353
354         touch $DIR/$tfile
355         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
356         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
357                 error "$tfile should be owned by UID $RUNAS_ID"
358         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
359         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
360                 error "$tfile should be owned by UID $RUNAS_ID"
361 }
362 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
363
364 test_6e() {
365         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
366
367         touch $DIR/$tfile
368         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
369         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
370                 error "$tfile should be owned by GID $UID"
371         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
372         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
373                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
374 }
375 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
376
377 test_6g() {
378         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
379
380         test_mkdir $DIR/$tdir
381         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
382         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
383         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
384         test_mkdir $DIR/$tdir/d/subdir
385         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
386                 error "$tdir/d/subdir should be GID $RUNAS_GID"
387         if [[ $MDSCOUNT -gt 1 ]]; then
388                 # check remote dir sgid inherite
389                 $LFS mkdir -i 0 $DIR/$tdir.local ||
390                         error "mkdir $tdir.local failed"
391                 chmod g+s $DIR/$tdir.local ||
392                         error "chmod $tdir.local failed"
393                 chgrp $RUNAS_GID $DIR/$tdir.local ||
394                         error "chgrp $tdir.local failed"
395                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
396                         error "mkdir $tdir.remote failed"
397                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
398                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
399                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
400                         error "$tdir.remote should be mode 02755"
401         fi
402 }
403 run_test 6g "verify new dir in sgid dir inherits group"
404
405 test_6h() { # bug 7331
406         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
407
408         touch $DIR/$tfile || error "touch failed"
409         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
410         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
411                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
412         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
413                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
414 }
415 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
416
417 test_7a() {
418         test_mkdir $DIR/$tdir
419         $MCREATE $DIR/$tdir/$tfile
420         chmod 0666 $DIR/$tdir/$tfile
421         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
422                 error "$tdir/$tfile should be mode 0666"
423 }
424 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
425
426 test_7b() {
427         if [ ! -d $DIR/$tdir ]; then
428                 test_mkdir $DIR/$tdir
429         fi
430         $MCREATE $DIR/$tdir/$tfile
431         echo -n foo > $DIR/$tdir/$tfile
432         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
433         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
434 }
435 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
436
437 test_8() {
438         test_mkdir $DIR/$tdir
439         touch $DIR/$tdir/$tfile
440         chmod 0666 $DIR/$tdir/$tfile
441         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
442                 error "$tfile mode not 0666"
443 }
444 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
445
446 test_9() {
447         test_mkdir $DIR/$tdir
448         test_mkdir $DIR/$tdir/d2
449         test_mkdir $DIR/$tdir/d2/d3
450         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
451 }
452 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
453
454 test_10() {
455         test_mkdir $DIR/$tdir
456         test_mkdir $DIR/$tdir/d2
457         touch $DIR/$tdir/d2/$tfile
458         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
459                 error "$tdir/d2/$tfile not a file"
460 }
461 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
462
463 test_11() {
464         test_mkdir $DIR/$tdir
465         test_mkdir $DIR/$tdir/d2
466         chmod 0666 $DIR/$tdir/d2
467         chmod 0705 $DIR/$tdir/d2
468         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
469                 error "$tdir/d2 mode not 0705"
470 }
471 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
472
473 test_12() {
474         test_mkdir $DIR/$tdir
475         touch $DIR/$tdir/$tfile
476         chmod 0666 $DIR/$tdir/$tfile
477         chmod 0654 $DIR/$tdir/$tfile
478         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
479                 error "$tdir/d2 mode not 0654"
480 }
481 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
482
483 test_13() {
484         test_mkdir $DIR/$tdir
485         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
486         >  $DIR/$tdir/$tfile
487         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
488                 error "$tdir/$tfile size not 0 after truncate"
489 }
490 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
491
492 test_14() {
493         test_mkdir $DIR/$tdir
494         touch $DIR/$tdir/$tfile
495         rm $DIR/$tdir/$tfile
496         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
497 }
498 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
499
500 test_15() {
501         test_mkdir $DIR/$tdir
502         touch $DIR/$tdir/$tfile
503         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
504         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
505                 error "$tdir/${tfile_2} not a file after rename"
506         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
507 }
508 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
509
510 test_16() {
511         test_mkdir $DIR/$tdir
512         touch $DIR/$tdir/$tfile
513         rm -rf $DIR/$tdir/$tfile
514         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
515 }
516 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
517
518 test_17a() {
519         test_mkdir $DIR/$tdir
520         touch $DIR/$tdir/$tfile
521         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
522         ls -l $DIR/$tdir
523         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
524                 error "$tdir/l-exist not a symlink"
525         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
526                 error "$tdir/l-exist not referencing a file"
527         rm -f $DIR/$tdir/l-exist
528         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
529 }
530 run_test 17a "symlinks: create, remove (real)"
531
532 test_17b() {
533         test_mkdir $DIR/$tdir
534         ln -s no-such-file $DIR/$tdir/l-dangle
535         ls -l $DIR/$tdir
536         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
537                 error "$tdir/l-dangle not referencing no-such-file"
538         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
539                 error "$tdir/l-dangle not referencing non-existent file"
540         rm -f $DIR/$tdir/l-dangle
541         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
542 }
543 run_test 17b "symlinks: create, remove (dangling)"
544
545 test_17c() { # bug 3440 - don't save failed open RPC for replay
546         test_mkdir $DIR/$tdir
547         ln -s foo $DIR/$tdir/$tfile
548         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
549 }
550 run_test 17c "symlinks: open dangling (should return error)"
551
552 test_17d() {
553         test_mkdir $DIR/$tdir
554         ln -s foo $DIR/$tdir/$tfile
555         touch $DIR/$tdir/$tfile || error "creating to new symlink"
556 }
557 run_test 17d "symlinks: create dangling"
558
559 test_17e() {
560         test_mkdir $DIR/$tdir
561         local foo=$DIR/$tdir/$tfile
562         ln -s $foo $foo || error "create symlink failed"
563         ls -l $foo || error "ls -l failed"
564         ls $foo && error "ls not failed" || true
565 }
566 run_test 17e "symlinks: create recursive symlink (should return error)"
567
568 test_17f() {
569         test_mkdir $DIR/$tdir
570         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
571         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
572         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
573         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
574         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
575         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
576         ls -l  $DIR/$tdir
577 }
578 run_test 17f "symlinks: long and very long symlink name"
579
580 # str_repeat(S, N) generate a string that is string S repeated N times
581 str_repeat() {
582         local s=$1
583         local n=$2
584         local ret=''
585         while [ $((n -= 1)) -ge 0 ]; do
586                 ret=$ret$s
587         done
588         echo $ret
589 }
590
591 # Long symlinks and LU-2241
592 test_17g() {
593         test_mkdir $DIR/$tdir
594         local TESTS="59 60 61 4094 4095"
595
596         # Fix for inode size boundary in 2.1.4
597         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
598                 TESTS="4094 4095"
599
600         # Patch not applied to 2.2 or 2.3 branches
601         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
602         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
603                 TESTS="4094 4095"
604
605         for i in $TESTS; do
606                 local SYMNAME=$(str_repeat 'x' $i)
607                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
608                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
609         done
610 }
611 run_test 17g "symlinks: really long symlink name and inode boundaries"
612
613 test_17h() { #bug 17378
614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
615         remote_mds_nodsh && skip "remote MDS with nodsh"
616
617         local mdt_idx
618
619         test_mkdir $DIR/$tdir
620         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
621         $LFS setstripe -c -1 $DIR/$tdir
622         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
623         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
624         touch $DIR/$tdir/$tfile || true
625 }
626 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
627
628 test_17i() { #bug 20018
629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
630         remote_mds_nodsh && skip "remote MDS with nodsh"
631
632         local foo=$DIR/$tdir/$tfile
633         local mdt_idx
634
635         test_mkdir -c1 $DIR/$tdir
636         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
637         ln -s $foo $foo || error "create symlink failed"
638 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
639         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
640         ls -l $foo && error "error not detected"
641         return 0
642 }
643 run_test 17i "don't panic on short symlink (should return error)"
644
645 test_17k() { #bug 22301
646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
647         [[ -z "$(which rsync 2>/dev/null)" ]] &&
648                 skip "no rsync command"
649         rsync --help | grep -q xattr ||
650                 skip_env "$(rsync --version | head -n1) does not support xattrs"
651         test_mkdir $DIR/$tdir
652         test_mkdir $DIR/$tdir.new
653         touch $DIR/$tdir/$tfile
654         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
655         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
656                 error "rsync failed with xattrs enabled"
657 }
658 run_test 17k "symlinks: rsync with xattrs enabled"
659
660 test_17l() { # LU-279
661         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
662                 skip "no getfattr command"
663
664         test_mkdir $DIR/$tdir
665         touch $DIR/$tdir/$tfile
666         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
667         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
668                 # -h to not follow symlinks. -m '' to list all the xattrs.
669                 # grep to remove first line: '# file: $path'.
670                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
671                 do
672                         lgetxattr_size_check $path $xattr ||
673                                 error "lgetxattr_size_check $path $xattr failed"
674                 done
675         done
676 }
677 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
678
679 # LU-1540
680 test_17m() {
681         [ $PARALLEL == "yes" ] && skip "skip parallel run"
682         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
683         remote_mds_nodsh && skip "remote MDS with nodsh"
684         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
685         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
686                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
687
688         local short_sym="0123456789"
689         local wdir=$DIR/$tdir
690         local i
691
692         test_mkdir $wdir
693         long_sym=$short_sym
694         # create a long symlink file
695         for ((i = 0; i < 4; ++i)); do
696                 long_sym=${long_sym}${long_sym}
697         done
698
699         echo "create 512 short and long symlink files under $wdir"
700         for ((i = 0; i < 256; ++i)); do
701                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
702                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
703         done
704
705         echo "erase them"
706         rm -f $wdir/*
707         sync
708         wait_delete_completed
709
710         echo "recreate the 512 symlink files with a shorter string"
711         for ((i = 0; i < 512; ++i)); do
712                 # rewrite the symlink file with a shorter string
713                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
714                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
715         done
716
717         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
718
719         echo "stop and checking mds${mds_index}:"
720         # e2fsck should not return error
721         stop mds${mds_index}
722         local devname=$(mdsdevname $mds_index)
723         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
724         rc=$?
725
726         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
727                 error "start mds${mds_index} failed"
728         df $MOUNT > /dev/null 2>&1
729         [ $rc -eq 0 ] ||
730                 error "e2fsck detected error for short/long symlink: rc=$rc"
731         rm -f $wdir/*
732 }
733 run_test 17m "run e2fsck against MDT which contains short/long symlink"
734
735 check_fs_consistency_17n() {
736         local mdt_index
737         local rc=0
738
739         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
740         # so it only check MDT1/MDT2 instead of all of MDTs.
741         for mdt_index in 1 2; do
742                 # e2fsck should not return error
743                 stop mds${mdt_index}
744                 local devname=$(mdsdevname $mdt_index)
745                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
746                         rc=$((rc + $?))
747
748                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
749                         error "mount mds$mdt_index failed"
750                 df $MOUNT > /dev/null 2>&1
751         done
752         return $rc
753 }
754
755 test_17n() {
756         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
757         [ $PARALLEL == "yes" ] && skip "skip parallel run"
758         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
759         remote_mds_nodsh && skip "remote MDS with nodsh"
760         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
761         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
762                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
763
764         local i
765
766         test_mkdir $DIR/$tdir
767         for ((i=0; i<10; i++)); do
768                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
769                         error "create remote dir error $i"
770                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
771                         error "create files under remote dir failed $i"
772         done
773
774         check_fs_consistency_17n ||
775                 error "e2fsck report error after create files under remote dir"
776
777         for ((i = 0; i < 10; i++)); do
778                 rm -rf $DIR/$tdir/remote_dir_${i} ||
779                         error "destroy remote dir error $i"
780         done
781
782         check_fs_consistency_17n ||
783                 error "e2fsck report error after unlink files under remote dir"
784
785         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
786                 skip "lustre < 2.4.50 does not support migrate mv"
787
788         for ((i = 0; i < 10; i++)); do
789                 mkdir -p $DIR/$tdir/remote_dir_${i}
790                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
791                         error "create files under remote dir failed $i"
792                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
793                         error "migrate remote dir error $i"
794         done
795         check_fs_consistency_17n || error "e2fsck report error after migration"
796
797         for ((i = 0; i < 10; i++)); do
798                 rm -rf $DIR/$tdir/remote_dir_${i} ||
799                         error "destroy remote dir error $i"
800         done
801
802         check_fs_consistency_17n || error "e2fsck report error after unlink"
803 }
804 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
805
806 test_17o() {
807         remote_mds_nodsh && skip "remote MDS with nodsh"
808         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
809                 skip "Need MDS version at least 2.3.64"
810
811         local wdir=$DIR/${tdir}o
812         local mdt_index
813         local rc=0
814
815         test_mkdir $wdir
816         touch $wdir/$tfile
817         mdt_index=$($LFS getstripe -m $wdir/$tfile)
818         mdt_index=$((mdt_index + 1))
819
820         cancel_lru_locks mdc
821         #fail mds will wait the failover finish then set
822         #following fail_loc to avoid interfer the recovery process.
823         fail mds${mdt_index}
824
825         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
826         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
827         ls -l $wdir/$tfile && rc=1
828         do_facet mds${mdt_index} lctl set_param fail_loc=0
829         [[ $rc -eq 0 ]] || error "stat file should fail"
830 }
831 run_test 17o "stat file with incompat LMA feature"
832
833 test_18() {
834         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
835         ls $DIR || error "Failed to ls $DIR: $?"
836 }
837 run_test 18 "touch .../f ; ls ... =============================="
838
839 test_19a() {
840         touch $DIR/$tfile
841         ls -l $DIR
842         rm $DIR/$tfile
843         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
844 }
845 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
846
847 test_19b() {
848         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
849 }
850 run_test 19b "ls -l .../f19 (should return error) =============="
851
852 test_19c() {
853         [ $RUNAS_ID -eq $UID ] &&
854                 skip_env "RUNAS_ID = UID = $UID -- skipping"
855
856         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
857 }
858 run_test 19c "$RUNAS touch .../f19 (should return error) =="
859
860 test_19d() {
861         cat $DIR/f19 && error || true
862 }
863 run_test 19d "cat .../f19 (should return error) =============="
864
865 test_20() {
866         touch $DIR/$tfile
867         rm $DIR/$tfile
868         touch $DIR/$tfile
869         rm $DIR/$tfile
870         touch $DIR/$tfile
871         rm $DIR/$tfile
872         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
873 }
874 run_test 20 "touch .../f ; ls -l ..."
875
876 test_21() {
877         test_mkdir $DIR/$tdir
878         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
879         ln -s dangle $DIR/$tdir/link
880         echo foo >> $DIR/$tdir/link
881         cat $DIR/$tdir/dangle
882         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
883         $CHECKSTAT -f -t file $DIR/$tdir/link ||
884                 error "$tdir/link not linked to a file"
885 }
886 run_test 21 "write to dangling link"
887
888 test_22() {
889         local wdir=$DIR/$tdir
890         test_mkdir $wdir
891         chown $RUNAS_ID:$RUNAS_GID $wdir
892         (cd $wdir || error "cd $wdir failed";
893                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
894                 $RUNAS tar xf -)
895         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
896         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
897         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
898                 error "checkstat -u failed"
899 }
900 run_test 22 "unpack tar archive as non-root user"
901
902 # was test_23
903 test_23a() {
904         test_mkdir $DIR/$tdir
905         local file=$DIR/$tdir/$tfile
906
907         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
908         openfile -f O_CREAT:O_EXCL $file &&
909                 error "$file recreate succeeded" || true
910 }
911 run_test 23a "O_CREAT|O_EXCL in subdir"
912
913 test_23b() { # bug 18988
914         test_mkdir $DIR/$tdir
915         local file=$DIR/$tdir/$tfile
916
917         rm -f $file
918         echo foo > $file || error "write filed"
919         echo bar >> $file || error "append filed"
920         $CHECKSTAT -s 8 $file || error "wrong size"
921         rm $file
922 }
923 run_test 23b "O_APPEND check"
924
925 # LU-9409, size with O_APPEND and tiny writes
926 test_23c() {
927         local file=$DIR/$tfile
928
929         # single dd
930         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
931         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
932         rm -f $file
933
934         # racing tiny writes
935         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
936         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
937         wait
938         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
939         rm -f $file
940
941         #racing tiny & normal writes
942         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
943         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
944         wait
945         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
946         rm -f $file
947
948         #racing tiny & normal writes 2, ugly numbers
949         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
950         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
951         wait
952         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
953         rm -f $file
954 }
955 run_test 23c "O_APPEND size checks for tiny writes"
956
957 # LU-11069 file offset is correct after appending writes
958 test_23d() {
959         local file=$DIR/$tfile
960         local offset
961
962         echo CentaurHauls > $file
963         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
964         if ((offset != 26)); then
965                 error "wrong offset, expected 26, got '$offset'"
966         fi
967 }
968 run_test 23d "file offset is correct after appending writes"
969
970 # rename sanity
971 test_24a() {
972         echo '-- same directory rename'
973         test_mkdir $DIR/$tdir
974         touch $DIR/$tdir/$tfile.1
975         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
976         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
977 }
978 run_test 24a "rename file to non-existent target"
979
980 test_24b() {
981         test_mkdir $DIR/$tdir
982         touch $DIR/$tdir/$tfile.{1,2}
983         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
984         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
985         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
986 }
987 run_test 24b "rename file to existing target"
988
989 test_24c() {
990         test_mkdir $DIR/$tdir
991         test_mkdir $DIR/$tdir/d$testnum.1
992         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
993         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
994         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
995 }
996 run_test 24c "rename directory to non-existent target"
997
998 test_24d() {
999         test_mkdir -c1 $DIR/$tdir
1000         test_mkdir -c1 $DIR/$tdir/d$testnum.1
1001         test_mkdir -c1 $DIR/$tdir/d$testnum.2
1002         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
1003         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
1004         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
1005 }
1006 run_test 24d "rename directory to existing target"
1007
1008 test_24e() {
1009         echo '-- cross directory renames --'
1010         test_mkdir $DIR/R5a
1011         test_mkdir $DIR/R5b
1012         touch $DIR/R5a/f
1013         mv $DIR/R5a/f $DIR/R5b/g
1014         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
1015         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
1016 }
1017 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
1018
1019 test_24f() {
1020         test_mkdir $DIR/R6a
1021         test_mkdir $DIR/R6b
1022         touch $DIR/R6a/f $DIR/R6b/g
1023         mv $DIR/R6a/f $DIR/R6b/g
1024         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1025         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1026 }
1027 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1028
1029 test_24g() {
1030         test_mkdir $DIR/R7a
1031         test_mkdir $DIR/R7b
1032         test_mkdir $DIR/R7a/d
1033         mv $DIR/R7a/d $DIR/R7b/e
1034         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1035         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1036 }
1037 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1038
1039 test_24h() {
1040         test_mkdir -c1 $DIR/R8a
1041         test_mkdir -c1 $DIR/R8b
1042         test_mkdir -c1 $DIR/R8a/d
1043         test_mkdir -c1 $DIR/R8b/e
1044         mrename $DIR/R8a/d $DIR/R8b/e
1045         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1046         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1047 }
1048 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1049
1050 test_24i() {
1051         echo "-- rename error cases"
1052         test_mkdir $DIR/R9
1053         test_mkdir $DIR/R9/a
1054         touch $DIR/R9/f
1055         mrename $DIR/R9/f $DIR/R9/a
1056         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1057         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1058         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1059 }
1060 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1061
1062 test_24j() {
1063         test_mkdir $DIR/R10
1064         mrename $DIR/R10/f $DIR/R10/g
1065         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1066         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1067         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1068 }
1069 run_test 24j "source does not exist ============================"
1070
1071 test_24k() {
1072         test_mkdir $DIR/R11a
1073         test_mkdir $DIR/R11a/d
1074         touch $DIR/R11a/f
1075         mv $DIR/R11a/f $DIR/R11a/d
1076         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1077         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1078 }
1079 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1080
1081 # bug 2429 - rename foo foo foo creates invalid file
1082 test_24l() {
1083         f="$DIR/f24l"
1084         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1085 }
1086 run_test 24l "Renaming a file to itself ========================"
1087
1088 test_24m() {
1089         f="$DIR/f24m"
1090         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1091         # on ext3 this does not remove either the source or target files
1092         # though the "expected" operation would be to remove the source
1093         $CHECKSTAT -t file ${f} || error "${f} missing"
1094         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1095 }
1096 run_test 24m "Renaming a file to a hard link to itself ========="
1097
1098 test_24n() {
1099     f="$DIR/f24n"
1100     # this stats the old file after it was renamed, so it should fail
1101     touch ${f}
1102     $CHECKSTAT ${f} || error "${f} missing"
1103     mv ${f} ${f}.rename
1104     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1105     $CHECKSTAT -a ${f} || error "${f} exists"
1106 }
1107 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1108
1109 test_24o() {
1110         test_mkdir $DIR/$tdir
1111         rename_many -s random -v -n 10 $DIR/$tdir
1112 }
1113 run_test 24o "rename of files during htree split"
1114
1115 test_24p() {
1116         test_mkdir $DIR/R12a
1117         test_mkdir $DIR/R12b
1118         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1119         mrename $DIR/R12a $DIR/R12b
1120         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1121         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1122         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1123         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1124 }
1125 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1126
1127 cleanup_multiop_pause() {
1128         trap 0
1129         kill -USR1 $MULTIPID
1130 }
1131
1132 test_24q() {
1133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1134
1135         test_mkdir $DIR/R13a
1136         test_mkdir $DIR/R13b
1137         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1138         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1139         MULTIPID=$!
1140
1141         trap cleanup_multiop_pause EXIT
1142         mrename $DIR/R13a $DIR/R13b
1143         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1144         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1145         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1146         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1147         cleanup_multiop_pause
1148         wait $MULTIPID || error "multiop close failed"
1149 }
1150 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1151
1152 test_24r() { #bug 3789
1153         test_mkdir $DIR/R14a
1154         test_mkdir $DIR/R14a/b
1155         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1156         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1157         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1158 }
1159 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1160
1161 test_24s() {
1162         test_mkdir $DIR/R15a
1163         test_mkdir $DIR/R15a/b
1164         test_mkdir $DIR/R15a/b/c
1165         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1166         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1167         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1168 }
1169 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1170
1171 test_24t() {
1172         test_mkdir $DIR/R16a
1173         test_mkdir $DIR/R16a/b
1174         test_mkdir $DIR/R16a/b/c
1175         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1176         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1177         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1178 }
1179 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1180
1181 test_24u() { # bug12192
1182         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1183         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1184 }
1185 run_test 24u "create stripe file"
1186
1187 simple_cleanup_common() {
1188         local createmany=$1
1189         local rc=0
1190
1191         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1192
1193         local start=$SECONDS
1194
1195         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1196         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1197         rc=$?
1198         wait_delete_completed
1199         echo "cleanup time $((SECONDS - start))"
1200         return $rc
1201 }
1202
1203 max_pages_per_rpc() {
1204         local mdtname="$(printf "MDT%04x" ${1:-0})"
1205         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1206 }
1207
1208 test_24v() {
1209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1210
1211         local nrfiles=${COUNT:-100000}
1212         local fname="$DIR/$tdir/$tfile"
1213
1214         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1215         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1216
1217         test_mkdir "$(dirname $fname)"
1218         # assume MDT0000 has the fewest inodes
1219         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1220         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1221         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1222
1223         stack_trap "simple_cleanup_common $nrfiles"
1224
1225         createmany -m "$fname" $nrfiles
1226
1227         cancel_lru_locks mdc
1228         lctl set_param mdc.*.stats clear
1229
1230         # was previously test_24D: LU-6101
1231         # readdir() returns correct number of entries after cursor reload
1232         local num_ls=$(ls $DIR/$tdir | wc -l)
1233         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1234         local num_all=$(ls -a $DIR/$tdir | wc -l)
1235         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1236                 [ $num_all -ne $((nrfiles + 2)) ]; then
1237                         error "Expected $nrfiles files, got $num_ls " \
1238                                 "($num_uniq unique $num_all .&..)"
1239         fi
1240         # LU-5 large readdir
1241         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1242         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1243         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1244         # take into account of overhead in lu_dirpage header and end mark in
1245         # each page, plus one in rpc_num calculation.
1246         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1247         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1248         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1249         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1250         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1251         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1252         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1253         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1254                 error "large readdir doesn't take effect: " \
1255                       "$mds_readpage should be about $rpc_max"
1256 }
1257 run_test 24v "list large directory (test hash collision, b=17560)"
1258
1259 test_24w() { # bug21506
1260         SZ1=234852
1261         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1262         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1263         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1264         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1265         [[ "$SZ1" -eq "$SZ2" ]] ||
1266                 error "Error reading at the end of the file $tfile"
1267 }
1268 run_test 24w "Reading a file larger than 4Gb"
1269
1270 test_24x() {
1271         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1273         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1274                 skip "Need MDS version at least 2.7.56"
1275
1276         local MDTIDX=1
1277         local remote_dir=$DIR/$tdir/remote_dir
1278
1279         test_mkdir $DIR/$tdir
1280         $LFS mkdir -i $MDTIDX $remote_dir ||
1281                 error "create remote directory failed"
1282
1283         test_mkdir $DIR/$tdir/src_dir
1284         touch $DIR/$tdir/src_file
1285         test_mkdir $remote_dir/tgt_dir
1286         touch $remote_dir/tgt_file
1287
1288         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1289                 error "rename dir cross MDT failed!"
1290
1291         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1292                 error "rename file cross MDT failed!"
1293
1294         touch $DIR/$tdir/ln_file
1295         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1296                 error "ln file cross MDT failed"
1297
1298         rm -rf $DIR/$tdir || error "Can not delete directories"
1299 }
1300 run_test 24x "cross MDT rename/link"
1301
1302 test_24y() {
1303         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1304         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1305
1306         local remote_dir=$DIR/$tdir/remote_dir
1307         local mdtidx=1
1308
1309         test_mkdir $DIR/$tdir
1310         $LFS mkdir -i $mdtidx $remote_dir ||
1311                 error "create remote directory failed"
1312
1313         test_mkdir $remote_dir/src_dir
1314         touch $remote_dir/src_file
1315         test_mkdir $remote_dir/tgt_dir
1316         touch $remote_dir/tgt_file
1317
1318         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1319                 error "rename subdir in the same remote dir failed!"
1320
1321         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1322                 error "rename files in the same remote dir failed!"
1323
1324         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1325                 error "link files in the same remote dir failed!"
1326
1327         rm -rf $DIR/$tdir || error "Can not delete directories"
1328 }
1329 run_test 24y "rename/link on the same dir should succeed"
1330
1331 test_24z() {
1332         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1333         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1334                 skip "Need MDS version at least 2.12.51"
1335
1336         local index
1337
1338         for index in 0 1; do
1339                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1340                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1341         done
1342
1343         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1344
1345         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1346         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1347
1348         local mdts=$(comma_list $(mdts_nodes))
1349
1350         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1351         stack_trap "do_nodes $mdts $LCTL \
1352                 set_param mdt.*.enable_remote_rename=1" EXIT
1353
1354         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1355
1356         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1357         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1358 }
1359 run_test 24z "cross-MDT rename is done as cp"
1360
1361 test_24A() { # LU-3182
1362         local NFILES=5000
1363
1364         test_mkdir $DIR/$tdir
1365         stack_trap "simple_cleanup_common $NFILES"
1366         createmany -m $DIR/$tdir/$tfile $NFILES
1367         local t=$(ls $DIR/$tdir | wc -l)
1368         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1369         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1370
1371         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1372                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1373 }
1374 run_test 24A "readdir() returns correct number of entries."
1375
1376 test_24B() { # LU-4805
1377         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1378
1379         local count
1380
1381         test_mkdir $DIR/$tdir
1382         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir/ ||
1383                 error "create striped dir failed"
1384
1385         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1386         [ $count -eq 2 ] || error "Expected 2, got $count"
1387
1388         touch $DIR/$tdir/striped_dir/a
1389
1390         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1391         [ $count -eq 3 ] || error "Expected 3, got $count"
1392
1393         touch $DIR/$tdir/striped_dir/.f
1394
1395         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1396         [ $count -eq 4 ] || error "Expected 4, got $count"
1397
1398         rm -rf $DIR/$tdir || error "Can not delete directories"
1399 }
1400 run_test 24B "readdir for striped dir return correct number of entries"
1401
1402 test_24C() {
1403         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1404
1405         mkdir $DIR/$tdir
1406         mkdir $DIR/$tdir/d0
1407         mkdir $DIR/$tdir/d1
1408
1409         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1410                 error "create striped dir failed"
1411
1412         cd $DIR/$tdir/d0/striped_dir
1413
1414         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1415         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1416         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1417
1418         [ "$d0_ino" = "$parent_ino" ] ||
1419                 error ".. wrong, expect $d0_ino, get $parent_ino"
1420
1421         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1422                 error "mv striped dir failed"
1423
1424         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1425
1426         [ "$d1_ino" = "$parent_ino" ] ||
1427                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1428 }
1429 run_test 24C "check .. in striped dir"
1430
1431 test_24E() {
1432         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1434
1435         mkdir -p $DIR/$tdir
1436         mkdir $DIR/$tdir/src_dir
1437         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1438                 error "create remote source failed"
1439
1440         touch $DIR/$tdir/src_dir/src_child/a
1441
1442         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1443                 error "create remote target dir failed"
1444
1445         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1446                 error "create remote target child failed"
1447
1448         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1449                 error "rename dir cross MDT failed!"
1450
1451         find $DIR/$tdir
1452
1453         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1454                 error "src_child still exists after rename"
1455
1456         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1457                 error "missing file(a) after rename"
1458
1459         rm -rf $DIR/$tdir || error "Can not delete directories"
1460 }
1461 run_test 24E "cross MDT rename/link"
1462
1463 test_24F () {
1464         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1465
1466         local repeats=1000
1467         [ "$SLOW" = "no" ] && repeats=100
1468
1469         mkdir -p $DIR/$tdir
1470
1471         echo "$repeats repeats"
1472         for ((i = 0; i < repeats; i++)); do
1473                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1474                 touch $DIR/$tdir/test/a || error "touch fails"
1475                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1476                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1477         done
1478
1479         true
1480 }
1481 run_test 24F "hash order vs readdir (LU-11330)"
1482
1483 test_24G () {
1484         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1485
1486         local ino1
1487         local ino2
1488
1489         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1490         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1491         touch $DIR/$tdir-0/f1 || error "touch f1"
1492         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1493         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1494         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1495         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1496         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1497 }
1498 run_test 24G "migrate symlink in rename"
1499
1500 test_24H() {
1501         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1502         [[ $(hostname) != $(facet_active_host mds2) ]] ||
1503                 skip "MDT1 should be on another node"
1504
1505         test_mkdir -i 1 -c 1 $DIR/$tdir
1506 #define OBD_FAIL_FLD_QUERY_REQ           0x1103
1507         do_facet mds2 $LCTL set_param fail_loc=0x80001103
1508         touch $DIR/$tdir/$tfile || error "touch failed"
1509 }
1510 run_test 24H "repeat FLD_QUERY rpc"
1511
1512 test_25a() {
1513         echo '== symlink sanity ============================================='
1514
1515         test_mkdir $DIR/d25
1516         ln -s d25 $DIR/s25
1517         touch $DIR/s25/foo ||
1518                 error "File creation in symlinked directory failed"
1519 }
1520 run_test 25a "create file in symlinked directory ==============="
1521
1522 test_25b() {
1523         [ ! -d $DIR/d25 ] && test_25a
1524         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1525 }
1526 run_test 25b "lookup file in symlinked directory ==============="
1527
1528 test_26a() {
1529         test_mkdir $DIR/d26
1530         test_mkdir $DIR/d26/d26-2
1531         ln -s d26/d26-2 $DIR/s26
1532         touch $DIR/s26/foo || error "File creation failed"
1533 }
1534 run_test 26a "multiple component symlink ======================="
1535
1536 test_26b() {
1537         test_mkdir -p $DIR/$tdir/d26-2
1538         ln -s $tdir/d26-2/foo $DIR/s26-2
1539         touch $DIR/s26-2 || error "File creation failed"
1540 }
1541 run_test 26b "multiple component symlink at end of lookup ======"
1542
1543 test_26c() {
1544         test_mkdir $DIR/d26.2
1545         touch $DIR/d26.2/foo
1546         ln -s d26.2 $DIR/s26.2-1
1547         ln -s s26.2-1 $DIR/s26.2-2
1548         ln -s s26.2-2 $DIR/s26.2-3
1549         chmod 0666 $DIR/s26.2-3/foo
1550 }
1551 run_test 26c "chain of symlinks"
1552
1553 # recursive symlinks (bug 439)
1554 test_26d() {
1555         ln -s d26-3/foo $DIR/d26-3
1556 }
1557 run_test 26d "create multiple component recursive symlink"
1558
1559 test_26e() {
1560         [ ! -h $DIR/d26-3 ] && test_26d
1561         rm $DIR/d26-3
1562 }
1563 run_test 26e "unlink multiple component recursive symlink"
1564
1565 # recursive symlinks (bug 7022)
1566 test_26f() {
1567         test_mkdir $DIR/$tdir
1568         test_mkdir $DIR/$tdir/$tfile
1569         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1570         test_mkdir -p lndir/bar1
1571         test_mkdir $DIR/$tdir/$tfile/$tfile
1572         cd $tfile                || error "cd $tfile failed"
1573         ln -s .. dotdot          || error "ln dotdot failed"
1574         ln -s dotdot/lndir lndir || error "ln lndir failed"
1575         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1576         output=`ls $tfile/$tfile/lndir/bar1`
1577         [ "$output" = bar1 ] && error "unexpected output"
1578         rm -r $tfile             || error "rm $tfile failed"
1579         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1580 }
1581 run_test 26f "rm -r of a directory which has recursive symlink"
1582
1583 test_27a() {
1584         test_mkdir $DIR/$tdir
1585         $LFS getstripe $DIR/$tdir
1586         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1587         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1588         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1589 }
1590 run_test 27a "one stripe file"
1591
1592 test_27b() {
1593         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1594
1595         test_mkdir $DIR/$tdir
1596         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1597         $LFS getstripe -c $DIR/$tdir/$tfile
1598         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1599                 error "two-stripe file doesn't have two stripes"
1600
1601         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1602 }
1603 run_test 27b "create and write to two stripe file"
1604
1605 # 27c family tests specific striping, setstripe -o
1606 test_27ca() {
1607         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1608         test_mkdir -p $DIR/$tdir
1609         local osts="1"
1610
1611         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1612         $LFS getstripe -i $DIR/$tdir/$tfile
1613         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1614                 error "stripe not on specified OST"
1615
1616         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1617 }
1618 run_test 27ca "one stripe on specified OST"
1619
1620 test_27cb() {
1621         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1622         test_mkdir -p $DIR/$tdir
1623         local osts="1,0"
1624         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1625         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1626         echo "$getstripe"
1627
1628         # Strip getstripe output to a space separated list of OSTs
1629         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1630                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1631         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1632                 error "stripes not on specified OSTs"
1633
1634         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1635 }
1636 run_test 27cb "two stripes on specified OSTs"
1637
1638 test_27cc() {
1639         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1640         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1641                 skip "server does not support overstriping"
1642
1643         test_mkdir -p $DIR/$tdir
1644         local osts="0,0"
1645         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1646         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1647         echo "$getstripe"
1648
1649         # Strip getstripe output to a space separated list of OSTs
1650         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1651                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1652         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1653                 error "stripes not on specified OSTs"
1654
1655         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1656 }
1657 run_test 27cc "two stripes on the same OST"
1658
1659 test_27cd() {
1660         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1661         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1662                 skip "server does not support overstriping"
1663         test_mkdir -p $DIR/$tdir
1664         local osts="0,1,1,0"
1665         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1666         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1667         echo "$getstripe"
1668
1669         # Strip getstripe output to a space separated list of OSTs
1670         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1671                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1672         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1673                 error "stripes not on specified OSTs"
1674
1675         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1676 }
1677 run_test 27cd "four stripes on two OSTs"
1678
1679 test_27ce() {
1680         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1681                 skip_env "too many osts, skipping"
1682         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1683                 skip "server does not support overstriping"
1684         # We do one more stripe than we have OSTs
1685         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1686                 skip_env "ea_inode feature disabled"
1687
1688         test_mkdir -p $DIR/$tdir
1689         local osts=""
1690         for i in $(seq 0 $OSTCOUNT);
1691         do
1692                 osts=$osts"0"
1693                 if [ $i -ne $OSTCOUNT ]; then
1694                         osts=$osts","
1695                 fi
1696         done
1697         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1698         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1699         echo "$getstripe"
1700
1701         # Strip getstripe output to a space separated list of OSTs
1702         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1703                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1704         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1705                 error "stripes not on specified OSTs"
1706
1707         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1708 }
1709 run_test 27ce "more stripes than OSTs with -o"
1710
1711 test_27cf() {
1712         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1713         local pid=0
1714
1715         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1716         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1717         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1718         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1719                 error "failed to set $osp_proc=0"
1720
1721         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1722         pid=$!
1723         sleep 1
1724         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1725         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1726                 error "failed to set $osp_proc=1"
1727         wait $pid
1728         [[ $pid -ne 0 ]] ||
1729                 error "should return error due to $osp_proc=0"
1730 }
1731 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1732
1733 test_27cg() {
1734         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1735                 skip "server does not support overstriping"
1736         [[ $mds1_FSTYPE != "ldiskfs" ]] && skip_env "ldiskfs only test"
1737         large_xattr_enabled || skip_env "ea_inode feature disabled"
1738
1739         local osts="0"
1740
1741         for ((i=1;i<1000;i++)); do
1742                 osts+=",$((i % OSTCOUNT))"
1743         done
1744
1745         local mdts=$(comma_list $(mdts_nodes))
1746         local before=$(do_nodes $mdts \
1747                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1748                 awk '/many credits/{print $3}' |
1749                 calc_sum)
1750
1751         $LFS setstripe -o $osts $DIR/$tfile || error "setstripe failed"
1752         $LFS getstripe $DIR/$tfile | grep stripe
1753
1754         rm -f $DIR/$tfile || error "can't unlink"
1755
1756         after=$(do_nodes $mdts \
1757                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1758                 awk '/many credits/{print $3}' |
1759                 calc_sum)
1760
1761         (( before == after )) ||
1762                 error "too many credits happened: $after > $before"
1763 }
1764 run_test 27cg "1000 shouldn't cause too many credits"
1765
1766 test_27d() {
1767         test_mkdir $DIR/$tdir
1768         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1769                 error "setstripe failed"
1770         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1771         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1772 }
1773 run_test 27d "create file with default settings"
1774
1775 test_27e() {
1776         # LU-5839 adds check for existed layout before setting it
1777         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1778                 skip "Need MDS version at least 2.7.56"
1779
1780         test_mkdir $DIR/$tdir
1781         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1782         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1783         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1784 }
1785 run_test 27e "setstripe existing file (should return error)"
1786
1787 test_27f() {
1788         test_mkdir $DIR/$tdir
1789         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1790                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1791         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1792                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1793         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1794         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1795 }
1796 run_test 27f "setstripe with bad stripe size (should return error)"
1797
1798 test_27g() {
1799         test_mkdir $DIR/$tdir
1800         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1801         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1802                 error "$DIR/$tdir/$tfile has object"
1803 }
1804 run_test 27g "$LFS getstripe with no objects"
1805
1806 test_27ga() {
1807         test_mkdir $DIR/$tdir
1808         touch $DIR/$tdir/$tfile || error "touch failed"
1809         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1810         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1811         local rc=$?
1812         (( rc == 2 )) || error "getstripe did not return ENOENT"
1813
1814         local err_msg=$($LFS getstripe $DIR/$tdir/typo $DIR/$tdir/$tfile \
1815                         2>&1 > /dev/null)
1816         [[ $err_msg =~ "typo" ]] ||
1817                 error "expected message with correct filename, got '$err_msg'"
1818 }
1819 run_test 27ga "$LFS getstripe with missing file (should return error)"
1820
1821 test_27i() {
1822         test_mkdir $DIR/$tdir
1823         touch $DIR/$tdir/$tfile || error "touch failed"
1824         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1825                 error "missing objects"
1826 }
1827 run_test 27i "$LFS getstripe with some objects"
1828
1829 test_27j() {
1830         test_mkdir $DIR/$tdir
1831         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1832                 error "setstripe failed" || true
1833 }
1834 run_test 27j "setstripe with bad stripe offset (should return error)"
1835
1836 test_27k() { # bug 2844
1837         test_mkdir $DIR/$tdir
1838         local file=$DIR/$tdir/$tfile
1839         local ll_max_blksize=$((4 * 1024 * 1024))
1840         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1841         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1842         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1843         dd if=/dev/zero of=$file bs=4k count=1
1844         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1845         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1846 }
1847 run_test 27k "limit i_blksize for broken user apps"
1848
1849 test_27l() {
1850         mcreate $DIR/$tfile || error "creating file"
1851         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1852                 error "setstripe should have failed" || true
1853 }
1854 run_test 27l "check setstripe permissions (should return error)"
1855
1856 test_27m() {
1857         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1858
1859         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1860                 skip_env "multiple clients -- skipping"
1861
1862         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1863                    head -n1)
1864         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1865                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1866         fi
1867         stack_trap simple_cleanup_common
1868         test_mkdir $DIR/$tdir
1869         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1870         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1871                 error "dd should fill OST0"
1872         i=2
1873         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1874                 i=$((i + 1))
1875                 [ $i -gt 256 ] && break
1876         done
1877         i=$((i + 1))
1878         touch $DIR/$tdir/$tfile.$i
1879         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1880             awk '{print $1}'| grep -w "0") ] &&
1881                 error "OST0 was full but new created file still use it"
1882         i=$((i + 1))
1883         touch $DIR/$tdir/$tfile.$i
1884         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1885             awk '{print $1}'| grep -w "0") ] &&
1886                 error "OST0 was full but new created file still use it" || true
1887 }
1888 run_test 27m "create file while OST0 was full"
1889
1890 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1891 # if the OST isn't full anymore.
1892 reset_enospc() {
1893         local ostidx=${1:-""}
1894         local delay
1895         local ready
1896         local get_prealloc
1897
1898         local list=$(comma_list $(osts_nodes))
1899         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1900
1901         do_nodes $list lctl set_param fail_loc=0
1902         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1903         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1904                 awk '{print $1 * 2;exit;}')
1905         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1906                         grep -v \"^0$\""
1907         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1908 }
1909
1910 test_27n() {
1911         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1913         remote_mds_nodsh && skip "remote MDS with nodsh"
1914         remote_ost_nodsh && skip "remote OST with nodsh"
1915
1916         reset_enospc
1917         rm -f $DIR/$tdir/$tfile
1918         exhaust_precreations 0 0x80000215
1919         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1920         touch $DIR/$tdir/$tfile || error "touch failed"
1921         $LFS getstripe $DIR/$tdir/$tfile
1922         reset_enospc
1923 }
1924 run_test 27n "create file with some full OSTs"
1925
1926 test_27o() {
1927         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1929         remote_mds_nodsh && skip "remote MDS with nodsh"
1930         remote_ost_nodsh && skip "remote OST with nodsh"
1931
1932         reset_enospc
1933         rm -f $DIR/$tdir/$tfile
1934         exhaust_all_precreations 0x215
1935
1936         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1937
1938         reset_enospc
1939         rm -rf $DIR/$tdir/*
1940 }
1941 run_test 27o "create file with all full OSTs (should error)"
1942
1943 function create_and_checktime() {
1944         local fname=$1
1945         local loops=$2
1946         local i
1947
1948         for ((i=0; i < $loops; i++)); do
1949                 local start=$SECONDS
1950                 multiop $fname-$i Oc
1951                 ((SECONDS-start < TIMEOUT)) ||
1952                         error "creation took " $((SECONDS-$start)) && return 1
1953         done
1954 }
1955
1956 test_27oo() {
1957         local mdts=$(comma_list $(mdts_nodes))
1958
1959         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1960                 skip "Need MDS version at least 2.13.57"
1961
1962         local f0=$DIR/${tfile}-0
1963         local f1=$DIR/${tfile}-1
1964
1965         wait_delete_completed
1966
1967         # refill precreated objects
1968         $LFS setstripe -i0 -c1 $f0
1969
1970         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1971         # force QoS allocation policy
1972         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1973         stack_trap "do_nodes $mdts $LCTL set_param \
1974                 lov.*.qos_threshold_rr=$saved" EXIT
1975         sleep_maxage
1976
1977         # one OST is unavailable, but still have few objects preallocated
1978         stop ost1
1979         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1980                 rm -rf $f1 $DIR/$tdir*" EXIT
1981
1982         for ((i=0; i < 7; i++)); do
1983                 mkdir $DIR/$tdir$i || error "can't create dir"
1984                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1985                         error "can't set striping"
1986         done
1987         for ((i=0; i < 7; i++)); do
1988                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1989         done
1990         wait
1991 }
1992 run_test 27oo "don't let few threads to reserve too many objects"
1993
1994 test_27p() {
1995         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1997         remote_mds_nodsh && skip "remote MDS with nodsh"
1998         remote_ost_nodsh && skip "remote OST with nodsh"
1999
2000         reset_enospc
2001         rm -f $DIR/$tdir/$tfile
2002         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
2003
2004         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
2005         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
2006         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
2007
2008         exhaust_precreations 0 0x80000215
2009         echo foo >> $DIR/$tdir/$tfile || error "append failed"
2010         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
2011         $LFS getstripe $DIR/$tdir/$tfile
2012
2013         reset_enospc
2014 }
2015 run_test 27p "append to a truncated file with some full OSTs"
2016
2017 test_27q() {
2018         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2019         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2020         remote_mds_nodsh && skip "remote MDS with nodsh"
2021         remote_ost_nodsh && skip "remote OST with nodsh"
2022
2023         reset_enospc
2024         rm -f $DIR/$tdir/$tfile
2025
2026         mkdir_on_mdt0 $DIR/$tdir
2027         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
2028         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
2029                 error "truncate $DIR/$tdir/$tfile failed"
2030         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
2031
2032         exhaust_all_precreations 0x215
2033
2034         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
2035         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
2036
2037         reset_enospc
2038 }
2039 run_test 27q "append to truncated file with all OSTs full (should error)"
2040
2041 test_27r() {
2042         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2044         remote_mds_nodsh && skip "remote MDS with nodsh"
2045         remote_ost_nodsh && skip "remote OST with nodsh"
2046
2047         reset_enospc
2048         rm -f $DIR/$tdir/$tfile
2049         exhaust_precreations 0 0x80000215
2050
2051         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2052
2053         reset_enospc
2054 }
2055 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2056
2057 test_27s() { # bug 10725
2058         test_mkdir $DIR/$tdir
2059         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2060         local stripe_count=0
2061         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2062         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2063                 error "stripe width >= 2^32 succeeded" || true
2064
2065 }
2066 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2067
2068 test_27t() { # bug 10864
2069         WDIR=$(pwd)
2070         WLFS=$(which lfs)
2071         cd $DIR
2072         touch $tfile
2073         $WLFS getstripe $tfile
2074         cd $WDIR
2075 }
2076 run_test 27t "check that utils parse path correctly"
2077
2078 test_27u() { # bug 4900
2079         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2080         remote_mds_nodsh && skip "remote MDS with nodsh"
2081
2082         local index
2083         local list=$(comma_list $(mdts_nodes))
2084
2085 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2086         do_nodes $list $LCTL set_param fail_loc=0x139
2087         test_mkdir -p $DIR/$tdir
2088         stack_trap "simple_cleanup_common 1000"
2089         createmany -o $DIR/$tdir/$tfile 1000
2090         do_nodes $list $LCTL set_param fail_loc=0
2091
2092         TLOG=$TMP/$tfile.getstripe
2093         $LFS getstripe $DIR/$tdir > $TLOG
2094         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2095         [[ $OBJS -gt 0 ]] &&
2096                 error "$OBJS objects created on OST-0. See $TLOG" ||
2097                 rm -f $TLOG
2098 }
2099 run_test 27u "skip object creation on OSC w/o objects"
2100
2101 test_27v() { # bug 4900
2102         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2104         remote_mds_nodsh && skip "remote MDS with nodsh"
2105         remote_ost_nodsh && skip "remote OST with nodsh"
2106
2107         exhaust_all_precreations 0x215
2108         reset_enospc
2109
2110         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2111
2112         touch $DIR/$tdir/$tfile
2113         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2114         # all except ost1
2115         for (( i=1; i < OSTCOUNT; i++ )); do
2116                 do_facet ost$i lctl set_param fail_loc=0x705
2117         done
2118         local START=`date +%s`
2119         createmany -o $DIR/$tdir/$tfile 32
2120
2121         local FINISH=`date +%s`
2122         local TIMEOUT=`lctl get_param -n timeout`
2123         local PROCESS=$((FINISH - START))
2124         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2125                error "$FINISH - $START >= $TIMEOUT / 2"
2126         sleep $((TIMEOUT / 2 - PROCESS))
2127         reset_enospc
2128 }
2129 run_test 27v "skip object creation on slow OST"
2130
2131 test_27w() { # bug 10997
2132         test_mkdir $DIR/$tdir
2133         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2134         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2135                 error "stripe size $size != 65536" || true
2136         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2137                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2138 }
2139 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2140
2141 test_27wa() {
2142         [[ $OSTCOUNT -lt 2 ]] &&
2143                 skip_env "skipping multiple stripe count/offset test"
2144
2145         test_mkdir $DIR/$tdir
2146         for i in $(seq 1 $OSTCOUNT); do
2147                 offset=$((i - 1))
2148                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2149                         error "setstripe -c $i -i $offset failed"
2150                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2151                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2152                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2153                 [ $index -ne $offset ] &&
2154                         error "stripe offset $index != $offset" || true
2155         done
2156 }
2157 run_test 27wa "check $LFS setstripe -c -i options"
2158
2159 test_27x() {
2160         remote_ost_nodsh && skip "remote OST with nodsh"
2161         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2163
2164         OFFSET=$(($OSTCOUNT - 1))
2165         OSTIDX=0
2166         local OST=$(ostname_from_index $OSTIDX)
2167
2168         test_mkdir $DIR/$tdir
2169         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2170         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2171         sleep_maxage
2172         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2173         for i in $(seq 0 $OFFSET); do
2174                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2175                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2176                 error "OST0 was degraded but new created file still use it"
2177         done
2178         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2179 }
2180 run_test 27x "create files while OST0 is degraded"
2181
2182 test_27y() {
2183         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2184         remote_mds_nodsh && skip "remote MDS with nodsh"
2185         remote_ost_nodsh && skip "remote OST with nodsh"
2186         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2187
2188         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2189         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2190                 osp.$mdtosc.prealloc_last_id)
2191         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2192                 osp.$mdtosc.prealloc_next_id)
2193         local fcount=$((last_id - next_id))
2194         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2195         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2196
2197         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2198                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2199         local OST_DEACTIVE_IDX=-1
2200         local OSC
2201         local OSTIDX
2202         local OST
2203
2204         for OSC in $MDS_OSCS; do
2205                 OST=$(osc_to_ost $OSC)
2206                 OSTIDX=$(index_from_ostuuid $OST)
2207                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2208                         OST_DEACTIVE_IDX=$OSTIDX
2209                 fi
2210                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2211                         echo $OSC "is Deactivated:"
2212                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2213                 fi
2214         done
2215
2216         OSTIDX=$(index_from_ostuuid $OST)
2217         test_mkdir $DIR/$tdir
2218         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2219
2220         for OSC in $MDS_OSCS; do
2221                 OST=$(osc_to_ost $OSC)
2222                 OSTIDX=$(index_from_ostuuid $OST)
2223                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2224                         echo $OST "is degraded:"
2225                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2226                                                 obdfilter.$OST.degraded=1
2227                 fi
2228         done
2229
2230         sleep_maxage
2231         createmany -o $DIR/$tdir/$tfile $fcount
2232
2233         for OSC in $MDS_OSCS; do
2234                 OST=$(osc_to_ost $OSC)
2235                 OSTIDX=$(index_from_ostuuid $OST)
2236                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2237                         echo $OST "is recovered from degraded:"
2238                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2239                                                 obdfilter.$OST.degraded=0
2240                 else
2241                         do_facet $SINGLEMDS lctl --device %$OSC activate
2242                 fi
2243         done
2244
2245         # all osp devices get activated, hence -1 stripe count restored
2246         local stripe_count=0
2247
2248         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2249         # devices get activated.
2250         sleep_maxage
2251         $LFS setstripe -c -1 $DIR/$tfile
2252         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2253         rm -f $DIR/$tfile
2254         [ $stripe_count -ne $OSTCOUNT ] &&
2255                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2256         return 0
2257 }
2258 run_test 27y "create files while OST0 is degraded and the rest inactive"
2259
2260 check_seq_oid()
2261 {
2262         log "check file $1"
2263
2264         lmm_count=$($LFS getstripe -c $1)
2265         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2266         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2267
2268         local old_ifs="$IFS"
2269         IFS=$'[:]'
2270         fid=($($LFS path2fid $1))
2271         IFS="$old_ifs"
2272
2273         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2274         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2275
2276         # compare lmm_seq and lu_fid->f_seq
2277         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2278         # compare lmm_object_id and lu_fid->oid
2279         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2280
2281         # check the trusted.fid attribute of the OST objects of the file
2282         local have_obdidx=false
2283         local stripe_nr=0
2284         $LFS getstripe $1 | while read obdidx oid hex seq; do
2285                 # skip lines up to and including "obdidx"
2286                 [ -z "$obdidx" ] && break
2287                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2288                 $have_obdidx || continue
2289
2290                 local ost=$((obdidx + 1))
2291                 local dev=$(ostdevname $ost)
2292                 local oid_hex
2293
2294                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2295
2296                 seq=$(echo $seq | sed -e "s/^0x//g")
2297                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2298                         oid_hex=$(echo $oid)
2299                 else
2300                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2301                 fi
2302                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2303
2304                 local ff=""
2305                 #
2306                 # Don't unmount/remount the OSTs if we don't need to do that.
2307                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2308                 # update too, until that use mount/ll_decode_filter_fid/mount.
2309                 # Re-enable when debugfs will understand new filter_fid.
2310                 #
2311                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2312                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2313                                 $dev 2>/dev/null" | grep "parent=")
2314                 fi
2315                 if [ -z "$ff" ]; then
2316                         stop ost$ost
2317                         mount_fstype ost$ost
2318                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2319                                 $(facet_mntpt ost$ost)/$obj_file)
2320                         unmount_fstype ost$ost
2321                         start ost$ost $dev $OST_MOUNT_OPTS
2322                         clients_up
2323                 fi
2324
2325                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2326
2327                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2328
2329                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2330                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2331                 #
2332                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2333                 #       stripe_size=1048576 component_id=1 component_start=0 \
2334                 #       component_end=33554432
2335                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2336                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2337                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2338                 local ff_pstripe
2339                 if grep -q 'stripe=' <<<$ff; then
2340                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2341                 else
2342                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2343                         # into f_ver in this case.  See comment on ff_parent.
2344                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2345                 fi
2346
2347                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2348                 [ $ff_pseq = $lmm_seq ] ||
2349                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2350                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2351                 [ $ff_poid = $lmm_oid ] ||
2352                         error "FF parent OID $ff_poid != $lmm_oid"
2353                 (($ff_pstripe == $stripe_nr)) ||
2354                         error "FF stripe $ff_pstripe != $stripe_nr"
2355
2356                 stripe_nr=$((stripe_nr + 1))
2357                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2358                         continue
2359                 if grep -q 'stripe_count=' <<<$ff; then
2360                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2361                                             -e 's/ .*//' <<<$ff)
2362                         [ $lmm_count = $ff_scnt ] ||
2363                                 error "FF stripe count $lmm_count != $ff_scnt"
2364                 fi
2365         done
2366 }
2367
2368 test_27z() {
2369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2370         remote_ost_nodsh && skip "remote OST with nodsh"
2371
2372         test_mkdir $DIR/$tdir
2373         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2374                 { error "setstripe -c -1 failed"; return 1; }
2375         # We need to send a write to every object to get parent FID info set.
2376         # This _should_ also work for setattr, but does not currently.
2377         # touch $DIR/$tdir/$tfile-1 ||
2378         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2379                 { error "dd $tfile-1 failed"; return 2; }
2380         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2381                 { error "setstripe -c -1 failed"; return 3; }
2382         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2383                 { error "dd $tfile-2 failed"; return 4; }
2384
2385         # make sure write RPCs have been sent to OSTs
2386         sync; sleep 5; sync
2387
2388         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2389         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2390 }
2391 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2392
2393 test_27A() { # b=19102
2394         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2395
2396         save_layout_restore_at_exit $MOUNT
2397         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2398         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2399                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2400         local default_size=$($LFS getstripe -S $MOUNT)
2401         local default_offset=$($LFS getstripe -i $MOUNT)
2402         local dsize=$(do_facet $SINGLEMDS \
2403                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2404         [ $default_size -eq $dsize ] ||
2405                 error "stripe size $default_size != $dsize"
2406         [ $default_offset -eq -1 ] ||
2407                 error "stripe offset $default_offset != -1"
2408 }
2409 run_test 27A "check filesystem-wide default LOV EA values"
2410
2411 test_27B() { # LU-2523
2412         test_mkdir $DIR/$tdir
2413         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2414         touch $DIR/$tdir/f0
2415         # open f1 with O_LOV_DELAY_CREATE
2416         # rename f0 onto f1
2417         # call setstripe ioctl on open file descriptor for f1
2418         # close
2419         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2420                 $DIR/$tdir/f0
2421
2422         rm -f $DIR/$tdir/f1
2423         # open f1 with O_LOV_DELAY_CREATE
2424         # unlink f1
2425         # call setstripe ioctl on open file descriptor for f1
2426         # close
2427         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2428
2429         # Allow multiop to fail in imitation of NFS's busted semantics.
2430         true
2431 }
2432 run_test 27B "call setstripe on open unlinked file/rename victim"
2433
2434 # 27C family tests full striping and overstriping
2435 test_27Ca() { #LU-2871
2436         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2437
2438         declare -a ost_idx
2439         local index
2440         local found
2441         local i
2442         local j
2443
2444         test_mkdir $DIR/$tdir
2445         cd $DIR/$tdir
2446         for i in $(seq 0 $((OSTCOUNT - 1))); do
2447                 # set stripe across all OSTs starting from OST$i
2448                 $LFS setstripe -i $i -c -1 $tfile$i
2449                 # get striping information
2450                 ost_idx=($($LFS getstripe $tfile$i |
2451                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2452                 echo "OST Index: ${ost_idx[*]}"
2453
2454                 # check the layout
2455                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2456                         error "${#ost_idx[@]} != $OSTCOUNT"
2457
2458                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2459                         found=0
2460                         for j in "${ost_idx[@]}"; do
2461                                 if [ $index -eq $j ]; then
2462                                         found=1
2463                                         break
2464                                 fi
2465                         done
2466                         [ $found = 1 ] ||
2467                                 error "Can not find $index in ${ost_idx[*]}"
2468                 done
2469         done
2470 }
2471 run_test 27Ca "check full striping across all OSTs"
2472
2473 test_27Cb() {
2474         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2475                 skip "server does not support overstriping"
2476         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2477                 skip_env "too many osts, skipping"
2478
2479         test_mkdir -p $DIR/$tdir
2480         local setcount=$(($OSTCOUNT * 2))
2481         [ $setcount -lt 160 ] || large_xattr_enabled ||
2482                 skip_env "ea_inode feature disabled"
2483
2484         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2485                 error "setstripe failed"
2486
2487         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2488         [ $count -eq $setcount ] ||
2489                 error "stripe count $count, should be $setcount"
2490
2491         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2492                 error "overstriped should be set in pattern"
2493
2494         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2495                 error "dd failed"
2496 }
2497 run_test 27Cb "more stripes than OSTs with -C"
2498
2499 test_27Cc() {
2500         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2501                 skip "server does not support overstriping"
2502         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2503
2504         test_mkdir -p $DIR/$tdir
2505         local setcount=$(($OSTCOUNT - 1))
2506
2507         [ $setcount -lt 160 ] || large_xattr_enabled ||
2508                 skip_env "ea_inode feature disabled"
2509
2510         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2511                 error "setstripe failed"
2512
2513         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2514         [ $count -eq $setcount ] ||
2515                 error "stripe count $count, should be $setcount"
2516
2517         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2518                 error "overstriped should not be set in pattern"
2519
2520         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2521                 error "dd failed"
2522 }
2523 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2524
2525 test_27Cd() {
2526         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2527                 skip "server does not support overstriping"
2528         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2529         large_xattr_enabled || skip_env "ea_inode feature disabled"
2530
2531         force_new_seq_all
2532
2533         test_mkdir -p $DIR/$tdir
2534         local setcount=$LOV_MAX_STRIPE_COUNT
2535
2536         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2537                 error "setstripe failed"
2538
2539         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2540         [ $count -eq $setcount ] ||
2541                 error "stripe count $count, should be $setcount"
2542
2543         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2544                 error "overstriped should be set in pattern"
2545
2546         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2547                 error "dd failed"
2548
2549         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2550 }
2551 run_test 27Cd "test maximum stripe count"
2552
2553 test_27Ce() {
2554         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2555                 skip "server does not support overstriping"
2556         test_mkdir -p $DIR/$tdir
2557
2558         pool_add $TESTNAME || error "Pool creation failed"
2559         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2560
2561         local setcount=8
2562
2563         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2564                 error "setstripe failed"
2565
2566         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2567         [ $count -eq $setcount ] ||
2568                 error "stripe count $count, should be $setcount"
2569
2570         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2571                 error "overstriped should be set in pattern"
2572
2573         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2574                 error "dd failed"
2575
2576         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2577 }
2578 run_test 27Ce "test pool with overstriping"
2579
2580 test_27Cf() {
2581         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2582                 skip "server does not support overstriping"
2583         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2584                 skip_env "too many osts, skipping"
2585
2586         test_mkdir -p $DIR/$tdir
2587
2588         local setcount=$(($OSTCOUNT * 2))
2589         [ $setcount -lt 160 ] || large_xattr_enabled ||
2590                 skip_env "ea_inode feature disabled"
2591
2592         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2593                 error "setstripe failed"
2594
2595         echo 1 > $DIR/$tdir/$tfile
2596
2597         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2598         [ $count -eq $setcount ] ||
2599                 error "stripe count $count, should be $setcount"
2600
2601         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2602                 error "overstriped should be set in pattern"
2603
2604         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2605                 error "dd failed"
2606
2607         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2608 }
2609 run_test 27Cf "test default inheritance with overstriping"
2610
2611 test_27Cg() {
2612         (( MDS1_VERSION >= $(version_code v2_15_55-80-gd96b98ee6b) )) ||
2613                 skip "need MDS version at least v2_15_55-80-gd96b98ee6b for fix"
2614
2615         $LFS setstripe -o 0,$OSTCOUNT $DIR/$tfile
2616         (( $? != 0 )) || error "must be an error for not existent OST#"
2617 }
2618 run_test 27Cg "test setstripe with wrong OST idx"
2619
2620 test_27Ci() {
2621         local tf=$DIR/$tfile
2622
2623         stack_trap "rm -f $DIR/$tfile"
2624
2625         $LFS setstripe -E1M $tf || error "create $tf failed"
2626         $LFS setstripe -Eeof --component-add -C 100 $tf ||
2627                 error "add component failed"
2628
2629         $LFS getstripe -I2 $tf | awk '/lmm_pattern/ { print $2 }' |
2630                 grep "overstriped" || {
2631                 $LFS getstripe $tf
2632                 echo "lose overstriping setting"
2633         }
2634         sc=$($LFS getstripe -I2 --stripe-count $tf)
2635         (( $sc == 100 )) || {
2636                 $LFS getstripe $tf
2637                 echo "lose overstriping setting"
2638         }
2639
2640         stack_trap "rm -f $tf"
2641         dd if=/dev/zero of=$tf bs=1M count=10 || error "write $tf"
2642         sc=$($LFS getstripe -I2 --stripe-count $tf)
2643         (( $sc == 100 )) || {
2644                 $LFS getstripe $tf
2645                 echo "lose overstriping setting after instantiation"
2646         }
2647 }
2648 run_test 27Ci "add an overstriping component"
2649
2650 test_27D() {
2651         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2652         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2653         remote_mds_nodsh && skip "remote MDS with nodsh"
2654
2655         local POOL=${POOL:-testpool}
2656         local first_ost=0
2657         local last_ost=$(($OSTCOUNT - 1))
2658         local ost_step=1
2659         local ost_list=$(seq $first_ost $ost_step $last_ost)
2660         local ost_range="$first_ost $last_ost $ost_step"
2661
2662         test_mkdir $DIR/$tdir
2663         pool_add $POOL || error "pool_add failed"
2664         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2665
2666         local skip27D
2667         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2668                 skip27D+="-s 29"
2669         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2670                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2671                         skip27D+=" -s 30,31"
2672         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2673           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2674                 skip27D+=" -s 32,33"
2675         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2676                 skip27D+=" -s 34"
2677         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2678                 error "llapi_layout_test failed"
2679
2680         destroy_test_pools || error "destroy test pools failed"
2681 }
2682 run_test 27D "validate llapi_layout API"
2683
2684 # Verify that default_easize is increased from its initial value after
2685 # accessing a widely striped file.
2686 test_27E() {
2687         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2688         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2689                 skip "client does not have LU-3338 fix"
2690
2691         # 72 bytes is the minimum space required to store striping
2692         # information for a file striped across one OST:
2693         # (sizeof(struct lov_user_md_v3) +
2694         #  sizeof(struct lov_user_ost_data_v1))
2695         local min_easize=72
2696         $LCTL set_param -n llite.*.default_easize $min_easize ||
2697                 error "lctl set_param failed"
2698         local easize=$($LCTL get_param -n llite.*.default_easize)
2699
2700         [ $easize -eq $min_easize ] ||
2701                 error "failed to set default_easize"
2702
2703         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2704                 error "setstripe failed"
2705         # In order to ensure stat() call actually talks to MDS we need to
2706         # do something drastic to this file to shake off all lock, e.g.
2707         # rename it (kills lookup lock forcing cache cleaning)
2708         mv $DIR/$tfile $DIR/${tfile}-1
2709         ls -l $DIR/${tfile}-1
2710         rm $DIR/${tfile}-1
2711
2712         easize=$($LCTL get_param -n llite.*.default_easize)
2713
2714         [ $easize -gt $min_easize ] ||
2715                 error "default_easize not updated"
2716 }
2717 run_test 27E "check that default extended attribute size properly increases"
2718
2719 test_27F() { # LU-5346/LU-7975
2720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2721         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2722         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2723                 skip "Need MDS version at least 2.8.51"
2724         remote_ost_nodsh && skip "remote OST with nodsh"
2725
2726         test_mkdir $DIR/$tdir
2727         rm -f $DIR/$tdir/f0
2728         $LFS setstripe -c 2 $DIR/$tdir
2729
2730         # stop all OSTs to reproduce situation for LU-7975 ticket
2731         for num in $(seq $OSTCOUNT); do
2732                 stop ost$num
2733         done
2734
2735         # open/create f0 with O_LOV_DELAY_CREATE
2736         # truncate f0 to a non-0 size
2737         # close
2738         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2739
2740         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2741         # open/write it again to force delayed layout creation
2742         cat /etc/hosts > $DIR/$tdir/f0 &
2743         catpid=$!
2744
2745         # restart OSTs
2746         for num in $(seq $OSTCOUNT); do
2747                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2748                         error "ost$num failed to start"
2749         done
2750
2751         wait $catpid || error "cat failed"
2752
2753         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2754         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2755                 error "wrong stripecount"
2756
2757 }
2758 run_test 27F "Client resend delayed layout creation with non-zero size"
2759
2760 test_27G() { #LU-10629
2761         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2762                 skip "Need MDS version at least 2.11.51"
2763         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2764         remote_mds_nodsh && skip "remote MDS with nodsh"
2765         local POOL=${POOL:-testpool}
2766         local ostrange="0 0 1"
2767
2768         test_mkdir $DIR/$tdir
2769         touch $DIR/$tdir/$tfile.nopool
2770         pool_add $POOL || error "pool_add failed"
2771         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2772         $LFS setstripe -p $POOL $DIR/$tdir
2773
2774         local pool=$($LFS getstripe -p $DIR/$tdir)
2775
2776         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2777         touch $DIR/$tdir/$tfile.default
2778         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2779         $LFS find $DIR/$tdir -type f --pool $POOL
2780         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2781         [[ "$found" == "2" ]] ||
2782                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2783
2784         $LFS setstripe -d $DIR/$tdir
2785
2786         pool=$($LFS getstripe -p -d $DIR/$tdir)
2787
2788         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2789 }
2790 run_test 27G "Clear OST pool from stripe"
2791
2792 test_27H() {
2793         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2794                 skip "Need MDS version newer than 2.11.54"
2795         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2796         test_mkdir $DIR/$tdir
2797         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2798         touch $DIR/$tdir/$tfile
2799         $LFS getstripe -c $DIR/$tdir/$tfile
2800         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2801                 error "two-stripe file doesn't have two stripes"
2802
2803         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2804         $LFS getstripe -y $DIR/$tdir/$tfile
2805         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2806              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2807                 error "expected l_ost_idx: [02]$ not matched"
2808
2809         # make sure ost list has been cleared
2810         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2811         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2812                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2813         touch $DIR/$tdir/f3
2814         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2815 }
2816 run_test 27H "Set specific OSTs stripe"
2817
2818 test_27I() {
2819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2820         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2821         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2822                 skip "Need MDS version newer than 2.12.52"
2823         local pool=$TESTNAME
2824         local ostrange="1 1 1"
2825
2826         save_layout_restore_at_exit $MOUNT
2827         $LFS setstripe -c 2 -i 0 $MOUNT
2828         pool_add $pool || error "pool_add failed"
2829         pool_add_targets $pool $ostrange ||
2830                 error "pool_add_targets failed"
2831         test_mkdir $DIR/$tdir
2832         $LFS setstripe -p $pool $DIR/$tdir
2833         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2834         $LFS getstripe $DIR/$tdir/$tfile
2835 }
2836 run_test 27I "check that root dir striping does not break parent dir one"
2837
2838 test_27J() {
2839         (( $MDS1_VERSION > $(version_code 2.12.51) )) ||
2840                 skip "Need MDS version newer than 2.12.51"
2841
2842         # skip basic ops on file with foreign LOV tests on 5.12-6.2 kernels
2843         # until the filemap_read() issue is fixed by v6.2-rc4-61-g5956592ce337
2844         (( $LINUX_VERSION_CODE < $(version_code 5.12.0) ||
2845            $LINUX_VERSION_CODE >= $(version_code 6.2.0) )) ||
2846                 skip "Need kernel < 5.12.0 or >= 6.2.0 for filemap_read() fix"
2847
2848         test_mkdir $DIR/$tdir
2849         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2850         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2851
2852         # create foreign file (raw way)
2853         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2854                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2855
2856         ! $LFS setstripe --foreign --flags foo \
2857                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2858                         error "creating $tfile with '--flags foo' should fail"
2859
2860         ! $LFS setstripe --foreign --flags 0xffffffff \
2861                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2862                         error "creating $tfile w/ 0xffffffff flags should fail"
2863
2864         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2865                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2866
2867         # verify foreign file (raw way)
2868         parse_foreign_file -f $DIR/$tdir/$tfile |
2869                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2870                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2871         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2872                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2873         parse_foreign_file -f $DIR/$tdir/$tfile |
2874                 grep "lov_foreign_size: 73" ||
2875                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2876         parse_foreign_file -f $DIR/$tdir/$tfile |
2877                 grep "lov_foreign_type: 1" ||
2878                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2879         parse_foreign_file -f $DIR/$tdir/$tfile |
2880                 grep "lov_foreign_flags: 0x0000DA08" ||
2881                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2882         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2883                 grep "lov_foreign_value: 0x" |
2884                 sed -e 's/lov_foreign_value: 0x//')
2885         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2886         [[ $lov = ${lov2// /} ]] ||
2887                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2888
2889         # create foreign file (lfs + API)
2890         $LFS setstripe --foreign=none --flags 0xda08 \
2891                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2892                 error "$DIR/$tdir/${tfile}2: create failed"
2893
2894         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2895                 grep "lfm_magic:.*0x0BD70BD0" ||
2896                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2897         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2898         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2899                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2900         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2901                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2902         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2903                 grep "lfm_flags:.*0x0000DA08" ||
2904                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2905         $LFS getstripe $DIR/$tdir/${tfile}2 |
2906                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2907                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2908
2909         # modify striping should fail
2910         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2911                 error "$DIR/$tdir/$tfile: setstripe should fail"
2912         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2913                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2914
2915         # R/W should fail
2916         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2917         cat $DIR/$tdir/${tfile}2 &&
2918                 error "$DIR/$tdir/${tfile}2: read should fail"
2919         cat /etc/passwd > $DIR/$tdir/$tfile &&
2920                 error "$DIR/$tdir/$tfile: write should fail"
2921         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2922                 error "$DIR/$tdir/${tfile}2: write should fail"
2923
2924         # chmod should work
2925         chmod 222 $DIR/$tdir/$tfile ||
2926                 error "$DIR/$tdir/$tfile: chmod failed"
2927         chmod 222 $DIR/$tdir/${tfile}2 ||
2928                 error "$DIR/$tdir/${tfile}2: chmod failed"
2929
2930         # chown should work
2931         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2932                 error "$DIR/$tdir/$tfile: chown failed"
2933         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2934                 error "$DIR/$tdir/${tfile}2: chown failed"
2935
2936         # rename should work
2937         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2938                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2939         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2940                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2941
2942         #remove foreign file
2943         rm $DIR/$tdir/${tfile}.new ||
2944                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2945         rm $DIR/$tdir/${tfile}2.new ||
2946                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2947 }
2948 run_test 27J "basic ops on file with foreign LOV"
2949
2950 test_27K() {
2951         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2952                 skip "Need MDS version newer than 2.12.49"
2953
2954         test_mkdir $DIR/$tdir
2955         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2956         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2957
2958         # create foreign dir (raw way)
2959         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2960                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2961
2962         ! $LFS setdirstripe --foreign --flags foo \
2963                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2964                         error "creating $tdir with '--flags foo' should fail"
2965
2966         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2967                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2968                         error "creating $tdir w/ 0xffffffff flags should fail"
2969
2970         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2971                 error "create_foreign_dir FAILED"
2972
2973         # verify foreign dir (raw way)
2974         parse_foreign_dir -d $DIR/$tdir/$tdir |
2975                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2976                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2977         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2978                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2979         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2980                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2981         parse_foreign_dir -d $DIR/$tdir/$tdir |
2982                 grep "lmv_foreign_flags: 55813$" ||
2983                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2984         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2985                 grep "lmv_foreign_value: 0x" |
2986                 sed 's/lmv_foreign_value: 0x//')
2987         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2988                 sed 's/ //g')
2989         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2990
2991         # create foreign dir (lfs + API)
2992         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2993                 $DIR/$tdir/${tdir}2 ||
2994                 error "$DIR/$tdir/${tdir}2: create failed"
2995
2996         $LFS getdirstripe -v $DIR/$tdir/${tdir}2
2997
2998         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2999                 grep "lfm_magic:.*0x0CD50CD0" ||
3000                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
3001         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
3002         # - sizeof(lfm_type) - sizeof(lfm_flags)
3003         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
3004                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
3005         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
3006                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
3007         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
3008                 grep "lfm_flags:.*0x0000DA05" ||
3009                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
3010         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
3011                 grep "lfm_value.*${uuid1}@${uuid2}" ||
3012                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
3013
3014         # file create in dir should fail
3015         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3016         touch $DIR/$tdir/${tdir}2/$tfile &&
3017                 error "$DIR/${tdir}2: file create should fail"
3018
3019         # chmod should work
3020         chmod 777 $DIR/$tdir/$tdir ||
3021                 error "$DIR/$tdir: chmod failed"
3022         chmod 777 $DIR/$tdir/${tdir}2 ||
3023                 error "$DIR/${tdir}2: chmod failed"
3024
3025         # chown should work
3026         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
3027                 error "$DIR/$tdir: chown failed"
3028         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
3029                 error "$DIR/${tdir}2: chown failed"
3030
3031         # rename should work
3032         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3033                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
3034         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
3035                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
3036
3037         #remove foreign dir
3038         rmdir $DIR/$tdir/${tdir}.new ||
3039                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
3040         rmdir $DIR/$tdir/${tdir}2.new ||
3041                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
3042 }
3043 run_test 27K "basic ops on dir with foreign LMV"
3044
3045 test_27L() {
3046         remote_mds_nodsh && skip "remote MDS with nodsh"
3047
3048         local POOL=${POOL:-$TESTNAME}
3049
3050         pool_add $POOL || error "pool_add failed"
3051
3052         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
3053                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
3054                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
3055 }
3056 run_test 27L "lfs pool_list gives correct pool name"
3057
3058 test_27M() {
3059         (( $MDS1_VERSION >= $(version_code 2.12.57) )) ||
3060                 skip "Need MDS version >= than 2.12.57"
3061         remote_mds_nodsh && skip "remote MDS with nodsh"
3062         (( $OSTCOUNT > 1 )) || skip "need > 1 OST"
3063
3064         # Set default striping on directory
3065         local setcount=4
3066         local stripe_opt
3067         local mdts=$(comma_list $(mdts_nodes))
3068
3069         # if we run against a 2.12 server which lacks overstring support
3070         # then the connect_flag will not report overstriping, even if client
3071         # is 2.14+
3072         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
3073                 stripe_opt="-C $setcount"
3074         elif (( $OSTCOUNT >= $setcount )); then
3075                 stripe_opt="-c $setcount"
3076         else
3077                 skip "server does not support overstriping"
3078         fi
3079
3080         test_mkdir $DIR/$tdir
3081
3082         # Validate existing append_* params and ensure restore
3083         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3084         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3085         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3086
3087         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3088         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
3089         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
3090
3091         $LFS setstripe $stripe_opt $DIR/$tdir
3092
3093         echo 1 > $DIR/$tdir/${tfile}.1
3094         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
3095         (( $count == $setcount )) ||
3096                 error "(1) stripe count $count, should be $setcount"
3097
3098         local appendcount=$orig_count
3099         echo 1 >> $DIR/$tdir/${tfile}.2_append
3100         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3101         (( $count == $appendcount )) ||
3102                 error "(2)stripe count $count, should be $appendcount for append"
3103
3104         # Disable O_APPEND striping, verify it works
3105         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3106
3107         # Should now get the default striping, which is 4
3108         setcount=4
3109         echo 1 >> $DIR/$tdir/${tfile}.3_append
3110         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3111         (( $count == $setcount )) ||
3112                 error "(3) stripe count $count, should be $setcount"
3113
3114         # Try changing the stripe count for append files
3115         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3116
3117         # Append striping is now 2 (directory default is still 4)
3118         appendcount=2
3119         echo 1 >> $DIR/$tdir/${tfile}.4_append
3120         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3121         (( $count == $appendcount )) ||
3122                 error "(4) stripe count $count, should be $appendcount for append"
3123
3124         # Test append stripe count of -1
3125         # Exercise LU-16872 patch with specific striping, only if MDS has fix
3126         (( $MDS1_VERSION > $(version_code 2.15.56.46) )) &&
3127                 $LFS setstripe -o 0,$((OSTCOUNT - 1)) $DIR/$tdir &&
3128                 touch $DIR/$tdir/$tfile.specific.{1..128}
3129         stack_trap "rm -f $DIR/$tdir/$tfile.*"
3130
3131         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3132         appendcount=$OSTCOUNT
3133         echo 1 >> $DIR/$tdir/${tfile}.5
3134         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3135         (( $count == $appendcount )) ||
3136                 error "(5) stripe count $count, should be $appendcount for append"
3137
3138         # Set append striping back to default of 1
3139         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3140
3141         # Try a new default striping, PFL + DOM
3142         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3143
3144         # Create normal DOM file, DOM returns stripe count == 0
3145         setcount=0
3146         touch $DIR/$tdir/${tfile}.6
3147         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3148         (( $count == $setcount )) ||
3149                 error "(6) stripe count $count, should be $setcount"
3150
3151         # Show
3152         appendcount=1
3153         echo 1 >> $DIR/$tdir/${tfile}.7_append
3154         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3155         (( $count == $appendcount )) ||
3156                 error "(7) stripe count $count, should be $appendcount for append"
3157
3158         # Clean up DOM layout
3159         $LFS setstripe -d $DIR/$tdir
3160
3161         save_layout_restore_at_exit $MOUNT
3162         # Now test that append striping works when layout is from root
3163         $LFS setstripe -c 2 $MOUNT
3164         # Make a special directory for this
3165         mkdir $DIR/${tdir}/${tdir}.2
3166
3167         # Verify for normal file
3168         setcount=2
3169         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3170         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3171         (( $count == $setcount )) ||
3172                 error "(8) stripe count $count, should be $setcount"
3173
3174         appendcount=1
3175         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3176         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3177         (( $count == $appendcount )) ||
3178                 error "(9) stripe count $count, should be $appendcount for append"
3179
3180         # Now test O_APPEND striping with pools
3181         pool_add $TESTNAME || error "pool creation failed"
3182         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3183         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3184
3185         echo 1 >> $DIR/$tdir/${tfile}.10_append
3186
3187         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3188         [[ "$pool" == "$TESTNAME" ]] || error "(10) incorrect pool: $pool"
3189
3190         # Check that count is still correct
3191         appendcount=1
3192         echo 1 >> $DIR/$tdir/${tfile}.11_append
3193         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3194         (( $count == $appendcount )) ||
3195                 error "(11) stripe count $count, should be $appendcount for append"
3196
3197         # Disable O_APPEND stripe count, verify pool works separately
3198         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3199
3200         echo 1 >> $DIR/$tdir/${tfile}.12_append
3201
3202         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3203         [[ "$pool" == "$TESTNAME" ]] || error "(12) incorrect pool: $pool"
3204
3205         # Remove pool setting, verify it's not applied
3206         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3207
3208         echo 1 >> $DIR/$tdir/${tfile}.13_append
3209
3210         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3211         [[ -z "$pool" ]] || error "(13) pool found: $pool"
3212 }
3213 run_test 27M "test O_APPEND striping"
3214
3215 test_27N() {
3216         combined_mgs_mds && skip "needs separate MGS/MDT"
3217
3218         pool_add $TESTNAME || error "pool_add failed"
3219         do_facet mgs "$LCTL pool_list $FSNAME" |
3220                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3221                 error "lctl pool_list on MGS failed"
3222 }
3223 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3224
3225 clean_foreign_symlink() {
3226         trap 0
3227         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3228         for i in $DIR/$tdir/* ; do
3229                 $LFS unlink_foreign $i || true
3230         done
3231 }
3232
3233 test_27O() {
3234         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3235                 skip "Need MDS version newer than 2.12.51"
3236
3237         test_mkdir $DIR/$tdir
3238         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3239         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3240
3241         trap clean_foreign_symlink EXIT
3242
3243         # enable foreign_symlink behaviour
3244         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3245
3246         # foreign symlink LOV format is a partial path by default
3247
3248         # create foreign file (lfs + API)
3249         $LFS setstripe --foreign=symlink --flags 0xda05 \
3250                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3251                 error "$DIR/$tdir/${tfile}: create failed"
3252
3253         $LFS getstripe -v $DIR/$tdir/${tfile} |
3254                 grep "lfm_magic:.*0x0BD70BD0" ||
3255                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3256         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3257                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3258         $LFS getstripe -v $DIR/$tdir/${tfile} |
3259                 grep "lfm_flags:.*0x0000DA05" ||
3260                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3261         $LFS getstripe $DIR/$tdir/${tfile} |
3262                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3263                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3264
3265         # modify striping should fail
3266         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3267                 error "$DIR/$tdir/$tfile: setstripe should fail"
3268
3269         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3270         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3271         cat /etc/passwd > $DIR/$tdir/$tfile &&
3272                 error "$DIR/$tdir/$tfile: write should fail"
3273
3274         # rename should succeed
3275         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3276                 error "$DIR/$tdir/$tfile: rename has failed"
3277
3278         #remove foreign_symlink file should fail
3279         rm $DIR/$tdir/${tfile}.new &&
3280                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3281
3282         #test fake symlink
3283         mkdir /tmp/${uuid1} ||
3284                 error "/tmp/${uuid1}: mkdir has failed"
3285         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3286                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3287         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3288         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3289                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3290         #read should succeed now
3291         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3292                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3293         #write should succeed now
3294         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3295                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3296         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3297                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3298         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3299                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3300
3301         #check that getstripe still works
3302         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3303                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3304
3305         # chmod should still succeed
3306         chmod 644 $DIR/$tdir/${tfile}.new ||
3307                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3308
3309         # chown should still succeed
3310         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3311                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3312
3313         # rename should still succeed
3314         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3315                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3316
3317         #remove foreign_symlink file should still fail
3318         rm $DIR/$tdir/${tfile} &&
3319                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3320
3321         #use special ioctl() to unlink foreign_symlink file
3322         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3323                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3324
3325 }
3326 run_test 27O "basic ops on foreign file of symlink type"
3327
3328 test_27P() {
3329         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3330                 skip "Need MDS version newer than 2.12.49"
3331
3332         test_mkdir $DIR/$tdir
3333         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3334         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3335
3336         trap clean_foreign_symlink EXIT
3337
3338         # enable foreign_symlink behaviour
3339         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3340
3341         # foreign symlink LMV format is a partial path by default
3342
3343         # create foreign dir (lfs + API)
3344         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3345                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3346                 error "$DIR/$tdir/${tdir}: create failed"
3347
3348         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3349
3350         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3351                 grep "lfm_magic:.*0x0CD50CD0" ||
3352                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3353         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3354                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3355         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3356                 grep "lfm_flags:.*0x0000DA05" ||
3357                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3358         $LFS getdirstripe $DIR/$tdir/${tdir} |
3359                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3360                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3361
3362         # file create in dir should fail
3363         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3364         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3365
3366         # rename should succeed
3367         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3368                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3369
3370         #remove foreign_symlink dir should fail
3371         rmdir $DIR/$tdir/${tdir}.new &&
3372                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3373
3374         #test fake symlink
3375         mkdir -p /tmp/${uuid1}/${uuid2} ||
3376                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3377         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3378                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3379         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3380         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3381                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3382         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3383                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3384
3385         #check that getstripe fails now that foreign_symlink enabled
3386         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3387                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3388
3389         # file create in dir should work now
3390         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3391                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3392         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3393                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3394         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3395                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3396
3397         # chmod should still succeed
3398         chmod 755 $DIR/$tdir/${tdir}.new ||
3399                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3400
3401         # chown should still succeed
3402         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3403                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3404
3405         # rename should still succeed
3406         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3407                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3408
3409         #remove foreign_symlink dir should still fail
3410         rmdir $DIR/$tdir/${tdir} &&
3411                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3412
3413         #use special ioctl() to unlink foreign_symlink file
3414         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3415                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3416
3417         #created file should still exist
3418         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3419                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3420         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3421                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3422 }
3423 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3424
3425 test_27Q() {
3426         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3427         stack_trap "rm -f $TMP/$tfile*"
3428
3429         test_mkdir $DIR/$tdir-1
3430         test_mkdir $DIR/$tdir-2
3431
3432         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3433         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3434
3435         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3436         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3437
3438         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3439         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3440
3441         # Create some bad symlinks and ensure that we don't loop
3442         # forever or something. These should return ELOOP (40) and
3443         # ENOENT (2) but I don't want to test for that because there's
3444         # always some weirdo architecture that needs to ruin
3445         # everything by defining these error numbers differently.
3446
3447         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3448         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3449
3450         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3451         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3452
3453         return 0
3454 }
3455 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3456
3457 test_27R() {
3458         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3459                 skip "need MDS 2.14.55 or later"
3460         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3461
3462         local testdir="$DIR/$tdir"
3463         test_mkdir -p $testdir
3464         stack_trap "rm -rf $testdir"
3465         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3466
3467         local f1="$testdir/f1"
3468         touch $f1 || error "failed to touch $f1"
3469         local count=$($LFS getstripe -c $f1)
3470         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3471
3472         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3473         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3474
3475         local maxcount=$(($OSTCOUNT - 1))
3476         local mdts=$(comma_list $(mdts_nodes))
3477         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3478         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3479
3480         local f2="$testdir/f2"
3481         touch $f2 || error "failed to touch $f2"
3482         local count=$($LFS getstripe -c $f2)
3483         (( $count == $maxcount )) || error "wrong stripe count"
3484 }
3485 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3486
3487 test_27T() {
3488         [ $(facet_host client) == $(facet_host ost1) ] &&
3489                 skip "need ost1 and client on different nodes"
3490
3491 #define OBD_FAIL_OSC_NO_GRANT            0x411
3492         $LCTL set_param fail_loc=0x20000411 fail_val=1
3493 #define OBD_FAIL_OST_ENOSPC              0x215
3494         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3495         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3496         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3497                 error "multiop failed"
3498 }
3499 run_test 27T "no eio on close on partial write due to enosp"
3500
3501 test_27U() {
3502         local dir=$DIR/$tdir
3503         local file=$dir/$tfile
3504         local append_pool=${TESTNAME}-append
3505         local normal_pool=${TESTNAME}-normal
3506         local pool
3507         local stripe_count
3508         local stripe_count2
3509         local mdts=$(comma_list $(mdts_nodes))
3510
3511         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
3512                 skip "Need MDS version at least 2.15.51 for append pool feature"
3513
3514         # Validate existing append_* params and ensure restore
3515         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3516         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3517         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3518
3519         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3520         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3521         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3522
3523         pool_add $append_pool || error "pool creation failed"
3524         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3525
3526         pool_add $normal_pool || error "pool creation failed"
3527         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3528
3529         test_mkdir $dir
3530         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3531
3532         echo XXX >> $file.1
3533         $LFS getstripe $file.1
3534
3535         pool=$($LFS getstripe -p $file.1)
3536         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3537
3538         stripe_count2=$($LFS getstripe -c $file.1)
3539         ((stripe_count2 == stripe_count)) ||
3540                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3541
3542         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3543
3544         echo XXX >> $file.2
3545         $LFS getstripe $file.2
3546
3547         pool=$($LFS getstripe -p $file.2)
3548         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3549
3550         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3551
3552         echo XXX >> $file.3
3553         $LFS getstripe $file.3
3554
3555         stripe_count2=$($LFS getstripe -c $file.3)
3556         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3557 }
3558 run_test 27U "append pool and stripe count work with composite default layout"
3559
3560 test_27V() {
3561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3562         (( $OSTCOUNT >= 4 )) || skip_env "needs >= 4 OSTs"
3563
3564         local dir=$DIR/$tdir
3565         local osp_param=osp.$FSNAME-OST0000-osc-MDT0000.max_create_count
3566         local lod_param=lod.$FSNAME-MDT0000-mdtlov.qos_threshold_rr
3567         local saved_max=$(do_facet mds1 $LCTL get_param -n $osp_param)
3568         local saved_qos=$(do_facet mds1 $LCTL get_param -n $lod_param)
3569         local pid
3570
3571         stack_trap "do_facet mds1 $LCTL set_param $osp_param=$saved_max"
3572
3573         do_facet mds1 $LCTL set_param $lod_param=0
3574         stack_trap "do_facet mds1 $LCTL set_param $lod_param=$saved_qos"
3575
3576         $LFS setdirstripe --mdt-count=1 --mdt-index=0 $dir
3577         stack_trap "rm -rf $dir"
3578
3579         # exercise race in LU-16981 with deactivating OST while creating a file
3580         (
3581                 while true; do
3582                         do_facet mds1 $LCTL set_param $osp_param=0 > /dev/null
3583                         sleep 0.1
3584                         do_facet mds1 \
3585                                 $LCTL set_param $osp_param=$saved_max > /dev/null
3586                 done
3587         ) &
3588
3589         pid=$!
3590         stack_trap "kill -9 $pid"
3591
3592         # errors here are OK so ignore them (just don't want to crash)
3593         $LFS setstripe -c -1 $dir/f.{1..200} 2> /dev/null
3594
3595         return 0
3596 }
3597 run_test 27V "creating widely striped file races with deactivating OST"
3598
3599 # createtest also checks that device nodes are created and
3600 # then visible correctly (#2091)
3601 test_28() { # bug 2091
3602         test_mkdir $DIR/d28
3603         $CREATETEST $DIR/d28/ct || error "createtest failed"
3604 }
3605 run_test 28 "create/mknod/mkdir with bad file types ============"
3606
3607 test_29() {
3608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3609
3610         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3611                 disable_opencache
3612                 stack_trap "restore_opencache"
3613         }
3614
3615         sync; sleep 1; sync # flush out any dirty pages from previous tests
3616         cancel_lru_locks
3617         test_mkdir $DIR/d29
3618         touch $DIR/d29/foo
3619         log 'first d29'
3620         ls -l $DIR/d29
3621
3622         local locks_orig=$(total_used_locks mdc)
3623         (( $locks_orig != 0 )) || error "No mdc lock count"
3624
3625         local locks_unused_orig=$(total_unused_locks mdc)
3626
3627         log 'second d29'
3628         ls -l $DIR/d29
3629         log 'done'
3630
3631         local locks_current=$(total_used_locks mdc)
3632
3633         local locks_unused_current=$(total_unused_locks mdc)
3634
3635         if (( $locks_current > $locks_orig )); then
3636                 $LCTL set_param -n ldlm.dump_namespaces ""
3637                 error "CURRENT: $locks_current > $locks_orig"
3638         fi
3639         if (( $locks_unused_current > $locks_unused_orig )); then
3640                 error "UNUSED: $locks_unused_current > $locks_unused_orig"
3641         fi
3642 }
3643 run_test 29 "IT_GETATTR regression  ============================"
3644
3645 test_30a() { # was test_30
3646         cp $(which ls) $DIR || cp /bin/ls $DIR
3647         $DIR/ls / || error "Can't execute binary from lustre"
3648         rm $DIR/ls
3649 }
3650 run_test 30a "execute binary from Lustre (execve) =============="
3651
3652 test_30b() {
3653         cp `which ls` $DIR || cp /bin/ls $DIR
3654         chmod go+rx $DIR/ls
3655         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3656         rm $DIR/ls
3657 }
3658 run_test 30b "execute binary from Lustre as non-root ==========="
3659
3660 test_30c() { # b=22376
3661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3662
3663         cp $(which ls) $DIR || cp /bin/ls $DIR
3664         chmod a-rw $DIR/ls
3665         cancel_lru_locks mdc
3666         cancel_lru_locks osc
3667         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3668         rm -f $DIR/ls
3669 }
3670 run_test 30c "execute binary from Lustre without read perms ===="
3671
3672 test_30d() {
3673         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3674
3675         for i in {1..10}; do
3676                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3677                 local PID=$!
3678                 sleep 1
3679                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3680                 wait $PID || error "executing dd from Lustre failed"
3681                 rm -f $DIR/$tfile
3682         done
3683
3684         rm -f $DIR/dd
3685 }
3686 run_test 30d "execute binary from Lustre while clear locks"
3687
3688 test_31a() {
3689         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3690         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3691 }
3692 run_test 31a "open-unlink file =================================="
3693
3694 test_31b() {
3695         touch $DIR/f31 || error "touch $DIR/f31 failed"
3696         ln $DIR/f31 $DIR/f31b || error "ln failed"
3697         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3698         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3699 }
3700 run_test 31b "unlink file with multiple links while open ======="
3701
3702 test_31c() {
3703         touch $DIR/f31 || error "touch $DIR/f31 failed"
3704         ln $DIR/f31 $DIR/f31c || error "ln failed"
3705         multiop_bg_pause $DIR/f31 O_uc ||
3706                 error "multiop_bg_pause for $DIR/f31 failed"
3707         MULTIPID=$!
3708         $MULTIOP $DIR/f31c Ouc
3709         kill -USR1 $MULTIPID
3710         wait $MULTIPID
3711 }
3712 run_test 31c "open-unlink file with multiple links ============="
3713
3714 test_31d() {
3715         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3716         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3717 }
3718 run_test 31d "remove of open directory ========================="
3719
3720 test_31e() { # bug 2904
3721         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3722 }
3723 run_test 31e "remove of open non-empty directory ==============="
3724
3725 test_31f() { # bug 4554
3726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3727
3728         set -vx
3729         test_mkdir $DIR/d31f
3730         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3731         cp /etc/hosts $DIR/d31f
3732         ls -l $DIR/d31f
3733         $LFS getstripe $DIR/d31f/hosts
3734         multiop_bg_pause $DIR/d31f D_c || return 1
3735         MULTIPID=$!
3736
3737         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3738         test_mkdir $DIR/d31f
3739         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3740         cp /etc/hosts $DIR/d31f
3741         ls -l $DIR/d31f
3742         $LFS getstripe $DIR/d31f/hosts
3743         multiop_bg_pause $DIR/d31f D_c || return 1
3744         MULTIPID2=$!
3745
3746         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3747         wait $MULTIPID || error "first opendir $MULTIPID failed"
3748
3749         sleep 6
3750
3751         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3752         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3753         set +vx
3754 }
3755 run_test 31f "remove of open directory with open-unlink file ==="
3756
3757 test_31g() {
3758         echo "-- cross directory link --"
3759         test_mkdir -c1 $DIR/${tdir}ga
3760         test_mkdir -c1 $DIR/${tdir}gb
3761         touch $DIR/${tdir}ga/f
3762         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3763         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3764         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3765         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3766         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3767 }
3768 run_test 31g "cross directory link==============="
3769
3770 test_31h() {
3771         echo "-- cross directory link --"
3772         test_mkdir -c1 $DIR/${tdir}
3773         test_mkdir -c1 $DIR/${tdir}/dir
3774         touch $DIR/${tdir}/f
3775         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3776         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3777         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3778         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3779         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3780 }
3781 run_test 31h "cross directory link under child==============="
3782
3783 test_31i() {
3784         echo "-- cross directory link --"
3785         test_mkdir -c1 $DIR/$tdir
3786         test_mkdir -c1 $DIR/$tdir/dir
3787         touch $DIR/$tdir/dir/f
3788         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3789         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3790         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3791         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3792         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3793 }
3794 run_test 31i "cross directory link under parent==============="
3795
3796 test_31j() {
3797         test_mkdir -c1 -p $DIR/$tdir
3798         test_mkdir -c1 -p $DIR/$tdir/dir1
3799         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3800         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3801         link $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "link to the same dir"
3802         return 0
3803 }
3804 run_test 31j "link for directory"
3805
3806 test_31k() {
3807         test_mkdir -c1 -p $DIR/$tdir
3808         touch $DIR/$tdir/s
3809         touch $DIR/$tdir/exist
3810         link $DIR/$tdir/s $DIR/$tdir/t || error "link"
3811         link $DIR/$tdir/s $DIR/$tdir/exist && error "link to exist file"
3812         link $DIR/$tdir/s $DIR/$tdir/s && error "link to the same file"
3813         link $DIR/$tdir/s $DIR/$tdir && error "link to parent dir"
3814         link $DIR/$tdir $DIR/$tdir/s && error "link parent dir to target"
3815         link $DIR/$tdir/not-exist $DIR/$tdir/foo && error "link non-existing to new"
3816         link $DIR/$tdir/not-exist $DIR/$tdir/s && error "link non-existing to exist"
3817         return 0
3818 }
3819 run_test 31k "link to file: the same, non-existing, dir"
3820
3821 test_31l() {
3822         local ln_ver=$(ln --version | awk '/coreutils/ { print $4 }')
3823
3824         (( $(version_code $ln_ver) < $(version_code 8.31) )) ||
3825         (( $(version_code $(uname -r)) >= $(version_code 5.18) )) ||
3826                 skip "need coreutils < 8.31 or kernel >= 5.18 for ln"
3827
3828         touch $DIR/$tfile || error "create failed"
3829         mkdir $DIR/$tdir || error "mkdir failed"
3830         ln $DIR/$tfile $DIR/$tdir/ || error "ln to '$tdir/' failed"
3831 }
3832 run_test 31l "link to file: target dir has trailing slash"
3833
3834 test_31m() {
3835         mkdir $DIR/d31m
3836         touch $DIR/d31m/s
3837         mkdir $DIR/d31m2
3838         touch $DIR/d31m2/exist
3839         link $DIR/d31m/s $DIR/d31m2/t || error "link"
3840         link $DIR/d31m/s $DIR/d31m2/exist && error "link to exist file"
3841         link $DIR/d31m/s $DIR/d31m2 && error "link to parent dir"
3842         link $DIR/d31m2 $DIR/d31m/s && error "link parent dir to target"
3843         link $DIR/d31m/not-exist $DIR/d31m2/foo && error "link non-existing to new"
3844         link $DIR/d31m/not-exist $DIR/d31m2/s && error "link non-existing to exist"
3845         return 0
3846 }
3847 run_test 31m "link to file: the same, non-existing, dir"
3848
3849 test_31n() {
3850         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3851         nlink=$(stat --format=%h $DIR/$tfile)
3852         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3853         local fd=$(free_fd)
3854         local cmd="exec $fd<$DIR/$tfile"
3855         eval $cmd
3856         cmd="exec $fd<&-"
3857         trap "eval $cmd" EXIT
3858         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3859         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3860         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3861         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3862         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3863         eval $cmd
3864 }
3865 run_test 31n "check link count of unlinked file"
3866
3867 link_one() {
3868         local tempfile=$(mktemp $1_XXXXXX)
3869         link $tempfile $1 2> /dev/null &&
3870                 echo "$BASHPID: link $tempfile to $1 succeeded"
3871         unlink $tempfile
3872 }
3873
3874 test_31o() { # LU-2901
3875         test_mkdir $DIR/$tdir
3876         for LOOP in $(seq 100); do
3877                 rm -f $DIR/$tdir/$tfile*
3878                 for THREAD in $(seq 8); do
3879                         link_one $DIR/$tdir/$tfile.$LOOP &
3880                 done
3881                 wait
3882                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3883                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3884                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3885                         break || true
3886         done
3887 }
3888 run_test 31o "duplicate hard links with same filename"
3889
3890 test_31p() {
3891         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3892
3893         test_mkdir $DIR/$tdir
3894         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3895         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3896
3897         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3898                 error "open unlink test1 failed"
3899         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3900                 error "open unlink test2 failed"
3901
3902         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3903                 error "test1 still exists"
3904         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3905                 error "test2 still exists"
3906 }
3907 run_test 31p "remove of open striped directory"
3908
3909 test_31q() {
3910         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3911
3912         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3913         index=$($LFS getdirstripe -i $DIR/$tdir)
3914         [ $index -eq 3 ] || error "first stripe index $index != 3"
3915         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3916         [ $index -eq 1 ] || error "second stripe index $index != 1"
3917
3918         # when "-c <stripe_count>" is set, the number of MDTs specified after
3919         # "-i" should equal to the stripe count
3920         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3921 }
3922 run_test 31q "create striped directory on specific MDTs"
3923
3924 #LU-14949
3925 test_31r() {
3926         touch $DIR/$tfile.target
3927         touch $DIR/$tfile.source
3928
3929         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3930         $LCTL set_param fail_loc=0x1419 fail_val=3
3931         cat $DIR/$tfile.target &
3932         CATPID=$!
3933
3934         # Guarantee open is waiting before we get here
3935         sleep 1
3936         mv $DIR/$tfile.source $DIR/$tfile.target
3937
3938         wait $CATPID
3939         RC=$?
3940         if [[ $RC -ne 0 ]]; then
3941                 error "open with cat failed, rc=$RC"
3942         fi
3943 }
3944 run_test 31r "open-rename(replace) race"
3945
3946 cleanup_test32_mount() {
3947         local rc=0
3948         trap 0
3949         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3950         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3951         losetup -d $loopdev || true
3952         rm -rf $DIR/$tdir
3953         return $rc
3954 }
3955
3956 test_32a() {
3957         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3958
3959         echo "== more mountpoints and symlinks ================="
3960         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3961         trap cleanup_test32_mount EXIT
3962         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3963         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3964                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3965         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3966                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3967         cleanup_test32_mount
3968 }
3969 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3970
3971 test_32b() {
3972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3973
3974         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3975         trap cleanup_test32_mount EXIT
3976         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3977         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3978                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3979         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3980                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3981         cleanup_test32_mount
3982 }
3983 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3984
3985 test_32c() {
3986         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3987
3988         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3989         trap cleanup_test32_mount EXIT
3990         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3991         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3992                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3993         test_mkdir -p $DIR/$tdir/d2/test_dir
3994         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3995                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3996         cleanup_test32_mount
3997 }
3998 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3999
4000 test_32d() {
4001         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4002
4003         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4004         trap cleanup_test32_mount EXIT
4005         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4006         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4007                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4008         test_mkdir -p $DIR/$tdir/d2/test_dir
4009         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
4010                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
4011         cleanup_test32_mount
4012 }
4013 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
4014
4015 test_32e() {
4016         rm -fr $DIR/$tdir
4017         test_mkdir -p $DIR/$tdir/tmp
4018         local tmp_dir=$DIR/$tdir/tmp
4019         ln -s $DIR/$tdir $tmp_dir/symlink11
4020         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
4021         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
4022         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
4023 }
4024 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
4025
4026 test_32f() {
4027         rm -fr $DIR/$tdir
4028         test_mkdir -p $DIR/$tdir/tmp
4029         local tmp_dir=$DIR/$tdir/tmp
4030         ln -s $DIR/$tdir $tmp_dir/symlink11
4031         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
4032         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
4033         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
4034 }
4035 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
4036
4037 test_32g() {
4038         local tmp_dir=$DIR/$tdir/tmp
4039         test_mkdir -p $tmp_dir
4040         test_mkdir $DIR/${tdir}2
4041         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
4042         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
4043         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
4044         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
4045         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
4046         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
4047 }
4048 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
4049
4050 test_32h() {
4051         rm -fr $DIR/$tdir $DIR/${tdir}2
4052         tmp_dir=$DIR/$tdir/tmp
4053         test_mkdir -p $tmp_dir
4054         test_mkdir $DIR/${tdir}2
4055         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
4056         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
4057         ls $tmp_dir/symlink12 || error "listing symlink12"
4058         ls $DIR/$tdir/symlink02  || error "listing symlink02"
4059 }
4060 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
4061
4062 test_32i() {
4063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4064
4065         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4066         trap cleanup_test32_mount EXIT
4067         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4068         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4069                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4070         touch $DIR/$tdir/test_file
4071         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
4072                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
4073         cleanup_test32_mount
4074 }
4075 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
4076
4077 test_32j() {
4078         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4079
4080         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4081         trap cleanup_test32_mount EXIT
4082         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4083         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4084                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4085         touch $DIR/$tdir/test_file
4086         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
4087                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
4088         cleanup_test32_mount
4089 }
4090 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
4091
4092 test_32k() {
4093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4094
4095         rm -fr $DIR/$tdir
4096         trap cleanup_test32_mount EXIT
4097         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4098         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4099                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4100         test_mkdir -p $DIR/$tdir/d2
4101         touch $DIR/$tdir/d2/test_file || error "touch failed"
4102         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4103                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
4104         cleanup_test32_mount
4105 }
4106 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
4107
4108 test_32l() {
4109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4110
4111         rm -fr $DIR/$tdir
4112         trap cleanup_test32_mount EXIT
4113         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4114         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4115                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4116         test_mkdir -p $DIR/$tdir/d2
4117         touch $DIR/$tdir/d2/test_file || error "touch failed"
4118         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4119                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
4120         cleanup_test32_mount
4121 }
4122 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
4123
4124 test_32m() {
4125         rm -fr $DIR/d32m
4126         test_mkdir -p $DIR/d32m/tmp
4127         TMP_DIR=$DIR/d32m/tmp
4128         ln -s $DIR $TMP_DIR/symlink11
4129         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4130         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
4131                 error "symlink11 not a link"
4132         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
4133                 error "symlink01 not a link"
4134 }
4135 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
4136
4137 test_32n() {
4138         rm -fr $DIR/d32n
4139         test_mkdir -p $DIR/d32n/tmp
4140         TMP_DIR=$DIR/d32n/tmp
4141         ln -s $DIR $TMP_DIR/symlink11
4142         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4143         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4144         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4145 }
4146 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4147
4148 test_32o() {
4149         touch $DIR/$tfile
4150         test_mkdir -p $DIR/d32o/tmp
4151         TMP_DIR=$DIR/d32o/tmp
4152         ln -s $DIR/$tfile $TMP_DIR/symlink12
4153         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4154         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4155                 error "symlink12 not a link"
4156         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4157         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4158                 error "$DIR/d32o/tmp/symlink12 not file type"
4159         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4160                 error "$DIR/d32o/symlink02 not file type"
4161 }
4162 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4163
4164 test_32p() {
4165         log 32p_1
4166         rm -fr $DIR/d32p
4167         log 32p_2
4168         rm -f $DIR/$tfile
4169         log 32p_3
4170         touch $DIR/$tfile
4171         log 32p_4
4172         test_mkdir -p $DIR/d32p/tmp
4173         log 32p_5
4174         TMP_DIR=$DIR/d32p/tmp
4175         log 32p_6
4176         ln -s $DIR/$tfile $TMP_DIR/symlink12
4177         log 32p_7
4178         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4179         log 32p_8
4180         cat $DIR/d32p/tmp/symlink12 ||
4181                 error "Can't open $DIR/d32p/tmp/symlink12"
4182         log 32p_9
4183         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4184         log 32p_10
4185 }
4186 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4187
4188 test_32q() {
4189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4190
4191         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4192         trap cleanup_test32_mount EXIT
4193         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4194         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4195         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4196                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4197         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4198         cleanup_test32_mount
4199 }
4200 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4201
4202 test_32r() {
4203         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4204
4205         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4206         trap cleanup_test32_mount EXIT
4207         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4208         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4209         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4210                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4211         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4212         cleanup_test32_mount
4213 }
4214 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4215
4216 test_33aa() {
4217         rm -f $DIR/$tfile
4218         touch $DIR/$tfile
4219         chmod 444 $DIR/$tfile
4220         chown $RUNAS_ID $DIR/$tfile
4221         log 33_1
4222         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4223         log 33_2
4224 }
4225 run_test 33aa "write file with mode 444 (should return error)"
4226
4227 test_33a() {
4228         rm -fr $DIR/$tdir
4229         test_mkdir $DIR/$tdir
4230         chown $RUNAS_ID $DIR/$tdir
4231         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4232                 error "$RUNAS create $tdir/$tfile failed"
4233         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4234                 error "open RDWR" || true
4235 }
4236 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4237
4238 test_33b() {
4239         rm -fr $DIR/$tdir
4240         test_mkdir $DIR/$tdir
4241         chown $RUNAS_ID $DIR/$tdir
4242         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4243 }
4244 run_test 33b "test open file with malformed flags (No panic)"
4245
4246 test_33c() {
4247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4248         remote_ost_nodsh && skip "remote OST with nodsh"
4249
4250         local ostnum
4251         local ostname
4252         local write_bytes
4253         local all_zeros
4254
4255         all_zeros=true
4256         test_mkdir $DIR/$tdir
4257         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4258
4259         sync
4260         for ostnum in $(seq $OSTCOUNT); do
4261                 # test-framework's OST numbering is one-based, while Lustre's
4262                 # is zero-based
4263                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4264                 # check if at least some write_bytes stats are counted
4265                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4266                               obdfilter.$ostname.stats |
4267                               awk '/^write_bytes/ {print $7}' )
4268                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4269                 if (( ${write_bytes:-0} > 0 )); then
4270                         all_zeros=false
4271                         break
4272                 fi
4273         done
4274
4275         $all_zeros || return 0
4276
4277         # Write four bytes
4278         echo foo > $DIR/$tdir/bar
4279         # Really write them
4280         sync
4281
4282         # Total up write_bytes after writing.  We'd better find non-zeros.
4283         for ostnum in $(seq $OSTCOUNT); do
4284                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4285                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4286                               obdfilter/$ostname/stats |
4287                               awk '/^write_bytes/ {print $7}' )
4288                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4289                 if (( ${write_bytes:-0} > 0 )); then
4290                         all_zeros=false
4291                         break
4292                 fi
4293         done
4294
4295         if $all_zeros; then
4296                 for ostnum in $(seq $OSTCOUNT); do
4297                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4298                         echo "Check write_bytes is in obdfilter.*.stats:"
4299                         do_facet ost$ostnum lctl get_param -n \
4300                                 obdfilter.$ostname.stats
4301                 done
4302                 error "OST not keeping write_bytes stats (b=22312)"
4303         fi
4304 }
4305 run_test 33c "test write_bytes stats"
4306
4307 test_33d() {
4308         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4309         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4310
4311         local MDTIDX=1
4312         local remote_dir=$DIR/$tdir/remote_dir
4313
4314         test_mkdir $DIR/$tdir
4315         $LFS mkdir -i $MDTIDX $remote_dir ||
4316                 error "create remote directory failed"
4317
4318         touch $remote_dir/$tfile
4319         chmod 444 $remote_dir/$tfile
4320         chown $RUNAS_ID $remote_dir/$tfile
4321
4322         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4323
4324         chown $RUNAS_ID $remote_dir
4325         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4326                                         error "create" || true
4327         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4328                                     error "open RDWR" || true
4329         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4330 }
4331 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4332
4333 test_33e() {
4334         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4335
4336         mkdir $DIR/$tdir
4337
4338         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4339         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4340         mkdir $DIR/$tdir/local_dir
4341
4342         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4343         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4344         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4345
4346         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4347                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4348
4349         rmdir $DIR/$tdir/* || error "rmdir failed"
4350
4351         umask 777
4352         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4353         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4354         mkdir $DIR/$tdir/local_dir
4355
4356         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4357         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4358         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4359
4360         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4361                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4362
4363         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4364
4365         umask 000
4366         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4367         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4368         mkdir $DIR/$tdir/local_dir
4369
4370         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4371         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4372         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4373
4374         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4375                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4376 }
4377 run_test 33e "mkdir and striped directory should have same mode"
4378
4379 cleanup_33f() {
4380         trap 0
4381         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4382 }
4383
4384 test_33f() {
4385         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4386         remote_mds_nodsh && skip "remote MDS with nodsh"
4387
4388         mkdir $DIR/$tdir
4389         chmod go+rwx $DIR/$tdir
4390         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4391         trap cleanup_33f EXIT
4392
4393         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4394                 error "cannot create striped directory"
4395
4396         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4397                 error "cannot create files in striped directory"
4398
4399         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4400                 error "cannot remove files in striped directory"
4401
4402         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4403                 error "cannot remove striped directory"
4404
4405         cleanup_33f
4406 }
4407 run_test 33f "nonroot user can create, access, and remove a striped directory"
4408
4409 test_33g() {
4410         mkdir -p $DIR/$tdir/dir2
4411
4412         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4413         echo $err
4414         [[ $err =~ "exists" ]] || error "Not exists error"
4415 }
4416 run_test 33g "nonroot user create already existing root created file"
4417
4418 sub_33h() {
4419         local hash_type=$1
4420         local count=250
4421
4422         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4423                 error "lfs mkdir -H $hash_type $tdir failed"
4424         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4425
4426         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4427         local index2
4428         local fname
4429
4430         for fname in $DIR/$tdir/$tfile.bak \
4431                      $DIR/$tdir/$tfile.SAV \
4432                      $DIR/$tdir/$tfile.orig \
4433                      $DIR/$tdir/$tfile~; do
4434                 touch $fname || error "touch $fname failed"
4435                 index2=$($LFS getstripe -m $fname)
4436                 (( $index == $index2 )) ||
4437                         error "$fname MDT index mismatch $index != $index2"
4438         done
4439
4440         local failed=0
4441         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4442         local pattern
4443
4444         for pattern in ${patterns[*]}; do
4445                 echo "pattern $pattern"
4446                 fname=$DIR/$tdir/$pattern
4447                 for (( i = 0; i < $count; i++ )); do
4448                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4449                                 error "mktemp $DIR/$tdir/$pattern failed"
4450                         index2=$($LFS getstripe -m $fname)
4451                         (( $index == $index2 )) && continue
4452
4453                         failed=$((failed + 1))
4454                         echo "$fname MDT index mismatch $index != $index2"
4455                 done
4456         done
4457
4458         echo "$failed/$count MDT index mismatches, expect ~2-4"
4459         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4460
4461         local same=0
4462         local expect
4463
4464         # verify that "crush" is still broken with all files on same MDT,
4465         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4466         [[ "$hash_type" == "crush" ]] && expect=$count ||
4467                 expect=$((count / MDSCOUNT))
4468
4469         # crush2 doesn't put all-numeric suffixes on the same MDT,
4470         # filename like $tfile.12345678 should *not* be considered temp
4471         for pattern in ${patterns[*]}; do
4472                 local base=${pattern%%X*}
4473                 local suff=${pattern#$base}
4474
4475                 echo "pattern $pattern"
4476                 for (( i = 0; i < $count; i++ )); do
4477                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4478                         touch $fname || error "touch $fname failed"
4479                         index2=$($LFS getstripe -m $fname)
4480                         (( $index != $index2 )) && continue
4481
4482                         same=$((same + 1))
4483                 done
4484         done
4485
4486         # the number of "bad" hashes is random, as it depends on the random
4487         # filenames generated by "mktemp".  Allow some margin in the results.
4488         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4489         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4490            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4491                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4492         same=0
4493
4494         # crush2 doesn't put suffixes with special characters on the same MDT
4495         # filename like $tfile.txt.1234 should *not* be considered temp
4496         for pattern in ${patterns[*]}; do
4497                 local base=${pattern%%X*}
4498                 local suff=${pattern#$base}
4499
4500                 pattern=$base...${suff/XXX}
4501                 echo "pattern=$pattern"
4502                 for (( i = 0; i < $count; i++ )); do
4503                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4504                                 error "touch $fname failed"
4505                         index2=$($LFS getstripe -m $fname)
4506                         (( $index != $index2 )) && continue
4507
4508                         same=$((same + 1))
4509                 done
4510         done
4511
4512         # the number of "bad" hashes is random, as it depends on the random
4513         # filenames generated by "mktemp".  Allow some margin in the results.
4514         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4515         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4516            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4517                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4518 }
4519
4520 test_33h() {
4521         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4522         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4523                 skip "Need MDS version at least 2.13.50"
4524
4525         sub_33h crush
4526 }
4527 run_test 33h "temp file is located on the same MDT as target (crush)"
4528
4529 test_33hh() {
4530         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4531         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4532         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4533                 skip "Need MDS version at least 2.15.0 for crush2"
4534
4535         sub_33h crush2
4536 }
4537 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4538
4539 test_33i()
4540 {
4541         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4542
4543         local FNAME=$(str_repeat 'f' 250)
4544
4545         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4546         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4547
4548         local count
4549         local total
4550
4551         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4552
4553         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4554
4555         lctl --device %$MDC deactivate
4556         stack_trap "lctl --device %$MDC activate"
4557         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4558         total=$(\ls -l $DIR/$tdir | wc -l)
4559         # "ls -l" will list total in the first line
4560         total=$((total - 1))
4561         (( total + count == 1000 )) ||
4562                 error "ls list $total files, $count files on MDT1"
4563 }
4564 run_test 33i "striped directory can be accessed when one MDT is down"
4565
4566 test_33j() {
4567         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4568
4569         mkdir -p $DIR/$tdir/
4570
4571         $LFS setdirstripe -D -i0,1 $DIR/$tdir/striped_dir_a &&
4572                 error "setdirstripe -D -i0,1 incorrectly succeeded"
4573
4574         $LFS setdirstripe -D -i0,1 -c1 $DIR/$tdir/striped_dir_b &&
4575                 error "setdirstripe -D -i0,1 -c1 incorrectly succeeded"
4576
4577         $LFS setdirstripe -D -i0,1 -c3 $DIR/$tdir/striped_dir_c &&
4578                 error "setdirstripe -D -i0,1 -c3 incorrectly succeeded"
4579
4580         $LFS setdirstripe -i0,1 $DIR/$tdir/striped_dir_e ||
4581                 error "-D was not specified, but still failed"
4582 }
4583 run_test 33j "lfs setdirstripe -D -i x,y,x should fail"
4584
4585 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4586 test_34a() {
4587         rm -f $DIR/f34
4588         $MCREATE $DIR/f34 || error "mcreate failed"
4589         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4590                 error "getstripe failed"
4591         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4592         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4593                 error "getstripe failed"
4594         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4595                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4596 }
4597 run_test 34a "truncate file that has not been opened ==========="
4598
4599 test_34b() {
4600         [ ! -f $DIR/f34 ] && test_34a
4601         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4602                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4603         $OPENFILE -f O_RDONLY $DIR/f34
4604         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4605                 error "getstripe failed"
4606         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4607                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4608 }
4609 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4610
4611 test_34c() {
4612         [ ! -f $DIR/f34 ] && test_34a
4613         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4614                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4615         $OPENFILE -f O_RDWR $DIR/f34
4616         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4617                 error "$LFS getstripe failed"
4618         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4619                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4620 }
4621 run_test 34c "O_RDWR opening file-with-size works =============="
4622
4623 test_34d() {
4624         [ ! -f $DIR/f34 ] && test_34a
4625         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4626                 error "dd failed"
4627         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4628                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4629         rm $DIR/f34
4630 }
4631 run_test 34d "write to sparse file ============================="
4632
4633 test_34e() {
4634         rm -f $DIR/f34e
4635         $MCREATE $DIR/f34e || error "mcreate failed"
4636         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4637         $CHECKSTAT -s 1000 $DIR/f34e ||
4638                 error "Size of $DIR/f34e not equal to 1000 bytes"
4639         $OPENFILE -f O_RDWR $DIR/f34e
4640         $CHECKSTAT -s 1000 $DIR/f34e ||
4641                 error "Size of $DIR/f34e not equal to 1000 bytes"
4642 }
4643 run_test 34e "create objects, some with size and some without =="
4644
4645 test_34f() { # bug 6242, 6243
4646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4647
4648         SIZE34F=48000
4649         rm -f $DIR/f34f
4650         $MCREATE $DIR/f34f || error "mcreate failed"
4651         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4652         dd if=$DIR/f34f of=$TMP/f34f
4653         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4654         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4655         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4656         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4657         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4658 }
4659 run_test 34f "read from a file with no objects until EOF ======="
4660
4661 test_34g() {
4662         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4663
4664         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4665                 error "dd failed"
4666         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4667         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4668                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4669         cancel_lru_locks osc
4670         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4671                 error "wrong size after lock cancel"
4672
4673         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4674         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4675                 error "expanding truncate failed"
4676         cancel_lru_locks osc
4677         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4678                 error "wrong expanded size after lock cancel"
4679 }
4680 run_test 34g "truncate long file ==============================="
4681
4682 test_34h() {
4683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4684
4685         local gid=10
4686         local sz=1000
4687
4688         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4689         sync # Flush the cache so that multiop below does not block on cache
4690              # flush when getting the group lock
4691         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4692         MULTIPID=$!
4693
4694         # Since just timed wait is not good enough, let's do a sync write
4695         # that way we are sure enough time for a roundtrip + processing
4696         # passed + 2 seconds of extra margin.
4697         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4698         rm $DIR/${tfile}-1
4699         sleep 2
4700
4701         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4702                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4703                 kill -9 $MULTIPID
4704         fi
4705         wait $MULTIPID
4706         local nsz=`stat -c %s $DIR/$tfile`
4707         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4708 }
4709 run_test 34h "ftruncate file under grouplock should not block"
4710
4711 test_35a() {
4712         cp /bin/sh $DIR/f35a
4713         chmod 444 $DIR/f35a
4714         chown $RUNAS_ID $DIR/f35a
4715         $RUNAS $DIR/f35a && error || true
4716         rm $DIR/f35a
4717 }
4718 run_test 35a "exec file with mode 444 (should return and not leak)"
4719
4720 test_36a() {
4721         rm -f $DIR/f36
4722         utime $DIR/f36 || error "utime failed for MDS"
4723 }
4724 run_test 36a "MDS utime check (mknod, utime)"
4725
4726 test_36b() {
4727         echo "" > $DIR/f36
4728         utime $DIR/f36 || error "utime failed for OST"
4729 }
4730 run_test 36b "OST utime check (open, utime)"
4731
4732 test_36c() {
4733         rm -f $DIR/d36/f36
4734         test_mkdir $DIR/d36
4735         chown $RUNAS_ID $DIR/d36
4736         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4737 }
4738 run_test 36c "non-root MDS utime check (mknod, utime)"
4739
4740 test_36d() {
4741         [ ! -d $DIR/d36 ] && test_36c
4742         echo "" > $DIR/d36/f36
4743         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4744 }
4745 run_test 36d "non-root OST utime check (open, utime)"
4746
4747 test_36e() {
4748         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4749
4750         test_mkdir $DIR/$tdir
4751         touch $DIR/$tdir/$tfile
4752         $RUNAS utime $DIR/$tdir/$tfile &&
4753                 error "utime worked, expected failure" || true
4754 }
4755 run_test 36e "utime on non-owned file (should return error)"
4756
4757 subr_36fh() {
4758         local fl="$1"
4759         local LANG_SAVE=$LANG
4760         local LC_LANG_SAVE=$LC_LANG
4761         export LANG=C LC_LANG=C # for date language
4762
4763         DATESTR="Dec 20  2000"
4764         test_mkdir $DIR/$tdir
4765         lctl set_param fail_loc=$fl
4766         date; date +%s
4767         cp /etc/hosts $DIR/$tdir/$tfile
4768         sync & # write RPC generated with "current" inode timestamp, but delayed
4769         sleep 1
4770         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4771         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4772         cancel_lru_locks $OSC
4773         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4774         date; date +%s
4775         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4776                 echo "BEFORE: $LS_BEFORE" && \
4777                 echo "AFTER : $LS_AFTER" && \
4778                 echo "WANT  : $DATESTR" && \
4779                 error "$DIR/$tdir/$tfile timestamps changed" || true
4780
4781         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4782 }
4783
4784 test_36f() {
4785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4786
4787         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4788         subr_36fh "0x80000214"
4789 }
4790 run_test 36f "utime on file racing with OST BRW write =========="
4791
4792 test_36g() {
4793         remote_ost_nodsh && skip "remote OST with nodsh"
4794         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4795         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4796                 skip "Need MDS version at least 2.12.51"
4797
4798         local fmd_max_age
4799         local fmd
4800         local facet="ost1"
4801         local tgt="obdfilter"
4802
4803         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4804
4805         test_mkdir $DIR/$tdir
4806         fmd_max_age=$(do_facet $facet \
4807                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4808                 head -n 1")
4809
4810         echo "FMD max age: ${fmd_max_age}s"
4811         touch $DIR/$tdir/$tfile
4812         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4813                 gawk '{cnt=cnt+$1}  END{print cnt}')
4814         echo "FMD before: $fmd"
4815         [[ $fmd == 0 ]] &&
4816                 error "FMD wasn't create by touch"
4817         sleep $((fmd_max_age + 12))
4818         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4819                 gawk '{cnt=cnt+$1}  END{print cnt}')
4820         echo "FMD after: $fmd"
4821         [[ $fmd == 0 ]] ||
4822                 error "FMD wasn't expired by ping"
4823 }
4824 run_test 36g "FMD cache expiry ====================="
4825
4826 test_36h() {
4827         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4828
4829         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4830         subr_36fh "0x80000227"
4831 }
4832 run_test 36h "utime on file racing with OST BRW write =========="
4833
4834 test_36i() {
4835         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4836
4837         test_mkdir $DIR/$tdir
4838         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4839
4840         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4841         local new_mtime=$((mtime + 200))
4842
4843         #change Modify time of striped dir
4844         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4845                         error "change mtime failed"
4846
4847         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4848
4849         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4850 }
4851 run_test 36i "change mtime on striped directory"
4852
4853 # test_37 - duplicate with tests 32q 32r
4854
4855 test_38() {
4856         local file=$DIR/$tfile
4857         touch $file
4858         openfile -f O_DIRECTORY $file
4859         local RC=$?
4860         local ENOTDIR=20
4861         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4862         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4863 }
4864 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4865
4866 test_39a() { # was test_39
4867         touch $DIR/$tfile
4868         touch $DIR/${tfile}2
4869 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4870 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4871 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4872         sleep 2
4873         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4874         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4875                 echo "mtime"
4876                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4877                 echo "atime"
4878                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4879                 echo "ctime"
4880                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4881                 error "O_TRUNC didn't change timestamps"
4882         fi
4883 }
4884 run_test 39a "mtime changed on create"
4885
4886 test_39b() {
4887         test_mkdir -c1 $DIR/$tdir
4888         cp -p /etc/passwd $DIR/$tdir/fopen
4889         cp -p /etc/passwd $DIR/$tdir/flink
4890         cp -p /etc/passwd $DIR/$tdir/funlink
4891         cp -p /etc/passwd $DIR/$tdir/frename
4892         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4893
4894         sleep 1
4895         echo "aaaaaa" >> $DIR/$tdir/fopen
4896         echo "aaaaaa" >> $DIR/$tdir/flink
4897         echo "aaaaaa" >> $DIR/$tdir/funlink
4898         echo "aaaaaa" >> $DIR/$tdir/frename
4899
4900         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4901         local link_new=`stat -c %Y $DIR/$tdir/flink`
4902         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4903         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4904
4905         cat $DIR/$tdir/fopen > /dev/null
4906         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4907         rm -f $DIR/$tdir/funlink2
4908         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4909
4910         for (( i=0; i < 2; i++ )) ; do
4911                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4912                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4913                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4914                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4915
4916                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4917                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4918                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4919                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4920
4921                 cancel_lru_locks $OSC
4922                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4923         done
4924 }
4925 run_test 39b "mtime change on open, link, unlink, rename  ======"
4926
4927 # this should be set to past
4928 TEST_39_MTIME=`date -d "1 year ago" +%s`
4929
4930 # bug 11063
4931 test_39c() {
4932         touch $DIR1/$tfile
4933         sleep 2
4934         local mtime0=`stat -c %Y $DIR1/$tfile`
4935
4936         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4937         local mtime1=`stat -c %Y $DIR1/$tfile`
4938         [ "$mtime1" = $TEST_39_MTIME ] || \
4939                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4940
4941         local d1=`date +%s`
4942         echo hello >> $DIR1/$tfile
4943         local d2=`date +%s`
4944         local mtime2=`stat -c %Y $DIR1/$tfile`
4945         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4946                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4947
4948         mv $DIR1/$tfile $DIR1/$tfile-1
4949
4950         for (( i=0; i < 2; i++ )) ; do
4951                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4952                 [ "$mtime2" = "$mtime3" ] || \
4953                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4954
4955                 cancel_lru_locks $OSC
4956                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4957         done
4958 }
4959 run_test 39c "mtime change on rename ==========================="
4960
4961 # bug 21114
4962 test_39d() {
4963         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4964
4965         touch $DIR1/$tfile
4966         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4967
4968         for (( i=0; i < 2; i++ )) ; do
4969                 local mtime=`stat -c %Y $DIR1/$tfile`
4970                 [ $mtime = $TEST_39_MTIME ] || \
4971                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4972
4973                 cancel_lru_locks $OSC
4974                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4975         done
4976 }
4977 run_test 39d "create, utime, stat =============================="
4978
4979 # bug 21114
4980 test_39e() {
4981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4982
4983         touch $DIR1/$tfile
4984         local mtime1=`stat -c %Y $DIR1/$tfile`
4985
4986         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4987
4988         for (( i=0; i < 2; i++ )) ; do
4989                 local mtime2=`stat -c %Y $DIR1/$tfile`
4990                 [ $mtime2 = $TEST_39_MTIME ] || \
4991                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4992
4993                 cancel_lru_locks $OSC
4994                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4995         done
4996 }
4997 run_test 39e "create, stat, utime, stat ========================"
4998
4999 # bug 21114
5000 test_39f() {
5001         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5002
5003         touch $DIR1/$tfile
5004         mtime1=`stat -c %Y $DIR1/$tfile`
5005
5006         sleep 2
5007         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5008
5009         for (( i=0; i < 2; i++ )) ; do
5010                 local mtime2=`stat -c %Y $DIR1/$tfile`
5011                 [ $mtime2 = $TEST_39_MTIME ] || \
5012                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
5013
5014                 cancel_lru_locks $OSC
5015                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5016         done
5017 }
5018 run_test 39f "create, stat, sleep, utime, stat ================="
5019
5020 # bug 11063
5021 test_39g() {
5022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5023
5024         echo hello >> $DIR1/$tfile
5025         local mtime1=`stat -c %Y $DIR1/$tfile`
5026
5027         sleep 2
5028         chmod o+r $DIR1/$tfile
5029
5030         for (( i=0; i < 2; i++ )) ; do
5031                 local mtime2=`stat -c %Y $DIR1/$tfile`
5032                 [ "$mtime1" = "$mtime2" ] || \
5033                         error "lost mtime: $mtime2, should be $mtime1"
5034
5035                 cancel_lru_locks $OSC
5036                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5037         done
5038 }
5039 run_test 39g "write, chmod, stat ==============================="
5040
5041 # bug 11063
5042 test_39h() {
5043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5044
5045         touch $DIR1/$tfile
5046         sleep 1
5047
5048         local d1=`date`
5049         echo hello >> $DIR1/$tfile
5050         local mtime1=`stat -c %Y $DIR1/$tfile`
5051
5052         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5053         local d2=`date`
5054         if [ "$d1" != "$d2" ]; then
5055                 echo "write and touch not within one second"
5056         else
5057                 for (( i=0; i < 2; i++ )) ; do
5058                         local mtime2=`stat -c %Y $DIR1/$tfile`
5059                         [ "$mtime2" = $TEST_39_MTIME ] || \
5060                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
5061
5062                         cancel_lru_locks $OSC
5063                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5064                 done
5065         fi
5066 }
5067 run_test 39h "write, utime within one second, stat ============="
5068
5069 test_39i() {
5070         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5071
5072         touch $DIR1/$tfile
5073         sleep 1
5074
5075         echo hello >> $DIR1/$tfile
5076         local mtime1=`stat -c %Y $DIR1/$tfile`
5077
5078         mv $DIR1/$tfile $DIR1/$tfile-1
5079
5080         for (( i=0; i < 2; i++ )) ; do
5081                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5082
5083                 [ "$mtime1" = "$mtime2" ] || \
5084                         error "lost mtime: $mtime2, should be $mtime1"
5085
5086                 cancel_lru_locks $OSC
5087                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5088         done
5089 }
5090 run_test 39i "write, rename, stat =============================="
5091
5092 test_39j() {
5093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5094
5095         start_full_debug_logging
5096         touch $DIR1/$tfile
5097         sleep 1
5098
5099         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
5100         lctl set_param fail_loc=0x80000412
5101         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
5102                 error "multiop failed"
5103         local multipid=$!
5104         local mtime1=`stat -c %Y $DIR1/$tfile`
5105
5106         mv $DIR1/$tfile $DIR1/$tfile-1
5107
5108         kill -USR1 $multipid
5109         wait $multipid || error "multiop close failed"
5110
5111         for (( i=0; i < 2; i++ )) ; do
5112                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5113                 [ "$mtime1" = "$mtime2" ] ||
5114                         error "mtime is lost on close: $mtime2, " \
5115                               "should be $mtime1"
5116
5117                 cancel_lru_locks
5118                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5119         done
5120         lctl set_param fail_loc=0
5121         stop_full_debug_logging
5122 }
5123 run_test 39j "write, rename, close, stat ======================="
5124
5125 test_39k() {
5126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5127
5128         touch $DIR1/$tfile
5129         sleep 1
5130
5131         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
5132         local multipid=$!
5133         local mtime1=`stat -c %Y $DIR1/$tfile`
5134
5135         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5136
5137         kill -USR1 $multipid
5138         wait $multipid || error "multiop close failed"
5139
5140         for (( i=0; i < 2; i++ )) ; do
5141                 local mtime2=`stat -c %Y $DIR1/$tfile`
5142
5143                 [ "$mtime2" = $TEST_39_MTIME ] || \
5144                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
5145
5146                 cancel_lru_locks
5147                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5148         done
5149 }
5150 run_test 39k "write, utime, close, stat ========================"
5151
5152 # this should be set to future
5153 TEST_39_ATIME=`date -d "1 year" +%s`
5154
5155 test_39l() {
5156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5157         remote_mds_nodsh && skip "remote MDS with nodsh"
5158
5159         local atime_diff=$(do_facet $SINGLEMDS \
5160                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5161         rm -rf $DIR/$tdir
5162         mkdir_on_mdt0 $DIR/$tdir
5163
5164         # test setting directory atime to future
5165         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5166         local atime=$(stat -c %X $DIR/$tdir)
5167         [ "$atime" = $TEST_39_ATIME ] ||
5168                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5169
5170         # test setting directory atime from future to now
5171         local now=$(date +%s)
5172         touch -a -d @$now $DIR/$tdir
5173
5174         atime=$(stat -c %X $DIR/$tdir)
5175         [ "$atime" -eq "$now"  ] ||
5176                 error "atime is not updated from future: $atime, $now"
5177
5178         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5179         sleep 3
5180
5181         # test setting directory atime when now > dir atime + atime_diff
5182         local d1=$(date +%s)
5183         ls $DIR/$tdir
5184         local d2=$(date +%s)
5185         cancel_lru_locks mdc
5186         atime=$(stat -c %X $DIR/$tdir)
5187         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5188                 error "atime is not updated  : $atime, should be $d2"
5189
5190         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5191         sleep 3
5192
5193         # test not setting directory atime when now < dir atime + atime_diff
5194         ls $DIR/$tdir
5195         cancel_lru_locks mdc
5196         atime=$(stat -c %X $DIR/$tdir)
5197         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5198                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5199
5200         do_facet $SINGLEMDS \
5201                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5202 }
5203 run_test 39l "directory atime update ==========================="
5204
5205 test_39m() {
5206         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5207
5208         touch $DIR1/$tfile
5209         sleep 2
5210         local far_past_mtime=$(date -d "May 29 1953" +%s)
5211         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5212
5213         touch -m -d @$far_past_mtime $DIR1/$tfile
5214         touch -a -d @$far_past_atime $DIR1/$tfile
5215
5216         for (( i=0; i < 2; i++ )) ; do
5217                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5218                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5219                         error "atime or mtime set incorrectly"
5220
5221                 cancel_lru_locks $OSC
5222                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5223         done
5224 }
5225 run_test 39m "test atime and mtime before 1970"
5226
5227 test_39n() { # LU-3832
5228         remote_mds_nodsh && skip "remote MDS with nodsh"
5229
5230         local atime_diff=$(do_facet $SINGLEMDS \
5231                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5232         local atime0
5233         local atime1
5234         local atime2
5235
5236         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5237
5238         rm -rf $DIR/$tfile
5239         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5240         atime0=$(stat -c %X $DIR/$tfile)
5241
5242         sleep 5
5243         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5244         atime1=$(stat -c %X $DIR/$tfile)
5245
5246         sleep 5
5247         cancel_lru_locks mdc
5248         cancel_lru_locks osc
5249         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5250         atime2=$(stat -c %X $DIR/$tfile)
5251
5252         do_facet $SINGLEMDS \
5253                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5254
5255         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5256         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5257 }
5258 run_test 39n "check that O_NOATIME is honored"
5259
5260 test_39o() {
5261         TESTDIR=$DIR/$tdir/$tfile
5262         [ -e $TESTDIR ] && rm -rf $TESTDIR
5263         mkdir -p $TESTDIR
5264         cd $TESTDIR
5265         links1=2
5266         ls
5267         mkdir a b
5268         ls
5269         links2=$(stat -c %h .)
5270         [ $(($links1 + 2)) != $links2 ] &&
5271                 error "wrong links count $(($links1 + 2)) != $links2"
5272         rmdir b
5273         links3=$(stat -c %h .)
5274         [ $(($links1 + 1)) != $links3 ] &&
5275                 error "wrong links count $links1 != $links3"
5276         return 0
5277 }
5278 run_test 39o "directory cached attributes updated after create"
5279
5280 test_39p() {
5281         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5282
5283         local MDTIDX=1
5284         TESTDIR=$DIR/$tdir/$tdir
5285         [ -e $TESTDIR ] && rm -rf $TESTDIR
5286         test_mkdir -p $TESTDIR
5287         cd $TESTDIR
5288         links1=2
5289         ls
5290         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5291         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5292         ls
5293         links2=$(stat -c %h .)
5294         [ $(($links1 + 2)) != $links2 ] &&
5295                 error "wrong links count $(($links1 + 2)) != $links2"
5296         rmdir remote_dir2
5297         links3=$(stat -c %h .)
5298         [ $(($links1 + 1)) != $links3 ] &&
5299                 error "wrong links count $links1 != $links3"
5300         return 0
5301 }
5302 run_test 39p "remote directory cached attributes updated after create ========"
5303
5304 test_39r() {
5305         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5306                 skip "no atime update on old OST"
5307         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5308                 skip_env "ldiskfs only test"
5309         fi
5310
5311         local saved_adiff
5312         local ahost=$(facet_active_host ost1)
5313         saved_adiff=$(do_facet ost1 \
5314                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5315         stack_trap "do_facet ost1 \
5316                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5317
5318         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5319
5320         $LFS setstripe -i 0 $DIR/$tfile
5321         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5322                 error "can't write initial file"
5323         cancel_lru_locks osc
5324
5325         # exceed atime_diff and access file
5326         sleep 10
5327         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5328                 error "can't udpate atime"
5329
5330         # atime_cli value is in decimal
5331         local atime_cli=$(stat -c %X $DIR/$tfile)
5332         echo "client atime: $atime_cli"
5333
5334         local ostdev=$(ostdevname 1)
5335         local fid=($($LFS getstripe $DIR/$tfile | grep 0x))
5336         local seq=${fid[3]#0x}
5337         local oid=${fid[1]}
5338         local oid_hex
5339
5340         if [ $seq == 0 ]; then
5341                 oid_hex=${fid[1]}
5342         else
5343                 oid_hex=${fid[2]#0x}
5344         fi
5345         local objpath="O/$seq/d$(($oid % 32))/$oid_hex"
5346         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5347
5348         # allow atime update to be written to device
5349         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync=1"
5350         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5351
5352         # Give enough time for server to get updated. Until then
5353         # the value read is defaulted to "0x00000000:00000000"
5354         # Wait until atime read via debugfs is not equal to zero.
5355         # Max limit to wait is 30 seconds.
5356         wait_update_cond $ahost                                         \
5357                 "$cmd |& awk -F'[: ]' '/atime:/ { print \\\$4 }'"       \
5358                 "-gt" "0" 30 || error "atime on ost is still 0 after 30 seconds"
5359         # atime_ost value is in hex
5360         local atime_ost=$(do_facet ost1 "$cmd" |&
5361                           awk -F'[: ]' '/atime:/ { print $4 }')
5362         # debugfs returns atime in 0xNNNNNNNN:00000000 format
5363         # convert Hex to decimal before comparing
5364         local atime_ost_dec=$((atime_ost))
5365
5366         # The test pass criteria is that the client time and server should
5367         # be same (2s gap accepted). This gap could arise due to VFS updating
5368         # the atime after the read(dd), stat and the updated time from the
5369         # inode
5370         (( $((atime_cli - atime_ost_dec)) <= 2 )) ||
5371                 error "atime on client $atime_cli != ost $atime_ost_dec"
5372 }
5373 run_test 39r "lazy atime update on OST"
5374
5375 test_39q() { # LU-8041
5376         local testdir=$DIR/$tdir
5377         mkdir -p $testdir
5378         multiop_bg_pause $testdir D_c || error "multiop failed"
5379         local multipid=$!
5380         cancel_lru_locks mdc
5381         kill -USR1 $multipid
5382         local atime=$(stat -c %X $testdir)
5383         [ "$atime" -ne 0 ] || error "atime is zero"
5384 }
5385 run_test 39q "close won't zero out atime"
5386
5387 test_39s() {
5388         local atime0
5389         local atime1
5390         local atime2
5391         local atime3
5392         local atime4
5393
5394         umount_client $MOUNT
5395         mount_client $MOUNT relatime
5396
5397         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer conv=fsync
5398         atime0=$(stat -c %X $DIR/$tfile)
5399
5400         # First read updates atime
5401         sleep 1
5402         cat $DIR/$tfile >/dev/null
5403         atime1=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5404
5405         # Next reads do not update atime
5406         sleep 1
5407         cat $DIR/$tfile >/dev/null
5408         atime2=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5409
5410         # If mtime is greater than atime, atime is updated
5411         sleep 1
5412         touch -m $DIR/$tfile # (mtime = now)
5413         sleep 1
5414         cat $DIR/$tfile >/dev/null # (atime is updated because atime < mtime)
5415         atime3=$(stat -c %X $DIR/$tfile) # (atime = mtime = atime0 + 3)
5416
5417         # Next reads do not update atime
5418         sleep 1
5419         cat $DIR/$tfile >/dev/null
5420         atime4=$(stat -c %X $DIR/$tfile)
5421
5422         # Remount the client to clear 'relatime' option
5423         remount_client $MOUNT
5424
5425         (( atime0 < atime1 )) ||
5426                 error "atime $atime0 should be smaller than $atime1"
5427         (( atime1 == atime2 )) ||
5428                 error "atime $atime1 was updated to $atime2"
5429         (( atime1 < atime3 )) || error "atime1 $atime1 != atime3 $atime3"
5430         (( atime3 == atime4 )) || error "atime3 $atime3 != atime4 $atime4"
5431 }
5432 run_test 39s "relatime is supported"
5433
5434 test_40() {
5435         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5436         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5437                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5438         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5439                 error "$tfile is not 4096 bytes in size"
5440 }
5441 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5442
5443 test_41() {
5444         # bug 1553
5445         small_write $DIR/f41 18
5446 }
5447 run_test 41 "test small file write + fstat ====================="
5448
5449 count_ost_writes() {
5450         lctl get_param -n ${OSC}.*.stats |
5451                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5452                         END { printf("%0.0f", writes) }'
5453 }
5454
5455 # decent default
5456 WRITEBACK_SAVE=500
5457 DIRTY_RATIO_SAVE=40
5458 MAX_DIRTY_RATIO=50
5459 BG_DIRTY_RATIO_SAVE=10
5460 MAX_BG_DIRTY_RATIO=25
5461
5462 start_writeback() {
5463         trap 0
5464         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5465         # dirty_ratio, dirty_background_ratio
5466         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5467                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5468                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5469                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5470         else
5471                 # if file not here, we are a 2.4 kernel
5472                 kill -CONT `pidof kupdated`
5473         fi
5474 }
5475
5476 stop_writeback() {
5477         # setup the trap first, so someone cannot exit the test at the
5478         # exact wrong time and mess up a machine
5479         trap start_writeback EXIT
5480         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5481         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5482                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5483                 sysctl -w vm.dirty_writeback_centisecs=0
5484                 sysctl -w vm.dirty_writeback_centisecs=0
5485                 # save and increase /proc/sys/vm/dirty_ratio
5486                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5487                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5488                 # save and increase /proc/sys/vm/dirty_background_ratio
5489                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5490                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5491         else
5492                 # if file not here, we are a 2.4 kernel
5493                 kill -STOP `pidof kupdated`
5494         fi
5495 }
5496
5497 # ensure that all stripes have some grant before we test client-side cache
5498 setup_test42() {
5499         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5500                 dd if=/dev/zero of=$i bs=4k count=1
5501                 rm $i
5502         done
5503 }
5504
5505 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5506 # file truncation, and file removal.
5507 test_42a() {
5508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5509
5510         setup_test42
5511         cancel_lru_locks $OSC
5512         stop_writeback
5513         sync; sleep 1; sync # just to be safe
5514         BEFOREWRITES=`count_ost_writes`
5515         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5516         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5517         AFTERWRITES=`count_ost_writes`
5518         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5519                 error "$BEFOREWRITES < $AFTERWRITES"
5520         start_writeback
5521 }
5522 run_test 42a "ensure that we don't flush on close"
5523
5524 test_42b() {
5525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5526
5527         setup_test42
5528         cancel_lru_locks $OSC
5529         stop_writeback
5530         sync
5531         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5532         BEFOREWRITES=$(count_ost_writes)
5533         unlink $DIR/f42b || error "unlink $DIR/f42b: $?"
5534         AFTERWRITES=$(count_ost_writes)
5535         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5536                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5537         fi
5538         BEFOREWRITES=$(count_ost_writes)
5539         sync || error "sync: $?"
5540         AFTERWRITES=$(count_ost_writes)
5541         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5542                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5543         fi
5544         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5545         start_writeback
5546         return 0
5547 }
5548 run_test 42b "test destroy of file with cached dirty data ======"
5549
5550 # if these tests just want to test the effect of truncation,
5551 # they have to be very careful.  consider:
5552 # - the first open gets a {0,EOF}PR lock
5553 # - the first write conflicts and gets a {0, count-1}PW
5554 # - the rest of the writes are under {count,EOF}PW
5555 # - the open for truncate tries to match a {0,EOF}PR
5556 #   for the filesize and cancels the PWs.
5557 # any number of fixes (don't get {0,EOF} on open, match
5558 # composite locks, do smarter file size management) fix
5559 # this, but for now we want these tests to verify that
5560 # the cancellation with truncate intent works, so we
5561 # start the file with a full-file pw lock to match against
5562 # until the truncate.
5563 trunc_test() {
5564         test=$1
5565         file=$DIR/$test
5566         offset=$2
5567         cancel_lru_locks $OSC
5568         stop_writeback
5569         # prime the file with 0,EOF PW to match
5570         touch $file
5571         $TRUNCATE $file 0
5572         sync; sync
5573         # now the real test..
5574         dd if=/dev/zero of=$file bs=1024 count=100
5575         BEFOREWRITES=`count_ost_writes`
5576         $TRUNCATE $file $offset
5577         cancel_lru_locks $OSC
5578         AFTERWRITES=`count_ost_writes`
5579         start_writeback
5580 }
5581
5582 test_42c() {
5583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5584
5585         trunc_test 42c 1024
5586         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5587                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5588         rm $file
5589 }
5590 run_test 42c "test partial truncate of file with cached dirty data"
5591
5592 test_42d() {
5593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5594
5595         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5596         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5597         $LCTL set_param debug=+cache
5598
5599         trunc_test 42d 0
5600         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5601                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5602         rm $file
5603 }
5604 run_test 42d "test complete truncate of file with cached dirty data"
5605
5606 test_42e() { # bug22074
5607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5608
5609         local TDIR=$DIR/${tdir}e
5610         local pages=16 # hardcoded 16 pages, don't change it.
5611         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5612         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5613         local max_dirty_mb
5614         local warmup_files
5615
5616         test_mkdir $DIR/${tdir}e
5617         $LFS setstripe -c 1 $TDIR
5618         createmany -o $TDIR/f $files
5619
5620         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5621
5622         # we assume that with $OSTCOUNT files, at least one of them will
5623         # be allocated on OST0.
5624         warmup_files=$((OSTCOUNT * max_dirty_mb))
5625         createmany -o $TDIR/w $warmup_files
5626
5627         # write a large amount of data into one file and sync, to get good
5628         # avail_grant number from OST.
5629         for ((i=0; i<$warmup_files; i++)); do
5630                 idx=$($LFS getstripe -i $TDIR/w$i)
5631                 [ $idx -ne 0 ] && continue
5632                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5633                 break
5634         done
5635         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5636         sync
5637         $LCTL get_param $proc_osc0/cur_dirty_bytes
5638         $LCTL get_param $proc_osc0/cur_grant_bytes
5639
5640         # create as much dirty pages as we can while not to trigger the actual
5641         # RPCs directly. but depends on the env, VFS may trigger flush during this
5642         # period, hopefully we are good.
5643         for ((i=0; i<$warmup_files; i++)); do
5644                 idx=$($LFS getstripe -i $TDIR/w$i)
5645                 [ $idx -ne 0 ] && continue
5646                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5647         done
5648         $LCTL get_param $proc_osc0/cur_dirty_bytes
5649         $LCTL get_param $proc_osc0/cur_grant_bytes
5650
5651         # perform the real test
5652         $LCTL set_param $proc_osc0/rpc_stats 0
5653         for ((;i<$files; i++)); do
5654                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5655                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5656         done
5657         sync
5658         $LCTL get_param $proc_osc0/rpc_stats
5659
5660         local percent=0
5661         local have_ppr=false
5662         $LCTL get_param $proc_osc0/rpc_stats |
5663                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5664                         # skip lines until we are at the RPC histogram data
5665                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5666                         $have_ppr || continue
5667
5668                         # we only want the percent stat for < 16 pages
5669                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5670
5671                         percent=$((percent + WPCT))
5672                         if [[ $percent -gt 15 ]]; then
5673                                 error "less than 16-pages write RPCs" \
5674                                       "$percent% > 15%"
5675                                 break
5676                         fi
5677                 done
5678         rm -rf $TDIR
5679 }
5680 run_test 42e "verify sub-RPC writes are not done synchronously"
5681
5682 test_43A() { # was test_43
5683         test_mkdir $DIR/$tdir
5684         cp -p /bin/ls $DIR/$tdir/$tfile
5685         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5686         pid=$!
5687         # give multiop a chance to open
5688         sleep 1
5689
5690         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5691         kill -USR1 $pid
5692         # Wait for multiop to exit
5693         wait $pid
5694 }
5695 run_test 43A "execution of file opened for write should return -ETXTBSY"
5696
5697 test_43a() {
5698         test_mkdir $DIR/$tdir
5699         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5700         $DIR/$tdir/sleep 60 &
5701         SLEEP_PID=$!
5702         # Make sure exec of $tdir/sleep wins race with truncate
5703         sleep 1
5704         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5705         kill $SLEEP_PID
5706 }
5707 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5708
5709 test_43b() {
5710         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5711
5712         test_mkdir $DIR/$tdir
5713         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5714         $DIR/$tdir/sleep 60 &
5715         SLEEP_PID=$!
5716         # Make sure exec of $tdir/sleep wins race with truncate
5717         sleep 1
5718         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5719         kill $SLEEP_PID
5720 }
5721 run_test 43b "truncate of file being executed should return -ETXTBSY"
5722
5723 test_43c() {
5724         local testdir="$DIR/$tdir"
5725         test_mkdir $testdir
5726         cp $SHELL $testdir/
5727         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5728                 ( cd $testdir && md5sum -c )
5729 }
5730 run_test 43c "md5sum of copy into lustre"
5731
5732 test_44A() { # was test_44
5733         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5734
5735         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5736         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5737 }
5738 run_test 44A "zero length read from a sparse stripe"
5739
5740 test_44a() {
5741         local nstripe=$($LFS getstripe -c -d $DIR)
5742         [ -z "$nstripe" ] && skip "can't get stripe info"
5743         [[ $nstripe -gt $OSTCOUNT ]] &&
5744                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5745
5746         local stride=$($LFS getstripe -S -d $DIR)
5747         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5748                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5749         fi
5750
5751         OFFSETS="0 $((stride/2)) $((stride-1))"
5752         for offset in $OFFSETS; do
5753                 for i in $(seq 0 $((nstripe-1))); do
5754                         local GLOBALOFFSETS=""
5755                         # size in Bytes
5756                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5757                         local myfn=$DIR/d44a-$size
5758                         echo "--------writing $myfn at $size"
5759                         ll_sparseness_write $myfn $size ||
5760                                 error "ll_sparseness_write"
5761                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5762                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5763                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5764
5765                         for j in $(seq 0 $((nstripe-1))); do
5766                                 # size in Bytes
5767                                 size=$((((j + $nstripe )*$stride + $offset)))
5768                                 ll_sparseness_write $myfn $size ||
5769                                         error "ll_sparseness_write"
5770                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5771                         done
5772                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5773                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5774                         rm -f $myfn
5775                 done
5776         done
5777 }
5778 run_test 44a "test sparse pwrite ==============================="
5779
5780 dirty_osc_total() {
5781         tot=0
5782         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5783                 tot=$(($tot + $d))
5784         done
5785         echo $tot
5786 }
5787 do_dirty_record() {
5788         before=`dirty_osc_total`
5789         echo executing "\"$*\""
5790         eval $*
5791         after=`dirty_osc_total`
5792         echo before $before, after $after
5793 }
5794 test_45() {
5795         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5796
5797         f="$DIR/f45"
5798         # Obtain grants from OST if it supports it
5799         echo blah > ${f}_grant
5800         stop_writeback
5801         sync
5802         do_dirty_record "echo blah > $f"
5803         [[ $before -eq $after ]] && error "write wasn't cached"
5804         do_dirty_record "> $f"
5805         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5806         do_dirty_record "echo blah > $f"
5807         [[ $before -eq $after ]] && error "write wasn't cached"
5808         do_dirty_record "sync"
5809         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5810         do_dirty_record "echo blah > $f"
5811         [[ $before -eq $after ]] && error "write wasn't cached"
5812         do_dirty_record "cancel_lru_locks osc"
5813         [[ $before -gt $after ]] ||
5814                 error "lock cancellation didn't lower dirty count"
5815         start_writeback
5816 }
5817 run_test 45 "osc io page accounting ============================"
5818
5819 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5820 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5821 # objects offset and an assert hit when an rpc was built with 1023's mapped
5822 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5823 test_46() {
5824         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5825
5826         f="$DIR/f46"
5827         stop_writeback
5828         sync
5829         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5830         sync
5831         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5832         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5833         sync
5834         start_writeback
5835 }
5836 run_test 46 "dirtying a previously written page ================"
5837
5838 # test_47 is removed "Device nodes check" is moved to test_28
5839
5840 test_48a() { # bug 2399
5841         [ "$mds1_FSTYPE" = "zfs" ] &&
5842         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5843                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5844
5845         test_mkdir $DIR/$tdir
5846         cd $DIR/$tdir
5847         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5848         test_mkdir $DIR/$tdir
5849         touch foo || error "'touch foo' failed after recreating cwd"
5850         test_mkdir bar
5851         touch .foo || error "'touch .foo' failed after recreating cwd"
5852         test_mkdir .bar
5853         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5854         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5855         cd . || error "'cd .' failed after recreating cwd"
5856         mkdir . && error "'mkdir .' worked after recreating cwd"
5857         rmdir . && error "'rmdir .' worked after recreating cwd"
5858         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5859         cd .. || error "'cd ..' failed after recreating cwd"
5860 }
5861 run_test 48a "Access renamed working dir (should return errors)="
5862
5863 test_48b() { # bug 2399
5864         rm -rf $DIR/$tdir
5865         test_mkdir $DIR/$tdir
5866         cd $DIR/$tdir
5867         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5868         touch foo && error "'touch foo' worked after removing cwd"
5869         mkdir foo && error "'mkdir foo' worked after removing cwd"
5870         touch .foo && error "'touch .foo' worked after removing cwd"
5871         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5872         ls . > /dev/null && error "'ls .' worked after removing cwd"
5873         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5874         mkdir . && error "'mkdir .' worked after removing cwd"
5875         rmdir . && error "'rmdir .' worked after removing cwd"
5876         ln -s . foo && error "'ln -s .' worked after removing cwd"
5877         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5878 }
5879 run_test 48b "Access removed working dir (should return errors)="
5880
5881 test_48c() { # bug 2350
5882         #lctl set_param debug=-1
5883         #set -vx
5884         rm -rf $DIR/$tdir
5885         test_mkdir -p $DIR/$tdir/dir
5886         cd $DIR/$tdir/dir
5887         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5888         $TRACE touch foo && error "touch foo worked after removing cwd"
5889         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5890         touch .foo && error "touch .foo worked after removing cwd"
5891         mkdir .foo && error "mkdir .foo worked after removing cwd"
5892         $TRACE ls . && error "'ls .' worked after removing cwd"
5893         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5894         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5895         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5896         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5897         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5898 }
5899 run_test 48c "Access removed working subdir (should return errors)"
5900
5901 test_48d() { # bug 2350
5902         #lctl set_param debug=-1
5903         #set -vx
5904         rm -rf $DIR/$tdir
5905         test_mkdir -p $DIR/$tdir/dir
5906         cd $DIR/$tdir/dir
5907         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5908         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5909         $TRACE touch foo && error "'touch foo' worked after removing parent"
5910         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5911         touch .foo && error "'touch .foo' worked after removing parent"
5912         mkdir .foo && error "mkdir .foo worked after removing parent"
5913         $TRACE ls . && error "'ls .' worked after removing parent"
5914         $TRACE ls .. && error "'ls ..' worked after removing parent"
5915         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5916         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5917         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5918         true
5919 }
5920 run_test 48d "Access removed parent subdir (should return errors)"
5921
5922 test_48e() { # bug 4134
5923         #lctl set_param debug=-1
5924         #set -vx
5925         rm -rf $DIR/$tdir
5926         test_mkdir -p $DIR/$tdir/dir
5927         cd $DIR/$tdir/dir
5928         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5929         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5930         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5931         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5932         # On a buggy kernel addition of "touch foo" after cd .. will
5933         # produce kernel oops in lookup_hash_it
5934         touch ../foo && error "'cd ..' worked after recreate parent"
5935         cd $DIR
5936         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5937 }
5938 run_test 48e "Access to recreated parent subdir (should return errors)"
5939
5940 test_48f() {
5941         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5942                 skip "need MDS >= 2.13.55"
5943         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5944         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5945                 skip "needs different host for mdt1 mdt2"
5946         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5947
5948         $LFS mkdir -i0 $DIR/$tdir
5949         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5950
5951         for d in sub1 sub2 sub3; do
5952                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5953                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5954                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5955         done
5956
5957         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5958 }
5959 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5960
5961 test_49() { # LU-1030
5962         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5963         remote_ost_nodsh && skip "remote OST with nodsh"
5964
5965         # get ost1 size - $FSNAME-OST0000
5966         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5967                 awk '{ print $4 }')
5968         # write 800M at maximum
5969         [[ $ost1_size -lt 2 ]] && ost1_size=2
5970         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5971
5972         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5973         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5974         local dd_pid=$!
5975
5976         # change max_pages_per_rpc while writing the file
5977         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5978         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5979         # loop until dd process exits
5980         while ps ax -opid | grep -wq $dd_pid; do
5981                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5982                 sleep $((RANDOM % 5 + 1))
5983         done
5984         # restore original max_pages_per_rpc
5985         $LCTL set_param $osc1_mppc=$orig_mppc
5986         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5987 }
5988 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5989
5990 test_50() {
5991         # bug 1485
5992         test_mkdir $DIR/$tdir
5993         cd $DIR/$tdir
5994         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5995 }
5996 run_test 50 "special situations: /proc symlinks  ==============="
5997
5998 test_51a() {    # was test_51
5999         # bug 1516 - create an empty entry right after ".." then split dir
6000         test_mkdir -c1 $DIR/$tdir
6001         touch $DIR/$tdir/foo
6002         $MCREATE $DIR/$tdir/bar
6003         rm $DIR/$tdir/foo
6004         createmany -m $DIR/$tdir/longfile 201
6005         FNUM=202
6006         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
6007                 $MCREATE $DIR/$tdir/longfile$FNUM
6008                 FNUM=$(($FNUM + 1))
6009                 echo -n "+"
6010         done
6011         echo
6012         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
6013 }
6014 run_test 51a "special situations: split htree with empty entry =="
6015
6016 cleanup_print_lfs_df () {
6017         trap 0
6018         $LFS df
6019         $LFS df -i
6020 }
6021
6022 test_51b() {
6023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6024
6025         local dir=$DIR/$tdir
6026         local nrdirs=$((65536 + 100))
6027
6028         # cleanup the directory
6029         rm -fr $dir
6030
6031         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
6032
6033         $LFS df
6034         $LFS df -i
6035         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
6036         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
6037         [[ $numfree -lt $nrdirs ]] &&
6038                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
6039
6040         # need to check free space for the directories as well
6041         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
6042         numfree=$(( blkfree / $(fs_inode_ksize) ))
6043         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
6044
6045         trap cleanup_print_lfs_df EXIT
6046
6047         # create files
6048         createmany -d $dir/d $nrdirs || {
6049                 unlinkmany $dir/d $nrdirs
6050                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
6051         }
6052
6053         # really created :
6054         nrdirs=$(ls -U $dir | wc -l)
6055
6056         # unlink all but 100 subdirectories, then check it still works
6057         local left=100
6058         local delete=$((nrdirs - left))
6059
6060         $LFS df
6061         $LFS df -i
6062
6063         # for ldiskfs the nlink count should be 1, but this is OSD specific
6064         # and so this is listed for informational purposes only
6065         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
6066         unlinkmany -d $dir/d $delete ||
6067                 error "unlink of first $delete subdirs failed"
6068
6069         echo "nlink between: $(stat -c %h $dir)"
6070         local found=$(ls -U $dir | wc -l)
6071         [ $found -ne $left ] &&
6072                 error "can't find subdirs: found only $found, expected $left"
6073
6074         unlinkmany -d $dir/d $delete $left ||
6075                 error "unlink of second $left subdirs failed"
6076         # regardless of whether the backing filesystem tracks nlink accurately
6077         # or not, the nlink count shouldn't be more than "." and ".." here
6078         local after=$(stat -c %h $dir)
6079         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
6080                 echo "nlink after: $after"
6081
6082         cleanup_print_lfs_df
6083 }
6084 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
6085
6086 test_51d_sub() {
6087         local stripecount=$1
6088         local nfiles=$2
6089
6090         log "create files with stripecount=$stripecount"
6091         $LFS setstripe -C $stripecount $DIR/$tdir
6092         createmany -o $DIR/$tdir/t- $nfiles
6093         $LFS getstripe $DIR/$tdir > $TMP/$tfile
6094         for ((n = 0; n < $OSTCOUNT; n++)); do
6095                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
6096                            END { printf("%0.0f", objs) }' $TMP/$tfile)
6097                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
6098                             '($1 == '$n') { objs += 1 } \
6099                             END { printf("%0.0f", objs) }')
6100                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
6101         done
6102         unlinkmany $DIR/$tdir/t- $nfiles
6103         rm  -f $TMP/$tfile
6104
6105         local nlast
6106         local min=4
6107         local max=6 # allow variance of (1 - $min/$max) = 33% by default
6108
6109         # For some combinations of stripecount and OSTCOUNT current code
6110         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
6111         # than others. Rather than skipping this test entirely, check that
6112         # and keep testing to ensure imbalance does not get worse. LU-15282
6113         (( (OSTCOUNT == 6 && stripecount == 4) ||
6114            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
6115            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
6116         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
6117                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
6118                         { $LFS df && $LFS df -i &&
6119                         error "stripecount=$stripecount: " \
6120                               "OST $n has fewer objects vs. OST $nlast " \
6121                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
6122                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
6123                         { $LFS df && $LFS df -i &&
6124                         error "stripecount=$stripecount: " \
6125                               "OST $n has more objects vs. OST $nlast " \
6126                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
6127
6128                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
6129                         { $LFS df && $LFS df -i &&
6130                         error "stripecount=$stripecount: " \
6131                               "OST $n has fewer #0 objects vs. OST $nlast " \
6132                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
6133                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
6134                         { $LFS df && $LFS df -i &&
6135                         error "stripecount=$stripecount: " \
6136                               "OST $n has more #0 objects vs. OST $nlast " \
6137                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
6138         done
6139 }
6140
6141 test_51d() {
6142         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6143         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
6144
6145         local stripecount
6146         local per_ost=100
6147         local nfiles=$((per_ost * OSTCOUNT))
6148         local mdts=$(comma_list $(mdts_nodes))
6149         local param="osp.*.create_count"
6150         local qos_old=$(do_facet mds1 \
6151                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
6152
6153         do_nodes $mdts \
6154                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
6155         stack_trap "do_nodes $mdts \
6156                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
6157
6158         test_mkdir $DIR/$tdir
6159         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
6160         (( dirstripes > 0 )) || dirstripes=1
6161
6162         # Ensure enough OST objects precreated for tests to pass without
6163         # running out of objects.  This is an LOV r-r OST algorithm test,
6164         # not an OST object precreation test.
6165         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
6166         (( old >= nfiles )) ||
6167         {
6168                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
6169
6170                 do_nodes $mdts "$LCTL set_param $param=$create_count"
6171                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
6172
6173                 # trigger precreation from all MDTs for all OSTs
6174                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
6175                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
6176                 done
6177         }
6178
6179         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
6180                 sleep 8  # allow object precreation to catch up
6181                 test_51d_sub $stripecount $nfiles
6182         done
6183 }
6184 run_test 51d "check LOV round-robin OST object distribution"
6185
6186 test_51e() {
6187         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6188                 skip_env "ldiskfs only test"
6189         fi
6190
6191         test_mkdir -c1 $DIR/$tdir
6192         test_mkdir -c1 $DIR/$tdir/d0
6193
6194         touch $DIR/$tdir/d0/foo
6195         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
6196                 error "file exceed 65000 nlink limit!"
6197         unlinkmany $DIR/$tdir/d0/f- 65001
6198         return 0
6199 }
6200 run_test 51e "check file nlink limit"
6201
6202 test_51f() {
6203         test_mkdir $DIR/$tdir
6204
6205         local max=100000
6206         local ulimit_old=$(ulimit -n)
6207         local spare=20 # number of spare fd's for scripts/libraries, etc.
6208         local mdt=$($LFS getstripe -m $DIR/$tdir)
6209         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
6210
6211         echo "MDT$mdt numfree=$numfree, max=$max"
6212         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
6213         if [ $((numfree + spare)) -gt $ulimit_old ]; then
6214                 while ! ulimit -n $((numfree + spare)); do
6215                         numfree=$((numfree * 3 / 4))
6216                 done
6217                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
6218         else
6219                 echo "left ulimit at $ulimit_old"
6220         fi
6221
6222         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
6223                 unlinkmany $DIR/$tdir/f $numfree
6224                 error "create+open $numfree files in $DIR/$tdir failed"
6225         }
6226         ulimit -n $ulimit_old
6227
6228         # if createmany exits at 120s there will be fewer than $numfree files
6229         unlinkmany $DIR/$tdir/f $numfree || true
6230 }
6231 run_test 51f "check many open files limit"
6232
6233 test_52a() {
6234         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
6235         test_mkdir $DIR/$tdir
6236         touch $DIR/$tdir/foo
6237         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6238         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6239         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6240         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6241         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6242                                         error "link worked"
6243         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6244         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6245         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6246                                                      error "lsattr"
6247         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6248         cp -r $DIR/$tdir $TMP/
6249         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6250 }
6251 run_test 52a "append-only flag test (should return errors)"
6252
6253 test_52b() {
6254         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6255         test_mkdir $DIR/$tdir
6256         touch $DIR/$tdir/foo
6257         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6258         cat test > $DIR/$tdir/foo && error "cat test worked"
6259         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6260         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6261         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6262                                         error "link worked"
6263         echo foo >> $DIR/$tdir/foo && error "echo worked"
6264         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6265         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6266         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6267         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6268                                                         error "lsattr"
6269         chattr -i $DIR/$tdir/foo || error "chattr failed"
6270
6271         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6272 }
6273 run_test 52b "immutable flag test (should return errors) ======="
6274
6275 test_53() {
6276         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6277         remote_mds_nodsh && skip "remote MDS with nodsh"
6278         remote_ost_nodsh && skip "remote OST with nodsh"
6279
6280         local param
6281         local param_seq
6282         local ostname
6283         local mds_last
6284         local mds_last_seq
6285         local ost_last
6286         local ost_last_seq
6287         local ost_last_id
6288         local ostnum
6289         local node
6290         local found=false
6291         local support_last_seq=true
6292
6293         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6294                 support_last_seq=false
6295
6296         # only test MDT0000
6297         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6298         local value
6299         for value in $(do_facet $SINGLEMDS \
6300                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6301                 param=$(echo ${value[0]} | cut -d "=" -f1)
6302                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6303
6304                 if $support_last_seq; then
6305                         param_seq=$(echo $param |
6306                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6307                         mds_last_seq=$(do_facet $SINGLEMDS \
6308                                        $LCTL get_param -n $param_seq)
6309                 fi
6310                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6311
6312                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6313                 node=$(facet_active_host ost$((ostnum+1)))
6314                 param="obdfilter.$ostname.last_id"
6315                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6316                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6317                         ost_last_id=$ost_last
6318
6319                         if $support_last_seq; then
6320                                 ost_last_id=$(echo $ost_last |
6321                                               awk -F':' '{print $2}' |
6322                                               sed -e "s/^0x//g")
6323                                 ost_last_seq=$(echo $ost_last |
6324                                                awk -F':' '{print $1}')
6325                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6326                         fi
6327
6328                         if [[ $ost_last_id != $mds_last ]]; then
6329                                 error "$ost_last_id != $mds_last"
6330                         else
6331                                 found=true
6332                                 break
6333                         fi
6334                 done
6335         done
6336         $found || error "can not match last_seq/last_id for $mdtosc"
6337         return 0
6338 }
6339 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6340
6341 test_54a() {
6342         LANG=C perl -MSocket -e ';' || skip "no Socket perl module installed"
6343
6344         LANG=C $SOCKETSERVER $DIR/socket ||
6345                 error "$SOCKETSERVER $DIR/socket failed: $?"
6346         LANG=C $SOCKETCLIENT $DIR/socket ||
6347                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6348         unlink $DIR/socket || error "unlink $DIR/socket failed: $?"
6349 }
6350 run_test 54a "unix domain socket test =========================="
6351
6352 test_54b() {
6353         f="$DIR/f54b"
6354         mknod $f c 1 3
6355         chmod 0666 $f
6356         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6357 }
6358 run_test 54b "char device works in lustre ======================"
6359
6360 find_loop_dev() {
6361         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6362         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6363         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6364
6365         for i in $(seq 3 7); do
6366                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6367                 LOOPDEV=$LOOPBASE$i
6368                 LOOPNUM=$i
6369                 break
6370         done
6371 }
6372
6373 cleanup_54c() {
6374         local rc=0
6375         loopdev="$DIR/loop54c"
6376
6377         trap 0
6378         $UMOUNT $DIR/$tdir || rc=$?
6379         losetup -d $loopdev || true
6380         losetup -d $LOOPDEV || true
6381         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6382         return $rc
6383 }
6384
6385 test_54c() {
6386         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6387
6388         loopdev="$DIR/loop54c"
6389
6390         find_loop_dev
6391         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6392         trap cleanup_54c EXIT
6393         mknod $loopdev b 7 $LOOPNUM
6394         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6395         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6396         losetup $loopdev $DIR/$tfile ||
6397                 error "can't set up $loopdev for $DIR/$tfile"
6398         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6399         test_mkdir $DIR/$tdir
6400         mount -t ext2 $loopdev $DIR/$tdir ||
6401                 error "error mounting $loopdev on $DIR/$tdir"
6402         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6403                 error "dd write"
6404         df $DIR/$tdir
6405         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6406                 error "dd read"
6407         cleanup_54c
6408 }
6409 run_test 54c "block device works in lustre ====================="
6410
6411 test_54d() {
6412         local pipe="$DIR/$tfile.pipe"
6413         local string="aaaaaa"
6414
6415         mknod $pipe p
6416         echo -n "$string" > $pipe &
6417         local result=$(cat $pipe)
6418         [[ "$result" == "$string" ]] || error "$result != $string"
6419 }
6420 run_test 54d "fifo device works in lustre ======================"
6421
6422 test_54e() {
6423         f="$DIR/f54e"
6424         string="aaaaaa"
6425         cp -aL /dev/console $f
6426         echo $string > $f || error "echo $string to $f failed"
6427 }
6428 run_test 54e "console/tty device works in lustre ======================"
6429
6430 test_55a() {
6431         local dev_path="/sys/kernel/debug/lustre/devices"
6432
6433         load_module kunit/obd_test verbose=2 || error "load_module failed"
6434
6435         # This must be run in iteractive mode, since attach and setup
6436         # are stateful
6437         eval "$LCTL <<-EOF || error 'OBD device creation failed'
6438                 attach obd_test obd_name obd_uuid
6439                 setup obd_test
6440         EOF"
6441
6442         echo "Devices:"
6443         cat "$dev_path" | tail -n 10
6444
6445         $LCTL --device "obd_name" cleanup
6446         $LCTL --device "obd_name" detach
6447
6448         dmesg | tail -n 25 | grep "Lustre: OBD:.*FAIL" &&
6449                 error "OBD unit test failed"
6450
6451         rmmod -v obd_test ||
6452                 error "rmmod failed (may trigger a failure in a later test)"
6453 }
6454 run_test 55a "OBD device life cycle unit tests"
6455
6456 test_55b() {
6457         local dev_path="/sys/kernel/debug/lustre/devices"
6458         local dev_count="$(wc -l $dev_path | awk '{print $1}')"
6459
6460         # Set up a large number of devices, using the number
6461         # that can be set up in about a minute (based on prior
6462         # testing). We don't want to run this test forever.
6463         local num_dev_to_create="$(( 24000 - $dev_count))"
6464
6465         load_module kunit/obd_test || error "load_module failed"
6466
6467         local start=$SECONDS
6468
6469         # This must be run in iteractive mode, since attach and setup
6470         # are stateful
6471         for ((i = 1; i <= num_dev_to_create; i++)); do
6472                 echo "attach obd_test obd_name_$i obd_uuid_$i"
6473                 echo "setup obd_test_$i"
6474         done | $LCTL || error "OBD device creation failed"
6475
6476         echo "Load time: $((SECONDS - start))"
6477         echo "Devices:"
6478         cat "$dev_path" | tail -n 10
6479
6480         for ((i = 1; i <= num_dev_to_create; i++)); do
6481                 echo "--device obd_name_$i cleanup"
6482                 echo "--device obd_name_$i detach"
6483         done | $LCTL || error "OBD device cleanup failed"
6484
6485         echo "Unload time: $((SECONDS - start))"
6486
6487         rmmod -v obd_test ||
6488                 error "rmmod failed (may trigger a failure in a later test)"
6489 }
6490 run_test 55b "Load and unload max OBD devices"
6491
6492 test_56a() {
6493         local numfiles=3
6494         local numdirs=2
6495         local dir=$DIR/$tdir
6496
6497         rm -rf $dir
6498         test_mkdir -p $dir/dir
6499         for i in $(seq $numfiles); do
6500                 touch $dir/file$i
6501                 touch $dir/dir/file$i
6502         done
6503
6504         local numcomp=$($LFS getstripe --component-count $dir)
6505
6506         [[ $numcomp == 0 ]] && numcomp=1
6507
6508         # test lfs getstripe with --recursive
6509         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6510
6511         [[ $filenum -eq $((numfiles * 2)) ]] ||
6512                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6513         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6514         [[ $filenum -eq $numfiles ]] ||
6515                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6516         echo "$LFS getstripe showed obdidx or l_ost_idx"
6517
6518         # test lfs getstripe with file instead of dir
6519         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6520         [[ $filenum -eq 1 ]] ||
6521                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6522         echo "$LFS getstripe file1 passed"
6523
6524         #test lfs getstripe with --verbose
6525         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6526         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6527                 error "$LFS getstripe --verbose $dir: "\
6528                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6529         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6530                 error "$LFS getstripe $dir: showed lmm_magic"
6531
6532         #test lfs getstripe with -v prints lmm_fid
6533         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6534         local countfids=$((numdirs + numfiles * numcomp))
6535         [[ $filenum -eq $countfids ]] ||
6536                 error "$LFS getstripe -v $dir: "\
6537                       "got $filenum want $countfids lmm_fid"
6538         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6539                 error "$LFS getstripe $dir: showed lmm_fid by default"
6540         echo "$LFS getstripe --verbose passed"
6541
6542         #check for FID information
6543         local fid1=$($LFS getstripe --fid $dir/file1)
6544         local fid2=$($LFS getstripe --verbose $dir/file1 |
6545                      awk '/lmm_fid: / { print $2; exit; }')
6546         local fid3=$($LFS path2fid $dir/file1)
6547
6548         [ "$fid1" != "$fid2" ] &&
6549                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6550         [ "$fid1" != "$fid3" ] &&
6551                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6552         echo "$LFS getstripe --fid passed"
6553
6554         #test lfs getstripe with --obd
6555         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6556                 error "$LFS getstripe --obd wrong_uuid: should return error"
6557
6558         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6559
6560         local ostidx=1
6561         local obduuid=$(ostuuid_from_index $ostidx)
6562         local found=$($LFS getstripe -r --obd $obduuid $dir |
6563                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6564
6565         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6566         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6567                 ((filenum--))
6568         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6569                 ((filenum--))
6570
6571         [[ $found -eq $filenum ]] ||
6572                 error "$LFS getstripe --obd: found $found expect $filenum"
6573         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6574                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6575                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6576                 error "$LFS getstripe --obd: should not show file on other obd"
6577         echo "$LFS getstripe --obd passed"
6578 }
6579 run_test 56a "check $LFS getstripe"
6580
6581 test_56b() {
6582         local dir=$DIR/$tdir
6583         local numdirs=3
6584
6585         test_mkdir $dir
6586         for i in $(seq $numdirs); do
6587                 test_mkdir $dir/dir$i
6588         done
6589
6590         # test lfs getdirstripe default mode is non-recursion, which is
6591         # different from lfs getstripe
6592         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6593
6594         [[ $dircnt -eq 1 ]] ||
6595                 error "$LFS getdirstripe: found $dircnt, not 1"
6596         dircnt=$($LFS getdirstripe --recursive $dir |
6597                 grep -c lmv_stripe_count)
6598         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6599                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6600 }
6601 run_test 56b "check $LFS getdirstripe"
6602
6603 test_56bb() {
6604         verify_yaml_available || skip_env "YAML verification not installed"
6605         local output_file=$DIR/$tfile.out
6606
6607         $LFS getdirstripe -v -D -y $DIR 1> $output_file
6608
6609         cat $output_file
6610         cat $output_file | verify_yaml || error "layout is not valid YAML"
6611 }
6612 run_test 56bb "check $LFS getdirstripe layout is YAML"
6613
6614 test_56c() {
6615         remote_ost_nodsh && skip "remote OST with nodsh"
6616
6617         local ost_idx=0
6618         local ost_name=$(ostname_from_index $ost_idx)
6619         local old_status=$(ost_dev_status $ost_idx)
6620         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6621
6622         [[ -z "$old_status" ]] ||
6623                 skip_env "OST $ost_name is in $old_status status"
6624
6625         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6626         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6627                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6628         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6629                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6630                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6631         fi
6632
6633         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6634                 error "$LFS df -v showing inactive devices"
6635         sleep_maxage
6636
6637         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6638
6639         [[ "$new_status" =~ "D" ]] ||
6640                 error "$ost_name status is '$new_status', missing 'D'"
6641         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6642                 [[ "$new_status" =~ "N" ]] ||
6643                         error "$ost_name status is '$new_status', missing 'N'"
6644         fi
6645         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6646                 [[ "$new_status" =~ "f" ]] ||
6647                         error "$ost_name status is '$new_status', missing 'f'"
6648         fi
6649
6650         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6651         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6652                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6653         [[ -z "$p" ]] && restore_lustre_params < $p || true
6654         sleep_maxage
6655
6656         new_status=$(ost_dev_status $ost_idx)
6657         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6658                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6659         # can't check 'f' as devices may actually be on flash
6660 }
6661 run_test 56c "check 'lfs df' showing device status"
6662
6663 test_56d() {
6664         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6665         local osts=$($LFS df -v $MOUNT | grep -c OST)
6666
6667         $LFS df $MOUNT
6668
6669         (( mdts == MDSCOUNT )) ||
6670                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6671         (( osts == OSTCOUNT )) ||
6672                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6673 }
6674 run_test 56d "'lfs df -v' prints only configured devices"
6675
6676 test_56e() {
6677         err_enoent=2 # No such file or directory
6678         err_eopnotsupp=95 # Operation not supported
6679
6680         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6681         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6682
6683         # Check for handling of path not exists
6684         output=$($LFS df $enoent_mnt 2>&1)
6685         ret=$?
6686
6687         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6688         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6689                 error "expect failure $err_enoent, not $ret"
6690
6691         # Check for handling of non-Lustre FS
6692         output=$($LFS df $notsup_mnt)
6693         ret=$?
6694
6695         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6696         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6697                 error "expect success $err_eopnotsupp, not $ret"
6698
6699         # Check for multiple LustreFS argument
6700         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6701         ret=$?
6702
6703         [[ $output -eq 3 && $ret -eq 0 ]] ||
6704                 error "expect success 3, not $output, rc = $ret"
6705
6706         # Check for correct non-Lustre FS handling among multiple
6707         # LustreFS argument
6708         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6709                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6710         ret=$?
6711
6712         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6713                 error "expect success 2, not $output, rc = $ret"
6714 }
6715 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6716
6717 NUMFILES=3
6718 NUMDIRS=3
6719 setup_56() {
6720         local local_tdir="$1"
6721         local local_numfiles="$2"
6722         local local_numdirs="$3"
6723         local dir_params="$4"
6724         local dir_stripe_params="$5"
6725
6726         if [ ! -d "$local_tdir" ] ; then
6727                 test_mkdir -p $dir_stripe_params $local_tdir
6728                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6729                 for i in $(seq $local_numfiles) ; do
6730                         touch $local_tdir/file$i
6731                 done
6732                 for i in $(seq $local_numdirs) ; do
6733                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6734                         for j in $(seq $local_numfiles) ; do
6735                                 touch $local_tdir/dir$i/file$j
6736                         done
6737                 done
6738         fi
6739 }
6740
6741 setup_56_special() {
6742         local local_tdir=$1
6743         local local_numfiles=$2
6744         local local_numdirs=$3
6745
6746         setup_56 $local_tdir $local_numfiles $local_numdirs
6747
6748         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6749                 for i in $(seq $local_numfiles) ; do
6750                         mknod $local_tdir/loop${i}b b 7 $i
6751                         mknod $local_tdir/null${i}c c 1 3
6752                         ln -s $local_tdir/file1 $local_tdir/link${i}
6753                 done
6754                 for i in $(seq $local_numdirs) ; do
6755                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6756                         mknod $local_tdir/dir$i/null${i}c c 1 3
6757                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6758                 done
6759         fi
6760 }
6761
6762 test_56g() {
6763         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6764         local expected=$(($NUMDIRS + 2))
6765
6766         setup_56 $dir $NUMFILES $NUMDIRS
6767
6768         # test lfs find with -name
6769         for i in $(seq $NUMFILES) ; do
6770                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6771
6772                 [ $nums -eq $expected ] ||
6773                         error "lfs find -name '*$i' $dir wrong: "\
6774                               "found $nums, expected $expected"
6775         done
6776 }
6777 run_test 56g "check lfs find -name"
6778
6779 test_56h() {
6780         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6781         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6782
6783         setup_56 $dir $NUMFILES $NUMDIRS
6784
6785         # test lfs find with ! -name
6786         for i in $(seq $NUMFILES) ; do
6787                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6788
6789                 [ $nums -eq $expected ] ||
6790                         error "lfs find ! -name '*$i' $dir wrong: "\
6791                               "found $nums, expected $expected"
6792         done
6793 }
6794 run_test 56h "check lfs find ! -name"
6795
6796 test_56i() {
6797         local dir=$DIR/$tdir
6798
6799         test_mkdir $dir
6800
6801         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6802         local out=$($cmd)
6803
6804         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6805 }
6806 run_test 56i "check 'lfs find -ost UUID' skips directories"
6807
6808 test_56j() {
6809         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6810
6811         setup_56_special $dir $NUMFILES $NUMDIRS
6812
6813         local expected=$((NUMDIRS + 1))
6814         local cmd="$LFS find -type d $dir"
6815         local nums=$($cmd | wc -l)
6816
6817         [ $nums -eq $expected ] ||
6818                 error "'$cmd' wrong: found $nums, expected $expected"
6819 }
6820 run_test 56j "check lfs find -type d"
6821
6822 test_56k() {
6823         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6824
6825         setup_56_special $dir $NUMFILES $NUMDIRS
6826
6827         local expected=$(((NUMDIRS + 1) * NUMFILES))
6828         local cmd="$LFS find -type f $dir"
6829         local nums=$($cmd | wc -l)
6830
6831         [ $nums -eq $expected ] ||
6832                 error "'$cmd' wrong: found $nums, expected $expected"
6833 }
6834 run_test 56k "check lfs find -type f"
6835
6836 test_56l() {
6837         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6838
6839         setup_56_special $dir $NUMFILES $NUMDIRS
6840
6841         local expected=$((NUMDIRS + NUMFILES))
6842         local cmd="$LFS find -type b $dir"
6843         local nums=$($cmd | wc -l)
6844
6845         [ $nums -eq $expected ] ||
6846                 error "'$cmd' wrong: found $nums, expected $expected"
6847 }
6848 run_test 56l "check lfs find -type b"
6849
6850 test_56m() {
6851         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6852
6853         setup_56_special $dir $NUMFILES $NUMDIRS
6854
6855         local expected=$((NUMDIRS + NUMFILES))
6856         local cmd="$LFS find -type c $dir"
6857         local nums=$($cmd | wc -l)
6858         [ $nums -eq $expected ] ||
6859                 error "'$cmd' wrong: found $nums, expected $expected"
6860 }
6861 run_test 56m "check lfs find -type c"
6862
6863 test_56n() {
6864         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6865         setup_56_special $dir $NUMFILES $NUMDIRS
6866
6867         local expected=$((NUMDIRS + NUMFILES))
6868         local cmd="$LFS find -type l $dir"
6869         local nums=$($cmd | wc -l)
6870
6871         [ $nums -eq $expected ] ||
6872                 error "'$cmd' wrong: found $nums, expected $expected"
6873 }
6874 run_test 56n "check lfs find -type l"
6875
6876 test_56o() {
6877         local dir=$DIR/$tdir
6878
6879         setup_56 $dir $NUMFILES $NUMDIRS
6880         utime $dir/file1 > /dev/null || error "utime (1)"
6881         utime $dir/file2 > /dev/null || error "utime (2)"
6882         utime $dir/dir1 > /dev/null || error "utime (3)"
6883         utime $dir/dir2 > /dev/null || error "utime (4)"
6884         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6885         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6886
6887         local expected=4
6888         local nums=$($LFS find -mtime +0 $dir | wc -l)
6889
6890         [ $nums -eq $expected ] ||
6891                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6892
6893         expected=12
6894         cmd="$LFS find -mtime 0 $dir"
6895         nums=$($cmd | wc -l)
6896         [ $nums -eq $expected ] ||
6897                 error "'$cmd' wrong: found $nums, expected $expected"
6898 }
6899 run_test 56o "check lfs find -mtime for old files"
6900
6901 test_56ob() {
6902         local dir=$DIR/$tdir
6903         local expected=1
6904         local count=0
6905
6906         # just to make sure there is something that won't be found
6907         test_mkdir $dir
6908         touch $dir/$tfile.now
6909
6910         for age in year week day hour min; do
6911                 count=$((count + 1))
6912
6913                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6914                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6915                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6916
6917                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6918                 local nums=$($cmd | wc -l)
6919                 [ $nums -eq $expected ] ||
6920                         error "'$cmd' wrong: found $nums, expected $expected"
6921
6922                 cmd="$LFS find $dir -atime $count${age:0:1}"
6923                 nums=$($cmd | wc -l)
6924                 [ $nums -eq $expected ] ||
6925                         error "'$cmd' wrong: found $nums, expected $expected"
6926         done
6927
6928         sleep 2
6929         cmd="$LFS find $dir -ctime +1s -type f"
6930         nums=$($cmd | wc -l)
6931         (( $nums == $count * 2 + 1)) ||
6932                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6933 }
6934 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6935
6936 test_newerXY_base() {
6937         local x=$1
6938         local y=$2
6939         local dir=$DIR/$tdir
6940         local ref
6941         local negref
6942
6943         if [ $y == "t" ]; then
6944                 if [ $x == "b" ]; then
6945                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6946                 else
6947                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6948                 fi
6949         else
6950                 ref=$DIR/$tfile.newer.$x$y
6951                 touch $ref || error "touch $ref failed"
6952         fi
6953
6954         echo "before = $ref"
6955         sleep 2
6956         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6957         sleep 2
6958         if [ $y == "t" ]; then
6959                 if [ $x == "b" ]; then
6960                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6961                 else
6962                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6963                 fi
6964         else
6965                 negref=$DIR/$tfile.negnewer.$x$y
6966                 touch $negref || error "touch $negref failed"
6967         fi
6968
6969         echo "after = $negref"
6970         local cmd="$LFS find $dir -newer$x$y $ref"
6971         local nums=$(eval $cmd | wc -l)
6972         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6973
6974         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6975                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6976
6977         cmd="$LFS find $dir ! -newer$x$y $negref"
6978         nums=$(eval $cmd | wc -l)
6979         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6980                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6981
6982         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6983         nums=$(eval $cmd | wc -l)
6984         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6985                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6986
6987         rm -rf $DIR/*
6988 }
6989
6990 test_56oc() {
6991         test_newerXY_base "a" "a"
6992         test_newerXY_base "a" "m"
6993         test_newerXY_base "a" "c"
6994         test_newerXY_base "m" "a"
6995         test_newerXY_base "m" "m"
6996         test_newerXY_base "m" "c"
6997         test_newerXY_base "c" "a"
6998         test_newerXY_base "c" "m"
6999         test_newerXY_base "c" "c"
7000
7001         test_newerXY_base "a" "t"
7002         test_newerXY_base "m" "t"
7003         test_newerXY_base "c" "t"
7004
7005         (( $MDS1_VERSION >= $(version_code v2_13_53-145-g186b97e68a) &&
7006            $CLIENT_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
7007                 { echo "btime needs v2_13_53-145-g186b97e68a"; return 0; }
7008
7009         test_newerXY_base "b" "b"
7010         test_newerXY_base "b" "t"
7011 }
7012 run_test 56oc "check lfs find -newerXY work"
7013
7014 test_56od() {
7015         (( $MDS1_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
7016                 skip "btime unsupported on MDS < v2_13_53-145-g186b97e68a"
7017
7018         (( $CLIENT_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
7019                 skip "btime unsupported on clients < v2_13_53-145-g186b97e68a"
7020
7021         local dir=$DIR/$tdir
7022         local ref=$DIR/$tfile.ref
7023         local negref=$DIR/$tfile.negref
7024
7025         mkdir $dir || error "mkdir $dir failed"
7026         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
7027         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
7028         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
7029         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
7030         touch $ref || error "touch $ref failed"
7031         # sleep 3 seconds at least
7032         sleep 3
7033
7034         local before=$(do_facet mds1 date +%s)
7035         local skew=$(($(date +%s) - before + 1))
7036
7037         if (( skew < 0 && skew > -5 )); then
7038                 sleep $((0 - skew + 1))
7039                 skew=0
7040         fi
7041
7042         # Set the dir stripe params to limit files all on MDT0,
7043         # otherwise we need to calc the max clock skew between
7044         # the client and MDTs.
7045         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
7046         sleep 2
7047         touch $negref || error "touch $negref failed"
7048
7049         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
7050         local nums=$($cmd | wc -l)
7051         local expected=$(((NUMFILES + 1) * NUMDIRS))
7052
7053         [ $nums -eq $expected ] ||
7054                 error "'$cmd' wrong: found $nums, expected $expected"
7055
7056         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
7057         nums=$($cmd | wc -l)
7058         expected=$((NUMFILES + 1))
7059         [ $nums -eq $expected ] ||
7060                 error "'$cmd' wrong: found $nums, expected $expected"
7061
7062         [ $skew -lt 0 ] && return
7063
7064         local after=$(do_facet mds1 date +%s)
7065         local age=$((after - before + 1 + skew))
7066
7067         cmd="$LFS find $dir -btime -${age}s -type f"
7068         nums=$($cmd | wc -l)
7069         expected=$(((NUMFILES + 1) * NUMDIRS))
7070
7071         echo "Clock skew between client and server: $skew, age:$age"
7072         [ $nums -eq $expected ] ||
7073                 error "'$cmd' wrong: found $nums, expected $expected"
7074
7075         expected=$(($NUMDIRS + 1))
7076         cmd="$LFS find $dir -btime -${age}s -type d"
7077         nums=$($cmd | wc -l)
7078         [ $nums -eq $expected ] ||
7079                 error "'$cmd' wrong: found $nums, expected $expected"
7080         rm -f $ref $negref || error "Failed to remove $ref $negref"
7081 }
7082 run_test 56od "check lfs find -btime with units"
7083
7084 test_56p() {
7085         [ $RUNAS_ID -eq $UID ] &&
7086                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7087
7088         local dir=$DIR/$tdir
7089
7090         setup_56 $dir $NUMFILES $NUMDIRS
7091         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
7092
7093         local expected=$NUMFILES
7094         local cmd="$LFS find -uid $RUNAS_ID $dir"
7095         local nums=$($cmd | wc -l)
7096
7097         [ $nums -eq $expected ] ||
7098                 error "'$cmd' wrong: found $nums, expected $expected"
7099
7100         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
7101         cmd="$LFS find ! -uid $RUNAS_ID $dir"
7102         nums=$($cmd | wc -l)
7103         [ $nums -eq $expected ] ||
7104                 error "'$cmd' wrong: found $nums, expected $expected"
7105 }
7106 run_test 56p "check lfs find -uid and ! -uid"
7107
7108 test_56q() {
7109         [ $RUNAS_ID -eq $UID ] &&
7110                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7111
7112         local dir=$DIR/$tdir
7113
7114         setup_56 $dir $NUMFILES $NUMDIRS
7115         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
7116
7117         local expected=$NUMFILES
7118         local cmd="$LFS find -gid $RUNAS_GID $dir"
7119         local nums=$($cmd | wc -l)
7120
7121         [ $nums -eq $expected ] ||
7122                 error "'$cmd' wrong: found $nums, expected $expected"
7123
7124         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
7125         cmd="$LFS find ! -gid $RUNAS_GID $dir"
7126         nums=$($cmd | wc -l)
7127         [ $nums -eq $expected ] ||
7128                 error "'$cmd' wrong: found $nums, expected $expected"
7129 }
7130 run_test 56q "check lfs find -gid and ! -gid"
7131
7132 test_56r() {
7133         local dir=$DIR/$tdir
7134
7135         setup_56 $dir $NUMFILES $NUMDIRS
7136
7137         local expected=12
7138         local cmd="$LFS find -size 0 -type f -lazy $dir"
7139         local nums=$($cmd | wc -l)
7140
7141         [ $nums -eq $expected ] ||
7142                 error "'$cmd' wrong: found $nums, expected $expected"
7143         cmd="$LFS find -size 0 -type f $dir"
7144         nums=$($cmd | wc -l)
7145         [ $nums -eq $expected ] ||
7146                 error "'$cmd' wrong: found $nums, expected $expected"
7147
7148         expected=0
7149         cmd="$LFS find ! -size 0 -type f -lazy $dir"
7150         nums=$($cmd | wc -l)
7151         [ $nums -eq $expected ] ||
7152                 error "'$cmd' wrong: found $nums, expected $expected"
7153         cmd="$LFS find ! -size 0 -type f $dir"
7154         nums=$($cmd | wc -l)
7155         [ $nums -eq $expected ] ||
7156                 error "'$cmd' wrong: found $nums, expected $expected"
7157
7158         echo "test" > $dir/$tfile
7159         echo "test2" > $dir/$tfile.2 && sync
7160         expected=1
7161         cmd="$LFS find -size 5c -type f -lazy $dir"
7162         nums=$($cmd | wc -l)
7163         [ $nums -eq $expected ] ||
7164                 error "'$cmd' wrong: found $nums, expected $expected"
7165         cmd="$LFS find -size 5c -type f $dir"
7166         nums=$($cmd | wc -l)
7167         [ $nums -eq $expected ] ||
7168                 error "'$cmd' wrong: found $nums, expected $expected"
7169
7170         expected=1
7171         cmd="$LFS find -size +5c -type f -lazy $dir"
7172         nums=$($cmd | wc -l)
7173         [ $nums -eq $expected ] ||
7174                 error "'$cmd' wrong: found $nums, expected $expected"
7175         cmd="$LFS find -size +5c -type f $dir"
7176         nums=$($cmd | wc -l)
7177         [ $nums -eq $expected ] ||
7178                 error "'$cmd' wrong: found $nums, expected $expected"
7179
7180         expected=2
7181         cmd="$LFS find -size +0 -type f -lazy $dir"
7182         nums=$($cmd | wc -l)
7183         [ $nums -eq $expected ] ||
7184                 error "'$cmd' wrong: found $nums, expected $expected"
7185         cmd="$LFS find -size +0 -type f $dir"
7186         nums=$($cmd | wc -l)
7187         [ $nums -eq $expected ] ||
7188                 error "'$cmd' wrong: found $nums, expected $expected"
7189
7190         expected=2
7191         cmd="$LFS find ! -size -5c -type f -lazy $dir"
7192         nums=$($cmd | wc -l)
7193         [ $nums -eq $expected ] ||
7194                 error "'$cmd' wrong: found $nums, expected $expected"
7195         cmd="$LFS find ! -size -5c -type f $dir"
7196         nums=$($cmd | wc -l)
7197         [ $nums -eq $expected ] ||
7198                 error "'$cmd' wrong: found $nums, expected $expected"
7199
7200         expected=12
7201         cmd="$LFS find -size -5c -type f -lazy $dir"
7202         nums=$($cmd | wc -l)
7203         [ $nums -eq $expected ] ||
7204                 error "'$cmd' wrong: found $nums, expected $expected"
7205         cmd="$LFS find -size -5c -type f $dir"
7206         nums=$($cmd | wc -l)
7207         [ $nums -eq $expected ] ||
7208                 error "'$cmd' wrong: found $nums, expected $expected"
7209 }
7210 run_test 56r "check lfs find -size works"
7211
7212 test_56ra_sub() {
7213         local expected=$1
7214         local glimpses=$2
7215         local cmd="$3"
7216
7217         cancel_lru_locks $OSC
7218
7219         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7220         local nums=$($cmd | wc -l)
7221
7222         [ $nums -eq $expected ] ||
7223                 error "'$cmd' wrong: found $nums, expected $expected"
7224
7225         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7226
7227         if (( rpcs_before + glimpses != rpcs_after )); then
7228                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
7229                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
7230
7231                 if [[ $glimpses == 0 ]]; then
7232                         error "'$cmd' should not send glimpse RPCs to OST"
7233                 else
7234                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
7235                 fi
7236         fi
7237 }
7238
7239 test_56ra() {
7240         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
7241                 skip "MDS < 2.12.58 doesn't return LSOM data"
7242         local dir=$DIR/$tdir
7243         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
7244
7245         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
7246
7247         # statahead_agl may cause extra glimpse which confuses results. LU-13017
7248         $LCTL set_param -n llite.*.statahead_agl=0
7249         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
7250
7251         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7252         # open and close all files to ensure LSOM is updated
7253         cancel_lru_locks $OSC
7254         find $dir -type f | xargs cat > /dev/null
7255
7256         #   expect_found  glimpse_rpcs  command_to_run
7257         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
7258         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
7259         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
7260         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
7261
7262         echo "test" > $dir/$tfile
7263         echo "test2" > $dir/$tfile.2 && sync
7264         cancel_lru_locks $OSC
7265         cat $dir/$tfile $dir/$tfile.2 > /dev/null
7266
7267         test_56ra_sub  1  0 "$LFS find -size 5c -type f -lazy $dir"
7268         test_56ra_sub  1 14 "$LFS find -size 5c -type f $dir"
7269         test_56ra_sub  1  0 "$LFS find -size +5c -type f -lazy $dir"
7270         test_56ra_sub  1 14 "$LFS find -size +5c -type f $dir"
7271
7272         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
7273         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
7274         test_56ra_sub  2  0 "$LFS find ! -size -5c -type f -lazy $dir"
7275         test_56ra_sub  2 14 "$LFS find ! -size -5c -type f $dir"
7276         test_56ra_sub 12  0 "$LFS find -size -5c -type f -lazy $dir"
7277         test_56ra_sub 12 14 "$LFS find -size -5c -type f $dir"
7278 }
7279 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
7280
7281 test_56rb() {
7282         local dir=$DIR/$tdir
7283         local tmp=$TMP/$tfile.log
7284         local mdt_idx;
7285
7286         test_mkdir -p $dir || error "failed to mkdir $dir"
7287         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
7288                 error "failed to setstripe $dir/$tfile"
7289         mdt_idx=$($LFS getdirstripe -i $dir)
7290         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
7291
7292         stack_trap "rm -f $tmp" EXIT
7293         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7294         ! grep -q obd_uuid $tmp ||
7295                 error "failed to find --size +100K --ost 0 $dir"
7296         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7297         ! grep -q obd_uuid $tmp ||
7298                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7299 }
7300 run_test 56rb "check lfs find --size --ost/--mdt works"
7301
7302 test_56rc() {
7303         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7304         local dir=$DIR/$tdir
7305         local found
7306
7307         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7308         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7309         (( $MDSCOUNT > 2 )) &&
7310                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7311         mkdir $dir/$tdir-{1..10}
7312         touch $dir/$tfile-{1..10}
7313
7314         found=$($LFS find $dir --mdt-count 2 | wc -l)
7315         expect=11
7316         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7317
7318         found=$($LFS find $dir -T +1 | wc -l)
7319         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7320         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7321
7322         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7323         expect=11
7324         (( $found == $expect )) || error "found $found all_char, expect $expect"
7325
7326         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7327         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7328         (( $found == $expect )) || error "found $found all_char, expect $expect"
7329 }
7330 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7331
7332 test_56rd() {
7333         local dir=$DIR/$tdir
7334
7335         test_mkdir $dir
7336         rm -f $dir/*
7337
7338         mkfifo $dir/fifo || error "failed to create fifo file"
7339         $LFS find $dir -t p --printf "%p %y %LP\n" ||
7340                 error "should not fail even cannot get projid from pipe file"
7341         found=$($LFS find $dir -t p --printf "%y")
7342         [[ "p" == $found ]] || error "found $found, expect p"
7343
7344         mknod $dir/chardev c 1 5 ||
7345                 error "failed to create character device file"
7346         $LFS find $dir -t c --printf "%p %y %LP\n" ||
7347                 error "should not fail even cannot get projid from chardev file"
7348         found=$($LFS find $dir -t c --printf "%y")
7349         [[ "c" == $found ]] || error "found $found, expect c"
7350
7351         found=$($LFS find $dir ! -type d --printf "%p %y %LP\n" | wc -l)
7352         (( found == 2 )) || error "unable to list all files"
7353 }
7354 run_test 56rd "check lfs find --printf special files"
7355
7356 test_56s() { # LU-611 #LU-9369
7357         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7358
7359         local dir=$DIR/$tdir
7360         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7361
7362         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7363         for i in $(seq $NUMDIRS); do
7364                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7365         done
7366
7367         local expected=$NUMDIRS
7368         local cmd="$LFS find -c $OSTCOUNT $dir"
7369         local nums=$($cmd | wc -l)
7370
7371         [ $nums -eq $expected ] || {
7372                 $LFS getstripe -R $dir
7373                 error "'$cmd' wrong: found $nums, expected $expected"
7374         }
7375
7376         expected=$((NUMDIRS + onestripe))
7377         cmd="$LFS find -stripe-count +0 -type f $dir"
7378         nums=$($cmd | wc -l)
7379         [ $nums -eq $expected ] || {
7380                 $LFS getstripe -R $dir
7381                 error "'$cmd' wrong: found $nums, expected $expected"
7382         }
7383
7384         expected=$onestripe
7385         cmd="$LFS find -stripe-count 1 -type f $dir"
7386         nums=$($cmd | wc -l)
7387         [ $nums -eq $expected ] || {
7388                 $LFS getstripe -R $dir
7389                 error "'$cmd' wrong: found $nums, expected $expected"
7390         }
7391
7392         cmd="$LFS find -stripe-count -2 -type f $dir"
7393         nums=$($cmd | wc -l)
7394         [ $nums -eq $expected ] || {
7395                 $LFS getstripe -R $dir
7396                 error "'$cmd' wrong: found $nums, expected $expected"
7397         }
7398
7399         expected=0
7400         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7401         nums=$($cmd | wc -l)
7402         [ $nums -eq $expected ] || {
7403                 $LFS getstripe -R $dir
7404                 error "'$cmd' wrong: found $nums, expected $expected"
7405         }
7406 }
7407 run_test 56s "check lfs find -stripe-count works"
7408
7409 test_56t() { # LU-611 #LU-9369
7410         local dir=$DIR/$tdir
7411
7412         setup_56 $dir 0 $NUMDIRS
7413         for i in $(seq $NUMDIRS); do
7414                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7415         done
7416
7417         local expected=$NUMDIRS
7418         local cmd="$LFS find -S 8M $dir"
7419         local nums=$($cmd | wc -l)
7420
7421         [ $nums -eq $expected ] || {
7422                 $LFS getstripe -R $dir
7423                 error "'$cmd' wrong: found $nums, expected $expected"
7424         }
7425         rm -rf $dir
7426
7427         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7428
7429         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7430
7431         expected=$(((NUMDIRS + 1) * NUMFILES))
7432         cmd="$LFS find -stripe-size 512k -type f $dir"
7433         nums=$($cmd | wc -l)
7434         [ $nums -eq $expected ] ||
7435                 error "'$cmd' wrong: found $nums, expected $expected"
7436
7437         cmd="$LFS find -stripe-size +320k -type f $dir"
7438         nums=$($cmd | wc -l)
7439         [ $nums -eq $expected ] ||
7440                 error "'$cmd' wrong: found $nums, expected $expected"
7441
7442         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7443         cmd="$LFS find -stripe-size +200k -type f $dir"
7444         nums=$($cmd | wc -l)
7445         [ $nums -eq $expected ] ||
7446                 error "'$cmd' wrong: found $nums, expected $expected"
7447
7448         cmd="$LFS find -stripe-size -640k -type f $dir"
7449         nums=$($cmd | wc -l)
7450         [ $nums -eq $expected ] ||
7451                 error "'$cmd' wrong: found $nums, expected $expected"
7452
7453         expected=4
7454         cmd="$LFS find -stripe-size 256k -type f $dir"
7455         nums=$($cmd | wc -l)
7456         [ $nums -eq $expected ] ||
7457                 error "'$cmd' wrong: found $nums, expected $expected"
7458
7459         cmd="$LFS find -stripe-size -320k -type f $dir"
7460         nums=$($cmd | wc -l)
7461         [ $nums -eq $expected ] ||
7462                 error "'$cmd' wrong: found $nums, expected $expected"
7463
7464         expected=0
7465         cmd="$LFS find -stripe-size 1024k -type f $dir"
7466         nums=$($cmd | wc -l)
7467         [ $nums -eq $expected ] ||
7468                 error "'$cmd' wrong: found $nums, expected $expected"
7469 }
7470 run_test 56t "check lfs find -stripe-size works"
7471
7472 test_56u() { # LU-611
7473         local dir=$DIR/$tdir
7474
7475         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7476
7477         if [[ $OSTCOUNT -gt 1 ]]; then
7478                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7479                 onestripe=4
7480         else
7481                 onestripe=0
7482         fi
7483
7484         local expected=$(((NUMDIRS + 1) * NUMFILES))
7485         local cmd="$LFS find -stripe-index 0 -type f $dir"
7486         local nums=$($cmd | wc -l)
7487
7488         [ $nums -eq $expected ] ||
7489                 error "'$cmd' wrong: found $nums, expected $expected"
7490
7491         expected=$onestripe
7492         cmd="$LFS find -stripe-index 1 -type f $dir"
7493         nums=$($cmd | wc -l)
7494         [ $nums -eq $expected ] ||
7495                 error "'$cmd' wrong: found $nums, expected $expected"
7496
7497         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7498         nums=$($cmd | wc -l)
7499         [ $nums -eq $expected ] ||
7500                 error "'$cmd' wrong: found $nums, expected $expected"
7501
7502         expected=0
7503         # This should produce an error and not return any files
7504         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7505         nums=$($cmd 2>/dev/null | wc -l)
7506         [ $nums -eq $expected ] ||
7507                 error "'$cmd' wrong: found $nums, expected $expected"
7508
7509         if [[ $OSTCOUNT -gt 1 ]]; then
7510                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7511                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7512                 nums=$($cmd | wc -l)
7513                 [ $nums -eq $expected ] ||
7514                         error "'$cmd' wrong: found $nums, expected $expected"
7515         fi
7516 }
7517 run_test 56u "check lfs find -stripe-index works"
7518
7519 test_56v() {
7520         local mdt_idx=0
7521         local dir=$DIR/$tdir
7522
7523         setup_56 $dir $NUMFILES $NUMDIRS
7524
7525         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7526         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7527
7528         for file in $($LFS find -m $UUID $dir); do
7529                 file_midx=$($LFS getstripe -m $file)
7530                 [ $file_midx -eq $mdt_idx ] ||
7531                         error "lfs find -m $UUID != getstripe -m $file_midx"
7532         done
7533 }
7534 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7535
7536 test_56wa() {
7537         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7539
7540         local dir=$DIR/$tdir
7541
7542         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7543         stack_trap "rm -rf $dir"
7544
7545         local stripe_size=$($LFS getstripe -S -d $dir) ||
7546                 error "$LFS getstripe -S -d $dir failed"
7547         stripe_size=${stripe_size%% *}
7548
7549         local file_size=$((stripe_size * OSTCOUNT))
7550         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7551         local required_space=$((file_num * file_size))
7552         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7553                            head -n1)
7554         (( free_space >= required_space / 1024 )) ||
7555                 skip_env "need $required_space, have $free_space kbytes"
7556
7557         local dd_bs=65536
7558         local dd_count=$((file_size / dd_bs))
7559
7560         # write data into the files
7561         local i
7562         local j
7563         local file
7564
7565         for ((i = 1; i <= NUMFILES; i++ )); do
7566                 file=$dir/file$i
7567                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7568                         error "write data into $file failed"
7569         done
7570         for ((i = 1; i <= NUMDIRS; i++ )); do
7571                 for ((j = 1; j <= NUMFILES; j++ )); do
7572                         file=$dir/dir$i/file$j
7573                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7574                                 error "write data into $file failed"
7575                 done
7576         done
7577
7578         # $LFS_MIGRATE will fail if hard link migration is unsupported
7579         if (( MDS1_VERSION > $(version_code 2.5.55) )); then
7580                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7581                         error "creating links to $dir/dir1/file1 failed"
7582         fi
7583
7584         local expected=-1
7585
7586         (( OSTCOUNT <= 1 )) || expected=$((OSTCOUNT - 1))
7587
7588         # lfs_migrate file
7589         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7590
7591         echo "$cmd"
7592         eval $cmd || error "$cmd failed"
7593
7594         check_stripe_count $dir/file1 $expected
7595
7596         if (( $MDS1_VERSION >= $(version_code 2.6.90) )); then
7597                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7598                 # OST 1 if it is on OST 0. This file is small enough to
7599                 # be on only one stripe.
7600                 file=$dir/migr_1_ost
7601                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7602                         error "write data into $file failed"
7603                 local obdidx=$($LFS getstripe -i $file)
7604                 local oldmd5=$(md5sum $file)
7605                 local newobdidx=0
7606
7607                 (( obdidx != 0 )) || newobdidx=1
7608                 cmd="$LFS migrate -i $newobdidx $file"
7609                 echo $cmd
7610                 eval $cmd || error "$cmd failed"
7611
7612                 local realobdix=$($LFS getstripe -i $file)
7613                 local newmd5=$(md5sum $file)
7614
7615                 (( $newobdidx == $realobdix )) ||
7616                         error "new OST is different (was=$obdidx, wanted=$newobdidx, got=$realobdix)"
7617                 [[ "$oldmd5" == "$newmd5" ]] ||
7618                         error "md5sum differ: $oldmd5, $newmd5"
7619         fi
7620
7621         # lfs_migrate dir
7622         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7623         echo "$cmd"
7624         eval $cmd || error "$cmd failed"
7625
7626         for (( j = 1; j <= NUMFILES; j++ )); do
7627                 check_stripe_count $dir/dir1/file$j $expected
7628         done
7629
7630         # lfs_migrate works with lfs find
7631         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7632              $LFS_MIGRATE -y -c $expected"
7633         echo "$cmd"
7634         eval $cmd || error "$cmd failed"
7635
7636         for (( i = 2; i <= NUMFILES; i++ )); do
7637                 check_stripe_count $dir/file$i $expected
7638         done
7639         for (( i = 2; i <= NUMDIRS; i++ )); do
7640                 for (( j = 1; j <= NUMFILES; j++ )); do
7641                         check_stripe_count $dir/dir$i/file$j $expected
7642                 done
7643         done
7644 }
7645 run_test 56wa "check lfs_migrate -c stripe_count works"
7646
7647 test_56wb() {
7648         local file1=$DIR/$tdir/file1
7649         local create_pool=false
7650         local initial_pool=$($LFS getstripe -p $DIR)
7651         local pool_list=()
7652         local pool=""
7653
7654         echo -n "Creating test dir..."
7655         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7656         echo "done."
7657
7658         echo -n "Creating test file..."
7659         touch $file1 || error "cannot create file"
7660         echo "done."
7661
7662         echo -n "Detecting existing pools..."
7663         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7664
7665         if [ ${#pool_list[@]} -gt 0 ]; then
7666                 echo "${pool_list[@]}"
7667                 for thispool in "${pool_list[@]}"; do
7668                         if [[ -z "$initial_pool" ||
7669                               "$initial_pool" != "$thispool" ]]; then
7670                                 pool="$thispool"
7671                                 echo "Using existing pool '$pool'"
7672                                 break
7673                         fi
7674                 done
7675         else
7676                 echo "none detected."
7677         fi
7678         if [ -z "$pool" ]; then
7679                 pool=${POOL:-testpool}
7680                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7681                 echo -n "Creating pool '$pool'..."
7682                 create_pool=true
7683                 pool_add $pool &> /dev/null ||
7684                         error "pool_add failed"
7685                 echo "done."
7686
7687                 echo -n "Adding target to pool..."
7688                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7689                         error "pool_add_targets failed"
7690                 echo "done."
7691         fi
7692
7693         echo -n "Setting pool using -p option..."
7694         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7695                 error "migrate failed rc = $?"
7696         echo "done."
7697
7698         echo -n "Verifying test file is in pool after migrating..."
7699         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7700                 error "file was not migrated to pool $pool"
7701         echo "done."
7702
7703         echo -n "Removing test file from pool '$pool'..."
7704         # "lfs migrate $file" won't remove the file from the pool
7705         # until some striping information is changed.
7706         $LFS migrate -c 1 $file1 &> /dev/null ||
7707                 error "cannot remove from pool"
7708         [ "$($LFS getstripe -p $file1)" ] &&
7709                 error "pool still set"
7710         echo "done."
7711
7712         echo -n "Setting pool using --pool option..."
7713         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7714                 error "migrate failed rc = $?"
7715         echo "done."
7716
7717         # Clean up
7718         rm -f $file1
7719         if $create_pool; then
7720                 destroy_test_pools 2> /dev/null ||
7721                         error "destroy test pools failed"
7722         fi
7723 }
7724 run_test 56wb "check lfs_migrate pool support"
7725
7726 test_56wc() {
7727         local file1="$DIR/$tdir/$tfile"
7728         local md5
7729         local parent_ssize
7730         local parent_scount
7731         local cur_ssize
7732         local cur_scount
7733         local orig_ssize
7734         local new_scount
7735         local cur_comp
7736
7737         echo -n "Creating test dir..."
7738         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7739         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7740                 error "cannot set stripe by '-S 1M -c 1'"
7741         echo "done"
7742
7743         echo -n "Setting initial stripe for test file..."
7744         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7745                 error "cannot set stripe"
7746         cur_ssize=$($LFS getstripe -S "$file1")
7747         (( cur_ssize == 524288 )) || error "setstripe -S $cur_ssize != 524288"
7748         echo "done."
7749
7750         dd if=/dev/urandom of=$file1 bs=1M count=12 || error "dd $file1 failed"
7751         stack_trap "rm -f $file1"
7752         md5="$(md5sum $file1)"
7753
7754         # File currently set to -S 512K -c 1
7755
7756         # Ensure -c and -S options are rejected when -R is set
7757         echo -n "Verifying incompatible options are detected..."
7758         $LFS_MIGRATE -R -c 1 "$file1" &&
7759                 error "incompatible -R and -c options not detected"
7760         $LFS_MIGRATE -R -S 1M "$file1" &&
7761                 error "incompatible -R and -S options not detected"
7762         $LFS_MIGRATE -R -p pool "$file1" &&
7763                 error "incompatible -R and -p options not detected"
7764         $LFS_MIGRATE -R -E eof -c 1 "$file1" &&
7765                 error "incompatible -R and -E options not detected"
7766         $LFS_MIGRATE -R -A "$file1" &&
7767                 error "incompatible -R and -A options not detected"
7768         $LFS_MIGRATE -A -c 1 "$file1" &&
7769                 error "incompatible -A and -c options not detected"
7770         $LFS_MIGRATE -A -S 1M "$file1" &&
7771                 error "incompatible -A and -S options not detected"
7772         $LFS_MIGRATE -A -p pool "$file1" &&
7773                 error "incompatible -A and -p options not detected"
7774         $LFS_MIGRATE -A -E eof -c 1 "$file1" &&
7775                 error "incompatible -A and -E options not detected"
7776         echo "done."
7777
7778         # Ensure unrecognized options are passed through to 'lfs migrate'
7779         echo -n "Verifying -S option is passed through to lfs migrate..."
7780         $LFS_MIGRATE -y -S 1M "$file1" || error "migration failed"
7781         cur_ssize=$($LFS getstripe -S "$file1")
7782         (( cur_ssize == 1048576 )) || error "migrate -S $cur_ssize != 1048576"
7783         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (1)"
7784         echo "done."
7785
7786         # File currently set to -S 1M -c 1
7787
7788         # Ensure long options are supported
7789         echo -n "Verifying long options supported..."
7790         $LFS_MIGRATE --non-block "$file1" ||
7791                 error "long option without argument not supported"
7792         $LFS_MIGRATE --stripe-size 512K "$file1" ||
7793                 error "long option with argument not supported"
7794         cur_ssize=$($LFS getstripe -S "$file1")
7795         (( cur_ssize == 524288 )) ||
7796                 error "migrate --stripe-size $cur_ssize != 524288"
7797         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (2)"
7798         echo "done."
7799
7800         # File currently set to -S 512K -c 1
7801
7802         if (( OSTCOUNT > 1 )); then
7803                 echo -n "Verifying explicit stripe count can be set..."
7804                 $LFS_MIGRATE -c 2 "$file1" || error "migrate failed"
7805                 cur_scount=$($LFS getstripe -c "$file1")
7806                 (( cur_scount == 2 )) || error "migrate -c $cur_scount != 2"
7807                 [[ "$(md5sum $file1)" == "$md5" ]] ||
7808                         error "file data has changed (3)"
7809                 echo "done."
7810         fi
7811
7812         # File currently set to -S 512K -c 1 or -S 512K -c 2
7813
7814         # Ensure parent striping is used if -R is set, and no stripe
7815         # count or size is specified
7816         echo -n "Setting stripe for parent directory..."
7817         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7818                 error "cannot set stripe '-S 2M -c 1'"
7819         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (4)"
7820         echo "done."
7821
7822         echo -n "Verifying restripe option uses parent stripe settings..."
7823         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7824         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7825         $LFS_MIGRATE -R "$file1" || error "migrate failed"
7826         cur_ssize=$($LFS getstripe -S "$file1")
7827         (( cur_ssize == parent_ssize )) ||
7828                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7829         cur_scount=$($LFS getstripe -c "$file1")
7830         (( cur_scount == parent_scount )) ||
7831                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7832         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (5)"
7833         echo "done."
7834
7835         # File currently set to -S 1M -c 1
7836
7837         # Ensure striping is preserved if -R is not set, and no stripe
7838         # count or size is specified
7839         echo -n "Verifying striping size preserved when not specified..."
7840         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7841         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7842                 error "cannot set stripe on parent directory"
7843         $LFS_MIGRATE "$file1" || error "migrate failed"
7844         cur_ssize=$($LFS getstripe -S "$file1")
7845         (( cur_ssize == orig_ssize )) ||
7846                 error "migrate by default $cur_ssize != $orig_ssize"
7847         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (6)"
7848         echo "done."
7849
7850         # Ensure file name properly detected when final option has no argument
7851         echo -n "Verifying file name properly detected..."
7852         $LFS_MIGRATE "$file1" ||
7853                 error "file name interpreted as option argument"
7854         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (7)"
7855         echo "done."
7856
7857         # Ensure PFL arguments are passed through properly
7858         echo -n "Verifying PFL options passed through..."
7859         new_scount=$(((OSTCOUNT + 1) / 2))
7860         $LFS_MIGRATE -E 1M -c 1 -E 16M -c $new_scount -E eof -c -1 "$file1" ||
7861                 error "migrate PFL arguments failed"
7862         cur_comp=$($LFS getstripe --comp-count $file1)
7863         (( cur_comp == 3 )) || error "component count '$cur_comp' != 3"
7864         cur_scount=$($LFS getstripe --stripe-count $file1)
7865         (( cur_scount == new_scount)) ||
7866                 error "PFL stripe count $cur_scount != $new_scount"
7867         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (8)"
7868         echo "done."
7869 }
7870 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7871
7872 test_56wd() {
7873         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7874
7875         local file1=$DIR/$tdir/$tfile
7876
7877         echo -n "Creating test dir..."
7878         test_mkdir $DIR/$tdir || error "cannot create dir"
7879         echo "done."
7880
7881         echo -n "Creating test file..."
7882         echo "$tfile" > $file1
7883         echo "done."
7884
7885         # Ensure 'lfs migrate' will fail by using a non-existent option,
7886         # and make sure rsync is not called to recover
7887         echo -n "Make sure --no-rsync option works..."
7888         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7889                 grep -q 'refusing to fall back to rsync' ||
7890                 error "rsync was called with --no-rsync set"
7891         echo "done."
7892
7893         # Ensure rsync is called without trying 'lfs migrate' first
7894         echo -n "Make sure --rsync option works..."
7895         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7896                 grep -q 'falling back to rsync' &&
7897                 error "lfs migrate was called with --rsync set"
7898         echo "done."
7899 }
7900 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7901
7902 test_56we() {
7903         local td=$DIR/$tdir
7904         local tf=$td/$tfile
7905
7906         test_mkdir $td || error "cannot create $td"
7907         touch $tf || error "cannot touch $tf"
7908
7909         echo -n "Make sure --non-direct|-D works..."
7910         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7911                 grep -q "lfs migrate --non-direct" ||
7912                 error "--non-direct option cannot work correctly"
7913         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7914                 grep -q "lfs migrate -D" ||
7915                 error "-D option cannot work correctly"
7916         echo "done."
7917 }
7918 run_test 56we "check lfs_migrate --non-direct|-D support"
7919
7920 test_56x() {
7921         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7922         check_swap_layouts_support
7923
7924         local dir=$DIR/$tdir
7925         local ref1=/etc/passwd
7926         local file1=$dir/file1
7927
7928         test_mkdir $dir || error "creating dir $dir"
7929         $LFS setstripe -c 2 $file1
7930         cp $ref1 $file1
7931         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7932         stripe=$($LFS getstripe -c $file1)
7933         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7934         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7935
7936         # clean up
7937         rm -f $file1
7938 }
7939 run_test 56x "lfs migration support"
7940
7941 test_56xa() {
7942         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7943         check_swap_layouts_support
7944
7945         local dir=$DIR/$tdir/$testnum
7946
7947         test_mkdir -p $dir
7948
7949         local ref1=/etc/passwd
7950         local file1=$dir/file1
7951
7952         $LFS setstripe -c 2 $file1
7953         cp $ref1 $file1
7954         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7955
7956         local stripe=$($LFS getstripe -c $file1)
7957
7958         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7959         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7960
7961         # clean up
7962         rm -f $file1
7963 }
7964 run_test 56xa "lfs migration --block support"
7965
7966 check_migrate_links() {
7967         [[ "$1" == "--rsync" ]] && local opts="--rsync -y" && shift
7968         local dir="$1"
7969         local file1="$dir/file1"
7970         local begin="$2"
7971         local count="$3"
7972         local runas="$4"
7973         local total_count=$(($begin + $count - 1))
7974         local symlink_count=10
7975         local uniq_count=10
7976
7977         if [ ! -f "$file1" ]; then
7978                 echo -n "creating initial file..."
7979                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7980                         error "cannot setstripe initial file"
7981                 echo "done"
7982
7983                 echo -n "creating symlinks..."
7984                 for s in $(seq 1 $symlink_count); do
7985                         ln -s "$file1" "$dir/slink$s" ||
7986                                 error "cannot create symlinks"
7987                 done
7988                 echo "done"
7989
7990                 echo -n "creating nonlinked files..."
7991                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7992                         error "cannot create nonlinked files"
7993                 echo "done"
7994         fi
7995
7996         # create hard links
7997         if [ ! -f "$dir/file$total_count" ]; then
7998                 echo -n "creating hard links $begin:$total_count..."
7999                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
8000                         /dev/null || error "cannot create hard links"
8001                 echo "done"
8002         fi
8003
8004         echo -n "checking number of hard links listed in xattrs..."
8005         local fid=$($LFS getstripe -F "$file1")
8006         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
8007
8008         echo "${#paths[*]}"
8009         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
8010                         skip "hard link list has unexpected size, skipping test"
8011         fi
8012         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
8013                         error "link names should exceed xattrs size"
8014         fi
8015
8016         echo -n "migrating files..."
8017         local migrate_out=$($runas $LFS_MIGRATE $opts -S '1m' $dir)
8018         local rc=$?
8019         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
8020         echo "done"
8021
8022         # make sure all links have been properly migrated
8023         echo -n "verifying files..."
8024         fid=$($LFS getstripe -F "$file1") ||
8025                 error "cannot get fid for file $file1"
8026         for i in $(seq 2 $total_count); do
8027                 local fid2=$($LFS getstripe -F $dir/file$i)
8028
8029                 [ "$fid2" == "$fid" ] ||
8030                         error "migrated hard link has mismatched FID"
8031         done
8032
8033         # make sure hard links were properly detected, and migration was
8034         # performed only once for the entire link set; nonlinked files should
8035         # also be migrated
8036         local actual=$(grep -c 'done' <<< "$migrate_out")
8037         local expected=$(($uniq_count + 1))
8038
8039         [ "$actual" -eq  "$expected" ] ||
8040                 error "hard links individually migrated ($actual != $expected)"
8041
8042         # make sure the correct number of hard links are present
8043         local hardlinks=$(stat -c '%h' "$file1")
8044
8045         [ $hardlinks -eq $total_count ] ||
8046                 error "num hard links $hardlinks != $total_count"
8047         echo "done"
8048
8049         return 0
8050 }
8051
8052 test_56xb() {
8053         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
8054                 skip "Need MDS version at least 2.10.55"
8055
8056         local dir="$DIR/$tdir"
8057
8058         test_mkdir "$dir" || error "cannot create dir $dir"
8059
8060         echo "testing lfs migrate mode when all links fit within xattrs"
8061         check_migrate_links "$dir" 2 99
8062
8063         echo "testing rsync mode when all links fit within xattrs"
8064         check_migrate_links --rsync "$dir" 2 99
8065
8066         echo "testing lfs migrate mode when all links do not fit within xattrs"
8067         check_migrate_links "$dir" 101 100
8068
8069         echo "testing rsync mode when all links do not fit within xattrs"
8070         check_migrate_links --rsync "$dir" 101 100
8071
8072         chown -R $RUNAS_ID $dir
8073         echo "testing non-root lfs migrate mode when not all links are in xattr"
8074         check_migrate_links "$dir" 101 100 "$RUNAS"
8075
8076         # clean up
8077         rm -rf $dir
8078 }
8079 run_test 56xb "lfs migration hard link support"
8080
8081 test_56xc() {
8082         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8083
8084         local dir="$DIR/$tdir"
8085
8086         test_mkdir "$dir" || error "cannot create dir $dir"
8087
8088         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
8089         echo -n "Setting initial stripe for 20MB test file..."
8090         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
8091                 error "cannot setstripe 20MB file"
8092         echo "done"
8093         echo -n "Sizing 20MB test file..."
8094         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
8095         echo "done"
8096         echo -n "Verifying small file autostripe count is 1..."
8097         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
8098                 error "cannot migrate 20MB file"
8099         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
8100                 error "cannot get stripe for $dir/20mb"
8101         [ $stripe_count -eq 1 ] ||
8102                 error "unexpected stripe count $stripe_count for 20MB file"
8103         rm -f "$dir/20mb"
8104         echo "done"
8105
8106         # Test 2: File is small enough to fit within the available space on
8107         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
8108         # have at least an additional 1KB for each desired stripe for test 3
8109         echo -n "Setting stripe for 1GB test file..."
8110         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
8111         echo "done"
8112         echo -n "Sizing 1GB test file..."
8113         # File size is 1GB + 3KB
8114         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
8115         echo "done"
8116
8117         # need at least 512MB per OST for 1GB file to fit in 2 stripes
8118         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
8119         if (( avail > 524288 * OSTCOUNT )); then
8120                 echo -n "Migrating 1GB file..."
8121                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
8122                         error "cannot migrate 1GB file"
8123                 echo "done"
8124                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
8125                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
8126                         error "cannot getstripe for 1GB file"
8127                 [ $stripe_count -eq 2 ] ||
8128                         error "unexpected stripe count $stripe_count != 2"
8129                 echo "done"
8130         fi
8131
8132         # Test 3: File is too large to fit within the available space on
8133         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
8134         if [ $OSTCOUNT -ge 3 ]; then
8135                 # The required available space is calculated as
8136                 # file size (1GB + 3KB) / OST count (3).
8137                 local kb_per_ost=349526
8138
8139                 echo -n "Migrating 1GB file with limit..."
8140                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
8141                         error "cannot migrate 1GB file with limit"
8142                 echo "done"
8143
8144                 stripe_count=$($LFS getstripe -c "$dir/1gb")
8145                 echo -n "Verifying 1GB autostripe count with limited space..."
8146                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
8147                         error "unexpected stripe count $stripe_count (min 3)"
8148                 echo "done"
8149         fi
8150
8151         # clean up
8152         rm -rf $dir
8153 }
8154 run_test 56xc "lfs migration autostripe"
8155
8156 test_56xd() {
8157         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8158
8159         local dir=$DIR/$tdir
8160         local f_mgrt=$dir/$tfile.mgrt
8161         local f_yaml=$dir/$tfile.yaml
8162         local f_copy=$dir/$tfile.copy
8163         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8164         local layout_copy="-c 2 -S 2M -i 1"
8165         local yamlfile=$dir/yamlfile
8166         local layout_before;
8167         local layout_after;
8168
8169         test_mkdir "$dir" || error "cannot create dir $dir"
8170         stack_trap "rm -rf $dir"
8171         $LFS setstripe $layout_yaml $f_yaml ||
8172                 error "cannot setstripe $f_yaml with layout $layout_yaml"
8173         $LFS getstripe --yaml $f_yaml > $yamlfile
8174         $LFS setstripe $layout_copy $f_copy ||
8175                 error "cannot setstripe $f_copy with layout $layout_copy"
8176         touch $f_mgrt
8177         dd if=/dev/zero of=$f_mgrt bs=1M count=4
8178
8179         # 1. test option --yaml
8180         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
8181                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
8182         layout_before=$(get_layout_param $f_yaml)
8183         layout_after=$(get_layout_param $f_mgrt)
8184         [ "$layout_after" == "$layout_before" ] ||
8185                 error "lfs_migrate --yaml: $layout_after != $layout_before"
8186
8187         # 2. test option --copy
8188         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
8189                 error "cannot migrate $f_mgrt with --copy $f_copy"
8190         layout_before=$(SKIP_INDEX=yes get_layout_param $f_copy)
8191         layout_after=$(SKIP_INDEX=yes get_layout_param $f_mgrt)
8192         [ "$layout_after" == "$layout_before" ] ||
8193                 error "lfs_migrate --copy: $layout_after != $layout_before"
8194 }
8195 run_test 56xd "check lfs_migrate --yaml and --copy support"
8196
8197 test_56xe() {
8198         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8199
8200         local dir=$DIR/$tdir
8201         local f_comp=$dir/$tfile
8202         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8203         local layout_before=""
8204         local layout_after=""
8205
8206         test_mkdir "$dir" || error "cannot create dir $dir"
8207         stack_trap "rm -rf $dir"
8208         $LFS setstripe $layout $f_comp ||
8209                 error "cannot setstripe $f_comp with layout $layout"
8210         layout_before=$(SKIP_INDEX=yes get_layout_param $f_comp)
8211         dd if=/dev/zero of=$f_comp bs=1M count=4
8212
8213         # 1. migrate a comp layout file by lfs_migrate
8214         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
8215         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8216         [ "$layout_before" == "$layout_after" ] ||
8217                 error "lfs_migrate: $layout_before != $layout_after"
8218
8219         # 2. migrate a comp layout file by lfs migrate
8220         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8221         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8222         [ "$layout_before" == "$layout_after" ] ||
8223                 error "lfs migrate: $layout_before != $layout_after"
8224 }
8225 run_test 56xe "migrate a composite layout file"
8226
8227 test_56xf() {
8228         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8229
8230         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
8231                 skip "Need server version at least 2.13.53"
8232
8233         local dir=$DIR/$tdir
8234         local f_comp=$dir/$tfile
8235         local layout="-E 1M -c1 -E -1 -c2"
8236         local fid_before=""
8237         local fid_after=""
8238
8239         test_mkdir "$dir" || error "cannot create dir $dir"
8240         stack_trap "rm -rf $dir"
8241         $LFS setstripe $layout $f_comp ||
8242                 error "cannot setstripe $f_comp with layout $layout"
8243         fid_before=$($LFS getstripe --fid $f_comp)
8244         dd if=/dev/zero of=$f_comp bs=1M count=4
8245
8246         # 1. migrate a comp layout file to a comp layout
8247         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8248         fid_after=$($LFS getstripe --fid $f_comp)
8249         [ "$fid_before" == "$fid_after" ] ||
8250                 error "comp-to-comp migrate: $fid_before != $fid_after"
8251
8252         # 2. migrate a comp layout file to a plain layout
8253         $LFS migrate -c2 $f_comp ||
8254                 error "cannot migrate $f_comp by lfs migrate"
8255         fid_after=$($LFS getstripe --fid $f_comp)
8256         [ "$fid_before" == "$fid_after" ] ||
8257                 error "comp-to-plain migrate: $fid_before != $fid_after"
8258
8259         # 3. migrate a plain layout file to a comp layout
8260         $LFS migrate $layout $f_comp ||
8261                 error "cannot migrate $f_comp by lfs migrate"
8262         fid_after=$($LFS getstripe --fid $f_comp)
8263         [ "$fid_before" == "$fid_after" ] ||
8264                 error "plain-to-comp migrate: $fid_before != $fid_after"
8265 }
8266 run_test 56xf "FID is not lost during migration of a composite layout file"
8267
8268 check_file_ost_range() {
8269         local file="$1"
8270         shift
8271         local range="$*"
8272         local -a file_range
8273         local idx
8274
8275         file_range=($($LFS getstripe -y "$file" |
8276                 awk '/l_ost_idx:/ { print $NF }'))
8277
8278         if [[ "${#file_range[@]}" = 0 ]]; then
8279                 echo "No osts found for $file"
8280                 return 1
8281         fi
8282
8283         for idx in "${file_range[@]}"; do
8284                 [[ " $range " =~ " $idx " ]] ||
8285                         return 1
8286         done
8287
8288         return 0
8289 }
8290
8291 sub_test_56xg() {
8292         local stripe_opt="$1"
8293         local pool="$2"
8294         shift 2
8295         local pool_ostidx="$(seq $* | tr '\n' ' ')"
8296
8297         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
8298                 error "Fail to migrate $tfile on $pool"
8299         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
8300                 error "$tfile is not in pool $pool"
8301         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
8302                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
8303 }
8304
8305 test_56xg() {
8306         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8307         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
8308         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
8309                 skip "Need MDS version newer than 2.14.52"
8310
8311         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
8312         local -a pool_ranges=("0 0" "1 1" "0 1")
8313
8314         # init pools
8315         for i in "${!pool_names[@]}"; do
8316                 pool_add ${pool_names[$i]} ||
8317                         error "pool_add failed (pool: ${pool_names[$i]})"
8318                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
8319                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
8320         done
8321
8322         # init the file to migrate
8323         $LFS setstripe -c1 -i1 $DIR/$tfile ||
8324                 error "Unable to create $tfile on OST1"
8325         stack_trap "rm -f $DIR/$tfile"
8326         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
8327                 error "Unable to write on $tfile"
8328
8329         echo "1. migrate $tfile on pool ${pool_names[0]}"
8330         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
8331
8332         echo "2. migrate $tfile on pool ${pool_names[2]}"
8333         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
8334
8335         echo "3. migrate $tfile on pool ${pool_names[1]}"
8336         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
8337
8338         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
8339         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
8340         echo
8341
8342         # Clean pools
8343         destroy_test_pools ||
8344                 error "pool_destroy failed"
8345 }
8346 run_test 56xg "lfs migrate pool support"
8347
8348 test_56xh() {
8349         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8350
8351         local size_mb=25
8352         local file1=$DIR/$tfile
8353         local tmp1=$TMP/$tfile.tmp
8354
8355         $LFS setstripe -c 2 $file1
8356
8357         stack_trap "rm -f $file1 $tmp1"
8358         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8359                         error "error creating $tmp1"
8360         ls -lsh $tmp1
8361         cp $tmp1 $file1
8362
8363         local start=$SECONDS
8364
8365         $LFS migrate --stats --stats-interval=1 -W 1M -c 1 $file1 ||
8366                 error "migrate failed rc = $?"
8367
8368         local elapsed=$((SECONDS - start))
8369
8370         # with 1MB/s, elapsed should equal size_mb
8371         (( elapsed >= size_mb * 95 / 100 )) ||
8372                 error "'lfs migrate -W' too fast ($elapsed < 0.95 * $size_mb)?"
8373
8374         (( elapsed <= size_mb * 120 / 100 )) ||
8375                 error_not_in_vm "'lfs migrate -W' slow ($elapsed > 1.2 * $size_mb)"
8376
8377         (( elapsed <= size_mb * 350 / 100 )) ||
8378                 error "'lfs migrate -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8379
8380         stripe=$($LFS getstripe -c $file1)
8381         (( $stripe == 1 )) || error "stripe of $file1 is $stripe != 1"
8382         cmp $file1 $tmp1 || error "content mismatch $file1 differs from $tmp1"
8383
8384         # Clean up file (since it is multiple MB)
8385         rm -f $file1 $tmp1
8386 }
8387 run_test 56xh "lfs migrate bandwidth limitation support"
8388
8389 test_56xi() {
8390         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8391         verify_yaml_available || skip_env "YAML verification not installed"
8392
8393         local size_mb=5
8394         local file1=$DIR/$tfile.1
8395         local file2=$DIR/$tfile.2
8396         local file3=$DIR/$tfile.3
8397         local output_file=$DIR/$tfile.out
8398         local tmp1=$TMP/$tfile.tmp
8399
8400         $LFS setstripe -c 2 $file1
8401         $LFS setstripe -c 2 $file2
8402         $LFS setstripe -c 2 $file3
8403
8404         stack_trap "rm -f $file1 $file2 $file3 $tmp1 $output_file"
8405         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8406                         error "error creating $tmp1"
8407         ls -lsh $tmp1
8408         cp $tmp1 $file1
8409         cp $tmp1 $file2
8410         cp $tmp1 $file3
8411
8412         $LFS migrate --stats --stats-interval=1 \
8413                 -c 1 $file1 $file2 $file3 1> $output_file ||
8414                 error "migrate failed rc = $?"
8415
8416         cat $output_file
8417         cat $output_file | verify_yaml || error "rename_stats is not valid YAML"
8418
8419         # Clean up file (since it is multiple MB)
8420         rm -f $file1 $file2 $file3 $tmp1 $output_file
8421 }
8422 run_test 56xi "lfs migrate stats support"
8423
8424 test_56xj() { # LU-16571 "lfs migrate -b" can cause thread starvation on OSS
8425         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8426
8427         local file=$DIR/$tfile
8428         local linkdir=$DIR/$tdir
8429
8430         test_mkdir $linkdir || error "fail to create $linkdir"
8431         $LFS setstripe -i 0 -c 1 -S1M $file
8432         stack_trap "rm -rf $file $linkdir"
8433         dd if=/dev/urandom of=$file bs=1M count=10 ||
8434                 error "fail to create $file"
8435
8436         # Create file links
8437         local cpts
8438         local threads_max
8439         local nlinks
8440
8441         thread_max=$(do_facet ost1 "$LCTL get_param -n ost.OSS.ost.threads_max")
8442         cpts=$(do_facet ost1 "$LCTL get_param -n cpu_partition_table | wc -l")
8443         (( nlinks = thread_max * 3 / 2 / cpts))
8444
8445         echo "create $nlinks hard links of $file"
8446         createmany -l $file $linkdir/link $nlinks
8447
8448         # Parallel migrates (should not block)
8449         local i
8450         for ((i = 0; i < nlinks; i++)); do
8451                 echo $linkdir/link$i
8452         done | xargs -n1 -P $nlinks $LFS migrate -c2
8453
8454         local stripe_count
8455         stripe_count=$($LFS getstripe -c $file) ||
8456                 error "fail to get stripe count on $file"
8457
8458         ((stripe_count == 2)) ||
8459                 error "fail to migrate $file (stripe_count = $stripe_count)"
8460 }
8461 run_test 56xj "lfs migrate -b should not cause starvation of threads on OSS"
8462
8463 test_56xk() {
8464         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8465
8466         local size_mb=5
8467         local file1=$DIR/$tfile
8468
8469         stack_trap "rm -f $file1"
8470         $LFS setstripe -c 1 $file1
8471         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8472                 error "error creating $file1"
8473         $LFS mirror extend -N $file1 || error "can't mirror"
8474         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8475                 error "can't dd"
8476         $LFS getstripe $file1 | grep stale ||
8477                 error "one component must be stale"
8478
8479         local start=$SECONDS
8480         $LFS mirror resync --stats --stats-interval=1 -W 1M $file1 ||
8481                 error "migrate failed rc = $?"
8482         local elapsed=$((SECONDS - start))
8483         $LFS getstripe $file1 | grep stale &&
8484                 error "all components must be sync"
8485
8486         # with 1MB/s, elapsed should equal size_mb
8487         (( elapsed >= size_mb * 95 / 100 )) ||
8488                 error "'lfs mirror resync -W' too fast ($elapsed < 0.95 * $size_mb)?"
8489
8490         (( elapsed <= size_mb * 120 / 100 )) ||
8491                 error_not_in_vm "'lfs mirror resync -W' slow ($elapsed > 1.2 * $size_mb)"
8492
8493         (( elapsed <= size_mb * 350 / 100 )) ||
8494                 error "'lfs mirror resync -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8495 }
8496 run_test 56xk "lfs mirror resync bandwidth limitation support"
8497
8498 test_56xl() {
8499         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8500         verify_yaml_available || skip_env "YAML verification not installed"
8501
8502         local size_mb=5
8503         local file1=$DIR/$tfile.1
8504         local output_file=$DIR/$tfile.out
8505
8506         stack_trap "rm -f $file1"
8507         $LFS setstripe -c 1 $file1
8508         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8509                 error "error creating $file1"
8510         $LFS mirror extend -N $file1 || error "can't mirror"
8511         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8512                 error "can't dd"
8513         $LFS getstripe $file1 | grep stale ||
8514                 error "one component must be stale"
8515         $LFS getstripe $file1
8516
8517         $LFS mirror resync --stats --stats-interval=1 $file1 >$output_file ||
8518                 error "resync failed rc = $?"
8519         $LFS getstripe $file1 | grep stale &&
8520                 error "all components must be sync"
8521
8522         cat $output_file
8523         cat $output_file | verify_yaml || error "stats is not valid YAML"
8524 }
8525 run_test 56xl "lfs mirror resync stats support"
8526
8527 test_56y() {
8528         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8529                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8530
8531         local res=""
8532         local dir=$DIR/$tdir
8533         local f1=$dir/file1
8534         local f2=$dir/file2
8535
8536         test_mkdir -p $dir || error "creating dir $dir"
8537         touch $f1 || error "creating std file $f1"
8538         $MULTIOP $f2 H2c || error "creating released file $f2"
8539
8540         # a directory can be raid0, so ask only for files
8541         res=$($LFS find $dir -L raid0 -type f | wc -l)
8542         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8543
8544         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8545         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8546
8547         # only files can be released, so no need to force file search
8548         res=$($LFS find $dir -L released)
8549         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8550
8551         res=$($LFS find $dir -type f \! -L released)
8552         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8553 }
8554 run_test 56y "lfs find -L raid0|released"
8555
8556 test_56z() { # LU-4824
8557         # This checks to make sure 'lfs find' continues after errors
8558         # There are two classes of errors that should be caught:
8559         # - If multiple paths are provided, all should be searched even if one
8560         #   errors out
8561         # - If errors are encountered during the search, it should not terminate
8562         #   early
8563         local dir=$DIR/$tdir
8564         local i
8565
8566         test_mkdir $dir
8567         for i in d{0..9}; do
8568                 test_mkdir $dir/$i
8569                 touch $dir/$i/$tfile
8570         done
8571         $LFS find $DIR/non_existent_dir $dir &&
8572                 error "$LFS find did not return an error"
8573         # Make a directory unsearchable. This should NOT be the last entry in
8574         # directory order.  Arbitrarily pick the 6th entry
8575         chmod 700 $($LFS find $dir -type d | sed '6!d')
8576
8577         $RUNAS $LFS find $DIR/non_existent $dir
8578         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8579
8580         # The user should be able to see 10 directories and 9 files
8581         (( count == 19 )) ||
8582                 error "$LFS find found $count != 19 entries after error"
8583 }
8584 run_test 56z "lfs find should continue after an error"
8585
8586 test_56aa() { # LU-5937
8587         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8588
8589         local dir=$DIR/$tdir
8590
8591         mkdir $dir
8592         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8593
8594         createmany -o $dir/striped_dir/${tfile}- 1024
8595         local dirs=$($LFS find --size +8k $dir/)
8596
8597         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8598 }
8599 run_test 56aa "lfs find --size under striped dir"
8600
8601 test_56ab() { # LU-10705
8602         test_mkdir $DIR/$tdir
8603         dd if=/dev/urandom of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8604         dd if=/dev/urandom of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8605         dd if=/dev/urandom of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8606         # Flush writes to ensure valid blocks.  Need to be more thorough for
8607         # ZFS, since blocks are not allocated/returned to client immediately.
8608         sync_all_data
8609         wait_zfs_commit ost1 2
8610         cancel_lru_locks osc
8611         ls -ls $DIR/$tdir
8612
8613         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8614
8615         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8616
8617         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8618         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8619
8620         rm -f $DIR/$tdir/$tfile.[123]
8621 }
8622 run_test 56ab "lfs find --blocks"
8623
8624 # LU-11188
8625 test_56aca() {
8626         local dir="$DIR/$tdir"
8627         local perms=(001 002 003 004 005 006 007
8628                      010 020 030 040 050 060 070
8629                      100 200 300 400 500 600 700
8630                      111 222 333 444 555 666 777)
8631         local perm_minus=(8 8 4 8 4 4 2
8632                           8 8 4 8 4 4 2
8633                           8 8 4 8 4 4 2
8634                           4 4 2 4 2 2 1)
8635         local perm_slash=(8  8 12  8 12 12 14
8636                           8  8 12  8 12 12 14
8637                           8  8 12  8 12 12 14
8638                          16 16 24 16 24 24 28)
8639
8640         test_mkdir "$dir"
8641         for perm in ${perms[*]}; do
8642                 touch "$dir/$tfile.$perm"
8643                 chmod $perm "$dir/$tfile.$perm"
8644         done
8645
8646         for ((i = 0; i < ${#perms[*]}; i++)); do
8647                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8648                 (( $num == 1 )) ||
8649                         error "lfs find -perm ${perms[i]}:"\
8650                               "$num != 1"
8651
8652                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8653                 (( $num == ${perm_minus[i]} )) ||
8654                         error "lfs find -perm -${perms[i]}:"\
8655                               "$num != ${perm_minus[i]}"
8656
8657                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8658                 (( $num == ${perm_slash[i]} )) ||
8659                         error "lfs find -perm /${perms[i]}:"\
8660                               "$num != ${perm_slash[i]}"
8661         done
8662 }
8663 run_test 56aca "check lfs find -perm with octal representation"
8664
8665 test_56acb() {
8666         local dir=$DIR/$tdir
8667         # p is the permission of write and execute for user, group and other
8668         # without the umask. It is used to test +wx.
8669         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8670         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8671         local symbolic=(+t  a+t u+t g+t o+t
8672                         g+s u+s o+s +s o+sr
8673                         o=r,ug+o,u+w
8674                         u+ g+ o+ a+ ugo+
8675                         u- g- o- a- ugo-
8676                         u= g= o= a= ugo=
8677                         o=r,ug+o,u+w u=r,a+u,u+w
8678                         g=r,ugo=g,u+w u+x,+X +X
8679                         u+x,u+X u+X u+x,g+X o+r,+X
8680                         u+x,go+X +wx +rwx)
8681
8682         test_mkdir $dir
8683         for perm in ${perms[*]}; do
8684                 touch "$dir/$tfile.$perm"
8685                 chmod $perm "$dir/$tfile.$perm"
8686         done
8687
8688         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8689                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8690
8691                 (( $num == 1 )) ||
8692                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8693         done
8694 }
8695 run_test 56acb "check lfs find -perm with symbolic representation"
8696
8697 test_56acc() {
8698         local dir=$DIR/$tdir
8699         local tests="17777 787 789 abcd
8700                 ug=uu ug=a ug=gu uo=ou urw
8701                 u+xg+x a=r,u+x,"
8702
8703         test_mkdir $dir
8704         for err in $tests; do
8705                 if $LFS find $dir -perm $err 2>/dev/null; then
8706                         error "lfs find -perm $err: parsing should have failed"
8707                 fi
8708         done
8709 }
8710 run_test 56acc "check parsing error for lfs find -perm"
8711
8712 test_56ba() {
8713         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8714                 skip "Need MDS version at least 2.10.50"
8715
8716         # Create composite files with one component
8717         local dir=$DIR/$tdir
8718
8719         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8720         # Create composite files with three components
8721         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8722         # LU-16904 Create plain layout files
8723         lfs setstripe -c 1 $dir/$tfile-{1..10}
8724
8725         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8726
8727         [[ $nfiles == 10 ]] ||
8728                 error "lfs find -E 1M found $nfiles != 10 files"
8729
8730         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8731         [[ $nfiles == 25 ]] ||
8732                 error "lfs find ! -E 1M found $nfiles != 25 files"
8733
8734         # All files have a component that starts at 0
8735         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8736         [[ $nfiles == 35 ]] ||
8737                 error "lfs find --component-start 0 - $nfiles != 35 files"
8738
8739         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8740         [[ $nfiles == 15 ]] ||
8741                 error "lfs find --component-start 2M - $nfiles != 15 files"
8742
8743         # All files created here have a componenet that does not starts at 2M
8744         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8745         [[ $nfiles == 35 ]] ||
8746                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8747
8748         # Find files with a specified number of components
8749         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8750         [[ $nfiles == 15 ]] ||
8751                 error "lfs find --component-count 3 - $nfiles != 15 files"
8752
8753         # Remember non-composite files have a component count of zero
8754         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8755         [[ $nfiles == 10 ]] ||
8756                 error "lfs find --component-count 0 - $nfiles != 10 files"
8757
8758         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8759         [[ $nfiles == 20 ]] ||
8760                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8761
8762         # All files have a flag called "init"
8763         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8764         [[ $nfiles == 35 ]] ||
8765                 error "lfs find --component-flags init - $nfiles != 35 files"
8766
8767         # Multi-component files will have a component not initialized
8768         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8769         [[ $nfiles == 15 ]] ||
8770                 error "lfs find !--component-flags init - $nfiles != 15 files"
8771
8772         rm -rf $dir
8773
8774 }
8775 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8776
8777 test_56ca() {
8778         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8779                 skip "Need MDS version at least 2.10.57"
8780
8781         local td=$DIR/$tdir
8782         local tf=$td/$tfile
8783         local dir
8784         local nfiles
8785         local cmd
8786         local i
8787         local j
8788
8789         # create mirrored directories and mirrored files
8790         mkdir $td || error "mkdir $td failed"
8791         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8792         createmany -o $tf- 10 || error "create $tf- failed"
8793
8794         for i in $(seq 2); do
8795                 dir=$td/dir$i
8796                 mkdir $dir || error "mkdir $dir failed"
8797                 $LFS mirror create -N$((3 + i)) $dir ||
8798                         error "create mirrored dir $dir failed"
8799                 createmany -o $dir/$tfile- 10 ||
8800                         error "create $dir/$tfile- failed"
8801         done
8802
8803         # change the states of some mirrored files
8804         echo foo > $tf-6
8805         for i in $(seq 2); do
8806                 dir=$td/dir$i
8807                 for j in $(seq 4 9); do
8808                         echo foo > $dir/$tfile-$j
8809                 done
8810         done
8811
8812         # find mirrored files with specific mirror count
8813         cmd="$LFS find --mirror-count 3 --type f $td"
8814         nfiles=$($cmd | wc -l)
8815         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8816
8817         cmd="$LFS find ! --mirror-count 3 --type f $td"
8818         nfiles=$($cmd | wc -l)
8819         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8820
8821         cmd="$LFS find --mirror-count +2 --type f $td"
8822         nfiles=$($cmd | wc -l)
8823         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8824
8825         cmd="$LFS find --mirror-count -6 --type f $td"
8826         nfiles=$($cmd | wc -l)
8827         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8828
8829         # find mirrored files with specific file state
8830         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8831         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8832
8833         cmd="$LFS find --mirror-state=ro --type f $td"
8834         nfiles=$($cmd | wc -l)
8835         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8836
8837         cmd="$LFS find ! --mirror-state=ro --type f $td"
8838         nfiles=$($cmd | wc -l)
8839         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8840
8841         cmd="$LFS find --mirror-state=wp --type f $td"
8842         nfiles=$($cmd | wc -l)
8843         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8844
8845         cmd="$LFS find ! --mirror-state=sp --type f $td"
8846         nfiles=$($cmd | wc -l)
8847         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8848 }
8849 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8850
8851 test_56da() { # LU-14179
8852         local path=$DIR/$tdir
8853
8854         test_mkdir $path
8855         cd $path
8856
8857         local longdir=$(str_repeat 'a' 255)
8858
8859         for i in {1..15}; do
8860                 path=$path/$longdir
8861                 test_mkdir $longdir
8862                 cd $longdir
8863         done
8864
8865         local len=${#path}
8866         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8867
8868         test_mkdir $lastdir
8869         cd $lastdir
8870         # PATH_MAX-1
8871         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8872
8873         # NAME_MAX
8874         touch $(str_repeat 'f' 255)
8875
8876         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8877                 error "lfs find reported an error"
8878
8879         rm -rf $DIR/$tdir
8880 }
8881 run_test 56da "test lfs find with long paths"
8882
8883 test_56ea() { #LU-10378
8884         local path=$DIR/$tdir
8885         local pool=$TESTNAME
8886
8887         # Create ost pool
8888         pool_add $pool || error "pool_add $pool failed"
8889         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8890                 error "adding targets to $pool failed"
8891
8892         # Set default pool on directory before creating file
8893         mkdir $path || error "mkdir $path failed"
8894         $LFS setstripe -p $pool $path ||
8895                 error "set OST pool on $pool failed"
8896         touch $path/$tfile || error "touch $path/$tfile failed"
8897
8898         # Compare basic file attributes from -printf and stat
8899         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G %n")
8900         local attr_stat=$(stat -c "%X %Y %Z %u %g %h" $path/$tfile)
8901
8902         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8903                 error "Attrs from lfs find and stat don't match"
8904
8905         # Compare Lustre attributes from lfs find and lfs getstripe
8906         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8907         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8908         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8909         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8910         local fpool=$($LFS getstripe --pool $path/$tfile)
8911         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8912
8913         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8914                 error "Attrs from lfs find and lfs getstripe don't match"
8915
8916         # Verify behavior for unknown escape/format sequences
8917         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8918
8919         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8920                 error "Escape/format codes don't match"
8921 }
8922 run_test 56ea "test lfs find -printf option"
8923
8924 test_56eb() {
8925         local dir=$DIR/$tdir
8926         local subdir_1=$dir/subdir_1
8927
8928         test_mkdir -p $subdir_1
8929         ln -s subdir_1 $dir/link_1
8930
8931         $LFS getstripe $dir | grep "^$dir/link_1$" -A1 ||
8932                 error "symlink is not followed"
8933
8934         $LFS getstripe --no-follow $dir |
8935                 grep "^$dir/link_1 has no stripe info$" ||
8936                 error "symlink should not have stripe info"
8937
8938         touch $dir/testfile
8939         ln -s testfile $dir/file_link_2
8940
8941         $LFS getstripe $dir | grep "^$dir/file_link_2$" -A1 ||
8942                 error "symlink is not followed"
8943
8944         $LFS getstripe --no-follow $dir |
8945                 grep "^$dir/file_link_2 has no stripe info$" ||
8946                 error "symlink should not have stripe info"
8947 }
8948 run_test 56eb "check lfs getstripe on symlink"
8949
8950 test_56ec() {
8951         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8952         local dir=$DIR/$tdir
8953         local srcfile=$dir/srcfile
8954         local srcyaml=$dir/srcyaml
8955         local destfile=$dir/destfile
8956
8957         test_mkdir -p $dir
8958
8959         $LFS setstripe -i 1 $srcfile
8960         $LFS getstripe --hex-idx --yaml $srcfile > $srcyaml
8961         # if the setstripe yaml parsing fails for any reason, the command can
8962         # randomly assign the correct OST index, leading to an erroneous
8963         # success. but the chance of false success is low enough that a
8964         # regression should still be quickly caught.
8965         $LFS setstripe --yaml=$srcyaml $destfile
8966
8967         local srcindex=$($LFS getstripe -i $srcfile)
8968         local destindex=$($LFS getstripe -i $destfile)
8969
8970         if [[ ! $srcindex -eq $destindex ]]; then
8971                 error "setstripe did not set OST index correctly"
8972         fi
8973 }
8974 run_test 56ec "check lfs getstripe,setstripe --hex --yaml"
8975
8976 test_56eda() {
8977         local dir=$DIR/$tdir
8978         local subdir=$dir/subdir
8979         local file1=$dir/$tfile
8980         local file2=$dir/$tfile\2
8981         local link=$dir/$tfile-link
8982         local nfiles
8983
8984         test_mkdir -p $dir
8985         $LFS setdirstripe -c1 $subdir
8986         touch $file1
8987         touch $file2
8988         ln $file2 $link
8989
8990         nfiles=$($LFS find --links 1 $dir | wc -l)
8991         (( $nfiles == 1 )) ||
8992                 error "lfs find --links expected 1 file, got $nfiles"
8993
8994         nfiles=$($LFS find --type f --links 2 $dir | wc -l)
8995         (( $nfiles == 2 )) ||
8996                 error "lfs find --links expected 2 files, got $nfiles"
8997
8998         nfiles=$($LFS find --type d --links 2 $dir | wc -l)
8999         (( $nfiles == 1 )) ||
9000                 error "lfs find --links expected 1 directory, got $nfiles"
9001 }
9002 run_test 56eda "check lfs find --links"
9003
9004 test_56edb() {
9005         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
9006
9007         local dir=$DIR/$tdir
9008         local stripedir=$dir/stripedir
9009         local nfiles
9010
9011         test_mkdir -p $dir
9012
9013         $LFS setdirstripe -c2 $stripedir
9014
9015         $LFS getdirstripe $stripedir
9016
9017         nfiles=$($LFS find --type d --links 2 $stripedir | wc -l)
9018         (( $nfiles == 1 )) ||
9019                 error "lfs find --links expected 1 directory, got $nfiles"
9020 }
9021 run_test 56edb "check lfs find --links for directory striped on multiple MDTs"
9022
9023 test_56ef() {
9024         local dir=$DIR/$tdir
9025         local dir1=$dir/d1
9026         local dir2=$dir/d2
9027         local nfiles
9028         local err_msg
9029
9030         test_mkdir -p $dir
9031
9032         mkdir $dir1
9033         mkdir $dir2
9034
9035         touch $dir1/f
9036         touch $dir2/f
9037
9038         nfiles=$($LFS find $dir1 $dir2 ! -type d | wc -l)
9039         (( $nfiles == 2 )) ||
9040                 error "(1) lfs find expected 2 files, got $nfiles"
9041
9042         nfiles=$($LFS find $dir1 $dir2 -type f | wc -l)
9043         (( $nfiles == 2 )) ||
9044                 error "(2) lfs find expected 2 files, got $nfiles"
9045
9046         nfiles=$($LFS find -type f $dir1 $dir2 | wc -l)
9047         (( $nfiles == 2 )) ||
9048                 error "(3) lfs find expected 2 files, got $nfiles"
9049
9050         err_msg=$($LFS find $dir1/typo $dir1/f 2>&1 > /dev/null)
9051         [[ $err_msg =~ "No such file or directory" ]] ||
9052                 error "expected standard error message, got: '$err_msg'"
9053 }
9054 run_test 56ef "lfs find with multiple paths"
9055
9056 test_56eg() {
9057         local dir=$DIR/$tdir
9058         local found
9059
9060         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9061
9062         test_mkdir -p $dir
9063
9064         touch $dir/$tfile
9065         ln -s $dir/$tfile $dir/$tfile.symlink
9066         setfattr -n "trusted.test" -v "test_target" $dir/$tfile
9067         setfattr --no-dereference -n "trusted.test" -v "test_link" \
9068                 $dir/$tfile.symlink
9069         setfattr --no-dereference -n "trusted.common" \
9070                 $dir/{$tfile,$tfile.symlink}
9071
9072         found=$($LFS find -xattr "trusted.*=test_target" \
9073                 -xattr "trusted.common" $dir)
9074         [[ "$found" == "$dir/$tfile" ]] || {
9075                 getfattr -d -m trusted.* $dir/$tfile
9076                 error "should have found '$tfile' with xattr 'trusted.test=test_target', got '$found'"
9077         }
9078
9079         found=$($LFS find -xattr "trusted.*=test_link" \
9080                 -xattr "trusted.common" $dir)
9081         [[ "$found" == "$dir/$tfile.symlink" ]] || {
9082                 getfattr --no-dereference -d -m trusted.* $dir/$tfile.symlink
9083                 error "should have found '$tfile.symlink' with xattr 'trusted.test=test_link', got '$found'"
9084         }
9085
9086         rm -f $dir/*
9087
9088         touch $dir/$tfile.1
9089         touch $dir/$tfile.2
9090         setfattr -n "user.test" -v "1" $dir/$tfile.1
9091         setfattr -n "user.test" -v "2" $dir/$tfile.2
9092         setfattr -n "user.test2" -v "common" $dir/$tfile.{1,2}
9093
9094         found=$($LFS find -xattr "user.*=common" -xattr "user.test=1" $dir)
9095         [[ "$found" == "$dir/$tfile.1" ]] || {
9096                 getfattr -d $dir/$tfile.1
9097                 error "should have found '$tfile.1' with xattr user.test=1', got '$found'"
9098         }
9099
9100         found=$($LFS find -xattr "user.*=common" ! -xattr "user.test=1" $dir)
9101         [[ "$found" == "$dir/$tfile.2" ]] || {
9102                 getfattr -d $dir/$tfile.2
9103                 error "should have found '$tfile.2' without xattr 'user.test=1', got '$found'"
9104         }
9105
9106         setfattr -n "user.empty" $dir/$tfile.1
9107         found=$($LFS find -xattr "user.empty" $dir)
9108         [[ "$found" == "$dir/$tfile.1" ]] || {
9109                 getfattr -d $dir/$tfile.1
9110                 error "should have found '$tfile.1' with xattr 'user.empty=', got '$found'"
9111         }
9112
9113         # setfattr command normally does not store terminating null byte
9114         # when writing a string as an xattr value.
9115         #
9116         # In order to test matching a value string that includes a terminating
9117         # null, explicitly encode the string "test\0" with the null terminator.
9118         setfattr -n "user.test" -v "0x7465737400" $dir/$tfile.1
9119         found=$($LFS find -xattr "user.test=test" $dir)
9120         [[ "$found" == "$dir/$tfile.1" ]] || {
9121                 getfattr -d --encoding=hex $dir/$tfile.1
9122                 error "should have found '$tfile.1' with xattr 'user.test=0x7465737400', got '$found'"
9123         }
9124 }
9125 run_test 56eg "lfs find -xattr"
9126
9127 test_57a() {
9128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9129         # note test will not do anything if MDS is not local
9130         if [ "$mds1_FSTYPE" != ldiskfs ]; then
9131                 skip_env "ldiskfs only test"
9132         fi
9133         remote_mds_nodsh && skip "remote MDS with nodsh"
9134
9135         local MNTDEV="osd*.*MDT*.mntdev"
9136         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
9137         [ -z "$DEV" ] && error "can't access $MNTDEV"
9138         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
9139                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
9140                         error "can't access $DEV"
9141                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
9142                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
9143                 rm $TMP/t57a.dump
9144         done
9145 }
9146 run_test 57a "verify MDS filesystem created with large inodes =="
9147
9148 test_57b() {
9149         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9150         if [ "$mds1_FSTYPE" != ldiskfs ]; then
9151                 skip_env "ldiskfs only test"
9152         fi
9153         remote_mds_nodsh && skip "remote MDS with nodsh"
9154
9155         local dir=$DIR/$tdir
9156         local filecount=100
9157         local file1=$dir/f1
9158         local fileN=$dir/f$filecount
9159
9160         rm -rf $dir || error "removing $dir"
9161         test_mkdir -c1 $dir
9162         local mdtidx=$($LFS getstripe -m $dir)
9163         local mdtname=MDT$(printf %04x $mdtidx)
9164         local facet=mds$((mdtidx + 1))
9165
9166         echo "mcreating $filecount files"
9167         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
9168
9169         # verify that files do not have EAs yet
9170         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
9171                 error "$file1 has an EA"
9172         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
9173                 error "$fileN has an EA"
9174
9175         sync
9176         sleep 1
9177         df $dir  #make sure we get new statfs data
9178         local mdsfree=$(do_facet $facet \
9179                         lctl get_param -n osd*.*$mdtname.kbytesfree)
9180         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
9181         local file
9182
9183         echo "opening files to create objects/EAs"
9184         for file in $(seq -f $dir/f%g 1 $filecount); do
9185                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
9186                         error "opening $file"
9187         done
9188
9189         # verify that files have EAs now
9190         $LFS getstripe -y $file1 | grep -q "l_ost_idx" ||
9191                 error "$file1 missing EA"
9192         $LFS getstripe -y $fileN | grep -q "l_ost_idx" ||
9193                 error "$fileN missing EA"
9194
9195         sleep 1  #make sure we get new statfs data
9196         df $dir
9197         local mdsfree2=$(do_facet $facet \
9198                          lctl get_param -n osd*.*$mdtname.kbytesfree)
9199         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
9200
9201         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
9202                 if [ "$mdsfree" != "$mdsfree2" ]; then
9203                         error "MDC before $mdcfree != after $mdcfree2"
9204                 else
9205                         echo "MDC before $mdcfree != after $mdcfree2"
9206                         echo "unable to confirm if MDS has large inodes"
9207                 fi
9208         fi
9209         rm -rf $dir
9210 }
9211 run_test 57b "default LOV EAs are stored inside large inodes ==="
9212
9213 test_58() {
9214         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9215         [ -z "$(which wiretest 2>/dev/null)" ] &&
9216                         skip_env "could not find wiretest"
9217
9218         wiretest
9219 }
9220 run_test 58 "verify cross-platform wire constants =============="
9221
9222 test_59() {
9223         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9224
9225         echo "touch 130 files"
9226         createmany -o $DIR/f59- 130
9227         echo "rm 130 files"
9228         unlinkmany $DIR/f59- 130
9229         sync
9230         # wait for commitment of removal
9231         wait_delete_completed
9232 }
9233 run_test 59 "verify cancellation of llog records async ========="
9234
9235 TEST60_HEAD="test_60 run $RANDOM"
9236 test_60a() {
9237         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9238         remote_mgs_nodsh && skip "remote MGS with nodsh"
9239         do_facet mgs "! which run-llog.sh &> /dev/null" &&
9240                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
9241                         skip_env "missing subtest run-llog.sh"
9242
9243         log "$TEST60_HEAD - from kernel mode"
9244         do_facet mgs "$LCTL dk > /dev/null"
9245         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
9246         do_facet mgs $LCTL dk > $TMP/$tfile
9247
9248         # LU-6388: test llog_reader
9249         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
9250         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
9251         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
9252                         skip_env "missing llog_reader"
9253         local fstype=$(facet_fstype mgs)
9254         [ $fstype != ldiskfs -a $fstype != zfs ] &&
9255                 skip_env "Only for ldiskfs or zfs type mgs"
9256
9257         local mntpt=$(facet_mntpt mgs)
9258         local mgsdev=$(mgsdevname 1)
9259         local fid_list
9260         local fid
9261         local rec_list
9262         local rec
9263         local rec_type
9264         local obj_file
9265         local path
9266         local seq
9267         local oid
9268         local pass=true
9269
9270         #get fid and record list
9271         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
9272                 tail -n 4))
9273         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
9274                 tail -n 4))
9275         #remount mgs as ldiskfs or zfs type
9276         stop mgs || error "stop mgs failed"
9277         mount_fstype mgs || error "remount mgs failed"
9278         for ((i = 0; i < ${#fid_list[@]}; i++)); do
9279                 fid=${fid_list[i]}
9280                 rec=${rec_list[i]}
9281                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
9282                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
9283                 oid=$((16#$oid))
9284
9285                 case $fstype in
9286                         ldiskfs )
9287                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
9288                         zfs )
9289                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
9290                 esac
9291                 echo "obj_file is $obj_file"
9292                 do_facet mgs $llog_reader $obj_file
9293
9294                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
9295                         awk '{ print $3 }' | sed -e "s/^type=//g")
9296                 if [ $rec_type != $rec ]; then
9297                         echo "FAILED test_60a wrong record type $rec_type," \
9298                               "should be $rec"
9299                         pass=false
9300                         break
9301                 fi
9302
9303                 #check obj path if record type is LLOG_LOGID_MAGIC
9304                 if [ "$rec" == "1064553b" ]; then
9305                         path=$(do_facet mgs $llog_reader $obj_file |
9306                                 grep "path=" | awk '{ print $NF }' |
9307                                 sed -e "s/^path=//g")
9308                         if [ $obj_file != $mntpt/$path ]; then
9309                                 echo "FAILED test_60a wrong obj path" \
9310                                       "$montpt/$path, should be $obj_file"
9311                                 pass=false
9312                                 break
9313                         fi
9314                 fi
9315         done
9316         rm -f $TMP/$tfile
9317         #restart mgs before "error", otherwise it will block the next test
9318         stop mgs || error "stop mgs failed"
9319         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
9320         $pass || error "test failed, see FAILED test_60a messages for specifics"
9321 }
9322 run_test 60a "llog_test run from kernel module and test llog_reader"
9323
9324 test_60b() { # bug 6411
9325         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9326
9327         dmesg > $DIR/$tfile
9328         LLOG_COUNT=$(do_facet mgs dmesg |
9329                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
9330                           /llog_[a-z]*.c:[0-9]/ {
9331                                 if (marker)
9332                                         from_marker++
9333                                 from_begin++
9334                           }
9335                           END {
9336                                 if (marker)
9337                                         print from_marker
9338                                 else
9339                                         print from_begin
9340                           }")
9341
9342         [[ $LLOG_COUNT -gt 120 ]] &&
9343                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
9344 }
9345 run_test 60b "limit repeated messages from CERROR/CWARN"
9346
9347 test_60c() {
9348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9349
9350         echo "create 5000 files"
9351         createmany -o $DIR/f60c- 5000
9352 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
9353         lctl set_param fail_loc=0x80000137
9354         unlinkmany $DIR/f60c- 5000
9355         lctl set_param fail_loc=0
9356 }
9357 run_test 60c "unlink file when mds full"
9358
9359 test_60d() {
9360         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9361
9362         SAVEPRINTK=$(lctl get_param -n printk)
9363         # verify "lctl mark" is even working"
9364         MESSAGE="test message ID $RANDOM $$"
9365         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9366         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
9367
9368         lctl set_param printk=0 || error "set lnet.printk failed"
9369         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
9370         MESSAGE="new test message ID $RANDOM $$"
9371         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
9372         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9373         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
9374
9375         lctl set_param -n printk="$SAVEPRINTK"
9376 }
9377 run_test 60d "test printk console message masking"
9378
9379 test_60e() {
9380         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9381         remote_mds_nodsh && skip "remote MDS with nodsh"
9382
9383         touch $DIR/$tfile
9384 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
9385         do_facet mds1 lctl set_param fail_loc=0x15b
9386         rm $DIR/$tfile
9387 }
9388 run_test 60e "no space while new llog is being created"
9389
9390 test_60f() {
9391         local old_path=$($LCTL get_param -n debug_path)
9392
9393         stack_trap "$LCTL set_param debug_path=$old_path"
9394         stack_trap "rm -f $TMP/$tfile*"
9395         rm -f $TMP/$tfile* 2> /dev/null
9396         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
9397         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
9398         test_mkdir $DIR/$tdir
9399         # retry in case the open is cached and not released
9400         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
9401                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
9402                 sleep 0.1
9403         done
9404         ls $TMP/$tfile*
9405         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
9406 }
9407 run_test 60f "change debug_path works"
9408
9409 test_60g() {
9410         local pid
9411         local i
9412
9413         test_mkdir -c $MDSCOUNT $DIR/$tdir
9414
9415         (
9416                 local index=0
9417                 while true; do
9418                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
9419                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
9420                                 2>/dev/null
9421                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
9422                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
9423                         index=$((index + 1))
9424                 done
9425         ) &
9426
9427         pid=$!
9428
9429         for i in {0..100}; do
9430                 # define OBD_FAIL_OSD_TXN_START    0x19a
9431                 local index=$((i % MDSCOUNT + 1))
9432
9433                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
9434                         > /dev/null
9435                 sleep 0.01
9436         done
9437
9438         kill -9 $pid
9439
9440         for i in $(seq $MDSCOUNT); do
9441                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
9442         done
9443
9444         mkdir $DIR/$tdir/new || error "mkdir failed"
9445         rmdir $DIR/$tdir/new || error "rmdir failed"
9446
9447         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
9448                 -t namespace
9449         for i in $(seq $MDSCOUNT); do
9450                 wait_update_facet mds$i "$LCTL get_param -n \
9451                         mdd.$(facet_svc mds$i).lfsck_namespace |
9452                         awk '/^status/ { print \\\$2 }'" "completed"
9453         done
9454
9455         ls -R $DIR/$tdir
9456         rm -rf $DIR/$tdir || error "rmdir failed"
9457 }
9458 run_test 60g "transaction abort won't cause MDT hung"
9459
9460 test_60h() {
9461         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
9462                 skip "Need MDS version at least 2.12.52"
9463         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
9464
9465         local f
9466
9467         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
9468         #define OBD_FAIL_MDS_STRIPE_FID          0x189
9469         for fail_loc in 0x80000188 0x80000189; do
9470                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
9471                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
9472                         error "mkdir $dir-$fail_loc failed"
9473                 for i in {0..10}; do
9474                         # create may fail on missing stripe
9475                         echo $i > $DIR/$tdir-$fail_loc/$i
9476                 done
9477                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9478                         error "getdirstripe $tdir-$fail_loc failed"
9479                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
9480                         error "migrate $tdir-$fail_loc failed"
9481                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9482                         error "getdirstripe $tdir-$fail_loc failed"
9483                 pushd $DIR/$tdir-$fail_loc
9484                 for f in *; do
9485                         echo $f | cmp $f - || error "$f data mismatch"
9486                 done
9487                 popd
9488                 rm -rf $DIR/$tdir-$fail_loc
9489         done
9490 }
9491 run_test 60h "striped directory with missing stripes can be accessed"
9492
9493 function t60i_load() {
9494         mkdir $DIR/$tdir
9495         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
9496         $LCTL set_param fail_loc=0x131c fail_val=1
9497         for ((i=0; i<5000; i++)); do
9498                 touch $DIR/$tdir/f$i
9499         done
9500 }
9501
9502 test_60i() {
9503         changelog_register || error "changelog_register failed"
9504         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
9505         changelog_users $SINGLEMDS | grep -q $cl_user ||
9506                 error "User $cl_user not found in changelog_users"
9507         changelog_chmask "ALL"
9508         t60i_load &
9509         local PID=$!
9510         for((i=0; i<100; i++)); do
9511                 changelog_dump >/dev/null ||
9512                         error "can't read changelog"
9513         done
9514         kill $PID
9515         wait $PID
9516         changelog_deregister || error "changelog_deregister failed"
9517         $LCTL set_param fail_loc=0
9518 }
9519 run_test 60i "llog: new record vs reader race"
9520
9521 test_60j() {
9522         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
9523                 skip "need MDS version at least 2.15.50"
9524         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9525         remote_mds_nodsh && skip "remote MDS with nodsh"
9526         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
9527
9528         changelog_users $SINGLEMDS | grep "^cl" &&
9529                 skip "active changelog user"
9530
9531         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
9532
9533         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
9534                 skip_env "missing llog_reader"
9535
9536         mkdir_on_mdt0 $DIR/$tdir
9537
9538         local f=$DIR/$tdir/$tfile
9539         local mdt_dev
9540         local tmpfile
9541         local plain
9542
9543         changelog_register || error "cannot register changelog user"
9544
9545         # set changelog_mask to ALL
9546         changelog_chmask "ALL"
9547         changelog_clear
9548
9549         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
9550         unlinkmany ${f}- 100 || error "unlinkmany failed"
9551
9552         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
9553         mdt_dev=$(facet_device $SINGLEMDS)
9554
9555         do_facet $SINGLEMDS sync
9556         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
9557                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
9558                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
9559
9560         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
9561
9562         # if $tmpfile is not on EXT3 filesystem for some reason
9563         [[ ${plain:0:1} == 'O' ]] ||
9564                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
9565
9566         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
9567                 $mdt_dev; stat -c %s $tmpfile")
9568         echo "Truncate llog from $size to $((size - size % 8192))"
9569         size=$((size - size % 8192))
9570         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
9571         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9572                 grep -c 'in bitmap only')
9573         (( $errs > 0 )) || error "llog_reader didn't find lost records"
9574
9575         size=$((size - 9000))
9576         echo "Corrupt llog in the middle at $size"
9577         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
9578                 count=333 conv=notrunc
9579         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9580                 grep -c 'next chunk')
9581         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
9582 }
9583 run_test 60j "llog_reader reports corruptions"
9584
9585 test_61a() {
9586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9587
9588         f="$DIR/f61"
9589         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
9590         cancel_lru_locks osc
9591         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
9592         sync
9593 }
9594 run_test 61a "mmap() writes don't make sync hang ================"
9595
9596 test_61b() {
9597         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
9598 }
9599 run_test 61b "mmap() of unstriped file is successful"
9600
9601 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
9602 # Though this test is irrelevant anymore, it helped to reveal some
9603 # other grant bugs (LU-4482), let's keep it.
9604 test_63a() {   # was test_63
9605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9606
9607         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
9608
9609         for i in `seq 10` ; do
9610                 dd if=/dev/zero of=$DIR/f63 bs=8k &
9611                 sleep 5
9612                 kill $!
9613                 sleep 1
9614         done
9615
9616         rm -f $DIR/f63 || true
9617 }
9618 run_test 63a "Verify oig_wait interruption does not crash ======="
9619
9620 # bug 2248 - async write errors didn't return to application on sync
9621 # bug 3677 - async write errors left page locked
9622 test_63b() {
9623         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9624
9625         debugsave
9626         lctl set_param debug=-1
9627
9628         # ensure we have a grant to do async writes
9629         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
9630         rm $DIR/$tfile
9631
9632         sync    # sync lest earlier test intercept the fail_loc
9633
9634         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9635         lctl set_param fail_loc=0x80000406
9636         $MULTIOP $DIR/$tfile Owy && \
9637                 error "sync didn't return ENOMEM"
9638         sync; sleep 2; sync     # do a real sync this time to flush page
9639         lctl get_param -n llite.*.dump_page_cache | grep locked && \
9640                 error "locked page left in cache after async error" || true
9641         debugrestore
9642 }
9643 run_test 63b "async write errors should be returned to fsync ==="
9644
9645 test_64a () {
9646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9647
9648         lfs df $DIR
9649         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
9650 }
9651 run_test 64a "verify filter grant calculations (in kernel) ====="
9652
9653 test_64b () {
9654         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9655
9656         bash oos.sh $MOUNT || error "oos.sh failed: $?"
9657 }
9658 run_test 64b "check out-of-space detection on client"
9659
9660 test_64c() {
9661         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
9662 }
9663 run_test 64c "verify grant shrink"
9664
9665 import_param() {
9666         local tgt=$1
9667         local param=$2
9668
9669         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
9670 }
9671
9672 # this does exactly what osc_request.c:osc_announce_cached() does in
9673 # order to calculate max amount of grants to ask from server
9674 want_grant() {
9675         local tgt=$1
9676
9677         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
9678         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
9679
9680         ((rpc_in_flight++));
9681         nrpages=$((nrpages * rpc_in_flight))
9682
9683         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
9684
9685         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
9686
9687         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
9688         local undirty=$((nrpages * PAGE_SIZE))
9689
9690         local max_extent_pages
9691         max_extent_pages=$(import_param $tgt grant_max_extent_size)
9692         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
9693         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
9694         local grant_extent_tax
9695         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9696
9697         undirty=$((undirty + nrextents * grant_extent_tax))
9698
9699         echo $undirty
9700 }
9701
9702 # this is size of unit for grant allocation. It should be equal to
9703 # what tgt_grant.c:tgt_grant_chunk() calculates
9704 grant_chunk() {
9705         local tgt=$1
9706         local max_brw_size
9707         local grant_extent_tax
9708
9709         max_brw_size=$(import_param $tgt max_brw_size)
9710
9711         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9712
9713         echo $(((max_brw_size + grant_extent_tax) * 2))
9714 }
9715
9716 test_64d() {
9717         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
9718                 skip "OST < 2.10.55 doesn't limit grants enough"
9719
9720         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9721
9722         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9723                 skip "no grant_param connect flag"
9724
9725         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9726
9727         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9728         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9729
9730
9731         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9732         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9733
9734         $LFS setstripe $DIR/$tfile -i 0 -c 1
9735         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9736         ddpid=$!
9737
9738         while kill -0 $ddpid; do
9739                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9740
9741                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9742                         kill $ddpid
9743                         error "cur_grant $cur_grant > $max_cur_granted"
9744                 fi
9745
9746                 sleep 1
9747         done
9748 }
9749 run_test 64d "check grant limit exceed"
9750
9751 check_grants() {
9752         local tgt=$1
9753         local expected=$2
9754         local msg=$3
9755         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9756
9757         ((cur_grants == expected)) ||
9758                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9759 }
9760
9761 round_up_p2() {
9762         echo $((($1 + $2 - 1) & ~($2 - 1)))
9763 }
9764
9765 test_64e() {
9766         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9767         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9768                 skip "Need OSS version at least 2.11.56"
9769
9770         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9771         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9772         $LCTL set_param debug=+cache
9773
9774         # Remount client to reset grant
9775         remount_client $MOUNT || error "failed to remount client"
9776         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9777
9778         local init_grants=$(import_param $osc_tgt initial_grant)
9779
9780         check_grants $osc_tgt $init_grants "init grants"
9781
9782         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9783         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9784         local gbs=$(import_param $osc_tgt grant_block_size)
9785
9786         # write random number of bytes from max_brw_size / 4 to max_brw_size
9787         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9788         # align for direct io
9789         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9790         # round to grant consumption unit
9791         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9792
9793         local grants=$((wb_round_up + extent_tax))
9794
9795         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9796         stack_trap "rm -f $DIR/$tfile"
9797
9798         # define OBD_FAIL_TGT_NO_GRANT 0x725
9799         # make the server not grant more back
9800         do_facet ost1 $LCTL set_param fail_loc=0x725
9801         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9802
9803         do_facet ost1 $LCTL set_param fail_loc=0
9804
9805         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9806
9807         rm -f $DIR/$tfile || error "rm failed"
9808
9809         # Remount client to reset grant
9810         remount_client $MOUNT || error "failed to remount client"
9811         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9812
9813         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9814
9815         # define OBD_FAIL_TGT_NO_GRANT 0x725
9816         # make the server not grant more back
9817         do_facet ost1 $LCTL set_param fail_loc=0x725
9818         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9819         do_facet ost1 $LCTL set_param fail_loc=0
9820
9821         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9822 }
9823 run_test 64e "check grant consumption (no grant allocation)"
9824
9825 test_64f() {
9826         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9827
9828         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9829         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9830         $LCTL set_param debug=+cache
9831
9832         # Remount client to reset grant
9833         remount_client $MOUNT || error "failed to remount client"
9834         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9835
9836         local init_grants=$(import_param $osc_tgt initial_grant)
9837         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9838         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9839         local gbs=$(import_param $osc_tgt grant_block_size)
9840         local chunk=$(grant_chunk $osc_tgt)
9841
9842         # write random number of bytes from max_brw_size / 4 to max_brw_size
9843         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9844         # align for direct io
9845         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9846         # round to grant consumption unit
9847         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9848
9849         local grants=$((wb_round_up + extent_tax))
9850
9851         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9852         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9853                 error "error writing to $DIR/$tfile"
9854
9855         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9856                 "direct io with grant allocation"
9857
9858         rm -f $DIR/$tfile || error "rm failed"
9859
9860         # Remount client to reset grant
9861         remount_client $MOUNT || error "failed to remount client"
9862         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9863
9864         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9865
9866         # Testing that buffered IO consumes grant on the client
9867
9868         # Delay the RPC on the server so it's guaranteed to not complete even
9869         # if the RPC is sent from the client
9870         #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
9871         $LCTL set_param fail_loc=0x50a fail_val=3
9872         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 conv=notrunc ||
9873                 error "error writing to $DIR/$tfile with buffered IO"
9874
9875         check_grants $osc_tgt $((init_grants - grants)) \
9876                 "buffered io, not write rpc"
9877
9878         # Clear the fail loc and do a sync on the client
9879         $LCTL set_param fail_loc=0 fail_val=0
9880         sync
9881
9882         # RPC is now known to have sent
9883         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9884                 "buffered io, one RPC"
9885 }
9886 run_test 64f "check grant consumption (with grant allocation)"
9887
9888 test_64g() {
9889         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9890                 skip "Need MDS version at least 2.14.56"
9891
9892         local mdts=$(comma_list $(mdts_nodes))
9893
9894         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9895                         tr '\n' ' ')
9896         stack_trap "$LCTL set_param $old"
9897
9898         # generate dirty pages and increase dirty granted on MDT
9899         stack_trap "rm -f $DIR/$tfile-*"
9900         for (( i = 0; i < 10; i++)); do
9901                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9902                         error "can't set stripe"
9903                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9904                         error "can't dd"
9905                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9906                         $LFS getstripe $DIR/$tfile-$i
9907                         error "not DoM file"
9908                 }
9909         done
9910
9911         # flush dirty pages
9912         sync
9913
9914         # wait until grant shrink reset grant dirty on MDTs
9915         for ((i = 0; i < 120; i++)); do
9916                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9917                         awk '{sum=sum+$1} END {print sum}')
9918                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9919                 echo "$grant_dirty grants, $vm_dirty pages"
9920                 (( grant_dirty + vm_dirty == 0 )) && break
9921                 (( i == 3 )) && sync &&
9922                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9923                 sleep 1
9924         done
9925
9926         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9927                 awk '{sum=sum+$1} END {print sum}')
9928         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9929 }
9930 run_test 64g "grant shrink on MDT"
9931
9932 test_64h() {
9933         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9934                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9935
9936         local instance=$($LFS getname -i $DIR)
9937         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9938         local num_exps=$(do_facet ost1 \
9939             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9940         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9941         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9942         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9943
9944         # 10MiB is for file to be written, max_brw_size * 16 *
9945         # num_exps is space reserve so that tgt_grant_shrink() decided
9946         # to not shrink
9947         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9948         (( avail * 1024 < expect )) &&
9949                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9950
9951         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9952         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9953         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9954         $LCTL set_param osc.*OST0000*.grant_shrink=1
9955         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9956
9957         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9958         stack_trap "rm -f $DIR/$tfile"
9959         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9960
9961         # drop cache so that coming read would do rpc
9962         cancel_lru_locks osc
9963
9964         # shrink interval is set to 10, pause for 7 seconds so that
9965         # grant thread did not wake up yet but coming read entered
9966         # shrink mode for rpc (osc_should_shrink_grant())
9967         sleep 7
9968
9969         declare -a cur_grant_bytes
9970         declare -a tot_granted
9971         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9972         tot_granted[0]=$(do_facet ost1 \
9973             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9974
9975         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9976
9977         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9978         tot_granted[1]=$(do_facet ost1 \
9979             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9980
9981         # grant change should be equal on both sides
9982         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9983                 tot_granted[0] - tot_granted[1])) ||
9984                 error "grant change mismatch, "                                \
9985                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9986                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9987 }
9988 run_test 64h "grant shrink on read"
9989
9990 test_64i() {
9991         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9992                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9993
9994         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9995         remote_ost_nodsh && skip "remote OSTs with nodsh"
9996
9997         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9998         stack_trap "rm -f $DIR/$tfile"
9999
10000         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
10001
10002         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
10003         local instance=$($LFS getname -i $DIR)
10004
10005         local osc_tgt="$FSNAME-OST0000-osc-$instance"
10006         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
10007
10008         # shrink grants and simulate rpc loss
10009         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
10010         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
10011         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
10012
10013         fail ost1
10014
10015         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
10016
10017         local testid=$(echo $TESTNAME | tr '_' ' ')
10018
10019         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
10020                 grep "GRANT, real grant" &&
10021                 error "client has more grants then it owns" || true
10022 }
10023 run_test 64i "shrink on reconnect"
10024
10025 # bug 1414 - set/get directories' stripe info
10026 test_65a() {
10027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10028
10029         test_mkdir $DIR/$tdir
10030         touch $DIR/$tdir/f1
10031         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
10032 }
10033 run_test 65a "directory with no stripe info"
10034
10035 test_65b() {
10036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10037
10038         test_mkdir $DIR/$tdir
10039         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10040
10041         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
10042                                                 error "setstripe"
10043         touch $DIR/$tdir/f2
10044         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
10045 }
10046 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
10047
10048 test_65c() {
10049         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10050         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
10051
10052         test_mkdir $DIR/$tdir
10053         local stripesize=$($LFS getstripe -S $DIR/$tdir)
10054
10055         $LFS setstripe -S $((stripesize * 4)) -i 1 \
10056                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
10057         touch $DIR/$tdir/f3
10058         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
10059 }
10060 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
10061
10062 test_65d() {
10063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10064
10065         test_mkdir $DIR/$tdir
10066         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
10067         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10068
10069         if [[ $STRIPECOUNT -le 0 ]]; then
10070                 sc=1
10071         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
10072                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
10073                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
10074         else
10075                 sc=$(($STRIPECOUNT - 1))
10076         fi
10077         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
10078         touch $DIR/$tdir/f4 $DIR/$tdir/f5
10079         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
10080                 error "lverify failed"
10081 }
10082 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
10083
10084 test_65e() {
10085         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10086
10087         # LU-16904 delete layout when root is set as PFL layout
10088         save_layout_restore_at_exit $MOUNT
10089         $LFS setstripe -d $MOUNT || error "setstripe failed"
10090
10091         test_mkdir $DIR/$tdir
10092
10093         $LFS setstripe $DIR/$tdir || error "setstripe"
10094         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
10095                                         error "no stripe info failed"
10096         touch $DIR/$tdir/f6
10097         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
10098 }
10099 run_test 65e "directory setstripe defaults"
10100
10101 test_65f() {
10102         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10103
10104         test_mkdir $DIR/${tdir}f
10105         $RUNAS $LFS setstripe $DIR/${tdir}f &&
10106                 error "setstripe succeeded" || true
10107 }
10108 run_test 65f "dir setstripe permission (should return error) ==="
10109
10110 test_65g() {
10111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10112
10113         # LU-16904 delete layout when root is set as PFL layout
10114         save_layout_restore_at_exit $MOUNT
10115         $LFS setstripe -d $MOUNT || error "setstripe failed"
10116
10117         test_mkdir $DIR/$tdir
10118         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10119
10120         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
10121                 error "setstripe -S failed"
10122         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
10123         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
10124                 error "delete default stripe failed"
10125 }
10126 run_test 65g "directory setstripe -d"
10127
10128 test_65h() {
10129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10130
10131         test_mkdir $DIR/$tdir
10132         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10133
10134         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
10135                 error "setstripe -S failed"
10136         test_mkdir $DIR/$tdir/dd1
10137         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
10138                 error "stripe info inherit failed"
10139 }
10140 run_test 65h "directory stripe info inherit ===================="
10141
10142 test_65i() {
10143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10144
10145         save_layout_restore_at_exit $MOUNT
10146
10147         # bug6367: set non-default striping on root directory
10148         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
10149
10150         # bug12836: getstripe on -1 default directory striping
10151         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
10152
10153         # bug12836: getstripe -v on -1 default directory striping
10154         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
10155
10156         # bug12836: new find on -1 default directory striping
10157         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
10158 }
10159 run_test 65i "various tests to set root directory striping"
10160
10161 test_65j() { # bug6367
10162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10163
10164         sync; sleep 1
10165
10166         # if we aren't already remounting for each test, do so for this test
10167         if [ "$I_MOUNTED" = "yes" ]; then
10168                 cleanup || error "failed to unmount"
10169                 setup
10170         fi
10171
10172         save_layout_restore_at_exit $MOUNT
10173
10174         $LFS setstripe -d $MOUNT || error "setstripe failed"
10175 }
10176 run_test 65j "set default striping on root directory (bug 6367)="
10177
10178 cleanup_65k() {
10179         rm -rf $DIR/$tdir
10180         wait_delete_completed
10181         do_facet $SINGLEMDS "lctl set_param -n \
10182                 osp.$ost*MDT0000.max_create_count=$max_count"
10183         do_facet $SINGLEMDS "lctl set_param -n \
10184                 osp.$ost*MDT0000.create_count=$count"
10185         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10186         echo $INACTIVE_OSC "is Activate"
10187
10188         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10189 }
10190
10191 test_65k() { # bug11679
10192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10193         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10194         remote_mds_nodsh && skip "remote MDS with nodsh"
10195
10196         local disable_precreate=true
10197         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
10198                 disable_precreate=false
10199
10200         echo "Check OST status: "
10201         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
10202                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
10203
10204         for OSC in $MDS_OSCS; do
10205                 echo $OSC "is active"
10206                 do_facet $SINGLEMDS lctl --device %$OSC activate
10207         done
10208
10209         for INACTIVE_OSC in $MDS_OSCS; do
10210                 local ost=$(osc_to_ost $INACTIVE_OSC)
10211                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
10212                                lov.*md*.target_obd |
10213                                awk -F: /$ost/'{ print $1 }' | head -n 1)
10214
10215                 mkdir -p $DIR/$tdir
10216                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
10217                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
10218
10219                 echo "Deactivate: " $INACTIVE_OSC
10220                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
10221
10222                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
10223                               osp.$ost*MDT0000.create_count")
10224                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
10225                                   osp.$ost*MDT0000.max_create_count")
10226                 $disable_precreate &&
10227                         do_facet $SINGLEMDS "lctl set_param -n \
10228                                 osp.$ost*MDT0000.max_create_count=0"
10229
10230                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
10231                         [ -f $DIR/$tdir/$idx ] && continue
10232                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
10233                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
10234                                 { cleanup_65k;
10235                                   error "setstripe $idx should succeed"; }
10236                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
10237                 done
10238                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
10239                 rmdir $DIR/$tdir
10240
10241                 do_facet $SINGLEMDS "lctl set_param -n \
10242                         osp.$ost*MDT0000.max_create_count=$max_count"
10243                 do_facet $SINGLEMDS "lctl set_param -n \
10244                         osp.$ost*MDT0000.create_count=$count"
10245                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10246                 echo $INACTIVE_OSC "is Activate"
10247
10248                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10249         done
10250 }
10251 run_test 65k "validate manual striping works properly with deactivated OSCs"
10252
10253 test_65l() { # bug 12836
10254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10255
10256         test_mkdir -p $DIR/$tdir/test_dir
10257         $LFS setstripe -c -1 $DIR/$tdir/test_dir
10258         $LFS find -mtime -1 $DIR/$tdir >/dev/null
10259 }
10260 run_test 65l "lfs find on -1 stripe dir ========================"
10261
10262 test_65m() {
10263         local layout=$(save_layout $MOUNT)
10264         $RUNAS $LFS setstripe -c 2 $MOUNT && {
10265                 restore_layout $MOUNT $layout
10266                 error "setstripe should fail by non-root users"
10267         }
10268         true
10269 }
10270 run_test 65m "normal user can't set filesystem default stripe"
10271
10272 test_65n() {
10273         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
10274         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
10275                 skip "Need MDS version at least 2.12.50"
10276         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
10277
10278         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
10279         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
10280         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
10281
10282         save_layout_restore_at_exit $MOUNT
10283
10284         # new subdirectory under root directory should not inherit
10285         # the default layout from root
10286         # LU-16904 check if the root is set as PFL layout
10287         local numcomp=$($LFS getstripe --component-count $MOUNT)
10288
10289         if [[ $numcomp -eq 0 ]]; then
10290                 local dir1=$MOUNT/$tdir-1
10291                 mkdir $dir1 || error "mkdir $dir1 failed"
10292                 ! getfattr -n trusted.lov $dir1 &> /dev/null ||
10293                         error "$dir1 shouldn't have LOV EA"
10294         fi
10295
10296         # delete the default layout on root directory
10297         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
10298
10299         local dir2=$MOUNT/$tdir-2
10300         mkdir $dir2 || error "mkdir $dir2 failed"
10301         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
10302                 error "$dir2 shouldn't have LOV EA"
10303
10304         # set a new striping pattern on root directory
10305         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10306         local new_def_stripe_size=$((def_stripe_size * 2))
10307         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
10308                 error "set stripe size on $MOUNT failed"
10309
10310         # new file created in $dir2 should inherit the new stripe size from
10311         # the filesystem default
10312         local file2=$dir2/$tfile-2
10313         touch $file2 || error "touch $file2 failed"
10314
10315         local file2_stripe_size=$($LFS getstripe -S $file2)
10316         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
10317         {
10318                 echo "file2_stripe_size: '$file2_stripe_size'"
10319                 echo "new_def_stripe_size: '$new_def_stripe_size'"
10320                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
10321         }
10322
10323         local dir3=$MOUNT/$tdir-3
10324         mkdir $dir3 || error "mkdir $dir3 failed"
10325         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
10326         # the root layout, which is the actual default layout that will be used
10327         # when new files are created in $dir3.
10328         local dir3_layout=$(get_layout_param $dir3)
10329         local root_dir_layout=$(get_layout_param $MOUNT)
10330         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
10331         {
10332                 echo "dir3_layout: '$dir3_layout'"
10333                 echo "root_dir_layout: '$root_dir_layout'"
10334                 error "$dir3 should show the default layout from $MOUNT"
10335         }
10336
10337         # set OST pool on root directory
10338         local pool=$TESTNAME
10339         pool_add $pool || error "add $pool failed"
10340         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10341                 error "add targets to $pool failed"
10342
10343         $LFS setstripe -p $pool $MOUNT ||
10344                 error "set OST pool on $MOUNT failed"
10345
10346         # new file created in $dir3 should inherit the pool from
10347         # the filesystem default
10348         local file3=$dir3/$tfile-3
10349         touch $file3 || error "touch $file3 failed"
10350
10351         local file3_pool=$($LFS getstripe -p $file3)
10352         [[ "$file3_pool" = "$pool" ]] ||
10353                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
10354
10355         local dir4=$MOUNT/$tdir-4
10356         mkdir $dir4 || error "mkdir $dir4 failed"
10357         local dir4_layout=$(get_layout_param $dir4)
10358         root_dir_layout=$(get_layout_param $MOUNT)
10359         echo "$LFS getstripe -d $dir4"
10360         $LFS getstripe -d $dir4
10361         echo "$LFS getstripe -d $MOUNT"
10362         $LFS getstripe -d $MOUNT
10363         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
10364         {
10365                 echo "dir4_layout: '$dir4_layout'"
10366                 echo "root_dir_layout: '$root_dir_layout'"
10367                 error "$dir4 should show the default layout from $MOUNT"
10368         }
10369
10370         # new file created in $dir4 should inherit the pool from
10371         # the filesystem default
10372         local file4=$dir4/$tfile-4
10373         touch $file4 || error "touch $file4 failed"
10374
10375         local file4_pool=$($LFS getstripe -p $file4)
10376         [[ "$file4_pool" = "$pool" ]] ||
10377                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
10378
10379         # new subdirectory under non-root directory should inherit
10380         # the default layout from its parent directory
10381         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
10382                 error "set directory layout on $dir4 failed"
10383
10384         local dir5=$dir4/$tdir-5
10385         mkdir $dir5 || error "mkdir $dir5 failed"
10386
10387         dir4_layout=$(get_layout_param $dir4)
10388         local dir5_layout=$(get_layout_param $dir5)
10389         [[ "$dir4_layout" = "$dir5_layout" ]] ||
10390         {
10391                 echo "dir4_layout: '$dir4_layout'"
10392                 echo "dir5_layout: '$dir5_layout'"
10393                 error "$dir5 should inherit the default layout from $dir4"
10394         }
10395
10396         # though subdir under ROOT doesn't inherit default layout, but
10397         # its sub dir/file should be created with default layout.
10398         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
10399         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
10400                 skip "Need MDS version at least 2.12.59"
10401
10402         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
10403         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
10404         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
10405
10406         if [ $default_lmv_hash == "none" ]; then
10407                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
10408         else
10409                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
10410                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
10411         fi
10412
10413         $LFS setdirstripe -D -c 2 $MOUNT ||
10414                 error "setdirstripe -D -c 2 failed"
10415         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
10416         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
10417         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
10418
10419         # $dir4 layout includes pool
10420         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
10421         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10422                 error "pool lost on setstripe"
10423         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
10424         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10425                 error "pool lost on compound layout setstripe"
10426 }
10427 run_test 65n "don't inherit default layout from root for new subdirectories"
10428
10429 test_65o() {
10430         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
10431                 skip "need MDS version at least 2.14.57"
10432
10433         # set OST pool on root directory
10434         local pool=$TESTNAME
10435
10436         pool_add $pool || error "add $pool failed"
10437         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10438                 error "add targets to $pool failed"
10439
10440         local dir1=$MOUNT/$tdir
10441
10442         mkdir $dir1 || error "mkdir $dir1 failed"
10443
10444         # set a new striping pattern on root directory
10445         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10446
10447         $LFS setstripe -p $pool $dir1 ||
10448                 error "set directory layout on $dir1 failed"
10449
10450         # $dir1 layout includes pool
10451         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
10452         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10453                 error "pool lost on setstripe"
10454         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
10455         $LFS getstripe $dir1
10456         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10457                 error "pool lost on compound layout setstripe"
10458
10459         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
10460                 error "setdirstripe failed on sub-dir with inherited pool"
10461         $LFS getstripe $dir1/dir2
10462         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
10463                 error "pool lost on compound layout setdirstripe"
10464
10465         $LFS setstripe -E -1 -c 1 $dir1
10466         $LFS getstripe -d $dir1
10467         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10468                 error "pool lost on setstripe"
10469 }
10470 run_test 65o "pool inheritance for mdt component"
10471
10472 test_65p () { # LU-16152
10473         local src_dir=$DIR/$tdir/src_dir
10474         local dst_dir=$DIR/$tdir/dst_dir
10475         local yaml_file=$DIR/$tdir/layout.yaml
10476         local border
10477
10478         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10479                 skip "Need at least version 2.15.51"
10480
10481         test_mkdir -p $src_dir
10482         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
10483                 error "failed to setstripe"
10484         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
10485                 error "failed to getstripe"
10486
10487         test_mkdir -p $dst_dir
10488         $LFS setstripe --yaml $yaml_file $dst_dir ||
10489                 error "failed to setstripe with yaml file"
10490         border=$($LFS getstripe -d $dst_dir |
10491                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
10492                 error "failed to getstripe"
10493
10494         # 2048M is 0x80000000, or 2147483648
10495         (( $border == 2147483648 )) ||
10496                 error "failed to handle huge number in yaml layout"
10497 }
10498 run_test 65p "setstripe with yaml file and huge number"
10499
10500 test_65p () { # LU-16194
10501         local src_dir=$DIR/$tdir/src_dir
10502
10503         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10504                 skip "Need at least version 2.15.51"
10505
10506         test_mkdir -p $src_dir
10507         # 8E is 0x8000 0000 0000 0000, which is negative as s64
10508         $LFS setstripe -E 8E -c 4 -E EOF -c 8 $src_dir &&
10509                 error "should fail if extent start/end >=8E"
10510
10511         # EOF should work as before
10512         $LFS setstripe -E 8M -c 4 -E EOF -c 8 $src_dir ||
10513                 error "failed to setstripe normally"
10514 }
10515 run_test 65p "setstripe with >=8E offset should fail"
10516
10517 # bug 2543 - update blocks count on client
10518 test_66() {
10519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10520
10521         local COUNT=${COUNT:-8}
10522         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
10523         sync; sync_all_data; sync; sync_all_data
10524         cancel_lru_locks osc
10525         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
10526         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
10527 }
10528 run_test 66 "update inode blocks count on client ==============="
10529
10530 meminfo() {
10531         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
10532 }
10533
10534 swap_used() {
10535         swapon -s | awk '($1 == "'$1'") { print $4 }'
10536 }
10537
10538 # bug5265, obdfilter oa2dentry return -ENOENT
10539 # #define OBD_FAIL_SRV_ENOENT 0x217
10540 test_69() {
10541         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10542         remote_ost_nodsh && skip "remote OST with nodsh"
10543
10544         f="$DIR/$tfile"
10545         $LFS setstripe -c 1 -i 0 $f
10546         stack_trap "rm -f $f ${f}.2"
10547
10548         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
10549
10550         do_facet ost1 lctl set_param fail_loc=0x217
10551         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
10552         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
10553
10554         do_facet ost1 lctl set_param fail_loc=0
10555         $DIRECTIO write $f 0 2 || error "write error"
10556
10557         cancel_lru_locks osc
10558         $DIRECTIO read $f 0 1 || error "read error"
10559
10560         do_facet ost1 lctl set_param fail_loc=0x217
10561         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
10562
10563         do_facet ost1 lctl set_param fail_loc=0
10564 }
10565 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
10566
10567 test_70a() {
10568         # Perform a really simple test of health write and health check
10569         (( $OST1_VERSION >= $(version_code 2.15.59) )) ||
10570                 skip "OSTs < 2.15.59 doesn't have enable_health_write"
10571
10572         local orig_value="$(do_facet ost1 $LCTL get_param -n enable_health_write)"
10573
10574         stack_trap "do_facet ost1 $LCTL set_param enable_health_write $orig_value"
10575
10576         # Test with health write off
10577         do_facet ost1 $LCTL set_param enable_health_write off ||
10578                 error "can't set enable_health_write off"
10579         do_facet ost1 $LCTL get_param enable_health_write ||
10580                 error "can't get enable_health_write"
10581
10582         [[ "$(do_facet ost1 $LCTL get_param health_check)" =~ "healthy" ]] ||
10583                 error "not healthy (1)"
10584
10585         # Test with health write on
10586         do_facet ost1 $LCTL set_param enable_health_write on ||
10587                 error "can't set enable_health_write on"
10588         do_facet ost1 $LCTL get_param enable_health_write ||
10589                 error "can't get enable_health_write"
10590
10591         [[ "$(do_facet ost1 $LCTL get_param health_check)" =~ "healthy" ]] ||
10592                 error "not healthy (2)"
10593 }
10594 run_test 70a "verify health_check, health_write don't explode (on OST)"
10595
10596 test_71() {
10597         test_mkdir $DIR/$tdir
10598         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
10599         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
10600 }
10601 run_test 71 "Running dbench on lustre (don't segment fault) ===="
10602
10603 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
10604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10605         [ "$RUNAS_ID" = "$UID" ] &&
10606                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10607         # Check that testing environment is properly set up. Skip if not
10608         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
10609                 skip_env "User $RUNAS_ID does not exist - skipping"
10610
10611         touch $DIR/$tfile
10612         chmod 777 $DIR/$tfile
10613         chmod ug+s $DIR/$tfile
10614         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
10615                 error "$RUNAS dd $DIR/$tfile failed"
10616         # See if we are still setuid/sgid
10617         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10618                 error "S/gid is not dropped on write"
10619         # Now test that MDS is updated too
10620         cancel_lru_locks mdc
10621         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10622                 error "S/gid is not dropped on MDS"
10623         rm -f $DIR/$tfile
10624 }
10625 run_test 72a "Test that remove suid works properly (bug5695) ===="
10626
10627 test_72b() { # bug 24226 -- keep mode setting when size is not changing
10628         local perm
10629
10630         [ "$RUNAS_ID" = "$UID" ] &&
10631                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10632         [ "$RUNAS_ID" -eq 0 ] &&
10633                 skip_env "RUNAS_ID = 0 -- skipping"
10634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10635         # Check that testing environment is properly set up. Skip if not
10636         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
10637                 skip_env "User $RUNAS_ID does not exist - skipping"
10638
10639         touch $DIR/${tfile}-f{g,u}
10640         test_mkdir $DIR/${tfile}-dg
10641         test_mkdir $DIR/${tfile}-du
10642         chmod 770 $DIR/${tfile}-{f,d}{g,u}
10643         chmod g+s $DIR/${tfile}-{f,d}g
10644         chmod u+s $DIR/${tfile}-{f,d}u
10645         for perm in 777 2777 4777; do
10646                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
10647                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
10648                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
10649                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
10650         done
10651         true
10652 }
10653 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
10654
10655 # bug 3462 - multiple simultaneous MDC requests
10656 test_73() {
10657         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10658
10659         test_mkdir $DIR/d73-1
10660         test_mkdir $DIR/d73-2
10661         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
10662         pid1=$!
10663
10664         lctl set_param fail_loc=0x80000129
10665         $MULTIOP $DIR/d73-1/f73-2 Oc &
10666         sleep 1
10667         lctl set_param fail_loc=0
10668
10669         $MULTIOP $DIR/d73-2/f73-3 Oc &
10670         pid3=$!
10671
10672         kill -USR1 $pid1
10673         wait $pid1 || return 1
10674
10675         sleep 25
10676
10677         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
10678         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
10679         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
10680
10681         rm -rf $DIR/d73-*
10682 }
10683 run_test 73 "multiple MDC requests (should not deadlock)"
10684
10685 test_74a() { # bug 6149, 6184
10686         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10687
10688         touch $DIR/f74a
10689         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10690         #
10691         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10692         # will spin in a tight reconnection loop
10693         $LCTL set_param fail_loc=0x8000030e
10694         # get any lock that won't be difficult - lookup works.
10695         ls $DIR/f74a
10696         $LCTL set_param fail_loc=0
10697         rm -f $DIR/f74a
10698         true
10699 }
10700 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
10701
10702 test_74b() { # bug 13310
10703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10704
10705         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10706         #
10707         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10708         # will spin in a tight reconnection loop
10709         $LCTL set_param fail_loc=0x8000030e
10710         # get a "difficult" lock
10711         touch $DIR/f74b
10712         $LCTL set_param fail_loc=0
10713         rm -f $DIR/f74b
10714         true
10715 }
10716 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
10717
10718 test_74c() {
10719         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10720
10721         #define OBD_FAIL_LDLM_NEW_LOCK
10722         $LCTL set_param fail_loc=0x319
10723         touch $DIR/$tfile && error "touch successful"
10724         $LCTL set_param fail_loc=0
10725         true
10726 }
10727 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
10728
10729 slab_lic=/sys/kernel/slab/lustre_inode_cache
10730 num_objects() {
10731         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
10732         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
10733                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
10734 }
10735
10736 test_76a() { # Now for b=20433, added originally in b=1443
10737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10738
10739         cancel_lru_locks osc
10740         # there may be some slab objects cached per core
10741         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10742         local before=$(num_objects)
10743         local count=$((512 * cpus))
10744         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10745         local margin=$((count / 10))
10746         if [[ -f $slab_lic/aliases ]]; then
10747                 local aliases=$(cat $slab_lic/aliases)
10748                 (( aliases > 0 )) && margin=$((margin * aliases))
10749         fi
10750
10751         echo "before slab objects: $before"
10752         for i in $(seq $count); do
10753                 touch $DIR/$tfile
10754                 rm -f $DIR/$tfile
10755         done
10756         cancel_lru_locks osc
10757         local after=$(num_objects)
10758         echo "created: $count, after slab objects: $after"
10759         # shared slab counts are not very accurate, allow significant margin
10760         # the main goal is that the cache growth is not permanently > $count
10761         while (( after > before + margin )); do
10762                 sleep 1
10763                 after=$(num_objects)
10764                 wait=$((wait + 1))
10765                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10766                 if (( wait > 60 )); then
10767                         error "inode slab grew from $before+$margin to $after"
10768                 fi
10769         done
10770 }
10771 run_test 76a "confirm clients recycle inodes properly ===="
10772
10773 test_76b() {
10774         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10775         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10776
10777         local count=512
10778         local before=$(num_objects)
10779
10780         for i in $(seq $count); do
10781                 mkdir $DIR/$tdir
10782                 rmdir $DIR/$tdir
10783         done
10784
10785         local after=$(num_objects)
10786         local wait=0
10787
10788         while (( after > before )); do
10789                 sleep 1
10790                 after=$(num_objects)
10791                 wait=$((wait + 1))
10792                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10793                 if (( wait > 60 )); then
10794                         error "inode slab grew from $before to $after"
10795                 fi
10796         done
10797
10798         echo "slab objects before: $before, after: $after"
10799 }
10800 run_test 76b "confirm clients recycle directory inodes properly ===="
10801
10802 export ORIG_CSUM=""
10803 set_checksums()
10804 {
10805         # Note: in sptlrpc modes which enable its own bulk checksum, the
10806         # original crc32_le bulk checksum will be automatically disabled,
10807         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10808         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10809         # In this case set_checksums() will not be no-op, because sptlrpc
10810         # bulk checksum will be enabled all through the test.
10811
10812         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10813         lctl set_param -n osc.*.checksums $1
10814         return 0
10815 }
10816
10817 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10818                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10819 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10820                              tr -d [] | head -n1)}
10821 set_checksum_type()
10822 {
10823         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10824         rc=$?
10825         log "set checksum type to $1, rc = $rc"
10826         return $rc
10827 }
10828
10829 get_osc_checksum_type()
10830 {
10831         # arugment 1: OST name, like OST0000
10832         ost=$1
10833         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10834                         sed 's/.*\[\(.*\)\].*/\1/g')
10835         rc=$?
10836         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10837         echo $checksum_type
10838 }
10839
10840 F77_TMP=$TMP/f77-temp
10841 F77SZ=8
10842 setup_f77() {
10843         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10844                 error "error writing to $F77_TMP"
10845 }
10846
10847 test_77a() { # bug 10889
10848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10849         $GSS && skip_env "could not run with gss"
10850
10851         [ ! -f $F77_TMP ] && setup_f77
10852         set_checksums 1
10853         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10854         set_checksums 0
10855         rm -f $DIR/$tfile
10856 }
10857 run_test 77a "normal checksum read/write operation"
10858
10859 test_77b() { # bug 10889
10860         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10861         $GSS && skip_env "could not run with gss"
10862
10863         [ ! -f $F77_TMP ] && setup_f77
10864         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10865         $LCTL set_param fail_loc=0x80000409
10866         set_checksums 1
10867
10868         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10869                 error "dd error: $?"
10870         $LCTL set_param fail_loc=0
10871
10872         for algo in $CKSUM_TYPES; do
10873                 cancel_lru_locks osc
10874                 set_checksum_type $algo
10875                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10876                 $LCTL set_param fail_loc=0x80000408
10877                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10878                 $LCTL set_param fail_loc=0
10879         done
10880         set_checksums 0
10881         set_checksum_type $ORIG_CSUM_TYPE
10882         rm -f $DIR/$tfile
10883 }
10884 run_test 77b "checksum error on client write, read"
10885
10886 cleanup_77c() {
10887         trap 0
10888         set_checksums 0
10889         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10890         $check_ost &&
10891                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10892         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10893         $check_ost && [ -n "$ost_file_prefix" ] &&
10894                 do_facet ost1 rm -f ${ost_file_prefix}\*
10895 }
10896
10897 test_77c() {
10898         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10899         $GSS && skip_env "could not run with gss"
10900         remote_ost_nodsh && skip "remote OST with nodsh"
10901
10902         local bad1
10903         local osc_file_prefix
10904         local osc_file
10905         local check_ost=false
10906         local ost_file_prefix
10907         local ost_file
10908         local orig_cksum
10909         local dump_cksum
10910         local fid
10911
10912         # ensure corruption will occur on first OSS/OST
10913         $LFS setstripe -i 0 $DIR/$tfile
10914
10915         [ ! -f $F77_TMP ] && setup_f77
10916         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10917                 error "dd write error: $?"
10918         fid=$($LFS path2fid $DIR/$tfile)
10919
10920         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10921         then
10922                 check_ost=true
10923                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10924                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10925         else
10926                 echo "OSS do not support bulk pages dump upon error"
10927         fi
10928
10929         osc_file_prefix=$($LCTL get_param -n debug_path)
10930         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10931
10932         trap cleanup_77c EXIT
10933
10934         set_checksums 1
10935         # enable bulk pages dump upon error on Client
10936         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10937         # enable bulk pages dump upon error on OSS
10938         $check_ost &&
10939                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10940
10941         # flush Client cache to allow next read to reach OSS
10942         cancel_lru_locks osc
10943
10944         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10945         $LCTL set_param fail_loc=0x80000408
10946         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10947         $LCTL set_param fail_loc=0
10948
10949         rm -f $DIR/$tfile
10950
10951         # check cksum dump on Client
10952         osc_file=$(ls ${osc_file_prefix}*)
10953         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10954         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10955         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10956         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10957         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10958                      cksum)
10959         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10960         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10961                 error "dump content does not match on Client"
10962
10963         $check_ost || skip "No need to check cksum dump on OSS"
10964
10965         # check cksum dump on OSS
10966         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10967         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10968         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10969         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10970         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10971                 error "dump content does not match on OSS"
10972
10973         cleanup_77c
10974 }
10975 run_test 77c "checksum error on client read with debug"
10976
10977 test_77d() { # bug 10889
10978         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10979         $GSS && skip_env "could not run with gss"
10980
10981         stack_trap "rm -f $DIR/$tfile"
10982         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10983         $LCTL set_param fail_loc=0x80000409
10984         set_checksums 1
10985         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10986                 error "direct write: rc=$?"
10987         $LCTL set_param fail_loc=0
10988         set_checksums 0
10989
10990         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10991         $LCTL set_param fail_loc=0x80000408
10992         set_checksums 1
10993         cancel_lru_locks osc
10994         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10995                 error "direct read: rc=$?"
10996         $LCTL set_param fail_loc=0
10997         set_checksums 0
10998 }
10999 run_test 77d "checksum error on OST direct write, read"
11000
11001 test_77f() { # bug 10889
11002         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11003         $GSS && skip_env "could not run with gss"
11004
11005         set_checksums 1
11006         stack_trap "rm -f $DIR/$tfile"
11007         for algo in $CKSUM_TYPES; do
11008                 cancel_lru_locks osc
11009                 set_checksum_type $algo
11010                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
11011                 $LCTL set_param fail_loc=0x409
11012                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
11013                         error "direct write succeeded"
11014                 $LCTL set_param fail_loc=0
11015         done
11016         set_checksum_type $ORIG_CSUM_TYPE
11017         set_checksums 0
11018 }
11019 run_test 77f "repeat checksum error on write (expect error)"
11020
11021 test_77g() { # bug 10889
11022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11023         $GSS && skip_env "could not run with gss"
11024         remote_ost_nodsh && skip "remote OST with nodsh"
11025
11026         [ ! -f $F77_TMP ] && setup_f77
11027
11028         local file=$DIR/$tfile
11029         stack_trap "rm -f $file" EXIT
11030
11031         $LFS setstripe -c 1 -i 0 $file
11032         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
11033         do_facet ost1 lctl set_param fail_loc=0x8000021a
11034         set_checksums 1
11035         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
11036                 error "write error: rc=$?"
11037         do_facet ost1 lctl set_param fail_loc=0
11038         set_checksums 0
11039
11040         cancel_lru_locks osc
11041         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
11042         do_facet ost1 lctl set_param fail_loc=0x8000021b
11043         set_checksums 1
11044         cmp $F77_TMP $file || error "file compare failed"
11045         do_facet ost1 lctl set_param fail_loc=0
11046         set_checksums 0
11047 }
11048 run_test 77g "checksum error on OST write, read"
11049
11050 test_77k() { # LU-10906
11051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11052         $GSS && skip_env "could not run with gss"
11053
11054         local cksum_param="osc.$FSNAME*.checksums"
11055         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
11056         local checksum
11057         local i
11058
11059         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
11060         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
11061         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
11062
11063         for i in 0 1; do
11064                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
11065                         error "failed to set checksum=$i on MGS"
11066                 wait_update $HOSTNAME "$get_checksum" $i
11067                 #remount
11068                 echo "remount client, checksum should be $i"
11069                 remount_client $MOUNT || error "failed to remount client"
11070                 checksum=$(eval $get_checksum)
11071                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
11072         done
11073         # remove persistent param to avoid races with checksum mountopt below
11074         do_facet mgs $LCTL set_param -P -d $cksum_param ||
11075                 error "failed to delete checksum on MGS"
11076
11077         for opt in "checksum" "nochecksum"; do
11078                 #remount with mount option
11079                 echo "remount client with option $opt, checksum should be $i"
11080                 umount_client $MOUNT || error "failed to umount client"
11081                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
11082                         error "failed to mount client with option '$opt'"
11083                 checksum=$(eval $get_checksum)
11084                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
11085                 i=$((i - 1))
11086         done
11087
11088         remount_client $MOUNT || error "failed to remount client"
11089 }
11090 run_test 77k "enable/disable checksum correctly"
11091
11092 test_77l() {
11093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11094         $GSS && skip_env "could not run with gss"
11095
11096         set_checksums 1
11097         stack_trap "set_checksums $ORIG_CSUM" EXIT
11098         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
11099
11100         set_checksum_type invalid && error "unexpected success of invalid checksum type"
11101
11102         $LFS setstripe -c 1 -i 0 $DIR/$tfile
11103         for algo in $CKSUM_TYPES; do
11104                 set_checksum_type $algo || error "fail to set checksum type $algo"
11105                 osc_algo=$(get_osc_checksum_type OST0000)
11106                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
11107
11108                 # no locks, no reqs to let the connection idle
11109                 cancel_lru_locks osc
11110                 lru_resize_disable osc
11111                 wait_osc_import_state client ost1 IDLE
11112
11113                 # ensure ost1 is connected
11114                 stat $DIR/$tfile >/dev/null || error "can't stat"
11115                 wait_osc_import_state client ost1 FULL
11116
11117                 osc_algo=$(get_osc_checksum_type OST0000)
11118                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
11119         done
11120         return 0
11121 }
11122 run_test 77l "preferred checksum type is remembered after reconnected"
11123
11124 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
11125 rm -f $F77_TMP
11126 unset F77_TMP
11127
11128 test_77m() {
11129         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
11130                 skip "Need at least version 2.14.52"
11131         local param=checksum_speed
11132
11133         $LCTL get_param $param || error "reading $param failed"
11134
11135         csum_speeds=$($LCTL get_param -n $param)
11136
11137         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
11138                 error "known checksum types are missing"
11139 }
11140 run_test 77m "Verify checksum_speed is correctly read"
11141
11142 check_filefrag_77n() {
11143         local nr_ext=0
11144         local starts=()
11145         local ends=()
11146
11147         while read extidx a b start end rest; do
11148                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
11149                         nr_ext=$(( $nr_ext + 1 ))
11150                         starts+=( ${start%..} )
11151                         ends+=( ${end%:} )
11152                 fi
11153         done < <( filefrag -sv $1 )
11154
11155         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
11156         return 1
11157 }
11158
11159 test_77n() {
11160         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
11161
11162         touch $DIR/$tfile
11163         $TRUNCATE $DIR/$tfile 0
11164         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
11165         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
11166         check_filefrag_77n $DIR/$tfile ||
11167                 skip "$tfile blocks not contiguous around hole"
11168
11169         set_checksums 1
11170         stack_trap "set_checksums $ORIG_CSUM" EXIT
11171         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
11172         stack_trap "rm -f $DIR/$tfile"
11173
11174         for algo in $CKSUM_TYPES; do
11175                 if [[ "$algo" =~ ^t10 ]]; then
11176                         set_checksum_type $algo ||
11177                                 error "fail to set checksum type $algo"
11178                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
11179                                 error "fail to read $tfile with $algo"
11180                 fi
11181         done
11182         rm -f $DIR/$tfile
11183         return 0
11184 }
11185 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
11186
11187 test_77o() {
11188         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
11189                 skip "Need MDS version at least 2.14.55"
11190         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
11191                 skip "Need OST version at least 2.14.55"
11192         local ofd=obdfilter
11193         local mdt=mdt
11194
11195         # print OST checksum_type
11196         echo "$ofd.$FSNAME-*.checksum_type:"
11197         do_nodes $(comma_list $(osts_nodes)) \
11198                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
11199
11200         # print MDT checksum_type
11201         echo "$mdt.$FSNAME-*.checksum_type:"
11202         do_nodes $(comma_list $(mdts_nodes)) \
11203                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
11204
11205         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
11206                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
11207
11208         (( $o_count == $OSTCOUNT )) ||
11209                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
11210
11211         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
11212                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
11213
11214         (( $m_count == $MDSCOUNT )) ||
11215                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
11216 }
11217 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
11218
11219 cleanup_test_78() {
11220         trap 0
11221         rm -f $DIR/$tfile
11222 }
11223
11224 test_78() { # bug 10901
11225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11226         remote_ost || skip_env "local OST"
11227
11228         NSEQ=5
11229         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
11230         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
11231         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
11232         echo "MemTotal: $MEMTOTAL"
11233
11234         # reserve 256MB of memory for the kernel and other running processes,
11235         # and then take 1/2 of the remaining memory for the read/write buffers.
11236         if [ $MEMTOTAL -gt 512 ] ;then
11237                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
11238         else
11239                 # for those poor memory-starved high-end clusters...
11240                 MEMTOTAL=$((MEMTOTAL / 2))
11241         fi
11242         echo "Mem to use for directio: $MEMTOTAL"
11243
11244         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
11245         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
11246         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
11247         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
11248                 head -n1)
11249         echo "Smallest OST: $SMALLESTOST"
11250         [[ $SMALLESTOST -lt 10240 ]] &&
11251                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
11252
11253         trap cleanup_test_78 EXIT
11254
11255         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
11256                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
11257
11258         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
11259         echo "File size: $F78SIZE"
11260         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
11261         for i in $(seq 1 $NSEQ); do
11262                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
11263                 echo directIO rdwr round $i of $NSEQ
11264                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
11265         done
11266
11267         cleanup_test_78
11268 }
11269 run_test 78 "handle large O_DIRECT writes correctly ============"
11270
11271 test_79() { # bug 12743
11272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11273
11274         wait_delete_completed
11275
11276         BKTOTAL=$(calc_osc_kbytes kbytestotal)
11277         BKFREE=$(calc_osc_kbytes kbytesfree)
11278         BKAVAIL=$(calc_osc_kbytes kbytesavail)
11279
11280         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
11281         DFTOTAL=`echo $STRING | cut -d, -f1`
11282         DFUSED=`echo $STRING  | cut -d, -f2`
11283         DFAVAIL=`echo $STRING | cut -d, -f3`
11284         DFFREE=$(($DFTOTAL - $DFUSED))
11285
11286         ALLOWANCE=$((64 * $OSTCOUNT))
11287
11288         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
11289            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
11290                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
11291         fi
11292         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
11293            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
11294                 error "df free($DFFREE) mismatch OST free($BKFREE)"
11295         fi
11296         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
11297            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
11298                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
11299         fi
11300 }
11301 run_test 79 "df report consistency check ======================="
11302
11303 test_80() { # bug 10718
11304         remote_ost_nodsh && skip "remote OST with nodsh"
11305         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11306
11307         # relax strong synchronous semantics for slow backends like ZFS
11308         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
11309                 local soc="obdfilter.*.sync_lock_cancel"
11310                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11311
11312                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
11313                 if [ -z "$save" ]; then
11314                         soc="obdfilter.*.sync_on_lock_cancel"
11315                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11316                 fi
11317
11318                 if [ "$save" != "never" ]; then
11319                         local hosts=$(comma_list $(osts_nodes))
11320
11321                         do_nodes $hosts $LCTL set_param $soc=never
11322                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
11323                 fi
11324         fi
11325
11326         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
11327         sync; sleep 1; sync
11328         local before=$(date +%s)
11329         cancel_lru_locks osc
11330         local after=$(date +%s)
11331         local diff=$((after - before))
11332         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
11333
11334         rm -f $DIR/$tfile
11335 }
11336 run_test 80 "Page eviction is equally fast at high offsets too"
11337
11338 test_81a() { # LU-456
11339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11340         remote_ost_nodsh && skip "remote OST with nodsh"
11341
11342         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11343         # MUST OR with the CFS_FAIL_ONCE (0x80000000)
11344         do_facet ost1 lctl set_param fail_loc=0x80000228
11345
11346         # write should trigger a retry and success
11347         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11348         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11349         RC=$?
11350         if [ $RC -ne 0 ] ; then
11351                 error "write should success, but failed for $RC"
11352         fi
11353 }
11354 run_test 81a "OST should retry write when get -ENOSPC ==============="
11355
11356 test_81b() { # LU-456
11357         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11358         remote_ost_nodsh && skip "remote OST with nodsh"
11359
11360         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11361         # Don't OR with the CFS_FAIL_ONCE (0x80000000)
11362         do_facet ost1 lctl set_param fail_loc=0x228
11363
11364         # write should retry several times and return -ENOSPC finally
11365         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11366         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11367         RC=$?
11368         ENOSPC=28
11369         if [ $RC -ne $ENOSPC ] ; then
11370                 error "dd should fail for -ENOSPC, but succeed."
11371         fi
11372 }
11373 run_test 81b "OST should return -ENOSPC when retry still fails ======="
11374
11375 test_99() {
11376         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
11377
11378         test_mkdir $DIR/$tdir.cvsroot
11379         chown $RUNAS_ID $DIR/$tdir.cvsroot
11380
11381         cd $TMP
11382         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
11383
11384         cd /etc/init.d
11385         # some versions of cvs import exit(1) when asked to import links or
11386         # files they can't read.  ignore those files.
11387         local toignore=$(find . -type l -printf '-I %f\n' -o \
11388                          ! -perm /4 -printf '-I %f\n')
11389         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
11390                 $tdir.reposname vtag rtag
11391
11392         cd $DIR
11393         test_mkdir $DIR/$tdir.reposname
11394         chown $RUNAS_ID $DIR/$tdir.reposname
11395         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
11396
11397         cd $DIR/$tdir.reposname
11398         $RUNAS touch foo99
11399         $RUNAS cvs add -m 'addmsg' foo99
11400         $RUNAS cvs update
11401         $RUNAS cvs commit -m 'nomsg' foo99
11402         rm -fr $DIR/$tdir.cvsroot
11403 }
11404 run_test 99 "cvs strange file/directory operations"
11405
11406 test_100() {
11407         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11408         [[ "$NETTYPE" =~ tcp ]] ||
11409                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
11410         [[ -n "$(type -p ss)" ]] || skip_env "ss not available"
11411         remote_ost_nodsh && skip "remote OST with nodsh"
11412         remote_mds_nodsh && skip "remote MDS with nodsh"
11413         remote_servers || skip "useless for local single node setup"
11414
11415         ss -tna | ( rc=1; while read STATE SND RCV LOCAL REMOTE STAT; do
11416                 [[ "${REMOTE/*:/}" == "$ACCEPTOR_PORT" ]] || continue
11417
11418                 rc=0
11419                 if (( ${LOCAL/*:/} >= 1024 )); then
11420                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
11421                         ss -tna
11422                         error "local: ${LOCAL/*:/} > 1024 remote: ${REMOTE/*:/}"
11423                 fi
11424         done
11425         (( $rc == 0 )) || error "privileged port not found" )
11426 }
11427 run_test 100 "check local port using privileged port"
11428
11429 function get_named_value()
11430 {
11431     local tag=$1
11432
11433     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
11434 }
11435
11436 test_101a() {
11437         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11438
11439         local s
11440         local discard
11441         local nreads=10000
11442         local cache_limit=32
11443
11444         $LCTL set_param -n osc.*-osc*.rpc_stats=0
11445         $LCTL set_param -n llite.*.read_ahead_stats=0
11446         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
11447                               awk '/^max_cached_mb/ { print $2 }')
11448         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
11449         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
11450
11451         #
11452         # randomly read 10000 of 64K chunks from file 3x 32MB in size
11453         #
11454         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
11455         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
11456
11457         discard=0
11458         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
11459                    get_named_value 'read.but.discarded'); do
11460                         discard=$(($discard + $s))
11461         done
11462
11463         $LCTL get_param osc.*-osc*.rpc_stats
11464         $LCTL get_param llite.*.read_ahead_stats
11465
11466         # Discard is generally zero, but sometimes a few random reads line up
11467         # and trigger larger readahead, which is wasted & leads to discards.
11468         if [[ $(($discard)) -gt $nreads ]]; then
11469                 error "too many ($discard) discarded pages"
11470         fi
11471         rm -f $DIR/$tfile || true
11472 }
11473 run_test 101a "check read-ahead for random reads"
11474
11475 setup_test101bc() {
11476         test_mkdir $DIR/$tdir
11477         local ssize=$1
11478         local FILE_LENGTH=$2
11479         STRIPE_OFFSET=0
11480
11481         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
11482
11483         local list=$(comma_list $(osts_nodes))
11484         set_osd_param $list '' read_cache_enable 0
11485         set_osd_param $list '' writethrough_cache_enable 0
11486
11487         trap cleanup_test101bc EXIT
11488         # prepare the read-ahead file
11489         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
11490
11491         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
11492                                 count=$FILE_SIZE_MB 2> /dev/null
11493
11494 }
11495
11496 cleanup_test101bc() {
11497         trap 0
11498         rm -rf $DIR/$tdir
11499         rm -f $DIR/$tfile
11500
11501         local list=$(comma_list $(osts_nodes))
11502         set_osd_param $list '' read_cache_enable 1
11503         set_osd_param $list '' writethrough_cache_enable 1
11504 }
11505
11506 ra_check_101() {
11507         local read_size=$1
11508         local stripe_size=$2
11509         local stride_length=$((stripe_size / read_size))
11510         local stride_width=$((stride_length * OSTCOUNT))
11511         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
11512                                 (stride_width - stride_length) ))
11513         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
11514                   get_named_value 'read.but.discarded' | calc_sum)
11515
11516         if [[ $discard -gt $discard_limit ]]; then
11517                 $LCTL get_param llite.*.read_ahead_stats
11518                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
11519         else
11520                 echo "Read-ahead success for size ${read_size}"
11521         fi
11522 }
11523
11524 test_101b() {
11525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11526         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11527
11528         local STRIPE_SIZE=1048576
11529         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
11530
11531         if [ $SLOW == "yes" ]; then
11532                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
11533         else
11534                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
11535         fi
11536
11537         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
11538
11539         # prepare the read-ahead file
11540         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11541         cancel_lru_locks osc
11542         for BIDX in 2 4 8 16 32 64 128 256
11543         do
11544                 local BSIZE=$((BIDX*4096))
11545                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
11546                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
11547                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
11548                 $LCTL set_param -n llite.*.read_ahead_stats=0
11549                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
11550                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
11551                 cancel_lru_locks osc
11552                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
11553         done
11554         cleanup_test101bc
11555         true
11556 }
11557 run_test 101b "check stride-io mode read-ahead ================="
11558
11559 test_101c() {
11560         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11561
11562         local STRIPE_SIZE=1048576
11563         local FILE_LENGTH=$((STRIPE_SIZE*100))
11564         local nreads=10000
11565         local rsize=65536
11566         local osc_rpc_stats
11567
11568         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11569
11570         cancel_lru_locks osc
11571         $LCTL set_param osc.*.rpc_stats=0
11572         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
11573         $LCTL get_param osc.*.rpc_stats
11574         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
11575                 local stats=$($LCTL get_param -n $osc_rpc_stats)
11576                 local lines=$(echo "$stats" | awk 'END {print NR;}')
11577                 local size
11578
11579                 if [ $lines -le 20 ]; then
11580                         echo "continue debug"
11581                         continue
11582                 fi
11583                 for size in 1 2 4 8; do
11584                         local rpc=$(echo "$stats" |
11585                                     awk '($1 == "'$size':") {print $2; exit; }')
11586                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
11587                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
11588                 done
11589                 echo "$osc_rpc_stats check passed!"
11590         done
11591         cleanup_test101bc
11592         true
11593 }
11594 run_test 101c "check stripe_size aligned read-ahead"
11595
11596 test_101d() {
11597         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11598
11599         local file=$DIR/$tfile
11600         local sz_MB=${FILESIZE_101d:-80}
11601         local ra_MB=${READAHEAD_MB:-40}
11602
11603         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
11604         [ $free_MB -lt $sz_MB ] &&
11605                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
11606
11607         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
11608         $LFS setstripe -c -1 $file || error "setstripe failed"
11609
11610         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
11611         echo Cancel LRU locks on lustre client to flush the client cache
11612         cancel_lru_locks osc
11613
11614         echo Disable read-ahead
11615         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11616         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11617         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
11618         $LCTL get_param -n llite.*.max_read_ahead_mb
11619
11620         echo "Reading the test file $file with read-ahead disabled"
11621         local sz_KB=$((sz_MB * 1024 / 4))
11622         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
11623         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
11624         # 83886080 bytes (84 MB, 80 MiB) copied, 16 s, 5.2 MB/s
11625         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11626                       sed -e '/records/d' -e 's/.* \([0-9][0-9\.]*\) *s.*/\1/')
11627
11628         echo "Cancel LRU locks on lustre client to flush the client cache"
11629         cancel_lru_locks osc
11630         echo Enable read-ahead with ${ra_MB}MB
11631         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
11632
11633         echo "Reading the test file $file with read-ahead enabled"
11634         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11635                       sed -e '/records/d' -e 's/.* \([0-9][0-9\.]*\) *s.*/\1/')
11636
11637         echo "read-ahead disabled time read '$raOFF'"
11638         echo "read-ahead enabled time read '$raON'"
11639
11640         rm -f $file
11641         wait_delete_completed
11642
11643         # use awk for this check instead of bash because it handles decimals
11644         awk "{ exit !($raOFF < 0.5 || $raOFF > $raON) }" <<<"ignore_me" ||
11645                 error "readahead ${raON}s > no-readahead ${raOFF}s (${sz_MB}M)"
11646 }
11647 run_test 101d "file read with and without read-ahead enabled"
11648
11649 test_101e() {
11650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11651
11652         local file=$DIR/$tfile
11653         local size_KB=500  #KB
11654         local count=100
11655         local bsize=1024
11656
11657         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
11658         local need_KB=$((count * size_KB))
11659         [[ $free_KB -le $need_KB ]] &&
11660                 skip_env "Need free space $need_KB, have $free_KB"
11661
11662         echo "Creating $count ${size_KB}K test files"
11663         for ((i = 0; i < $count; i++)); do
11664                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
11665         done
11666
11667         echo "Cancel LRU locks on lustre client to flush the client cache"
11668         cancel_lru_locks $OSC
11669
11670         echo "Reset readahead stats"
11671         $LCTL set_param -n llite.*.read_ahead_stats=0
11672
11673         for ((i = 0; i < $count; i++)); do
11674                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
11675         done
11676
11677         $LCTL get_param llite.*.max_cached_mb
11678         $LCTL get_param llite.*.read_ahead_stats
11679         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11680                      get_named_value 'misses' | calc_sum)
11681
11682         for ((i = 0; i < $count; i++)); do
11683                 rm -rf $file.$i 2>/dev/null
11684         done
11685
11686         #10000 means 20% reads are missing in readahead
11687         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
11688 }
11689 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
11690
11691 test_101f() {
11692         which iozone || skip_env "no iozone installed"
11693
11694         local old_debug=$($LCTL get_param debug)
11695         old_debug=${old_debug#*=}
11696         $LCTL set_param debug="reada mmap"
11697
11698         # create a test file
11699         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
11700
11701         echo Cancel LRU locks on lustre client to flush the client cache
11702         cancel_lru_locks osc
11703
11704         echo Reset readahead stats
11705         $LCTL set_param -n llite.*.read_ahead_stats=0
11706
11707         echo mmap read the file with small block size
11708         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
11709                 > /dev/null 2>&1
11710
11711         echo checking missing pages
11712         $LCTL get_param llite.*.read_ahead_stats
11713         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11714                         get_named_value 'misses' | calc_sum)
11715
11716         $LCTL set_param debug="$old_debug"
11717         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
11718         rm -f $DIR/$tfile
11719 }
11720 run_test 101f "check mmap read performance"
11721
11722 test_101g_brw_size_test() {
11723         local mb=$1
11724         local pages=$((mb * 1048576 / PAGE_SIZE))
11725         local file=$DIR/$tfile
11726
11727         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11728                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11729         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11730                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11731                         return 2
11732         done
11733
11734         stack_trap "rm -f $file" EXIT
11735         $LCTL set_param -n osc.*.rpc_stats=0
11736
11737         # 10 RPCs should be enough for the test
11738         local count=10
11739         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11740                 { error "dd write ${mb} MB blocks failed"; return 3; }
11741         cancel_lru_locks osc
11742         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11743                 { error "dd write ${mb} MB blocks failed"; return 4; }
11744
11745         # calculate number of full-sized read and write RPCs
11746         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11747                 sed -n '/pages per rpc/,/^$/p' |
11748                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11749                 END { print reads,writes }'))
11750         # allow one extra full-sized read RPC for async readahead
11751         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11752                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11753         [[ ${rpcs[1]} == $count ]] ||
11754                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11755 }
11756
11757 test_101g() {
11758         remote_ost_nodsh && skip "remote OST with nodsh"
11759
11760         local rpcs
11761         local osts=$(get_facets OST)
11762         local list=$(comma_list $(osts_nodes))
11763         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11764         local brw_size="obdfilter.*.brw_size"
11765
11766         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11767
11768         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11769
11770         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11771                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11772                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11773            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11774                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11775                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11776
11777                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11778                         suffix="M"
11779
11780                 if [[ $orig_mb -lt 16 ]]; then
11781                         save_lustre_params $osts "$brw_size" > $p
11782                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11783                                 error "set 16MB RPC size failed"
11784
11785                         echo "remount client to enable new RPC size"
11786                         remount_client $MOUNT || error "remount_client failed"
11787                 fi
11788
11789                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11790                 # should be able to set brw_size=12, but no rpc_stats for that
11791                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11792         fi
11793
11794         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11795
11796         if [[ $orig_mb -lt 16 ]]; then
11797                 restore_lustre_params < $p
11798                 remount_client $MOUNT || error "remount_client restore failed"
11799         fi
11800
11801         rm -f $p $DIR/$tfile
11802 }
11803 run_test 101g "Big bulk(4/16 MiB) readahead"
11804
11805 test_101h() {
11806         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11807
11808         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11809                 error "dd 70M file failed"
11810         echo Cancel LRU locks on lustre client to flush the client cache
11811         cancel_lru_locks osc
11812
11813         echo "Reset readahead stats"
11814         $LCTL set_param -n llite.*.read_ahead_stats 0
11815
11816         echo "Read 10M of data but cross 64M bundary"
11817         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11818         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11819                      get_named_value 'misses' | calc_sum)
11820         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11821         rm -f $p $DIR/$tfile
11822 }
11823 run_test 101h "Readahead should cover current read window"
11824
11825 test_101i() {
11826         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11827                 error "dd 10M file failed"
11828
11829         local max_per_file_mb=$($LCTL get_param -n \
11830                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11831         cancel_lru_locks osc
11832         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11833         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11834                 error "set max_read_ahead_per_file_mb to 1 failed"
11835
11836         echo "Reset readahead stats"
11837         $LCTL set_param llite.*.read_ahead_stats=0
11838
11839         dd if=$DIR/$tfile of=/dev/null bs=2M
11840
11841         $LCTL get_param llite.*.read_ahead_stats
11842         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11843                      awk '/misses/ { print $2 }')
11844         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11845         rm -f $DIR/$tfile
11846 }
11847 run_test 101i "allow current readahead to exceed reservation"
11848
11849 test_101j() {
11850         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11851                 error "setstripe $DIR/$tfile failed"
11852         local file_size=$((1048576 * 16))
11853         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11854         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11855
11856         echo Disable read-ahead
11857         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11858
11859         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11860         for blk in $PAGE_SIZE 1048576 $file_size; do
11861                 cancel_lru_locks osc
11862                 echo "Reset readahead stats"
11863                 $LCTL set_param -n llite.*.read_ahead_stats=0
11864                 local count=$(($file_size / $blk))
11865                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11866                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11867                              get_named_value 'failed.to.fast.read' | calc_sum)
11868                 $LCTL get_param -n llite.*.read_ahead_stats
11869                 [ $miss -eq $count ] || error "expected $count got $miss"
11870         done
11871
11872         rm -f $p $DIR/$tfile
11873 }
11874 run_test 101j "A complete read block should be submitted when no RA"
11875
11876 test_readahead_base() {
11877         local file=$DIR/$tfile
11878         local size=$1
11879         local iosz
11880         local ramax
11881         local ranum
11882
11883         $LCTL set_param -n llite.*.read_ahead_stats=0
11884         # The first page is not accounted into readahead
11885         ramax=$(((size + PAGE_SIZE - 1) / PAGE_SIZE - 1))
11886         iosz=$(((size + 1048575) / 1048576 * 1048576))
11887         echo "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11888
11889         $LCTL mark  "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11890         fallocate -l $size $file || error "failed to fallocate $file"
11891         cancel_lru_locks osc
11892         $MULTIOP $file or${iosz}c || error "failed to read $file"
11893         $LCTL get_param -n llite.*.read_ahead_stats
11894         ranum=$($LCTL get_param -n llite.*.read_ahead_stats |
11895                 awk '/readahead.pages/ { print $7 }' | calc_sum)
11896         (( $ranum <= $ramax )) ||
11897                 error "read-ahead pages is $ranum more than $ramax"
11898         rm -rf $file || error "failed to remove $file"
11899 }
11900
11901 test_101m()
11902 {
11903         local file=$DIR/$tfile
11904         local ramax
11905         local ranum
11906         local size
11907         local iosz
11908
11909         check_set_fallocate_or_skip
11910         stack_trap "rm -f $file" EXIT
11911
11912         test_readahead_base 4096
11913
11914         # file size: 16K = 16384
11915         test_readahead_base 16384
11916         test_readahead_base 16385
11917         test_readahead_base 16383
11918
11919         # file size: 1M + 1 = 1048576 + 1
11920         test_readahead_base 1048577
11921         # file size: 1M + 16K
11922         test_readahead_base $((1048576 + 16384))
11923
11924         # file size: stripe_size * (stripe_count - 1) + 16K
11925         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11926         test_readahead_base $((1048576 * (OSTCOUNT - 1) + 16384))
11927         # file size: stripe_size * stripe_count + 16K
11928         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11929         test_readahead_base $((1048576 * OSTCOUNT + 16384))
11930         # file size: 2 * stripe_size * stripe_count + 16K
11931         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11932         test_readahead_base $((2 * 1048576 * OSTCOUNT + 16384))
11933 }
11934 run_test 101m "read ahead for small file and last stripe of the file"
11935
11936 setup_test102() {
11937         test_mkdir $DIR/$tdir
11938         chown $RUNAS_ID $DIR/$tdir
11939         STRIPE_SIZE=65536
11940         STRIPE_OFFSET=1
11941         STRIPE_COUNT=$OSTCOUNT
11942         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11943
11944         trap cleanup_test102 EXIT
11945         cd $DIR
11946         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11947         cd $DIR/$tdir
11948         for num in 1 2 3 4; do
11949                 for count in $(seq 1 $STRIPE_COUNT); do
11950                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11951                                 local size=`expr $STRIPE_SIZE \* $num`
11952                                 local file=file"$num-$idx-$count"
11953                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11954                         done
11955                 done
11956         done
11957
11958         cd $DIR
11959         $1 tar cf $TMP/f102.tar $tdir --xattrs
11960 }
11961
11962 cleanup_test102() {
11963         trap 0
11964         rm -f $TMP/f102.tar
11965         rm -rf $DIR/d0.sanity/d102
11966 }
11967
11968 test_102a() {
11969         [ "$UID" != 0 ] && skip "must run as root"
11970         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11971                 skip_env "must have user_xattr"
11972
11973         [ -z "$(which setfattr 2>/dev/null)" ] &&
11974                 skip_env "could not find setfattr"
11975
11976         local testfile=$DIR/$tfile
11977
11978         touch $testfile
11979         echo "set/get xattr..."
11980         setfattr -n trusted.name1 -v value1 $testfile ||
11981                 error "setfattr -n trusted.name1=value1 $testfile failed"
11982         getfattr -n trusted.name1 $testfile 2> /dev/null |
11983           grep "trusted.name1=.value1" ||
11984                 error "$testfile missing trusted.name1=value1"
11985
11986         setfattr -n user.author1 -v author1 $testfile ||
11987                 error "setfattr -n user.author1=author1 $testfile failed"
11988         getfattr -n user.author1 $testfile 2> /dev/null |
11989           grep "user.author1=.author1" ||
11990                 error "$testfile missing trusted.author1=author1"
11991
11992         echo "listxattr..."
11993         setfattr -n trusted.name2 -v value2 $testfile ||
11994                 error "$testfile unable to set trusted.name2"
11995         setfattr -n trusted.name3 -v value3 $testfile ||
11996                 error "$testfile unable to set trusted.name3"
11997         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11998             grep "trusted.name" | wc -l) -eq 3 ] ||
11999                 error "$testfile missing 3 trusted.name xattrs"
12000
12001         setfattr -n user.author2 -v author2 $testfile ||
12002                 error "$testfile unable to set user.author2"
12003         setfattr -n user.author3 -v author3 $testfile ||
12004                 error "$testfile unable to set user.author3"
12005         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
12006             grep "user.author" | wc -l) -eq 3 ] ||
12007                 error "$testfile missing 3 user.author xattrs"
12008
12009         echo "remove xattr..."
12010         setfattr -x trusted.name1 $testfile ||
12011                 error "$testfile error deleting trusted.name1"
12012         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
12013                 error "$testfile did not delete trusted.name1 xattr"
12014
12015         setfattr -x user.author1 $testfile ||
12016                 error "$testfile error deleting user.author1"
12017         echo "set lustre special xattr ..."
12018         $LFS setstripe -c1 $testfile
12019         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
12020                 awk -F "=" '/trusted.lov/ { print $2 }' )
12021         setfattr -n "trusted.lov" -v $lovea $testfile ||
12022                 error "$testfile doesn't ignore setting trusted.lov again"
12023         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
12024                 error "$testfile allow setting invalid trusted.lov"
12025         rm -f $testfile
12026 }
12027 run_test 102a "user xattr test =================================="
12028
12029 check_102b_layout() {
12030         local layout="$*"
12031         local testfile=$DIR/$tfile
12032
12033         echo "test layout '$layout'"
12034         $LFS setstripe $layout $testfile || error "setstripe failed"
12035         $LFS getstripe -y $testfile
12036
12037         echo "get/set/list trusted.lov xattr ..." # b=10930
12038         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
12039         [[ "$value" =~ "trusted.lov" ]] ||
12040                 error "can't get trusted.lov from $testfile"
12041         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
12042                 error "getstripe failed"
12043
12044         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
12045
12046         value=$(cut -d= -f2 <<<$value)
12047         # LU-13168: truncated xattr should fail if short lov_user_md header
12048         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
12049                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
12050         for len in $lens; do
12051                 echo "setfattr $len $testfile.2"
12052                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
12053                         [ $len -lt 66 ] && error "short xattr len=$len worked"
12054         done
12055         local stripe_size=$($LFS getstripe -S $testfile.2)
12056         local stripe_count=$($LFS getstripe -c $testfile.2)
12057         [[ $stripe_size -eq 65536 ]] ||
12058                 error "stripe size $stripe_size != 65536"
12059         [[ $stripe_count -eq $stripe_count_orig ]] ||
12060                 error "stripe count $stripe_count != $stripe_count_orig"
12061         rm $testfile $testfile.2
12062 }
12063
12064 test_102b() {
12065         [ -z "$(which setfattr 2>/dev/null)" ] &&
12066                 skip_env "could not find setfattr"
12067         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12068
12069         # check plain layout
12070         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
12071
12072         # and also check composite layout
12073         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
12074
12075 }
12076 run_test 102b "getfattr/setfattr for trusted.lov EAs"
12077
12078 test_102c() {
12079         [ -z "$(which setfattr 2>/dev/null)" ] &&
12080                 skip_env "could not find setfattr"
12081         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12082
12083         # b10930: get/set/list lustre.lov xattr
12084         echo "get/set/list lustre.lov xattr ..."
12085         test_mkdir $DIR/$tdir
12086         chown $RUNAS_ID $DIR/$tdir
12087         local testfile=$DIR/$tdir/$tfile
12088         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
12089                 error "setstripe failed"
12090         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
12091                 error "getstripe failed"
12092         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
12093         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
12094
12095         local testfile2=${testfile}2
12096         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
12097                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
12098
12099         $RUNAS $MCREATE $testfile2
12100         $RUNAS setfattr -n lustre.lov -v $value $testfile2
12101         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
12102         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
12103         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
12104         [ $stripe_count -eq $STRIPECOUNT ] ||
12105                 error "stripe count $stripe_count != $STRIPECOUNT"
12106 }
12107 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
12108
12109 compare_stripe_info1() {
12110         local stripe_index_all_zero=true
12111
12112         for num in 1 2 3 4; do
12113                 for count in $(seq 1 $STRIPE_COUNT); do
12114                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
12115                                 local size=$((STRIPE_SIZE * num))
12116                                 local file=file"$num-$offset-$count"
12117                                 stripe_size=$($LFS getstripe -S $PWD/$file)
12118                                 [[ $stripe_size -ne $size ]] &&
12119                                     error "$file: size $stripe_size != $size"
12120                                 stripe_count=$($LFS getstripe -c $PWD/$file)
12121                                 # allow fewer stripes to be created, ORI-601
12122                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
12123                                     error "$file: count $stripe_count != $count"
12124                                 stripe_index=$($LFS getstripe -i $PWD/$file)
12125                                 [[ $stripe_index -ne 0 ]] &&
12126                                         stripe_index_all_zero=false
12127                         done
12128                 done
12129         done
12130         $stripe_index_all_zero &&
12131                 error "all files are being extracted starting from OST index 0"
12132         return 0
12133 }
12134
12135 have_xattrs_include() {
12136         tar --help | grep -q xattrs-include &&
12137                 echo --xattrs-include="lustre.*"
12138 }
12139
12140 test_102d() {
12141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12142         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12143
12144         XINC=$(have_xattrs_include)
12145         setup_test102
12146         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
12147         cd $DIR/$tdir/$tdir
12148         compare_stripe_info1
12149 }
12150 run_test 102d "tar restore stripe info from tarfile,not keep osts"
12151
12152 test_102f() {
12153         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12154         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12155
12156         XINC=$(have_xattrs_include)
12157         setup_test102
12158         test_mkdir $DIR/$tdir.restore
12159         cd $DIR
12160         tar cf - --xattrs $tdir | tar xf - \
12161                 -C $DIR/$tdir.restore --xattrs $XINC
12162         cd $DIR/$tdir.restore/$tdir
12163         compare_stripe_info1
12164 }
12165 run_test 102f "tar copy files, not keep osts"
12166
12167 grow_xattr() {
12168         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
12169                 skip "must have user_xattr"
12170         [ -z "$(which setfattr 2>/dev/null)" ] &&
12171                 skip_env "could not find setfattr"
12172         [ -z "$(which getfattr 2>/dev/null)" ] &&
12173                 skip_env "could not find getfattr"
12174
12175         local xsize=${1:-1024}  # in bytes
12176         local file=$DIR/$tfile
12177         local value="$(generate_string $xsize)"
12178         local xbig=trusted.big
12179         local toobig=$2
12180
12181         touch $file
12182         log "save $xbig on $file"
12183         if [ -z "$toobig" ]
12184         then
12185                 setfattr -n $xbig -v $value $file ||
12186                         error "saving $xbig on $file failed"
12187         else
12188                 setfattr -n $xbig -v $value $file &&
12189                         error "saving $xbig on $file succeeded"
12190                 return 0
12191         fi
12192
12193         local orig=$(get_xattr_value $xbig $file)
12194         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
12195
12196         local xsml=trusted.sml
12197         log "save $xsml on $file"
12198         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
12199
12200         local new=$(get_xattr_value $xbig $file)
12201         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
12202
12203         log "grow $xsml on $file"
12204         setfattr -n $xsml -v "$value" $file ||
12205                 error "growing $xsml on $file failed"
12206
12207         new=$(get_xattr_value $xbig $file)
12208         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
12209         log "$xbig still valid after growing $xsml"
12210
12211         rm -f $file
12212 }
12213
12214 test_102h() { # bug 15777
12215         grow_xattr 1024
12216 }
12217 run_test 102h "grow xattr from inside inode to external block"
12218
12219 test_102ha() {
12220         large_xattr_enabled || skip_env "ea_inode feature disabled"
12221
12222         echo "setting xattr of max xattr size: $(max_xattr_size)"
12223         grow_xattr $(max_xattr_size)
12224
12225         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
12226         echo "This should fail:"
12227         grow_xattr $(($(max_xattr_size) + 10)) 1
12228 }
12229 run_test 102ha "grow xattr from inside inode to external inode"
12230
12231 test_102i() { # bug 17038
12232         [ -z "$(which getfattr 2>/dev/null)" ] &&
12233                 skip "could not find getfattr"
12234
12235         touch $DIR/$tfile
12236         ln -s $DIR/$tfile $DIR/${tfile}link
12237         getfattr -n trusted.lov $DIR/$tfile ||
12238                 error "lgetxattr on $DIR/$tfile failed"
12239         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
12240                 grep -i "no such attr" ||
12241                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
12242         rm -f $DIR/$tfile $DIR/${tfile}link
12243 }
12244 run_test 102i "lgetxattr test on symbolic link ============"
12245
12246 test_102j() {
12247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12248         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12249
12250         XINC=$(have_xattrs_include)
12251         setup_test102 "$RUNAS"
12252         chown $RUNAS_ID $DIR/$tdir
12253         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
12254         cd $DIR/$tdir/$tdir
12255         compare_stripe_info1 "$RUNAS"
12256 }
12257 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
12258
12259 test_102k() {
12260         [ -z "$(which setfattr 2>/dev/null)" ] &&
12261                 skip "could not find setfattr"
12262
12263         touch $DIR/$tfile
12264         # b22187 just check that does not crash for regular file.
12265         setfattr -n trusted.lov $DIR/$tfile
12266         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
12267         local test_kdir=$DIR/$tdir
12268         test_mkdir $test_kdir
12269         local default_size=$($LFS getstripe -S $test_kdir)
12270         local default_count=$($LFS getstripe -c $test_kdir)
12271         local default_offset=$($LFS getstripe -i $test_kdir)
12272         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
12273                 error 'dir setstripe failed'
12274         setfattr -n trusted.lov $test_kdir
12275         local stripe_size=$($LFS getstripe -S $test_kdir)
12276         local stripe_count=$($LFS getstripe -c $test_kdir)
12277         local stripe_offset=$($LFS getstripe -i $test_kdir)
12278         [ $stripe_size -eq $default_size ] ||
12279                 error "stripe size $stripe_size != $default_size"
12280         [ $stripe_count -eq $default_count ] ||
12281                 error "stripe count $stripe_count != $default_count"
12282         [ $stripe_offset -eq $default_offset ] ||
12283                 error "stripe offset $stripe_offset != $default_offset"
12284         rm -rf $DIR/$tfile $test_kdir
12285 }
12286 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
12287
12288 test_102l() {
12289         [ -z "$(which getfattr 2>/dev/null)" ] &&
12290                 skip "could not find getfattr"
12291
12292         # LU-532 trusted. xattr is invisible to non-root
12293         local testfile=$DIR/$tfile
12294
12295         touch $testfile
12296
12297         echo "listxattr as user..."
12298         chown $RUNAS_ID $testfile
12299         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
12300             grep -q "trusted" &&
12301                 error "$testfile trusted xattrs are user visible"
12302
12303         return 0;
12304 }
12305 run_test 102l "listxattr size test =================================="
12306
12307 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
12308         local path=$DIR/$tfile
12309         touch $path
12310
12311         listxattr_size_check $path || error "listattr_size_check $path failed"
12312 }
12313 run_test 102m "Ensure listxattr fails on small bufffer ========"
12314
12315 cleanup_test102
12316
12317 getxattr() { # getxattr path name
12318         # Return the base64 encoding of the value of xattr name on path.
12319         local path=$1
12320         local name=$2
12321
12322         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
12323         # file: $path
12324         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12325         #
12326         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12327
12328         getfattr --absolute-names --encoding=base64 --name=$name $path |
12329                 awk -F= -v name=$name '$1 == name {
12330                         print substr($0, index($0, "=") + 1);
12331         }'
12332 }
12333
12334 test_102n() { # LU-4101 mdt: protect internal xattrs
12335         [ -z "$(which setfattr 2>/dev/null)" ] &&
12336                 skip "could not find setfattr"
12337         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
12338         then
12339                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
12340         fi
12341
12342         local file0=$DIR/$tfile.0
12343         local file1=$DIR/$tfile.1
12344         local xattr0=$TMP/$tfile.0
12345         local xattr1=$TMP/$tfile.1
12346         local namelist="lov lma lmv link fid version som hsm"
12347         local name
12348         local value
12349
12350         rm -rf $file0 $file1 $xattr0 $xattr1
12351         touch $file0 $file1
12352
12353         # Get 'before' xattrs of $file1.
12354         getfattr --absolute-names --dump --match=- $file1 > $xattr0
12355
12356         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
12357                 namelist+=" lfsck_namespace"
12358         for name in $namelist; do
12359                 # Try to copy xattr from $file0 to $file1.
12360                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12361
12362                 setfattr --name=trusted.$name --value="$value" $file1 ||
12363                         error "setxattr 'trusted.$name' failed"
12364
12365                 # Try to set a garbage xattr.
12366                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12367
12368                 if [[ x$name == "xlov" ]]; then
12369                         setfattr --name=trusted.lov --value="$value" $file1 &&
12370                         error "setxattr invalid 'trusted.lov' success"
12371                 else
12372                         setfattr --name=trusted.$name --value="$value" $file1 ||
12373                                 error "setxattr invalid 'trusted.$name' failed"
12374                 fi
12375
12376                 # Try to remove the xattr from $file1. We don't care if this
12377                 # appears to succeed or fail, we just don't want there to be
12378                 # any changes or crashes.
12379                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12380         done
12381
12382         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
12383         then
12384                 name="lfsck_ns"
12385                 # Try to copy xattr from $file0 to $file1.
12386                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12387
12388                 setfattr --name=trusted.$name --value="$value" $file1 ||
12389                         error "setxattr 'trusted.$name' failed"
12390
12391                 # Try to set a garbage xattr.
12392                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12393
12394                 setfattr --name=trusted.$name --value="$value" $file1 ||
12395                         error "setxattr 'trusted.$name' failed"
12396
12397                 # Try to remove the xattr from $file1. We don't care if this
12398                 # appears to succeed or fail, we just don't want there to be
12399                 # any changes or crashes.
12400                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12401         fi
12402
12403         # Get 'after' xattrs of file1.
12404         getfattr --absolute-names --dump --match=- $file1 > $xattr1
12405
12406         if ! diff $xattr0 $xattr1; then
12407                 error "before and after xattrs of '$file1' differ"
12408         fi
12409
12410         rm -rf $file0 $file1 $xattr0 $xattr1
12411
12412         return 0
12413 }
12414 run_test 102n "silently ignore setxattr on internal trusted xattrs"
12415
12416 test_102p() { # LU-4703 setxattr did not check ownership
12417         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
12418                 skip "MDS needs to be at least 2.5.56"
12419
12420         local testfile=$DIR/$tfile
12421
12422         touch $testfile
12423
12424         echo "setfacl as user..."
12425         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
12426         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
12427
12428         echo "setfattr as user..."
12429         setfacl -m "u:$RUNAS_ID:---" $testfile
12430         $RUNAS setfattr -x system.posix_acl_access $testfile
12431         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
12432 }
12433 run_test 102p "check setxattr(2) correctly fails without permission"
12434
12435 test_102q() {
12436         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
12437                 skip "MDS needs to be at least 2.6.92"
12438
12439         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
12440 }
12441 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
12442
12443 test_102r() {
12444         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
12445                 skip "MDS needs to be at least 2.6.93"
12446
12447         touch $DIR/$tfile || error "touch"
12448         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
12449         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
12450         rm $DIR/$tfile || error "rm"
12451
12452         #normal directory
12453         mkdir -p $DIR/$tdir || error "mkdir"
12454         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12455         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12456         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12457                 error "$testfile error deleting user.author1"
12458         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12459                 grep "user.$(basename $tdir)" &&
12460                 error "$tdir did not delete user.$(basename $tdir)"
12461         rmdir $DIR/$tdir || error "rmdir"
12462
12463         #striped directory
12464         test_mkdir $DIR/$tdir
12465         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12466         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12467         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12468                 error "$testfile error deleting user.author1"
12469         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12470                 grep "user.$(basename $tdir)" &&
12471                 error "$tdir did not delete user.$(basename $tdir)"
12472         rmdir $DIR/$tdir || error "rm striped dir"
12473 }
12474 run_test 102r "set EAs with empty values"
12475
12476 test_102s() {
12477         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12478                 skip "MDS needs to be at least 2.11.52"
12479
12480         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12481
12482         save_lustre_params client "llite.*.xattr_cache" > $save
12483
12484         for cache in 0 1; do
12485                 lctl set_param llite.*.xattr_cache=$cache
12486
12487                 rm -f $DIR/$tfile
12488                 touch $DIR/$tfile || error "touch"
12489                 for prefix in lustre security system trusted user; do
12490                         # Note getxattr() may fail with 'Operation not
12491                         # supported' or 'No such attribute' depending
12492                         # on prefix and cache.
12493                         getfattr -n $prefix.n102s $DIR/$tfile &&
12494                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
12495                 done
12496         done
12497
12498         restore_lustre_params < $save
12499 }
12500 run_test 102s "getting nonexistent xattrs should fail"
12501
12502 test_102t() {
12503         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12504                 skip "MDS needs to be at least 2.11.52"
12505
12506         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12507
12508         save_lustre_params client "llite.*.xattr_cache" > $save
12509
12510         for cache in 0 1; do
12511                 lctl set_param llite.*.xattr_cache=$cache
12512
12513                 for buf_size in 0 256; do
12514                         rm -f $DIR/$tfile
12515                         touch $DIR/$tfile || error "touch"
12516                         setfattr -n user.multiop $DIR/$tfile
12517                         $MULTIOP $DIR/$tfile oa$buf_size ||
12518                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
12519                 done
12520         done
12521
12522         restore_lustre_params < $save
12523 }
12524 run_test 102t "zero length xattr values handled correctly"
12525
12526 run_acl_subtest()
12527 {
12528         local test=$LUSTRE/tests/acl/$1.test
12529         local tmp=$(mktemp -t $1-XXXXXX).test
12530         local bin=$2
12531         local dmn=$3
12532         local grp=$4
12533         local nbd=$5
12534         export LANG=C
12535
12536
12537         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
12538         local sedgroups="-e s/:users/:$grp/g"
12539         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
12540
12541         sed $sedusers $sedgroups < $test > $tmp
12542         stack_trap "rm -f $tmp"
12543         [[ -s $tmp ]] || error "sed failed to create test script"
12544
12545         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
12546         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
12547 }
12548
12549 test_103a() {
12550         [ "$UID" != 0 ] && skip "must run as root"
12551         $GSS && skip_env "could not run under gss"
12552         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
12553                 skip_env "must have acl enabled"
12554         which setfacl || skip_env "could not find setfacl"
12555         remote_mds_nodsh && skip "remote MDS with nodsh"
12556
12557         local mdts=$(comma_list $(mdts_nodes))
12558         local saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
12559
12560         [[ -z "$saved" ]] || do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE
12561         stack_trap "[[ -z \"$saved\" ]] || \
12562                     do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$saved" EXIT
12563
12564         ACLBIN=${ACLBIN:-"bin"}
12565         ACLDMN=${ACLDMN:-"daemon"}
12566         ACLGRP=${ACLGRP:-"users"}
12567         ACLNBD=${ACLNBD:-"nobody"}
12568
12569         if ! id $ACLBIN ||
12570            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
12571                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
12572                 ACLBIN=$USER0
12573                 if ! id $ACLBIN ; then
12574                         cat /etc/passwd
12575                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
12576                 fi
12577         fi
12578         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
12579            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
12580                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
12581                 ACLDMN=$USER1
12582                 if ! id $ACLDMN ; then
12583                         cat /etc/passwd
12584                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
12585                 fi
12586         fi
12587         if ! getent group $ACLGRP; then
12588                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
12589                 ACLGRP="$TSTUSR"
12590                 if ! getent group $ACLGRP; then
12591                         echo "cannot find group '$ACLGRP', adding it"
12592                         cat /etc/group
12593                         add_group 60000 $ACLGRP
12594                 fi
12595         fi
12596
12597         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
12598         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
12599         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12600
12601         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12602                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
12603                 ACLGRP="$TSTUSR"
12604                 if ! getent group $ACLGRP; then
12605                         echo "cannot find group '$ACLGRP', adding it"
12606                         cat /etc/group
12607                         add_group 60000 $ACLGRP
12608                 fi
12609                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12610                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12611                         cat /etc/group
12612                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
12613                 fi
12614         fi
12615
12616         gpasswd -a $ACLDMN $ACLBIN ||
12617                 error "setting client group failed"             # LU-5641
12618         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
12619                 error "setting MDS group failed"                # LU-5641
12620
12621         declare -a identity_old
12622
12623         for ((num = 1; num <= $MDSCOUNT; num++)); do
12624                 switch_identity $num true || identity_old[$num]=$?
12625         done
12626
12627         SAVE_UMASK=$(umask)
12628         umask 0022
12629         mkdir -p $DIR/$tdir
12630         cd $DIR/$tdir
12631
12632         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
12633         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
12634         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
12635         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
12636         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
12637         # CentOS7- uses nobody=99, while newer distros use nobody=65534
12638         if ! id -u $ACLNBD ||
12639            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
12640                 ACLNBD="nfsnobody"
12641                 if ! id -u $ACLNBD; then
12642                         ACLNBD=""
12643                 fi
12644         fi
12645         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
12646                 add_group $(id -u $ACLNBD) $ACLNBD
12647                 if ! getent group $ACLNBD; then
12648                         ACLNBD=""
12649                 fi
12650         fi
12651         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
12652            [[ -n "$ACLNBD" ]] && which setfattr; then
12653                 run_acl_subtest permissions_xattr \
12654                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
12655         elif [[ -z "$ACLNBD" ]]; then
12656                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
12657         else
12658                 echo "skip 'permission_xattr' test - missing setfattr command"
12659         fi
12660         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
12661
12662         # inheritance test got from HP
12663         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
12664         chmod +x make-tree || error "chmod +x failed"
12665         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
12666         rm -f make-tree
12667
12668         echo "LU-974 ignore umask when acl is enabled..."
12669         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
12670         if [ $MDSCOUNT -ge 2 ]; then
12671                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
12672         fi
12673
12674         echo "LU-2561 newly created file is same size as directory..."
12675         if [ "$mds1_FSTYPE" != "zfs" ]; then
12676                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
12677         else
12678                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
12679         fi
12680
12681         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
12682
12683         cd $SAVE_PWD
12684         umask $SAVE_UMASK
12685
12686         for ((num = 1; num <= $MDSCOUNT; num++)); do
12687                 if [[ "${identity_old[$num]}" == 1 ]]; then
12688                         switch_identity $num false || identity_old[$num]=$?
12689                 fi
12690         done
12691 }
12692 run_test 103a "acl test"
12693
12694 test_103b() {
12695         declare -a pids
12696         local U
12697
12698         stack_trap "rm -f $DIR/$tfile.*"
12699         for U in {0..511}; do
12700                 {
12701                 local O=$(printf "%04o" $U)
12702
12703                 umask $(printf "%04o" $((511 ^ $O)))
12704                 $LFS setstripe -c 1 $DIR/$tfile.s$O
12705                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
12706
12707                 (( $S == ($O & 0666) )) ||
12708                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
12709
12710                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
12711                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
12712                 (( $S == ($O & 0666) )) ||
12713                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
12714
12715                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
12716                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
12717                 (( $S == ($O & 0666) )) ||
12718                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
12719                 rm -f $DIR/$tfile.[smp]$0
12720                 } &
12721                 local pid=$!
12722
12723                 # limit the concurrently running threads to 64. LU-11878
12724                 local idx=$((U % 64))
12725                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
12726                 pids[idx]=$pid
12727         done
12728         wait
12729 }
12730 run_test 103b "umask lfs setstripe"
12731
12732 test_103c() {
12733         mkdir -p $DIR/$tdir
12734         cp -rp $DIR/$tdir $DIR/$tdir.bak
12735
12736         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
12737                 error "$DIR/$tdir shouldn't contain default ACL"
12738         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
12739                 error "$DIR/$tdir.bak shouldn't contain default ACL"
12740         true
12741 }
12742 run_test 103c "'cp -rp' won't set empty acl"
12743
12744 test_103e() {
12745         local numacl
12746         local fileacl
12747         local saved_debug=$($LCTL get_param -n debug)
12748
12749         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
12750                 skip "MDS needs to be at least 2.14.52"
12751
12752         large_xattr_enabled || skip_env "ea_inode feature disabled"
12753
12754         mkdir -p $DIR/$tdir
12755         # add big LOV EA to cause reply buffer overflow earlier
12756         $LFS setstripe -C 1000 $DIR/$tdir
12757         lctl set_param mdc.*-mdc*.stats=clear
12758
12759         $LCTL set_param debug=0
12760         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
12761         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
12762
12763         # add a large number of default ACLs (expect 8000+ for 2.13+)
12764         for U in {2..7000}; do
12765                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
12766                         error "Able to add just $U default ACLs"
12767         done
12768         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
12769         echo "$numacl default ACLs created"
12770
12771         stat $DIR/$tdir || error "Cannot stat directory"
12772         # check file creation
12773         touch $DIR/$tdir/$tfile ||
12774                 error "failed to create $tfile with $numacl default ACLs"
12775         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
12776         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12777         echo "$fileacl ACLs were inherited"
12778         (( $fileacl == $numacl )) ||
12779                 error "Not all default ACLs were inherited: $numacl != $fileacl"
12780         # check that new ACLs creation adds new ACLs to inherited ACLs
12781         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
12782                 error "Cannot set new ACL"
12783         numacl=$((numacl + 1))
12784         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12785         (( $fileacl == $numacl )) ||
12786                 error "failed to add new ACL: $fileacl != $numacl as expected"
12787         # adds more ACLs to a file to reach their maximum at 8000+
12788         numacl=0
12789         for U in {20000..25000}; do
12790                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12791                 numacl=$((numacl + 1))
12792         done
12793         echo "Added $numacl more ACLs to the file"
12794         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12795         echo "Total $fileacl ACLs in file"
12796         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12797         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12798         rmdir $DIR/$tdir || error "Cannot remove directory"
12799 }
12800 run_test 103e "inheritance of big amount of default ACLs"
12801
12802 test_103f() {
12803         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12804                 skip "MDS needs to be at least 2.14.51"
12805
12806         large_xattr_enabled || skip_env "ea_inode feature disabled"
12807
12808         # enable changelog to consume more internal MDD buffers
12809         changelog_register
12810
12811         mkdir -p $DIR/$tdir
12812         # add big LOV EA
12813         $LFS setstripe -C 1000 $DIR/$tdir
12814         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12815         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12816         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12817         rmdir $DIR/$tdir || error "Cannot remove directory"
12818 }
12819 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12820
12821 test_104a() {
12822         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12823
12824         touch $DIR/$tfile
12825         lfs df || error "lfs df failed"
12826         lfs df -ih || error "lfs df -ih failed"
12827         lfs df -h $DIR || error "lfs df -h $DIR failed"
12828         lfs df -i $DIR || error "lfs df -i $DIR failed"
12829         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12830         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12831
12832         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12833         lctl --device %$OSC deactivate
12834         lfs df || error "lfs df with deactivated OSC failed"
12835         lctl --device %$OSC activate
12836         # wait the osc back to normal
12837         wait_osc_import_ready client ost
12838
12839         lfs df || error "lfs df with reactivated OSC failed"
12840         rm -f $DIR/$tfile
12841 }
12842 run_test 104a "lfs df [-ih] [path] test ========================="
12843
12844 test_104b() {
12845         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12846         [ $RUNAS_ID -eq $UID ] &&
12847                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12848
12849         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12850                         grep "Permission denied" | wc -l)))
12851         if [ $denied_cnt -ne 0 ]; then
12852                 error "lfs check servers test failed"
12853         fi
12854 }
12855 run_test 104b "$RUNAS lfs check servers test ===================="
12856
12857 #
12858 # Verify $1 is within range of $2.
12859 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12860 # $1 is <= 2% of $2. Else Fail.
12861 #
12862 value_in_range() {
12863         # Strip all units (M, G, T)
12864         actual=$(echo $1 | tr -d A-Z)
12865         expect=$(echo $2 | tr -d A-Z)
12866
12867         expect_lo=$(($expect * 98 / 100)) # 2% below
12868         expect_hi=$(($expect * 102 / 100)) # 2% above
12869
12870         # permit 2% drift above and below
12871         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12872 }
12873
12874 test_104c() {
12875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12876         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12877
12878         local ost_param="osd-zfs.$FSNAME-OST0000."
12879         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12880         local ofacets=$(get_facets OST)
12881         local mfacets=$(get_facets MDS)
12882         local saved_ost_blocks=
12883         local saved_mdt_blocks=
12884
12885         echo "Before recordsize change"
12886         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12887         df=($(df -h | grep "$MOUNT"$))
12888
12889         # For checking.
12890         echo "lfs output : ${lfs_df[*]}"
12891         echo "df  output : ${df[*]}"
12892
12893         for facet in ${ofacets//,/ }; do
12894                 if [ -z $saved_ost_blocks ]; then
12895                         saved_ost_blocks=$(do_facet $facet \
12896                                 lctl get_param -n $ost_param.blocksize)
12897                         echo "OST Blocksize: $saved_ost_blocks"
12898                 fi
12899                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12900                 do_facet $facet zfs set recordsize=32768 $ost
12901         done
12902
12903         # BS too small. Sufficient for functional testing.
12904         for facet in ${mfacets//,/ }; do
12905                 if [ -z $saved_mdt_blocks ]; then
12906                         saved_mdt_blocks=$(do_facet $facet \
12907                                 lctl get_param -n $mdt_param.blocksize)
12908                         echo "MDT Blocksize: $saved_mdt_blocks"
12909                 fi
12910                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12911                 do_facet $facet zfs set recordsize=32768 $mdt
12912         done
12913
12914         # Give new values chance to reflect change
12915         sleep 2
12916
12917         echo "After recordsize change"
12918         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12919         df_after=($(df -h | grep "$MOUNT"$))
12920
12921         # For checking.
12922         echo "lfs output : ${lfs_df_after[*]}"
12923         echo "df  output : ${df_after[*]}"
12924
12925         # Verify lfs df
12926         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12927                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12928         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12929                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12930         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12931                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12932
12933         # Verify df
12934         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12935                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12936         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12937                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12938         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12939                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12940
12941         # Restore MDT recordize back to original
12942         for facet in ${mfacets//,/ }; do
12943                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12944                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12945         done
12946
12947         # Restore OST recordize back to original
12948         for facet in ${ofacets//,/ }; do
12949                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12950                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12951         done
12952
12953         return 0
12954 }
12955 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12956
12957 test_104d() {
12958         (( $RUNAS_ID != $UID )) ||
12959                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12960
12961         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12962                 skip "lustre version doesn't support lctl dl with non-root"
12963
12964         # debugfs only allows root users to access files, so the
12965         # previous move of the "devices" file to debugfs broke
12966         # "lctl dl" for non-root users. The LU-9680 Netlink
12967         # interface again allows non-root users to list devices.
12968         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12969                 error "lctl dl doesn't work for non root"
12970
12971         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12972         [ "$ost_count" -eq $OSTCOUNT ]  ||
12973                 error "lctl dl reports wrong number of OST devices"
12974
12975         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12976         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12977                 error "lctl dl reports wrong number of MDT devices"
12978 }
12979 run_test 104d "$RUNAS lctl dl test"
12980
12981 test_105a() {
12982         # doesn't work on 2.4 kernels
12983         touch $DIR/$tfile
12984         if $(flock_is_enabled); then
12985                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12986         else
12987                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12988         fi
12989         rm -f $DIR/$tfile
12990 }
12991 run_test 105a "flock when mounted without -o flock test ========"
12992
12993 test_105b() {
12994         touch $DIR/$tfile
12995         if $(flock_is_enabled); then
12996                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12997         else
12998                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12999         fi
13000         rm -f $DIR/$tfile
13001 }
13002 run_test 105b "fcntl when mounted without -o flock test ========"
13003
13004 test_105c() {
13005         touch $DIR/$tfile
13006         if $(flock_is_enabled); then
13007                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
13008         else
13009                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
13010         fi
13011         rm -f $DIR/$tfile
13012 }
13013 run_test 105c "lockf when mounted without -o flock test"
13014
13015 test_105d() { # bug 15924
13016         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13017
13018         test_mkdir $DIR/$tdir
13019         flock_is_enabled || skip_env "mount w/o flock enabled"
13020         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
13021         $LCTL set_param fail_loc=0x80000315
13022         flocks_test 2 $DIR/$tdir
13023 }
13024 run_test 105d "flock race (should not freeze) ========"
13025
13026 test_105e() { # bug 22660 && 22040
13027         flock_is_enabled || skip_env "mount w/o flock enabled"
13028
13029         touch $DIR/$tfile
13030         flocks_test 3 $DIR/$tfile
13031 }
13032 run_test 105e "Two conflicting flocks from same process"
13033
13034 test_106() { #bug 10921
13035         test_mkdir $DIR/$tdir
13036         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
13037         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
13038 }
13039 run_test 106 "attempt exec of dir followed by chown of that dir"
13040
13041 test_107() {
13042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13043
13044         CDIR=`pwd`
13045         local file=core
13046
13047         cd $DIR
13048         rm -f $file
13049
13050         local save_pattern=$(sysctl -n kernel.core_pattern)
13051         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
13052         sysctl -w kernel.core_pattern=$file
13053         sysctl -w kernel.core_uses_pid=0
13054
13055         ulimit -c unlimited
13056         sleep 60 &
13057         SLEEPPID=$!
13058
13059         sleep 1
13060
13061         kill -s 11 $SLEEPPID
13062         wait $SLEEPPID
13063         if [ -e $file ]; then
13064                 size=`stat -c%s $file`
13065                 [ $size -eq 0 ] && error "Fail to create core file $file"
13066         else
13067                 error "Fail to create core file $file"
13068         fi
13069         rm -f $file
13070         sysctl -w kernel.core_pattern=$save_pattern
13071         sysctl -w kernel.core_uses_pid=$save_uses_pid
13072         cd $CDIR
13073 }
13074 run_test 107 "Coredump on SIG"
13075
13076 test_110() {
13077         test_mkdir $DIR/$tdir
13078         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
13079         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
13080                 error "mkdir with 256 char should fail, but did not"
13081         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
13082                 error "create with 255 char failed"
13083         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
13084                 error "create with 256 char should fail, but did not"
13085
13086         ls -l $DIR/$tdir
13087         rm -rf $DIR/$tdir
13088 }
13089 run_test 110 "filename length checking"
13090
13091 test_116a() { # was previously test_116()
13092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13093         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13094         remote_mds_nodsh && skip "remote MDS with nodsh"
13095
13096         echo -n "Free space priority "
13097         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
13098                 head -n1
13099         declare -a AVAIL
13100         free_min_max
13101
13102         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
13103         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
13104         stack_trap simple_cleanup_common
13105
13106         # Check if we need to generate uneven OSTs
13107         test_mkdir -p $DIR/$tdir/OST${MINI}
13108         local FILL=$((MINV / 4))
13109         local DIFF=$((MAXV - MINV))
13110         local DIFF2=$((DIFF * 100 / MINV))
13111
13112         local threshold=$(do_facet $SINGLEMDS \
13113                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
13114         threshold=${threshold%%%}
13115         echo -n "Check for uneven OSTs: "
13116         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
13117
13118         if [[ $DIFF2 -gt $threshold ]]; then
13119                 echo "ok"
13120                 echo "Don't need to fill OST$MINI"
13121         else
13122                 # generate uneven OSTs. Write 2% over the QOS threshold value
13123                 echo "no"
13124                 DIFF=$((threshold - DIFF2 + 2))
13125                 DIFF2=$((MINV * DIFF / 100))
13126                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
13127                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
13128                         error "setstripe failed"
13129                 DIFF=$((DIFF2 / 2048))
13130                 i=0
13131                 while [ $i -lt $DIFF ]; do
13132                         i=$((i + 1))
13133                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
13134                                 bs=2M count=1 2>/dev/null
13135                         echo -n .
13136                 done
13137                 echo .
13138                 sync
13139                 sleep_maxage
13140                 free_min_max
13141         fi
13142
13143         DIFF=$((MAXV - MINV))
13144         DIFF2=$((DIFF * 100 / MINV))
13145         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
13146         if [ $DIFF2 -gt $threshold ]; then
13147                 echo "ok"
13148         else
13149                 skip "QOS imbalance criteria not met"
13150         fi
13151
13152         MINI1=$MINI
13153         MINV1=$MINV
13154         MAXI1=$MAXI
13155         MAXV1=$MAXV
13156
13157         # now fill using QOS
13158         $LFS setstripe -c 1 $DIR/$tdir
13159         FILL=$((FILL / 200))
13160         if [ $FILL -gt 600 ]; then
13161                 FILL=600
13162         fi
13163         echo "writing $FILL files to QOS-assigned OSTs"
13164         i=0
13165         while [ $i -lt $FILL ]; do
13166                 i=$((i + 1))
13167                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
13168                         count=1 2>/dev/null
13169                 echo -n .
13170         done
13171         echo "wrote $i 200k files"
13172         sync
13173         sleep_maxage
13174
13175         echo "Note: free space may not be updated, so measurements might be off"
13176         free_min_max
13177         DIFF2=$((MAXV - MINV))
13178         echo "free space delta: orig $DIFF final $DIFF2"
13179         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
13180         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
13181         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
13182         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
13183         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
13184         if [[ $DIFF -gt 0 ]]; then
13185                 FILL=$((DIFF2 * 100 / DIFF - 100))
13186                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
13187         fi
13188
13189         # Figure out which files were written where
13190         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
13191                awk '/'$MINI1': / {print $2; exit}')
13192         echo $UUID
13193         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
13194         echo "$MINC files created on smaller OST $MINI1"
13195         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
13196                awk '/'$MAXI1': / {print $2; exit}')
13197         echo $UUID
13198         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
13199         echo "$MAXC files created on larger OST $MAXI1"
13200         if [[ $MINC -gt 0 ]]; then
13201                 FILL=$((MAXC * 100 / MINC - 100))
13202                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
13203         fi
13204         [[ $MAXC -gt $MINC ]] ||
13205                 error_ignore LU-9 "stripe QOS didn't balance free space"
13206 }
13207 run_test 116a "stripe QOS: free space balance ==================="
13208
13209 test_116b() { # LU-2093
13210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13211         remote_mds_nodsh && skip "remote MDS with nodsh"
13212
13213 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
13214         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
13215                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
13216         [ -z "$old_rr" ] && skip "no QOS"
13217         do_facet $SINGLEMDS lctl set_param \
13218                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
13219         mkdir -p $DIR/$tdir
13220         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
13221         createmany -o $DIR/$tdir/f- 20 || error "can't create"
13222         do_facet $SINGLEMDS lctl set_param fail_loc=0
13223         rm -rf $DIR/$tdir
13224         do_facet $SINGLEMDS lctl set_param \
13225                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
13226 }
13227 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
13228
13229 test_117() # bug 10891
13230 {
13231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13232
13233         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
13234         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
13235         lctl set_param fail_loc=0x21e
13236         > $DIR/$tfile || error "truncate failed"
13237         lctl set_param fail_loc=0
13238         echo "Truncate succeeded."
13239         rm -f $DIR/$tfile
13240 }
13241 run_test 117 "verify osd extend =========="
13242
13243 NO_SLOW_RESENDCOUNT=4
13244 export OLD_RESENDCOUNT=""
13245 set_resend_count () {
13246         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
13247         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
13248         lctl set_param -n $PROC_RESENDCOUNT $1
13249         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
13250 }
13251
13252 # for reduce test_118* time (b=14842)
13253 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13254
13255 # Reset async IO behavior after error case
13256 reset_async() {
13257         FILE=$DIR/reset_async
13258
13259         # Ensure all OSCs are cleared
13260         $LFS setstripe -c -1 $FILE
13261         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
13262         sync
13263         rm $FILE
13264 }
13265
13266 test_118a() #bug 11710
13267 {
13268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13269
13270         reset_async
13271
13272         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13273         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13274         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13275
13276         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13277                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13278                 return 1;
13279         fi
13280         rm -f $DIR/$tfile
13281 }
13282 run_test 118a "verify O_SYNC works =========="
13283
13284 test_118b()
13285 {
13286         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13287         remote_ost_nodsh && skip "remote OST with nodsh"
13288
13289         reset_async
13290
13291         #define OBD_FAIL_SRV_ENOENT 0x217
13292         set_nodes_failloc "$(osts_nodes)" 0x217
13293         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13294         RC=$?
13295         set_nodes_failloc "$(osts_nodes)" 0
13296         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13297         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13298                     grep -c writeback)
13299
13300         if [[ $RC -eq 0 ]]; then
13301                 error "Must return error due to dropped pages, rc=$RC"
13302                 return 1;
13303         fi
13304
13305         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13306                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13307                 return 1;
13308         fi
13309
13310         echo "Dirty pages not leaked on ENOENT"
13311
13312         # Due to the above error the OSC will issue all RPCs syncronously
13313         # until a subsequent RPC completes successfully without error.
13314         $MULTIOP $DIR/$tfile Ow4096yc
13315         rm -f $DIR/$tfile
13316
13317         return 0
13318 }
13319 run_test 118b "Reclaim dirty pages on fatal error =========="
13320
13321 test_118c()
13322 {
13323         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13324
13325         # for 118c, restore the original resend count, LU-1940
13326         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
13327                                 set_resend_count $OLD_RESENDCOUNT
13328         remote_ost_nodsh && skip "remote OST with nodsh"
13329
13330         reset_async
13331
13332         #define OBD_FAIL_OST_EROFS               0x216
13333         set_nodes_failloc "$(osts_nodes)" 0x216
13334
13335         # multiop should block due to fsync until pages are written
13336         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13337         MULTIPID=$!
13338         sleep 1
13339
13340         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13341                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13342         fi
13343
13344         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13345                     grep -c writeback)
13346         if [[ $WRITEBACK -eq 0 ]]; then
13347                 error "No page in writeback, writeback=$WRITEBACK"
13348         fi
13349
13350         set_nodes_failloc "$(osts_nodes)" 0
13351         wait $MULTIPID
13352         RC=$?
13353         if [[ $RC -ne 0 ]]; then
13354                 error "Multiop fsync failed, rc=$RC"
13355         fi
13356
13357         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13358         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13359                     grep -c writeback)
13360         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13361                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13362         fi
13363
13364         rm -f $DIR/$tfile
13365         echo "Dirty pages flushed via fsync on EROFS"
13366         return 0
13367 }
13368 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
13369
13370 # continue to use small resend count to reduce test_118* time (b=14842)
13371 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13372
13373 test_118d()
13374 {
13375         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13376         remote_ost_nodsh && skip "remote OST with nodsh"
13377
13378         reset_async
13379
13380         #define OBD_FAIL_OST_BRW_PAUSE_BULK
13381         set_nodes_failloc "$(osts_nodes)" 0x214
13382         # multiop should block due to fsync until pages are written
13383         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13384         MULTIPID=$!
13385         sleep 1
13386
13387         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13388                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13389         fi
13390
13391         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13392                     grep -c writeback)
13393         if [[ $WRITEBACK -eq 0 ]]; then
13394                 error "No page in writeback, writeback=$WRITEBACK"
13395         fi
13396
13397         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
13398         set_nodes_failloc "$(osts_nodes)" 0
13399
13400         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13401         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13402                     grep -c writeback)
13403         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13404                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13405         fi
13406
13407         rm -f $DIR/$tfile
13408         echo "Dirty pages gaurenteed flushed via fsync"
13409         return 0
13410 }
13411 run_test 118d "Fsync validation inject a delay of the bulk =========="
13412
13413 test_118f() {
13414         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13415
13416         reset_async
13417
13418         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
13419         lctl set_param fail_loc=0x8000040a
13420
13421         # Should simulate EINVAL error which is fatal
13422         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13423         RC=$?
13424         if [[ $RC -eq 0 ]]; then
13425                 error "Must return error due to dropped pages, rc=$RC"
13426         fi
13427
13428         lctl set_param fail_loc=0x0
13429
13430         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13431         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13432         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13433                     grep -c writeback)
13434         if [[ $LOCKED -ne 0 ]]; then
13435                 error "Locked pages remain in cache, locked=$LOCKED"
13436         fi
13437
13438         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13439                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13440         fi
13441
13442         rm -f $DIR/$tfile
13443         echo "No pages locked after fsync"
13444
13445         reset_async
13446         return 0
13447 }
13448 run_test 118f "Simulate unrecoverable OSC side error =========="
13449
13450 test_118g() {
13451         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13452
13453         reset_async
13454
13455         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
13456         lctl set_param fail_loc=0x406
13457
13458         # simulate local -ENOMEM
13459         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13460         RC=$?
13461
13462         lctl set_param fail_loc=0
13463         if [[ $RC -eq 0 ]]; then
13464                 error "Must return error due to dropped pages, rc=$RC"
13465         fi
13466
13467         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13468         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13469         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13470                         grep -c writeback)
13471         if [[ $LOCKED -ne 0 ]]; then
13472                 error "Locked pages remain in cache, locked=$LOCKED"
13473         fi
13474
13475         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13476                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13477         fi
13478
13479         rm -f $DIR/$tfile
13480         echo "No pages locked after fsync"
13481
13482         reset_async
13483         return 0
13484 }
13485 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
13486
13487 test_118h() {
13488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13489         remote_ost_nodsh && skip "remote OST with nodsh"
13490
13491         reset_async
13492
13493         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13494         set_nodes_failloc "$(osts_nodes)" 0x20e
13495         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13496         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13497         RC=$?
13498
13499         set_nodes_failloc "$(osts_nodes)" 0
13500         if [[ $RC -eq 0 ]]; then
13501                 error "Must return error due to dropped pages, rc=$RC"
13502         fi
13503
13504         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13505         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13506         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13507                     grep -c writeback)
13508         if [[ $LOCKED -ne 0 ]]; then
13509                 error "Locked pages remain in cache, locked=$LOCKED"
13510         fi
13511
13512         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13513                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13514         fi
13515
13516         rm -f $DIR/$tfile
13517         echo "No pages locked after fsync"
13518
13519         return 0
13520 }
13521 run_test 118h "Verify timeout in handling recoverables errors  =========="
13522
13523 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13524
13525 test_118i() {
13526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13527         remote_ost_nodsh && skip "remote OST with nodsh"
13528
13529         reset_async
13530
13531         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13532         set_nodes_failloc "$(osts_nodes)" 0x20e
13533
13534         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13535         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13536         PID=$!
13537         sleep 5
13538         set_nodes_failloc "$(osts_nodes)" 0
13539
13540         wait $PID
13541         RC=$?
13542         if [[ $RC -ne 0 ]]; then
13543                 error "got error, but should be not, rc=$RC"
13544         fi
13545
13546         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13547         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13548         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13549         if [[ $LOCKED -ne 0 ]]; then
13550                 error "Locked pages remain in cache, locked=$LOCKED"
13551         fi
13552
13553         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13554                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13555         fi
13556
13557         rm -f $DIR/$tfile
13558         echo "No pages locked after fsync"
13559
13560         return 0
13561 }
13562 run_test 118i "Fix error before timeout in recoverable error  =========="
13563
13564 [ "$SLOW" = "no" ] && set_resend_count 4
13565
13566 test_118j() {
13567         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13568         remote_ost_nodsh && skip "remote OST with nodsh"
13569
13570         reset_async
13571
13572         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
13573         set_nodes_failloc "$(osts_nodes)" 0x220
13574
13575         # return -EIO from OST
13576         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13577         RC=$?
13578         set_nodes_failloc "$(osts_nodes)" 0x0
13579         if [[ $RC -eq 0 ]]; then
13580                 error "Must return error due to dropped pages, rc=$RC"
13581         fi
13582
13583         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13584         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13585         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13586         if [[ $LOCKED -ne 0 ]]; then
13587                 error "Locked pages remain in cache, locked=$LOCKED"
13588         fi
13589
13590         # in recoverable error on OST we want resend and stay until it finished
13591         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13592                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13593         fi
13594
13595         rm -f $DIR/$tfile
13596         echo "No pages locked after fsync"
13597
13598         return 0
13599 }
13600 run_test 118j "Simulate unrecoverable OST side error =========="
13601
13602 test_118k()
13603 {
13604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13605         remote_ost_nodsh && skip "remote OSTs with nodsh"
13606
13607         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13608         set_nodes_failloc "$(osts_nodes)" 0x20e
13609         test_mkdir $DIR/$tdir
13610
13611         for ((i=0;i<10;i++)); do
13612                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
13613                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
13614                 SLEEPPID=$!
13615                 sleep 0.500s
13616                 kill $SLEEPPID
13617                 wait $SLEEPPID
13618         done
13619
13620         set_nodes_failloc "$(osts_nodes)" 0
13621         rm -rf $DIR/$tdir
13622 }
13623 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
13624
13625 test_118l() # LU-646
13626 {
13627         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13628
13629         test_mkdir $DIR/$tdir
13630         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
13631         rm -rf $DIR/$tdir
13632 }
13633 run_test 118l "fsync dir"
13634
13635 test_118m() # LU-3066
13636 {
13637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13638
13639         test_mkdir $DIR/$tdir
13640         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
13641         rm -rf $DIR/$tdir
13642 }
13643 run_test 118m "fdatasync dir ========="
13644
13645 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13646
13647 test_118n()
13648 {
13649         local begin
13650         local end
13651
13652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13653         remote_ost_nodsh && skip "remote OSTs with nodsh"
13654
13655         # Sleep to avoid a cached response.
13656         #define OBD_STATFS_CACHE_SECONDS 1
13657         sleep 2
13658
13659         # Inject a 10 second delay in the OST_STATFS handler.
13660         #define OBD_FAIL_OST_STATFS_DELAY 0x242
13661         set_nodes_failloc "$(osts_nodes)" 0x242
13662
13663         begin=$SECONDS
13664         stat --file-system $MOUNT > /dev/null
13665         end=$SECONDS
13666
13667         set_nodes_failloc "$(osts_nodes)" 0
13668
13669         if ((end - begin > 20)); then
13670             error "statfs took $((end - begin)) seconds, expected 10"
13671         fi
13672 }
13673 run_test 118n "statfs() sends OST_STATFS requests in parallel"
13674
13675 test_119a() # bug 11737
13676 {
13677         BSIZE=$((512 * 1024))
13678         directio write $DIR/$tfile 0 1 $BSIZE
13679         # We ask to read two blocks, which is more than a file size.
13680         # directio will indicate an error when requested and actual
13681         # sizes aren't equeal (a normal situation in this case) and
13682         # print actual read amount.
13683         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
13684         if [ "$NOB" != "$BSIZE" ]; then
13685                 error "read $NOB bytes instead of $BSIZE"
13686         fi
13687         rm -f $DIR/$tfile
13688 }
13689 run_test 119a "Short directIO read must return actual read amount"
13690
13691 test_119b() # bug 11737
13692 {
13693         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13694
13695         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
13696         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
13697         sync
13698         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
13699                 error "direct read failed"
13700         rm -f $DIR/$tfile
13701 }
13702 run_test 119b "Sparse directIO read must return actual read amount"
13703
13704 test_119c() # bug 13099
13705 {
13706         BSIZE=1048576
13707         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
13708         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
13709         rm -f $DIR/$tfile
13710 }
13711 run_test 119c "Testing for direct read hitting hole"
13712
13713 # Note: test 119d was removed, skipping 119d for new tests to avoid polluting
13714 # Maloo test history
13715
13716 test_119e()
13717 {
13718         (( $MDS1_VERSION >= $(version_code 2.15.58) )) ||
13719                 skip "Need server version at least 2.15.58"
13720         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13721
13722         local stripe_size=$((1024 * 1024)) #1 MiB
13723         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13724         local file_size=$((25 * stripe_size))
13725         local bsizes
13726
13727         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13728         stack_trap "rm -f $DIR/$tfile*"
13729
13730         # Just a bit bigger than the largest size in the test set below
13731         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13732                 error "buffered i/o to create file failed"
13733
13734         # trivial test of unaligned DIO
13735         dd if=$DIR/$tfile.1 bs=4095 of=$DIR/$tfile.2 count=4 \
13736                 iflag=direct oflag=direct ||
13737                 error "trivial unaligned dio failed"
13738
13739         # Test of disabling unaligned DIO support
13740         $LCTL set_param llite.*.unaligned_dio=0
13741         stack_trap "$LCTL set_param llite.*.unaligned_dio=1"
13742         echo "testing disabling unaligned DIO - 'invalid argument' expected:"
13743         dd if=$DIR/$tfile.1 bs=1024 of=$DIR/$tfile.2 count=4 \
13744                 iflag=direct oflag=direct &&
13745                 error "unaligned dio succeeded when disabled"
13746         $LCTL set_param llite.*.unaligned_dio=1
13747
13748         # Clean up before next part of test
13749         rm -f $DIR/$tfile.2
13750
13751         if zfs_or_rotational; then
13752                 # DIO on ZFS can take up to 2 seconds per IO
13753                 # rotational is better, but still slow.
13754                 # Limit testing on those media to larger sizes
13755                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13756                         $((stripe_size + 1024))"
13757         else
13758                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13759                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13760                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13761                         $((stripe_size - 1)) $stripe_size \
13762                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13763                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13764         fi
13765
13766         for bs in $bsizes; do
13767                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13768                 echo "Read/write with DIO at size $bs"
13769                 # Read and write with DIO from source to dest
13770                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 \
13771                         iflag=direct oflag=direct ||
13772                         error "dio failed"
13773
13774                 ls -la $DIR/$tfile.1 $DIR/$tfile.2
13775                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13776                         error "size incorrect, file copy read/write bsize: $bs"
13777                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13778                         error "files differ, bsize $bs"
13779                 rm -f $DIR/$tfile.2
13780         done
13781 }
13782 run_test 119e "Basic tests of dio read and write at various sizes"
13783
13784 test_119f()
13785 {
13786         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13787
13788         local stripe_size=$((1024 * 1024)) #1 MiB
13789         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13790         local file_size=$((25 * stripe_size))
13791         local bsizes
13792
13793         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13794         stack_trap "rm -f $DIR/$tfile*"
13795
13796         # Just a bit bigger than the largest size in the test set below
13797         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13798                 error "buffered i/o to create file failed"
13799
13800         if zfs_or_rotational; then
13801                 # DIO on ZFS can take up to 2 seconds per IO
13802                 # rotational is better, but still slow.
13803                 # Limit testing on those media to larger sizes
13804                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13805                         $((stripe_size + 1024))"
13806         else
13807                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13808                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13809                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13810                         $((stripe_size - 1)) $stripe_size \
13811                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13812                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13813         fi
13814
13815         for bs in $bsizes; do
13816                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13817                 # Read and write with DIO from source to dest in two
13818                 # threads - should give correct copy of file
13819
13820                 echo "bs: $bs"
13821                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13822                         oflag=direct conv=notrunc &
13823                 pid_dio1=$!
13824                 # Note block size is different here for a more interesting race
13825                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
13826                         iflag=direct oflag=direct conv=notrunc &
13827                 pid_dio2=$!
13828                 wait $pid_dio1
13829                 rc1=$?
13830                 wait $pid_dio2
13831                 rc2=$?
13832                 if (( rc1 != 0 )); then
13833                         error "dio copy 1 w/bsize $bs failed: $rc1"
13834                 fi
13835                 if (( rc2 != 0 )); then
13836                         error "dio copy 2 w/bsize $bs failed: $rc2"
13837                 fi
13838
13839
13840                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13841                         error "size incorrect, file copy read/write bsize: $bs"
13842                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13843                         error "files differ, bsize $bs"
13844                 rm -f $DIR/$tfile.2
13845         done
13846 }
13847 run_test 119f "dio vs dio race"
13848
13849 test_119g()
13850 {
13851         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13852
13853         local stripe_size=$((1024 * 1024)) #1 MiB
13854         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13855         local file_size=$((25 * stripe_size))
13856         local bsizes
13857
13858         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13859         stack_trap "rm -f $DIR/$tfile*"
13860
13861         # Just a bit bigger than the largest size in the test set below
13862         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13863                 error "buffered i/o to create file failed"
13864
13865         if zfs_or_rotational; then
13866                 # DIO on ZFS can take up to 2 seconds per IO
13867                 # rotational is better, but still slow.
13868                 # Limit testing on those media to larger sizes
13869                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13870                         $((stripe_size + 1024))"
13871         else
13872                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13873                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13874                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13875                         $((stripe_size - 1)) $stripe_size \
13876                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13877                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13878         fi
13879
13880         for bs in $bsizes; do
13881                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13882                 echo "bs: $bs"
13883                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13884                         oflag=direct conv=notrunc &
13885                 pid_dio1=$!
13886                 # Buffered I/O with similar but not the same block size
13887                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 &
13888                 pid_bio2=$!
13889                 wait $pid_dio1
13890                 rc1=$?
13891                 wait $pid_bio2
13892                 rc2=$?
13893                 if (( rc1 != 0 )); then
13894                         error "dio copy 1 w/bsize $bs failed: $rc1"
13895                 fi
13896                 if (( rc2 != 0 )); then
13897                         error "buffered copy 2 w/bsize $bs failed: $rc2"
13898                 fi
13899
13900                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13901                         error "size incorrect"
13902                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13903                         error "files differ, bsize $bs"
13904                 rm -f $DIR/$tfile.2
13905         done
13906 }
13907 run_test 119g "dio vs buffered I/O race"
13908
13909 test_119h()
13910 {
13911         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13912
13913         local stripe_size=$((1024 * 1024)) #1 MiB
13914         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13915         local file_size=$((25 * stripe_size))
13916         local bsizes
13917
13918         stack_trap "rm -f $DIR/$tfile.*"
13919
13920         if zfs_or_rotational; then
13921                 # DIO on ZFS can take up to 2 seconds per IO
13922                 # rotational is better, but still slow.
13923                 # Limit testing on those media to larger sizes
13924                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13925                         $((stripe_size + 1024))"
13926         else
13927                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13928                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13929                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13930                         $((stripe_size - 1)) $stripe_size \
13931                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13932                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13933         fi
13934
13935         for bs in $bsizes; do
13936                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13937                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13938                 echo "unaligned writes of blocksize: $bs"
13939                 # Write a file with unaligned DIO and regular DIO, and compare
13940                 # them
13941                 # with 'u', multiop randomly unaligns the io from the buffer
13942                 $MULTIOP $DIR/$tfile.1 \
13943                 oO_CREAT:O_RDWR:O_DIRECT:wu${bs}wu${bs}wu${bs}wu${bs}wu${bs} ||
13944                         error "multiop memory unaligned write failed, $bs"
13945                 $MULTIOP $DIR/$tfile.2 \
13946                 oO_CREAT:O_RDWR:O_DIRECT:w${bs}w${bs}w${bs}w${bs}w${bs} ||
13947                         error "multiop memory aligned write failed, $bs"
13948
13949                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13950                         error "files differ, bsize $bs"
13951                 rm -f $DIR/$tfile.*
13952         done
13953
13954         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13955         dd if=/dev/zero bs=$((stripe_size * 5)) of=$DIR/$tfile.1 count=5 ||
13956                 error "dd to create source file for read failed"
13957
13958         # Just a few quick tests to make sure unaligned DIO reads don't crash
13959         for bs in $bsizes; do
13960
13961                 echo "unaligned reads of blocksize: $bs"
13962                 # with 'u', multiop randomly unaligns the io from the buffer
13963                 $MULTIOP $DIR/$tfile.1 \
13964                 oO_CREAT:O_RDWR:O_DIRECT:ru${bs}ru${bs}ru${bs}ru${bs}ru${bs} ||
13965                         error "multiop memory unaligned read failed, $bs"
13966
13967         done
13968         rm -f $DIR/$tfile*
13969 }
13970 run_test 119h "basic tests of memory unaligned dio"
13971
13972 # aiocp with the '-a' option makes testing memory unaligned aio trivial
13973 test_119i()
13974 {
13975         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13976         which aiocp || skip_env "no aiocp installed"
13977
13978         local stripe_size=$((1024 * 1024)) #1 MiB
13979         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13980         local file_size=$((25 * stripe_size))
13981         local bsizes
13982
13983         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13984         stack_trap "rm -f $DIR/$tfile.*"
13985
13986         # Just a bit bigger than the largest size in the test set below
13987         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13988                 error "buffered i/o to create file failed"
13989
13990         if zfs_or_rotational; then
13991                 # DIO on ZFS can take up to 2 seconds per IO
13992                 # rotational is better, but still slow.
13993                 # Limit testing on those media to larger sizes
13994                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13995                         $((stripe_size + 1024))"
13996         else
13997                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13998                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13999                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
14000                         $((stripe_size - 1)) $stripe_size \
14001                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
14002                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
14003         fi
14004
14005         # Do page aligned and NOT page aligned AIO
14006         for align in 8 512 $((PAGE_SIZE)); do
14007         # Deliberately includes a few aligned sizes
14008         for bs in $bsizes; do
14009                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
14010
14011                 echo "bs: $bs, align: $align, file_size $file_size"
14012                 aiocp -a $align -b $bs -s $file_size -f O_DIRECT \
14013                         $DIR/$tfile.1 $DIR/$tfile.2 ||
14014                         error "unaligned aio failed, bs: $bs, align: $align"
14015
14016                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
14017                         error "size incorrect"
14018                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
14019                         error "files differ"
14020                 rm -f $DIR/$tfile.2
14021         done
14022         done
14023 }
14024 run_test 119i "test unaligned aio at varying sizes"
14025
14026 test_120a() {
14027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14028         remote_mds_nodsh && skip "remote MDS with nodsh"
14029         test_mkdir -i0 -c1 $DIR/$tdir
14030         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14031                 skip_env "no early lock cancel on server"
14032
14033         lru_resize_disable mdc
14034         lru_resize_disable osc
14035         cancel_lru_locks mdc
14036         # asynchronous object destroy at MDT could cause bl ast to client
14037         cancel_lru_locks osc
14038
14039         stat $DIR/$tdir > /dev/null
14040         can1=$(do_facet mds1 \
14041                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14042                awk '/ldlm_cancel/ {print $2}')
14043         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14044                awk '/ldlm_bl_callback/ {print $2}')
14045         test_mkdir -i0 -c1 $DIR/$tdir/d1
14046         can2=$(do_facet mds1 \
14047                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14048                awk '/ldlm_cancel/ {print $2}')
14049         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14050                awk '/ldlm_bl_callback/ {print $2}')
14051         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14052         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14053         lru_resize_enable mdc
14054         lru_resize_enable osc
14055 }
14056 run_test 120a "Early Lock Cancel: mkdir test"
14057
14058 test_120b() {
14059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14060         remote_mds_nodsh && skip "remote MDS with nodsh"
14061         test_mkdir $DIR/$tdir
14062         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14063                 skip_env "no early lock cancel on server"
14064
14065         lru_resize_disable mdc
14066         lru_resize_disable osc
14067         cancel_lru_locks mdc
14068         stat $DIR/$tdir > /dev/null
14069         can1=$(do_facet $SINGLEMDS \
14070                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14071                awk '/ldlm_cancel/ {print $2}')
14072         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14073                awk '/ldlm_bl_callback/ {print $2}')
14074         touch $DIR/$tdir/f1
14075         can2=$(do_facet $SINGLEMDS \
14076                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14077                awk '/ldlm_cancel/ {print $2}')
14078         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14079                awk '/ldlm_bl_callback/ {print $2}')
14080         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14081         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14082         lru_resize_enable mdc
14083         lru_resize_enable osc
14084 }
14085 run_test 120b "Early Lock Cancel: create test"
14086
14087 test_120c() {
14088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14089         remote_mds_nodsh && skip "remote MDS with nodsh"
14090         test_mkdir -i0 -c1 $DIR/$tdir
14091         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14092                 skip "no early lock cancel on server"
14093
14094         lru_resize_disable mdc
14095         lru_resize_disable osc
14096         test_mkdir -i0 -c1 $DIR/$tdir/d1
14097         test_mkdir -i0 -c1 $DIR/$tdir/d2
14098         touch $DIR/$tdir/d1/f1
14099         cancel_lru_locks mdc
14100         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
14101         can1=$(do_facet mds1 \
14102                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14103                awk '/ldlm_cancel/ {print $2}')
14104         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14105                awk '/ldlm_bl_callback/ {print $2}')
14106         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
14107         can2=$(do_facet mds1 \
14108                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14109                awk '/ldlm_cancel/ {print $2}')
14110         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14111                awk '/ldlm_bl_callback/ {print $2}')
14112         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14113         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14114         lru_resize_enable mdc
14115         lru_resize_enable osc
14116 }
14117 run_test 120c "Early Lock Cancel: link test"
14118
14119 test_120d() {
14120         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14121         remote_mds_nodsh && skip "remote MDS with nodsh"
14122         test_mkdir -i0 -c1 $DIR/$tdir
14123         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14124                 skip_env "no early lock cancel on server"
14125
14126         lru_resize_disable mdc
14127         lru_resize_disable osc
14128         touch $DIR/$tdir
14129         cancel_lru_locks mdc
14130         stat $DIR/$tdir > /dev/null
14131         can1=$(do_facet mds1 \
14132                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14133                awk '/ldlm_cancel/ {print $2}')
14134         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14135                awk '/ldlm_bl_callback/ {print $2}')
14136         chmod a+x $DIR/$tdir
14137         can2=$(do_facet mds1 \
14138                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14139                awk '/ldlm_cancel/ {print $2}')
14140         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14141                awk '/ldlm_bl_callback/ {print $2}')
14142         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14143         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14144         lru_resize_enable mdc
14145         lru_resize_enable osc
14146 }
14147 run_test 120d "Early Lock Cancel: setattr test"
14148
14149 test_120e() {
14150         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14151         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14152                 skip_env "no early lock cancel on server"
14153         remote_mds_nodsh && skip "remote MDS with nodsh"
14154
14155         local dlmtrace_set=false
14156
14157         test_mkdir -i0 -c1 $DIR/$tdir
14158         lru_resize_disable mdc
14159         lru_resize_disable osc
14160         ! $LCTL get_param debug | grep -q dlmtrace &&
14161                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
14162         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
14163         cancel_lru_locks mdc
14164         cancel_lru_locks osc
14165         dd if=$DIR/$tdir/f1 of=/dev/null
14166         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
14167         # XXX client can not do early lock cancel of OST lock
14168         # during unlink (LU-4206), so cancel osc lock now.
14169         sleep 2
14170         cancel_lru_locks osc
14171         can1=$(do_facet mds1 \
14172                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14173                awk '/ldlm_cancel/ {print $2}')
14174         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14175                awk '/ldlm_bl_callback/ {print $2}')
14176         unlink $DIR/$tdir/f1
14177         sleep 5
14178         can2=$(do_facet mds1 \
14179                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14180                awk '/ldlm_cancel/ {print $2}')
14181         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14182                awk '/ldlm_bl_callback/ {print $2}')
14183         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
14184                 $LCTL dk $TMP/cancel.debug.txt
14185         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
14186                 $LCTL dk $TMP/blocking.debug.txt
14187         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
14188         lru_resize_enable mdc
14189         lru_resize_enable osc
14190 }
14191 run_test 120e "Early Lock Cancel: unlink test"
14192
14193 test_120f() {
14194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14195         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14196                 skip_env "no early lock cancel on server"
14197         remote_mds_nodsh && skip "remote MDS with nodsh"
14198
14199         test_mkdir -i0 -c1 $DIR/$tdir
14200         lru_resize_disable mdc
14201         lru_resize_disable osc
14202         test_mkdir -i0 -c1 $DIR/$tdir/d1
14203         test_mkdir -i0 -c1 $DIR/$tdir/d2
14204         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
14205         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
14206         cancel_lru_locks mdc
14207         cancel_lru_locks osc
14208         dd if=$DIR/$tdir/d1/f1 of=/dev/null
14209         dd if=$DIR/$tdir/d2/f2 of=/dev/null
14210         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
14211         # XXX client can not do early lock cancel of OST lock
14212         # during rename (LU-4206), so cancel osc lock now.
14213         sleep 2
14214         cancel_lru_locks osc
14215         can1=$(do_facet mds1 \
14216                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14217                awk '/ldlm_cancel/ {print $2}')
14218         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14219                awk '/ldlm_bl_callback/ {print $2}')
14220         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
14221         sleep 5
14222         can2=$(do_facet mds1 \
14223                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14224                awk '/ldlm_cancel/ {print $2}')
14225         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14226                awk '/ldlm_bl_callback/ {print $2}')
14227         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14228         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14229         lru_resize_enable mdc
14230         lru_resize_enable osc
14231 }
14232 run_test 120f "Early Lock Cancel: rename test"
14233
14234 test_120g() {
14235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14236         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14237                 skip_env "no early lock cancel on server"
14238         remote_mds_nodsh && skip "remote MDS with nodsh"
14239
14240         lru_resize_disable mdc
14241         lru_resize_disable osc
14242         count=10000
14243         echo create $count files
14244         test_mkdir $DIR/$tdir
14245         cancel_lru_locks mdc
14246         cancel_lru_locks osc
14247         t0=$(date +%s)
14248
14249         can0=$(do_facet $SINGLEMDS \
14250                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14251                awk '/ldlm_cancel/ {print $2}')
14252         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14253                awk '/ldlm_bl_callback/ {print $2}')
14254         createmany -o $DIR/$tdir/f $count
14255         sync
14256         can1=$(do_facet $SINGLEMDS \
14257                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14258                awk '/ldlm_cancel/ {print $2}')
14259         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14260                awk '/ldlm_bl_callback/ {print $2}')
14261         t1=$(date +%s)
14262         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
14263         echo rm $count files
14264         rm -r $DIR/$tdir
14265         sync
14266         can2=$(do_facet $SINGLEMDS \
14267                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14268                awk '/ldlm_cancel/ {print $2}')
14269         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14270                awk '/ldlm_bl_callback/ {print $2}')
14271         t2=$(date +%s)
14272         echo total: $count removes in $((t2-t1))
14273         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
14274         sleep 2
14275         # wait for commitment of removal
14276         lru_resize_enable mdc
14277         lru_resize_enable osc
14278 }
14279 run_test 120g "Early Lock Cancel: performance test"
14280
14281 test_121() { #bug #10589
14282         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14283
14284         rm -rf $DIR/$tfile
14285         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
14286 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
14287         lctl set_param fail_loc=0x310
14288         cancel_lru_locks osc > /dev/null
14289         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
14290         lctl set_param fail_loc=0
14291         [[ $reads -eq $writes ]] ||
14292                 error "read $reads blocks, must be $writes blocks"
14293 }
14294 run_test 121 "read cancel race ========="
14295
14296 test_123a_base() { # was test 123, statahead(bug 11401)
14297         local lsx="$1"
14298
14299         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
14300
14301         SLOWOK=0
14302         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
14303                 log "testing UP system. Performance may be lower than expected."
14304                 SLOWOK=1
14305         fi
14306         running_in_vm && SLOWOK=1
14307
14308         $LCTL set_param mdc.*.batch_stats=0
14309
14310         rm -rf $DIR/$tdir
14311         test_mkdir $DIR/$tdir
14312         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
14313         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
14314         MULT=10
14315         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
14316                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
14317
14318                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
14319                 lctl set_param -n llite.*.statahead_max 0
14320                 lctl get_param llite.*.statahead_max
14321                 cancel_lru_locks mdc
14322                 cancel_lru_locks osc
14323                 stime=$(date +%s)
14324                 time $lsx $DIR/$tdir | wc -l
14325                 etime=$(date +%s)
14326                 delta=$((etime - stime))
14327                 log "$lsx $i files without statahead: $delta sec"
14328                 lctl set_param llite.*.statahead_max=$max
14329
14330                 swrong=$(lctl get_param -n llite.*.statahead_stats |
14331                          awk '/statahead.wrong:/ { print $NF }')
14332                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
14333                 cancel_lru_locks mdc
14334                 cancel_lru_locks osc
14335                 stime=$(date +%s)
14336                 time $lsx $DIR/$tdir | wc -l
14337                 etime=$(date +%s)
14338                 delta_sa=$((etime - stime))
14339                 log "$lsx $i files with statahead: $delta_sa sec"
14340                 lctl get_param -n llite.*.statahead_stats
14341                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
14342                          awk '/statahead.wrong:/ { print $NF }')
14343
14344                 [[ $swrong -lt $ewrong ]] &&
14345                         log "statahead was stopped, maybe too many locks held!"
14346                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
14347
14348                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
14349                         max=$(lctl get_param -n llite.*.statahead_max |
14350                                 head -n 1)
14351                         lctl set_param -n llite.*.statahead_max 0
14352                         lctl get_param llite.*.statahead_max
14353                         cancel_lru_locks mdc
14354                         cancel_lru_locks osc
14355                         stime=$(date +%s)
14356                         time $lsx $DIR/$tdir | wc -l
14357                         etime=$(date +%s)
14358                         delta=$((etime - stime))
14359                         log "$lsx $i files again without statahead: $delta sec"
14360                         lctl set_param llite.*.statahead_max=$max
14361                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
14362                                 if [ $SLOWOK -eq 0 ]; then
14363                                         error "$lsx $i files is slower with statahead!"
14364                                 else
14365                                         log "$lsx $i files is slower with statahead!"
14366                                 fi
14367                                 break
14368                         fi
14369                 fi
14370
14371                 [ $delta -gt 20 ] && break
14372                 [ $delta -gt 8 ] && MULT=$((50 / delta))
14373                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
14374         done
14375         log "$lsx done"
14376
14377         stime=$(date +%s)
14378         rm -r $DIR/$tdir
14379         sync
14380         etime=$(date +%s)
14381         delta=$((etime - stime))
14382         log "rm -r $DIR/$tdir/: $delta seconds"
14383         log "rm done"
14384         lctl get_param -n llite.*.statahead_stats
14385         $LCTL get_param mdc.*.batch_stats
14386 }
14387
14388 test_123aa() {
14389         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14390
14391         test_123a_base "ls -l"
14392 }
14393 run_test 123aa "verify statahead work"
14394
14395 test_123ab() {
14396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14397
14398         statx_supported || skip_env "Test must be statx() syscall supported"
14399
14400         test_123a_base "$STATX -l"
14401 }
14402 run_test 123ab "verify statahead work by using statx"
14403
14404 test_123ac() {
14405         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14406
14407         statx_supported || skip_env "Test must be statx() syscall supported"
14408
14409         local rpcs_before
14410         local rpcs_after
14411         local agl_before
14412         local agl_after
14413
14414         cancel_lru_locks $OSC
14415         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14416         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
14417                      awk '/agl.total:/ { print $NF }')
14418         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
14419         test_123a_base "$STATX --cached=always -D"
14420         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
14421                     awk '/agl.total:/ { print $NF }')
14422         [ $agl_before -eq $agl_after ] ||
14423                 error "Should not trigger AGL thread - $agl_before:$agl_after"
14424         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14425         [ $rpcs_after -eq $rpcs_before ] ||
14426                 error "$STATX should not send glimpse RPCs to $OSC"
14427 }
14428 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
14429
14430 test_batch_statahead() {
14431         local max=$1
14432         local batch_max=$2
14433         local num=10000
14434         local batch_rpcs
14435         local unbatch_rpcs
14436         local hit_total
14437
14438         echo -e "\nbatching: statahead_max=$max statahead_batch_max=$batch_max"
14439         $LCTL set_param mdc.*.batch_stats=0
14440         $LCTL set_param llite.*.statahead_max=$max
14441         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14442         # Verify that batched statahead is faster than one without statahead
14443         test_123a_base "ls -l"
14444
14445         stack_trap "rm -rf $DIR/$tdir" EXIT
14446         mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
14447         createmany -o $DIR/$tdir/$tfile $num || error "failed to create files"
14448
14449         # unbatched statahead
14450         $LCTL set_param llite.*.statahead_batch_max=0
14451         $LCTL set_param llite.*.statahead_stats=clear
14452         $LCTL set_param mdc.*.stats=clear
14453         cancel_lru_locks mdc
14454         cancel_lru_locks osc
14455         time ls -l $DIR/$tdir | wc -l
14456         unbatch_rpcs=$(calc_stats mdc.*.stats ldlm_ibits_enqueue)
14457         wait_update_facet client "pgrep ll_sa" "" 35 ||
14458                 error "ll_sa thread is still running"
14459         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14460                     awk '/hit.total:/ { print $NF }')
14461         # hit ratio should be larger than 75% (7500).
14462         (( $hit_total > 7500 )) ||
14463                 error "unbatched statahead hit count ($hit_total) is too low"
14464
14465         # batched statahead
14466         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14467         $LCTL set_param llite.*.statahead_stats=clear
14468         $LCTL set_param mdc.*.batch_stats=clear
14469         $LCTL set_param mdc.*.stats=clear
14470         cancel_lru_locks mdc
14471         cancel_lru_locks osc
14472         time ls -l $DIR/$tdir | wc -l
14473         batch_rpcs=$(calc_stats mdc.*.stats mds_batch)
14474         # wait for statahead thread to quit and update statahead stats
14475         wait_update_facet client "pgrep ll_sa" "" 35 ||
14476                 error "ll_sa thread is still running"
14477         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14478                     awk '/hit.total:/ { print $NF }')
14479         # hit ratio should be larger than 75% (7500).
14480         (( $hit_total > 7500 )) ||
14481                 error "batched statahead hit count ($hit_total) is too low"
14482
14483         echo "unbatched RPCs: $unbatch_rpcs, batched RPCs: $batch_rpcs"
14484         (( $unbatch_rpcs > $batch_rpcs )) ||
14485                 error "batched statahead does not reduce RPC count"
14486         $LCTL get_param mdc.*.batch_stats
14487 }
14488
14489 test_123ad() {
14490         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14491
14492         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
14493                 skip "Need server version at least 2.15.53"
14494
14495         local max
14496         local batch_max
14497
14498         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14499         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14500
14501         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14502         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14503
14504         test_batch_statahead 32 32
14505         test_batch_statahead 2048 256
14506 }
14507 run_test 123ad "Verify batching statahead works correctly"
14508
14509 test_123b () { # statahead(bug 15027)
14510         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14511
14512         test_mkdir $DIR/$tdir
14513         createmany -o $DIR/$tdir/$tfile-%d 1000
14514
14515         cancel_lru_locks mdc
14516         cancel_lru_locks osc
14517
14518 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
14519         lctl set_param fail_loc=0x80000803
14520         ls -lR $DIR/$tdir > /dev/null
14521         log "ls done"
14522         lctl set_param fail_loc=0x0
14523         lctl get_param -n llite.*.statahead_stats
14524         rm -r $DIR/$tdir
14525         sync
14526
14527 }
14528 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
14529
14530 test_123c() {
14531         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
14532
14533         test_mkdir -i 0 -c 1 $DIR/$tdir.0
14534         test_mkdir -i 1 -c 1 $DIR/$tdir.1
14535         touch $DIR/$tdir.1/{1..3}
14536         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
14537
14538         remount_client $MOUNT
14539
14540         $MULTIOP $DIR/$tdir.0 Q
14541
14542         # let statahead to complete
14543         ls -l $DIR/$tdir.0 > /dev/null
14544
14545         testid=$(echo $TESTNAME | tr '_' ' ')
14546         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
14547                 error "statahead warning" || true
14548 }
14549 run_test 123c "Can not initialize inode warning on DNE statahead"
14550
14551 test_123d() {
14552         local num=100
14553         local swrong
14554         local ewrong
14555
14556         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
14557         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
14558                 error "setdirstripe $DIR/$tdir failed"
14559         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
14560         remount_client $MOUNT
14561         $LCTL get_param llite.*.statahead_max
14562         $LCTL set_param llite.*.statahead_stats=0 ||
14563                 error "clear statahead_stats failed"
14564         swrong=$(lctl get_param -n llite.*.statahead_stats |
14565                  awk '/statahead.wrong:/ { print $NF }')
14566         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
14567         # wait for statahead thread finished to update hit/miss stats.
14568         sleep 1
14569         $LCTL get_param -n llite.*.statahead_stats
14570         ewrong=$(lctl get_param -n llite.*.statahead_stats |
14571                  awk '/statahead.wrong:/ { print $NF }')
14572         (( $swrong == $ewrong )) ||
14573                 log "statahead was stopped, maybe too many locks held!"
14574 }
14575 run_test 123d "Statahead on striped directories works correctly"
14576
14577 test_123e() {
14578         local max
14579         local batch_max
14580         local dir=$DIR/$tdir
14581
14582         mkdir $dir || error "mkdir $dir failed"
14583         $LFS setstripe -C 32 $dir || error "setstripe $dir failed"
14584         stack_trap "rm -rf $dir"
14585
14586         touch $dir/$tfile.{0..1000} || error "touch 1000 files failed"
14587
14588         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14589         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14590         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14591         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14592
14593         $LCTL set_param llite.*.statahead_max=2048
14594         $LCTL set_param llite.*.statahead_batch_max=1024
14595
14596         ls -l $dir
14597         $LCTL get_param mdc.*.batch_stats
14598         $LCTL get_param llite.*.statahead_*
14599 }
14600 run_test 123e "statahead with large wide striping"
14601
14602 test_123f() {
14603         local max
14604         local batch_max
14605         local dir=$DIR/$tdir
14606
14607         mkdir $dir || error "mkdir $dir failed"
14608         $LFS setstripe -C 1000 $dir || error "setstripe $dir failed"
14609         stack_trap "rm -rf $dir"
14610
14611         touch $dir/$tfile.{0..200} || error "touch 200 files failed"
14612
14613         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14614         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14615
14616         $LCTL set_param llite.*.statahead_max=64
14617         $LCTL set_param llite.*.statahead_batch_max=64
14618
14619         ls -l $dir
14620         lctl get_param mdc.*.batch_stats
14621         lctl get_param llite.*.statahead_*
14622
14623         $LCTL set_param llite.*.statahead_max=$max
14624         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14625 }
14626 run_test 123f "Retry mechanism with large wide striping files"
14627
14628 test_123g() {
14629         local dir=$DIR/$tdir
14630         local num=1000
14631
14632         mkdir $dir || error "failed to mkdir $dir"
14633         createmany -o $dir/$tfile $num || error "failed creatmany files"
14634         cancel_lru_locks mdc
14635         cancel_lru_locks osc
14636
14637         $LCTL set_param llite.*.statahead_stats=clear
14638         $LCTL set_param mdc.*.batch_stats=clear
14639         aheadmany -c stat -s 0 -e $num -b $tfile -d $dir ||
14640                 error "aheadmany $dir with $tfile failed"
14641         wait_update_facet client "pgrep ll_sa" "" 35 ||
14642                 error "ll_sa thread is still running"
14643         $LCTL get_param -n llite.*.statahead_stats
14644         $LCTL get_param -n mdc.*.batch_stats
14645
14646         local count
14647
14648         count=$($LCTL get_param -n llite.*.statahead_stats |
14649                 awk '/hit.total:/ {print $2}')
14650         echo "Hit total: $count"
14651         # Hit ratio should be >= 75%
14652         (( $count > num * 75 / 100 )) ||
14653                 error "hit total $count is be > 75% of $num"
14654 }
14655 run_test 123g "Test for stat-ahead advise"
14656
14657 test_123h_base() {
14658         local dir=$DIR/$tdir
14659         local cmd="touch $dir/$tfile.{$1}"
14660         local fcnt=$2
14661
14662         stack_trap "rm -rf $dir"
14663         mkdir -p $dir || error "failed to mkdir $dir"
14664         eval $cmd
14665
14666         cancel_lru_locks mdc
14667         $LCTL set_param llite.*.statahead_stats=clear
14668         $LCTL set_param mdc.*.batch_stats=0
14669         $LCTL set_param llite.*.statahead_max=1024
14670         $LCTL set_param llite.*.statahead_batch_max=1024
14671         lctl get_param -n llite.*.statahead_stats
14672         du -a $dir > /dev/null
14673         echo "Wait statahead thread (ll_sa_xxx) to exit..."
14674         wait_update_facet client "pgrep ll_sa" "" 35 ||
14675                 error "ll_sa statahead thread does not quit in 35s"
14676         $LCTL get_param -n llite.*.statahead_stats
14677         $LCTL get_param -n mdc.*.batch_stats
14678
14679         local count=$($LCTL get_param -n llite.*.statahead_stats |
14680                         awk '/fname.total:/ {print $2}')
14681
14682         [ $count == 1 ] || error "File name pattern statahead not trigger"
14683         count=$($LCTL get_param -n llite.*.statahead_stats |
14684                 awk '/hit.total:/ {print $2}')
14685         # Hit ratio should be >= 75%
14686         (( $count > fcnt * 75 / 100 )) ||
14687                 error "hit total is too low: $count"
14688         rm -rf $dir || error "rm -rf $dir failed"
14689 }
14690
14691 test_123h() {
14692         local max
14693         local batch_max
14694         local enabled
14695
14696         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14697         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14698         enabled=$($LCTL get_param -n llite.*.enable_statahead_fname | head -n 1)
14699         stack_trap "$LCTL set_param llite.*.statahead_max=$max"
14700         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max"
14701         stack_trap "$LCTL set_param llite.*.enable_statahead_fname=$enabled"
14702
14703         $LCTL set_param llite.*.enable_statahead_fname=1
14704
14705         echo "Scan a directory with number regularized fname"
14706         test_123h_base "0..10000" 10000
14707
14708         echo "Scan a directory with zeroed padding number regularized fname"
14709         test_123h_base "000000..010000" 10000
14710 }
14711 run_test 123h "Verify statahead work with the fname pattern via du"
14712
14713 test_123i_base() {
14714         local fmt=$1
14715         local iocmd=$2
14716         local dir=$DIR/$tdir
14717         local cmd="createmany -m $fmt"
14718
14719         echo "Command:"
14720         echo "- $cmd"
14721         echo "- $iocmd"
14722         stack_trap "unlinkmany $fmt"
14723         mkdir -p $dir || error "failed to mkdir $dir"
14724         eval $cmd
14725
14726         cancel_lru_locks mdc
14727         $LCTL set_param llite.*.statahead_stats=clear
14728         $LCTL set_param mdc.*.batch_stats=0
14729
14730         echo "statahead_stats (Pre):"
14731         lctl get_param -n llite.*.statahead_stats
14732         eval $iocmd || error "$iocmd failed"
14733         echo "statahead_stats (Post):"
14734         $LCTL get_param -n llite.*.statahead_stats
14735         $LCTL get_param -n mdc.*.batch_stats
14736
14737         echo "Wait the statahead thread (ll_sa_xxx) to exit ..."
14738         wait_update_facet client "pgrep ll_sa" "" 35 ||
14739                 error "ll_sa statahead thread does not quit in 35s"
14740         $LCTL get_param -n llite.*.statahead_stats
14741         $LCTL get_param -n mdc.*.batch_stats
14742
14743         local count=$($LCTL get_param -n llite.*.statahead_stats |
14744                         awk '/fname.total:/ {print $2}')
14745
14746         [ $count == 1 ] || error "File name pattern statahead not trigger"
14747         count=$($LCTL get_param -n llite.*.statahead_stats |
14748                 awk '/hit.total:/ {print $2}')
14749         # Hit ratio should be >= 75%
14750         (( $count > 750 )) || error "hit total is too low: $count"
14751 }
14752
14753 test_123i() {
14754         local dir=$DIR/$tdir
14755         local cnt=1000
14756         local max
14757         local batch_max
14758         local enabled
14759         local min
14760
14761         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14762         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14763         min=$($LCTL get_param -n llite.*.statahead_min | head -n 1)
14764         enabled=$($LCTL get_param -n llite.*.enable_statahead_fname | head -n 1)
14765         stack_trap "$LCTL set_param llite.*.statahead_max=$max"
14766         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max"
14767         stack_trap "$LCTL set_param llite.*.statahead_min=$min"
14768         stack_trap "$LCTL set_param llite.*.enable_statahead_fname=$enabled"
14769         $LCTL set_param llite.*.statahead_max=1024
14770         $LCTL set_param llite.*.statahead_batch_max=32
14771         $LCTL set_param llite.*.statahead_min=64
14772         $LCTL set_param llite.*.enable_statahead_fname=1
14773
14774         test_123i_base "$dir/$tfile.%06d $cnt" "ls $dir/* > /dev/null"
14775         test_123i_base "$dir/$tfile $cnt" \
14776                 "aheadmany -c stat -N -s 0 -e $cnt -b $tfile -d $dir"
14777 }
14778 run_test 123i "Verify statahead work with the fname indexing pattern"
14779
14780 test_124a() {
14781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14782         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14783                 skip_env "no lru resize on server"
14784
14785         local NR=2000
14786
14787         test_mkdir $DIR/$tdir
14788
14789         log "create $NR files at $DIR/$tdir"
14790         createmany -o $DIR/$tdir/f $NR ||
14791                 error "failed to create $NR files in $DIR/$tdir"
14792
14793         cancel_lru_locks mdc
14794         ls -l $DIR/$tdir > /dev/null
14795
14796         local NSDIR=""
14797         local LRU_SIZE=0
14798         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
14799                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
14800                 LRU_SIZE=$($LCTL get_param -n $PARAM)
14801                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
14802                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
14803                         log "NSDIR=$NSDIR"
14804                         log "NS=$(basename $NSDIR)"
14805                         break
14806                 fi
14807         done
14808
14809         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
14810                 skip "Not enough cached locks created!"
14811         fi
14812         log "LRU=$LRU_SIZE"
14813
14814         local SLEEP=30
14815
14816         # We know that lru resize allows one client to hold $LIMIT locks
14817         # for 10h. After that locks begin to be killed by client.
14818         local MAX_HRS=10
14819         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
14820         log "LIMIT=$LIMIT"
14821         if [ $LIMIT -lt $LRU_SIZE ]; then
14822                 skip "Limit is too small $LIMIT"
14823         fi
14824
14825         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
14826         # killing locks. Some time was spent for creating locks. This means
14827         # that up to the moment of sleep finish we must have killed some of
14828         # them (10-100 locks). This depends on how fast ther were created.
14829         # Many of them were touched in almost the same moment and thus will
14830         # be killed in groups.
14831         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
14832
14833         # Use $LRU_SIZE_B here to take into account real number of locks
14834         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
14835         local LRU_SIZE_B=$LRU_SIZE
14836         log "LVF=$LVF"
14837         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
14838         log "OLD_LVF=$OLD_LVF"
14839         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
14840
14841         # Let's make sure that we really have some margin. Client checks
14842         # cached locks every 10 sec.
14843         SLEEP=$((SLEEP+20))
14844         log "Sleep ${SLEEP} sec"
14845         local SEC=0
14846         while ((SEC<$SLEEP)); do
14847                 echo -n "..."
14848                 sleep 5
14849                 SEC=$((SEC+5))
14850                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
14851                 echo -n "$LRU_SIZE"
14852         done
14853         echo ""
14854         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
14855         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
14856
14857         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
14858                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
14859                 unlinkmany $DIR/$tdir/f $NR
14860                 return
14861         }
14862
14863         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
14864         log "unlink $NR files at $DIR/$tdir"
14865         unlinkmany $DIR/$tdir/f $NR
14866 }
14867 run_test 124a "lru resize ======================================="
14868
14869 get_max_pool_limit()
14870 {
14871         local limit=$($LCTL get_param \
14872                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
14873         local max=0
14874         for l in $limit; do
14875                 if [[ $l -gt $max ]]; then
14876                         max=$l
14877                 fi
14878         done
14879         echo $max
14880 }
14881
14882 test_124b() {
14883         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14884         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14885                 skip_env "no lru resize on server"
14886
14887         LIMIT=$(get_max_pool_limit)
14888
14889         NR=$(($(default_lru_size)*20))
14890         if [[ $NR -gt $LIMIT ]]; then
14891                 log "Limit lock number by $LIMIT locks"
14892                 NR=$LIMIT
14893         fi
14894
14895         IFree=$(mdsrate_inodes_available)
14896         if [ $IFree -lt $NR ]; then
14897                 log "Limit lock number by $IFree inodes"
14898                 NR=$IFree
14899         fi
14900
14901         lru_resize_disable mdc
14902         test_mkdir -p $DIR/$tdir/disable_lru_resize
14903
14904         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
14905         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
14906         cancel_lru_locks mdc
14907         stime=`date +%s`
14908         PID=""
14909         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14910         PID="$PID $!"
14911         sleep 2
14912         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14913         PID="$PID $!"
14914         sleep 2
14915         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14916         PID="$PID $!"
14917         wait $PID
14918         etime=`date +%s`
14919         nolruresize_delta=$((etime-stime))
14920         log "ls -la time: $nolruresize_delta seconds"
14921         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14922         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
14923
14924         lru_resize_enable mdc
14925         test_mkdir -p $DIR/$tdir/enable_lru_resize
14926
14927         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
14928         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
14929         cancel_lru_locks mdc
14930         stime=`date +%s`
14931         PID=""
14932         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14933         PID="$PID $!"
14934         sleep 2
14935         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14936         PID="$PID $!"
14937         sleep 2
14938         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14939         PID="$PID $!"
14940         wait $PID
14941         etime=`date +%s`
14942         lruresize_delta=$((etime-stime))
14943         log "ls -la time: $lruresize_delta seconds"
14944         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14945
14946         if [ $lruresize_delta -gt $nolruresize_delta ]; then
14947                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
14948         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
14949                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
14950         else
14951                 log "lru resize performs the same with no lru resize"
14952         fi
14953         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
14954 }
14955 run_test 124b "lru resize (performance test) ======================="
14956
14957 test_124c() {
14958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14959         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14960                 skip_env "no lru resize on server"
14961
14962         # cache ununsed locks on client
14963         local nr=100
14964         cancel_lru_locks mdc
14965         test_mkdir $DIR/$tdir
14966         createmany -o $DIR/$tdir/f $nr ||
14967                 error "failed to create $nr files in $DIR/$tdir"
14968         ls -l $DIR/$tdir > /dev/null
14969
14970         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14971         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14972         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14973         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14974         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14975
14976         # set lru_max_age to 1 sec
14977         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14978         echo "sleep $((recalc_p * 2)) seconds..."
14979         sleep $((recalc_p * 2))
14980
14981         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14982         # restore lru_max_age
14983         $LCTL set_param -n $nsdir.lru_max_age $max_age
14984         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14985         unlinkmany $DIR/$tdir/f $nr
14986 }
14987 run_test 124c "LRUR cancel very aged locks"
14988
14989 test_124d() {
14990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14991         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14992                 skip_env "no lru resize on server"
14993
14994         # cache ununsed locks on client
14995         local nr=100
14996
14997         lru_resize_disable mdc
14998         stack_trap "lru_resize_enable mdc" EXIT
14999
15000         cancel_lru_locks mdc
15001
15002         # asynchronous object destroy at MDT could cause bl ast to client
15003         test_mkdir $DIR/$tdir
15004         createmany -o $DIR/$tdir/f $nr ||
15005                 error "failed to create $nr files in $DIR/$tdir"
15006         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
15007
15008         ls -l $DIR/$tdir > /dev/null
15009
15010         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15011         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15012         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
15013         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
15014
15015         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
15016
15017         # set lru_max_age to 1 sec
15018         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
15019         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
15020
15021         echo "sleep $((recalc_p * 2)) seconds..."
15022         sleep $((recalc_p * 2))
15023
15024         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
15025
15026         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
15027 }
15028 run_test 124d "cancel very aged locks if lru-resize disabled"
15029
15030 test_125() { # 13358
15031         $LCTL get_param -n llite.*.client_type | grep -q local ||
15032                 skip "must run as local client"
15033         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
15034                 skip_env "must have acl enabled"
15035         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15036         id $USER0 || skip_env "missing user $USER0"
15037
15038         test_mkdir $DIR/$tdir
15039         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
15040         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
15041                 error "setfacl $DIR/$tdir failed"
15042         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
15043 }
15044 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
15045
15046 test_126() { # bug 12829/13455
15047         $GSS && skip_env "must run as gss disabled"
15048         $LCTL get_param -n llite.*.client_type | grep -q local ||
15049                 skip "must run as local client"
15050         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
15051
15052         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
15053         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
15054         rm -f $DIR/$tfile
15055         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
15056 }
15057 run_test 126 "check that the fsgid provided by the client is taken into account"
15058
15059 test_127a() { # bug 15521
15060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15061         local name count samp unit min max sum sumsq
15062         local tmpfile=$TMP/$tfile.tmp
15063
15064         # enable stats header if it is disabled
15065         $LCTL set_param enable_stats_header=1
15066
15067         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
15068         echo "stats before reset"
15069         stack_trap "rm -f $tmpfile"
15070         local now=$(date +%s)
15071
15072         $LCTL get_param osc.*.stats | tee $tmpfile
15073
15074         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
15075         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
15076         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
15077         local uptime=$(awk '{ print $1 }' /proc/uptime)
15078
15079         # snapshot_time should match POSIX epoch time, allow some delta for VMs
15080         (( ${snapshot_time%\.*} >= $now - 5 &&
15081            ${snapshot_time%\.*} <= $now + 5 )) ||
15082                 error "snapshot_time=$snapshot_time != now=$now"
15083         # elapsed _should_ be from mount, but at least less than uptime
15084         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
15085                 error "elapsed=$elapsed > uptime=$uptime"
15086         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
15087            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
15088                 error "elapsed=$elapsed != $snapshot_time - $start_time"
15089
15090         $LCTL set_param osc.*.stats=0
15091         local reset=$(date +%s)
15092         local fsize=$((2048 * 1024))
15093
15094         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
15095         cancel_lru_locks osc
15096         dd if=$DIR/$tfile of=/dev/null bs=$fsize
15097
15098         now=$(date +%s)
15099         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
15100         while read name count samp unit min max sum sumsq; do
15101                 [[ "$samp" == "samples" ]] || continue
15102
15103                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
15104                 [ ! $min ] && error "Missing min value for $name proc entry"
15105                 eval $name=$count || error "Wrong proc format"
15106
15107                 case $name in
15108                 read_bytes|write_bytes)
15109                         [[ "$unit" =~ "bytes" ]] ||
15110                                 error "unit is not 'bytes': $unit"
15111                         (( $min >= 4096 )) || error "min is too small: $min"
15112                         (( $min <= $fsize )) || error "min is too big: $min"
15113                         (( $max >= 4096 )) || error "max is too small: $max"
15114                         (( $max <= $fsize )) || error "max is too big: $max"
15115                         (( $sum == $fsize )) || error "sum is wrong: $sum"
15116                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
15117                                 error "sumsquare is too small: $sumsq"
15118                         (( $sumsq <= $fsize * $fsize )) ||
15119                                 error "sumsquare is too big: $sumsq"
15120                         ;;
15121                 ost_read|ost_write)
15122                         [[ "$unit" =~ "usec" ]] ||
15123                                 error "unit is not 'usec': $unit"
15124                         ;;
15125                 *)      ;;
15126                 esac
15127         done < $tmpfile
15128
15129         #check that we actually got some stats
15130         [ "$read_bytes" ] || error "Missing read_bytes stats"
15131         [ "$write_bytes" ] || error "Missing write_bytes stats"
15132         [ "$read_bytes" != 0 ] || error "no read done"
15133         [ "$write_bytes" != 0 ] || error "no write done"
15134
15135         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
15136         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
15137         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
15138
15139         # snapshot_time should match POSIX epoch time, allow some delta for VMs
15140         (( ${snapshot_time%\.*} >= $now - 5 &&
15141            ${snapshot_time%\.*} <= $now + 5 )) ||
15142                 error "reset snapshot_time=$snapshot_time != now=$now"
15143         # elapsed should be from time of stats reset
15144         (( ${elapsed%\.*} >= $now - $reset - 2 &&
15145            ${elapsed%\.*} <= $now - $reset + 2 )) ||
15146                 error "reset elapsed=$elapsed > $now - $reset"
15147         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
15148            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
15149                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
15150 }
15151 run_test 127a "verify the client stats are sane"
15152
15153 test_127b() { # bug LU-333
15154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15155         local name count samp unit min max sum sumsq
15156
15157         echo "stats before reset"
15158         $LCTL get_param llite.*.stats
15159         $LCTL set_param llite.*.stats=0
15160
15161         # perform 2 reads and writes so MAX is different from SUM.
15162         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
15163         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
15164         cancel_lru_locks osc
15165         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
15166         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
15167
15168         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
15169         stack_trap "rm -f $TMP/$tfile.tmp"
15170         while read name count samp unit min max sum sumsq; do
15171                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
15172                 eval $name=$count || error "Wrong proc format"
15173
15174                 case $name in
15175                 read_bytes|write_bytes)
15176                         [[ "$unit" =~ "bytes" ]] ||
15177                                 error "unit is not 'bytes': $unit"
15178                         (( $count == 2 )) || error "count is not 2: $count"
15179                         (( $min == $PAGE_SIZE )) ||
15180                                 error "min is not $PAGE_SIZE: $min"
15181                         (( $max == $PAGE_SIZE )) ||
15182                                 error "max is not $PAGE_SIZE: $max"
15183                         (( $sum == $PAGE_SIZE * 2 )) ||
15184                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
15185                         ;;
15186                 read|write)
15187                         [[ "$unit" =~ "usec" ]] ||
15188                                 error "unit is not 'usec': $unit"
15189                         ;;
15190                 *)      ;;
15191                 esac
15192         done < $TMP/$tfile.tmp
15193
15194         #check that we actually got some stats
15195         [ "$read_bytes" ] || error "Missing read_bytes stats"
15196         [ "$write_bytes" ] || error "Missing write_bytes stats"
15197         [ "$read_bytes" != 0 ] || error "no read done"
15198         [ "$write_bytes" != 0 ] || error "no write done"
15199 }
15200 run_test 127b "verify the llite client stats are sane"
15201
15202 test_127c() { # LU-12394
15203         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
15204         local size
15205         local bsize
15206         local reads
15207         local writes
15208         local count
15209
15210         $LCTL set_param llite.*.extents_stats=1
15211         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
15212
15213         # Use two stripes so there is enough space in default config
15214         $LFS setstripe -c 2 $DIR/$tfile
15215
15216         # Extent stats start at 0-4K and go in power of two buckets
15217         # LL_HIST_START = 12 --> 2^12 = 4K
15218         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
15219         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
15220         # small configs
15221         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
15222                 do
15223                 # Write and read, 2x each, second time at a non-zero offset
15224                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
15225                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
15226                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
15227                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
15228                 rm -f $DIR/$tfile
15229         done
15230
15231         $LCTL get_param llite.*.extents_stats
15232
15233         count=2
15234         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
15235                 do
15236                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
15237                                 grep -m 1 $bsize)
15238                 reads=$(echo $bucket | awk '{print $5}')
15239                 writes=$(echo $bucket | awk '{print $9}')
15240                 [ "$reads" -eq $count ] ||
15241                         error "$reads reads in < $bsize bucket, expect $count"
15242                 [ "$writes" -eq $count ] ||
15243                         error "$writes writes in < $bsize bucket, expect $count"
15244         done
15245
15246         # Test mmap write and read
15247         $LCTL set_param llite.*.extents_stats=c
15248         size=512
15249         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
15250         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
15251         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
15252
15253         $LCTL get_param llite.*.extents_stats
15254
15255         count=$(((size*1024) / PAGE_SIZE))
15256
15257         bsize=$((2 * PAGE_SIZE / 1024))K
15258
15259         bucket=$($LCTL get_param -n llite.*.extents_stats |
15260                         grep -m 1 $bsize)
15261         reads=$(echo $bucket | awk '{print $5}')
15262         writes=$(echo $bucket | awk '{print $9}')
15263         # mmap writes fault in the page first, creating an additonal read
15264         [ "$reads" -eq $((2 * count)) ] ||
15265                 error "$reads reads in < $bsize bucket, expect $count"
15266         [ "$writes" -eq $count ] ||
15267                 error "$writes writes in < $bsize bucket, expect $count"
15268 }
15269 run_test 127c "test llite extent stats with regular & mmap i/o"
15270
15271 test_128() { # bug 15212
15272         touch $DIR/$tfile
15273         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
15274                 find $DIR/$tfile
15275                 find $DIR/$tfile
15276         EOF
15277
15278         result=$(grep error $TMP/$tfile.log)
15279         rm -f $DIR/$tfile $TMP/$tfile.log
15280         [ -z "$result" ] ||
15281                 error "consecutive find's under interactive lfs failed"
15282 }
15283 run_test 128 "interactive lfs for 2 consecutive find's"
15284
15285 set_dir_limits () {
15286         local mntdev
15287         local canondev
15288         local node
15289
15290         local ldproc=/proc/fs/ldiskfs
15291         local facets=$(get_facets MDS)
15292
15293         for facet in ${facets//,/ }; do
15294                 canondev=$(ldiskfs_canon \
15295                            *.$(convert_facet2label $facet).mntdev $facet)
15296                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
15297                         ldproc=/sys/fs/ldiskfs
15298                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
15299                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
15300         done
15301 }
15302
15303 check_mds_dmesg() {
15304         local facets=$(get_facets MDS)
15305         for facet in ${facets//,/ }; do
15306                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
15307         done
15308         return 1
15309 }
15310
15311 test_129() {
15312         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15313         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
15314                 skip "Need MDS version with at least 2.5.56"
15315         if [ "$mds1_FSTYPE" != ldiskfs ]; then
15316                 skip_env "ldiskfs only test"
15317         fi
15318         remote_mds_nodsh && skip "remote MDS with nodsh"
15319
15320         local ENOSPC=28
15321         local has_warning=false
15322
15323         rm -rf $DIR/$tdir
15324         mkdir -p $DIR/$tdir
15325
15326         # block size of mds1
15327         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
15328         set_dir_limits $maxsize $((maxsize * 6 / 8))
15329         stack_trap "set_dir_limits 0 0"
15330         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
15331         local dirsize=$(stat -c%s "$DIR/$tdir")
15332         local nfiles=0
15333         while (( $dirsize <= $maxsize )); do
15334                 $MCREATE $DIR/$tdir/file_base_$nfiles
15335                 rc=$?
15336                 # check two errors:
15337                 # ENOSPC for ext4 max_dir_size, which has been used since
15338                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
15339                 if (( rc == ENOSPC )); then
15340                         set_dir_limits 0 0
15341                         echo "rc=$rc returned as expected after $nfiles files"
15342
15343                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
15344                                 error "create failed w/o dir size limit"
15345
15346                         # messages may be rate limited if test is run repeatedly
15347                         check_mds_dmesg '"is approaching max"' ||
15348                                 echo "warning message should be output"
15349                         check_mds_dmesg '"has reached max"' ||
15350                                 echo "reached message should be output"
15351
15352                         dirsize=$(stat -c%s "$DIR/$tdir")
15353
15354                         [[ $dirsize -ge $maxsize ]] && return 0
15355                         error "dirsize $dirsize < $maxsize after $nfiles files"
15356                 elif (( rc != 0 )); then
15357                         break
15358                 fi
15359                 nfiles=$((nfiles + 1))
15360                 dirsize=$(stat -c%s "$DIR/$tdir")
15361         done
15362
15363         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
15364 }
15365 run_test 129 "test directory size limit ========================"
15366
15367 OLDIFS="$IFS"
15368 cleanup_130() {
15369         trap 0
15370         IFS="$OLDIFS"
15371         rm -f $DIR/$tfile
15372 }
15373
15374 test_130a() {
15375         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
15376         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
15377
15378         trap cleanup_130 EXIT RETURN
15379
15380         local fm_file=$DIR/$tfile
15381         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
15382         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
15383                 error "dd failed for $fm_file"
15384
15385         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
15386         filefrag -ves $fm_file
15387         local rc=$?
15388         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15389                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15390         (( $rc == 0 )) || error "filefrag $fm_file failed"
15391
15392         filefrag_op=$(filefrag -ve -k $fm_file |
15393                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15394         local lun=$($LFS getstripe -i $fm_file)
15395
15396         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
15397         IFS=$'\n'
15398         local tot_len=0
15399         for line in $filefrag_op; do
15400                 local frag_lun=$(echo $line | cut -d: -f5)
15401                 local ext_len=$(echo $line | cut -d: -f4)
15402
15403                 if (( $frag_lun != $lun )); then
15404                         error "FIEMAP on 1-stripe file($fm_file) failed"
15405                         return
15406                 fi
15407                 (( tot_len += ext_len ))
15408         done
15409
15410         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
15411                 error "FIEMAP on 1-stripe file($fm_file) failed"
15412                 return
15413         fi
15414
15415         echo "FIEMAP on single striped file succeeded"
15416 }
15417 run_test 130a "FIEMAP (1-stripe file)"
15418
15419 test_130b() {
15420         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15421
15422         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15423         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15424         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15425                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15426
15427         trap cleanup_130 EXIT RETURN
15428
15429         local fm_file=$DIR/$tfile
15430         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15431                 error "setstripe on $fm_file"
15432
15433         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
15434                 error "dd failed on $fm_file"
15435
15436         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15437         filefrag_op=$(filefrag -ve -k $fm_file |
15438                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15439
15440         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15441                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15442
15443         IFS=$'\n'
15444         local tot_len=0
15445         local num_luns=1
15446
15447         for line in $filefrag_op; do
15448                 local frag_lun=$(echo $line | cut -d: -f5 |
15449                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15450                 local ext_len=$(echo $line | cut -d: -f4)
15451                 if (( $frag_lun != $last_lun )); then
15452                         if (( tot_len != 1024 )); then
15453                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15454                                 return
15455                         else
15456                                 (( num_luns += 1 ))
15457                                 tot_len=0
15458                         fi
15459                 fi
15460                 (( tot_len += ext_len ))
15461                 last_lun=$frag_lun
15462         done
15463         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
15464                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15465                 return
15466         fi
15467
15468         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
15469 }
15470 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
15471
15472 test_130c() {
15473         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15474
15475         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15476         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15477         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15478                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15479
15480         trap cleanup_130 EXIT RETURN
15481
15482         local fm_file=$DIR/$tfile
15483         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
15484
15485         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
15486                 error "dd failed on $fm_file"
15487
15488         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15489         filefrag_op=$(filefrag -ve -k $fm_file |
15490                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15491
15492         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15493                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15494
15495         IFS=$'\n'
15496         local tot_len=0
15497         local num_luns=1
15498         for line in $filefrag_op; do
15499                 local frag_lun=$(echo $line | cut -d: -f5 |
15500                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15501                 local ext_len=$(echo $line | cut -d: -f4)
15502                 if (( $frag_lun != $last_lun )); then
15503                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
15504                         if (( logical != 512 )); then
15505                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
15506                                 return
15507                         fi
15508                         if (( tot_len != 512 )); then
15509                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15510                                 return
15511                         else
15512                                 (( num_luns += 1 ))
15513                                 tot_len=0
15514                         fi
15515                 fi
15516                 (( tot_len += ext_len ))
15517                 last_lun=$frag_lun
15518         done
15519         if (( num_luns != 2 || tot_len != 512 )); then
15520                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15521                 return
15522         fi
15523
15524         echo "FIEMAP on 2-stripe file with hole succeeded"
15525 }
15526 run_test 130c "FIEMAP (2-stripe file with hole)"
15527
15528 test_130d() {
15529         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
15530
15531         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15532         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15533         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15534                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15535
15536         trap cleanup_130 EXIT RETURN
15537
15538         local fm_file=$DIR/$tfile
15539         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15540                         error "setstripe on $fm_file"
15541
15542         local actual_stripe_count=$($LFS getstripe -c $fm_file)
15543         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
15544                 error "dd failed on $fm_file"
15545
15546         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15547         filefrag_op=$(filefrag -ve -k $fm_file |
15548                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15549
15550         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15551                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15552
15553         IFS=$'\n'
15554         local tot_len=0
15555         local num_luns=1
15556         for line in $filefrag_op; do
15557                 local frag_lun=$(echo $line | cut -d: -f5 |
15558                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15559                 local ext_len=$(echo $line | cut -d: -f4)
15560                 if (( $frag_lun != $last_lun )); then
15561                         if (( tot_len != 1024 )); then
15562                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15563                                 return
15564                         else
15565                                 (( num_luns += 1 ))
15566                                 local tot_len=0
15567                         fi
15568                 fi
15569                 (( tot_len += ext_len ))
15570                 last_lun=$frag_lun
15571         done
15572         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
15573                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15574                 return
15575         fi
15576
15577         echo "FIEMAP on N-stripe file succeeded"
15578 }
15579 run_test 130d "FIEMAP (N-stripe file)"
15580
15581 test_130e() {
15582         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15583
15584         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15585         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15586         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15587                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15588
15589         trap cleanup_130 EXIT RETURN
15590
15591         local fm_file=$DIR/$tfile
15592         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
15593         stack_trap "rm -f $fm_file"
15594
15595         local num_blks=512
15596         local expected_len=$(( (num_blks / 2) * 64 ))
15597         for ((i = 0; i < $num_blks; i++)); do
15598                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
15599                         conv=notrunc > /dev/null 2>&1
15600         done
15601
15602         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15603         filefrag_op=$(filefrag -ve -k $fm_file |
15604                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15605
15606         local last_lun=$(echo $filefrag_op | cut -d: -f5)
15607
15608         IFS=$'\n'
15609         local tot_len=0
15610         local num_luns=1
15611         for line in $filefrag_op; do
15612                 local frag_lun=$(echo $line | cut -d: -f5)
15613                 local ext_len=$(echo $line | cut -d: -f4)
15614                 if (( $frag_lun != $last_lun )); then
15615                         if (( tot_len != $expected_len )); then
15616                                 error "OST$last_lun $tot_len != $expected_len"
15617                         else
15618                                 (( num_luns += 1 ))
15619                                 tot_len=0
15620                         fi
15621                 fi
15622                 (( tot_len += ext_len ))
15623                 last_lun=$frag_lun
15624         done
15625         if (( num_luns != 2 || tot_len != $expected_len )); then
15626                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
15627         fi
15628
15629         echo "FIEMAP with continuation calls succeeded"
15630 }
15631 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
15632
15633 test_130f() {
15634         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15635         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15636         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15637                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15638
15639         local fm_file=$DIR/$tfile
15640         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
15641                 error "multiop create with lov_delay_create on $fm_file"
15642
15643         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15644         filefrag_extents=$(filefrag -vek $fm_file |
15645                            awk '/extents? found/ { print $2 }')
15646         if (( $filefrag_extents != 0 )); then
15647                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
15648         fi
15649
15650         rm -f $fm_file
15651 }
15652 run_test 130f "FIEMAP (unstriped file)"
15653
15654 test_130g() {
15655         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
15656                 skip "Need MDS version with at least 2.12.53 for overstriping"
15657         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15658         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15659         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15660                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15661
15662         local file=$DIR/$tfile
15663         local nr=$((OSTCOUNT * 100))
15664
15665         $LFS setstripe -C $nr -S1M $file ||
15666                 error "failed to setstripe -C $nr $file"
15667
15668         stack_trap "rm -f $file"
15669         dd if=/dev/zero of=$file count=$nr bs=1M
15670         sync
15671         nr=$($LFS getstripe -c $file)
15672
15673         local extents=$(filefrag -v $file |
15674                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
15675
15676         echo "filefrag list $extents extents in file with stripecount $nr"
15677         if (( extents < nr )); then
15678                 $LFS getstripe $file
15679                 filefrag -v $file
15680                 error "filefrag printed $extents < $nr extents"
15681         fi
15682 }
15683 run_test 130g "FIEMAP (overstripe file)"
15684
15685 # Test for writev/readv
15686 test_131a() {
15687         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
15688                 error "writev test failed"
15689         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
15690                 error "readv failed"
15691         rm -f $DIR/$tfile
15692 }
15693 run_test 131a "test iov's crossing stripe boundary for writev/readv"
15694
15695 test_131b() {
15696         local fsize=$((524288 + 1048576 + 1572864))
15697         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
15698                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15699                         error "append writev test failed"
15700
15701         ((fsize += 1572864 + 1048576))
15702         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
15703                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15704                         error "append writev test failed"
15705         rm -f $DIR/$tfile
15706 }
15707 run_test 131b "test append writev"
15708
15709 test_131c() {
15710         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
15711         error "NOT PASS"
15712 }
15713 run_test 131c "test read/write on file w/o objects"
15714
15715 test_131d() {
15716         rwv -f $DIR/$tfile -w -n 1 1572864
15717         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
15718         if [ "$NOB" != 1572864 ]; then
15719                 error "Short read filed: read $NOB bytes instead of 1572864"
15720         fi
15721         rm -f $DIR/$tfile
15722 }
15723 run_test 131d "test short read"
15724
15725 test_131e() {
15726         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
15727         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
15728         error "read hitting hole failed"
15729         rm -f $DIR/$tfile
15730 }
15731 run_test 131e "test read hitting hole"
15732
15733 check_stats() {
15734         local facet=$1
15735         local op=$2
15736         local want=${3:-0}
15737         local res
15738
15739         # open             11 samples [usecs] 468 4793 13658 35791898
15740         case $facet in
15741         mds*) res=($(do_facet $facet \
15742                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
15743                  ;;
15744         ost*) res=($(do_facet $facet \
15745                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
15746                  ;;
15747         *) error "Wrong facet '$facet'" ;;
15748         esac
15749         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
15750         # if $want is zero, it means any stat increment is ok.
15751         if (( $want > 0 )); then
15752                 local count=${res[1]}
15753
15754                 if (( $count != $want )); then
15755                         if [[ $facet =~ "mds" ]]; then
15756                                 do_nodes $(comma_list $(mdts_nodes)) \
15757                                         $LCTL get_param mdt.*.md_stats
15758                         else
15759                                 do_nodes $(comma_list $(osts-nodes)) \
15760                                         $LCTL get_param obdfilter.*.stats
15761                         fi
15762                         error "The $op counter on $facet is $count, not $want"
15763                 fi
15764         fi
15765 }
15766
15767 test_133a() {
15768         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15769         remote_ost_nodsh && skip "remote OST with nodsh"
15770         remote_mds_nodsh && skip "remote MDS with nodsh"
15771         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15772                 skip_env "MDS doesn't support rename stats"
15773
15774         local testdir=$DIR/${tdir}/stats_testdir
15775
15776         mkdir_on_mdt0 $DIR/${tdir}
15777
15778         # clear stats.
15779         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15780         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15781
15782         # verify mdt stats first.
15783         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15784         check_stats $SINGLEMDS "mkdir" 1
15785
15786         # clear "open" from "lfs mkdir" above
15787         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15788         touch ${testdir}/${tfile} || error "touch failed"
15789         check_stats $SINGLEMDS "open" 1
15790         check_stats $SINGLEMDS "close" 1
15791         # open should match close
15792         ls -lR ${testdir}
15793         check_stats $SINGLEMDS "open" 2
15794         check_stats $SINGLEMDS "close" 2
15795         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
15796                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
15797                 check_stats $SINGLEMDS "mknod" 2
15798         }
15799         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
15800         check_stats $SINGLEMDS "unlink" 1
15801         rm -f ${testdir}/${tfile} || error "file remove failed"
15802         check_stats $SINGLEMDS "unlink" 2
15803
15804         # remove working dir and check mdt stats again.
15805         rmdir ${testdir} || error "rmdir failed"
15806         check_stats $SINGLEMDS "rmdir" 1
15807
15808         local testdir1=$DIR/${tdir}/stats_testdir1
15809         mkdir_on_mdt0 ${testdir}
15810         mkdir_on_mdt0 ${testdir1}
15811         touch ${testdir1}/test1
15812         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
15813         check_stats $SINGLEMDS "crossdir_rename" 1
15814
15815         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
15816         check_stats $SINGLEMDS "samedir_rename" 1
15817
15818         rm -rf $DIR/${tdir}
15819 }
15820 run_test 133a "Verifying MDT stats ========================================"
15821
15822 test_133b() {
15823         local res
15824
15825         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15826         remote_ost_nodsh && skip "remote OST with nodsh"
15827         remote_mds_nodsh && skip "remote MDS with nodsh"
15828
15829         local testdir=$DIR/${tdir}/stats_testdir
15830
15831         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15832         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15833         touch ${testdir}/${tfile} || error "touch failed"
15834         cancel_lru_locks mdc
15835
15836         # clear stats.
15837         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15838         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15839
15840         # extra mdt stats verification.
15841         chmod 444 ${testdir}/${tfile} || error "chmod failed"
15842         check_stats $SINGLEMDS "setattr" 1
15843         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15844         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
15845         then            # LU-1740
15846                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
15847                 check_stats $SINGLEMDS "getattr" 1
15848         fi
15849         rm -rf $DIR/${tdir}
15850
15851         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
15852         # so the check below is not reliable
15853         [ $MDSCOUNT -eq 1 ] || return 0
15854
15855         # Sleep to avoid a cached response.
15856         #define OBD_STATFS_CACHE_SECONDS 1
15857         sleep 2
15858         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15859         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15860         $LFS df || error "lfs failed"
15861         check_stats $SINGLEMDS "statfs" 1
15862
15863         # check aggregated statfs (LU-10018)
15864         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
15865                 return 0
15866         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
15867                 return 0
15868         sleep 2
15869         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15870         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15871         df $DIR
15872         check_stats $SINGLEMDS "statfs" 1
15873
15874         # We want to check that the client didn't send OST_STATFS to
15875         # ost1 but the MDT also uses OST_STATFS for precreate. So some
15876         # extra care is needed here.
15877         if remote_mds; then
15878                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
15879                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
15880
15881                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
15882                 [ "$res" ] && error "OST got STATFS"
15883         fi
15884
15885         return 0
15886 }
15887 run_test 133b "Verifying extra MDT stats =================================="
15888
15889 test_133c() {
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
15894         local testdir=$DIR/$tdir/stats_testdir
15895
15896         test_mkdir -p $testdir
15897
15898         # verify obdfilter stats.
15899         $LFS setstripe -c 1 -i 0 $testdir/$tfile
15900         sync
15901         cancel_lru_locks osc
15902         wait_delete_completed
15903
15904         # clear stats.
15905         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15906         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15907
15908         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
15909                 error "dd failed"
15910         sync
15911         cancel_lru_locks osc
15912         check_stats ost1 "write" 1
15913
15914         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
15915         check_stats ost1 "read" 1
15916
15917         > $testdir/$tfile || error "truncate failed"
15918         check_stats ost1 "punch" 1
15919
15920         rm -f $testdir/$tfile || error "file remove failed"
15921         wait_delete_completed
15922         check_stats ost1 "destroy" 1
15923
15924         rm -rf $DIR/$tdir
15925 }
15926 run_test 133c "Verifying OST stats ========================================"
15927
15928 order_2() {
15929         local value=$1
15930         local orig=$value
15931         local order=1
15932
15933         while [ $value -ge 2 ]; do
15934                 order=$((order*2))
15935                 value=$((value/2))
15936         done
15937
15938         if [ $orig -gt $order ]; then
15939                 order=$((order*2))
15940         fi
15941         echo $order
15942 }
15943
15944 size_in_KMGT() {
15945     local value=$1
15946     local size=('K' 'M' 'G' 'T');
15947     local i=0
15948     local size_string=$value
15949
15950     while [ $value -ge 1024 ]; do
15951         if [ $i -gt 3 ]; then
15952             #T is the biggest unit we get here, if that is bigger,
15953             #just return XXXT
15954             size_string=${value}T
15955             break
15956         fi
15957         value=$((value >> 10))
15958         if [ $value -lt 1024 ]; then
15959             size_string=${value}${size[$i]}
15960             break
15961         fi
15962         i=$((i + 1))
15963     done
15964
15965     echo $size_string
15966 }
15967
15968 get_rename_size() {
15969         local size=$1
15970         local context=${2:-.}
15971         local sample=$(do_facet $SINGLEMDS $LCTL \
15972                 get_param mdt.$FSNAME-MDT0000.rename_stats |
15973                 grep -A1 $context |
15974                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
15975         echo $sample
15976 }
15977
15978 test_133d() {
15979         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15980         remote_ost_nodsh && skip "remote OST with nodsh"
15981         remote_mds_nodsh && skip "remote MDS with nodsh"
15982         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15983                 skip_env "MDS doesn't support rename stats"
15984
15985         local testdir1=$DIR/${tdir}/stats_testdir1
15986         local testdir2=$DIR/${tdir}/stats_testdir2
15987         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
15988
15989         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15990
15991         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
15992         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
15993
15994         createmany -o $testdir1/test 512 || error "createmany failed"
15995
15996         # check samedir rename size
15997         mv ${testdir1}/test0 ${testdir1}/test_0
15998
15999         local testdir1_size=$(ls -l $DIR/${tdir} |
16000                 awk '/stats_testdir1/ {print $5}')
16001         local testdir2_size=$(ls -l $DIR/${tdir} |
16002                 awk '/stats_testdir2/ {print $5}')
16003
16004         testdir1_size=$(order_2 $testdir1_size)
16005         testdir2_size=$(order_2 $testdir2_size)
16006
16007         testdir1_size=$(size_in_KMGT $testdir1_size)
16008         testdir2_size=$(size_in_KMGT $testdir2_size)
16009
16010         echo "source rename dir size: ${testdir1_size}"
16011         echo "target rename dir size: ${testdir2_size}"
16012
16013         local cmd="do_facet $SINGLEMDS $LCTL "
16014         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
16015
16016         eval $cmd || error "$cmd failed"
16017         local samedir=$($cmd | grep 'same_dir')
16018         local same_sample=$(get_rename_size $testdir1_size)
16019         [ -z "$samedir" ] && error "samedir_rename_size count error"
16020         [[ $same_sample -eq 1 ]] ||
16021                 error "samedir_rename_size error $same_sample"
16022         echo "Check same dir rename stats success"
16023
16024         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
16025
16026         # check crossdir rename size
16027         mv ${testdir1}/test_0 ${testdir2}/test_0
16028
16029         testdir1_size=$(ls -l $DIR/${tdir} |
16030                 awk '/stats_testdir1/ {print $5}')
16031         testdir2_size=$(ls -l $DIR/${tdir} |
16032                 awk '/stats_testdir2/ {print $5}')
16033
16034         testdir1_size=$(order_2 $testdir1_size)
16035         testdir2_size=$(order_2 $testdir2_size)
16036
16037         testdir1_size=$(size_in_KMGT $testdir1_size)
16038         testdir2_size=$(size_in_KMGT $testdir2_size)
16039
16040         echo "source rename dir size: ${testdir1_size}"
16041         echo "target rename dir size: ${testdir2_size}"
16042
16043         eval $cmd || error "$cmd failed"
16044         local crossdir=$($cmd | grep 'crossdir')
16045         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
16046         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
16047         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
16048         [[ $src_sample -eq 1 ]] ||
16049                 error "crossdir_rename_size error $src_sample"
16050         [[ $tgt_sample -eq 1 ]] ||
16051                 error "crossdir_rename_size error $tgt_sample"
16052         echo "Check cross dir rename stats success"
16053         rm -rf $DIR/${tdir}
16054 }
16055 run_test 133d "Verifying rename_stats ========================================"
16056
16057 test_133e() {
16058         remote_mds_nodsh && skip "remote MDS with nodsh"
16059         remote_ost_nodsh && skip "remote OST with nodsh"
16060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16061
16062         local testdir=$DIR/${tdir}/stats_testdir
16063         local ctr f0 f1 bs=32768 count=42 sum
16064
16065         mkdir -p ${testdir} || error "mkdir failed"
16066
16067         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
16068
16069         for ctr in {write,read}_bytes; do
16070                 sync
16071                 cancel_lru_locks osc
16072
16073                 do_facet ost1 $LCTL set_param -n \
16074                         "obdfilter.*.exports.clear=clear"
16075
16076                 if [ $ctr = write_bytes ]; then
16077                         f0=/dev/zero
16078                         f1=${testdir}/${tfile}
16079                 else
16080                         f0=${testdir}/${tfile}
16081                         f1=/dev/null
16082                 fi
16083
16084                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
16085                         error "dd failed"
16086                 sync
16087                 cancel_lru_locks osc
16088
16089                 sum=$(do_facet ost1 $LCTL get_param \
16090                         "obdfilter.*.exports.*.stats" |
16091                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
16092                                 $1 == ctr { sum += $7 }
16093                                 END { printf("%0.0f", sum) }')
16094
16095                 if ((sum != bs * count)); then
16096                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
16097                 fi
16098         done
16099
16100         rm -rf $DIR/${tdir}
16101 }
16102 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
16103
16104 test_133f() {
16105         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
16106                 skip "too old lustre for get_param -R ($facet_ver)"
16107
16108         # verifying readability.
16109         $LCTL get_param -R '*' &> /dev/null
16110
16111         # Verifing writability with badarea_io.
16112         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
16113         local skipped_params='force_lbug|changelog_mask|daemon_file'
16114         $LCTL list_param -FR '*' | grep '=' | tr -d = |
16115                 egrep -v "$skipped_params" |
16116                 xargs -n 1 find $proc_dirs -name |
16117                 xargs -n 1 badarea_io ||
16118                 error "client badarea_io failed"
16119
16120         # remount the FS in case writes/reads /proc break the FS
16121         cleanup || error "failed to unmount"
16122         setup || error "failed to setup"
16123 }
16124 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
16125
16126 test_133g() {
16127         remote_mds_nodsh && skip "remote MDS with nodsh"
16128         remote_ost_nodsh && skip "remote OST with nodsh"
16129
16130         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
16131         local proc_dirs_str=$(eval echo $proc_dirs)
16132         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
16133         local facet
16134         for facet in mds1 ost1; do
16135                 local facet_ver=$(lustre_version_code $facet)
16136                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
16137                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
16138                 else
16139                         log "$facet: too old lustre for get_param -R"
16140                 fi
16141                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
16142                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
16143                                 tr -d = | egrep -v $skipped_params |
16144                                 xargs -n 1 find $proc_dirs_str -name |
16145                                 xargs -n 1 badarea_io" ||
16146                                         error "$facet badarea_io failed"
16147                 else
16148                         skip_noexit "$facet: too old lustre for get_param -R"
16149                 fi
16150         done
16151
16152         # remount the FS in case writes/reads /proc break the FS
16153         cleanup || error "failed to unmount"
16154         setup || error "failed to setup"
16155 }
16156 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
16157
16158 test_133h() {
16159         remote_mds_nodsh && skip "remote MDS with nodsh"
16160         remote_ost_nodsh && skip "remote OST with nodsh"
16161         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
16162                 skip "Need MDS version at least 2.9.54"
16163
16164         local facet
16165         for facet in client mds1 ost1; do
16166                 # Get the list of files that are missing the terminating newline
16167                 local plist=$(do_facet $facet
16168                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
16169                 local ent
16170                 for ent in $plist; do
16171                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
16172                                 awk -v FS='\v' -v RS='\v\v' \
16173                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
16174                                         print FILENAME}'" 2>/dev/null)
16175                         [ -z $missing ] || {
16176                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
16177                                 error "file does not end with newline: $facet-$ent"
16178                         }
16179                 done
16180         done
16181 }
16182 run_test 133h "Proc files should end with newlines"
16183
16184 test_134a() {
16185         remote_mds_nodsh && skip "remote MDS with nodsh"
16186         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
16187                 skip "Need MDS version at least 2.7.54"
16188
16189         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
16190         cancel_lru_locks mdc
16191
16192         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
16193         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
16194         [ $unused -eq 0 ] || error "$unused locks are not cleared"
16195
16196         local nr=1000
16197         createmany -o $DIR/$tdir/f $nr ||
16198                 error "failed to create $nr files in $DIR/$tdir"
16199         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
16200
16201         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
16202         do_facet mds1 $LCTL set_param fail_loc=0x327
16203         do_facet mds1 $LCTL set_param fail_val=500
16204         touch $DIR/$tdir/m
16205
16206         echo "sleep 10 seconds ..."
16207         sleep 10
16208         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
16209
16210         do_facet mds1 $LCTL set_param fail_loc=0
16211         do_facet mds1 $LCTL set_param fail_val=0
16212         [ $lck_cnt -lt $unused ] ||
16213                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
16214
16215         rm $DIR/$tdir/m
16216         unlinkmany $DIR/$tdir/f $nr
16217 }
16218 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
16219
16220 test_134b() {
16221         remote_mds_nodsh && skip "remote MDS with nodsh"
16222         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
16223                 skip "Need MDS version at least 2.7.54"
16224
16225         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
16226         cancel_lru_locks mdc
16227
16228         local low_wm=$(do_facet mds1 $LCTL get_param -n \
16229                         ldlm.lock_reclaim_threshold_mb)
16230         # disable reclaim temporarily
16231         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
16232
16233         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
16234         do_facet mds1 $LCTL set_param fail_loc=0x328
16235         do_facet mds1 $LCTL set_param fail_val=500
16236
16237         $LCTL set_param debug=+trace
16238
16239         local nr=600
16240         createmany -o $DIR/$tdir/f $nr &
16241         local create_pid=$!
16242
16243         echo "Sleep $TIMEOUT seconds ..."
16244         sleep $TIMEOUT
16245         if ! ps -p $create_pid  > /dev/null 2>&1; then
16246                 do_facet mds1 $LCTL set_param fail_loc=0
16247                 do_facet mds1 $LCTL set_param fail_val=0
16248                 do_facet mds1 $LCTL set_param \
16249                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
16250                 error "createmany finished incorrectly!"
16251         fi
16252         do_facet mds1 $LCTL set_param fail_loc=0
16253         do_facet mds1 $LCTL set_param fail_val=0
16254         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
16255         wait $create_pid || return 1
16256
16257         unlinkmany $DIR/$tdir/f $nr
16258 }
16259 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
16260
16261 test_135() {
16262         remote_mds_nodsh && skip "remote MDS with nodsh"
16263         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
16264                 skip "Need MDS version at least 2.13.50"
16265         local fname
16266
16267         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
16268
16269 #define OBD_FAIL_PLAIN_RECORDS 0x1319
16270         #set only one record at plain llog
16271         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
16272
16273         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
16274
16275         #fill already existed plain llog each 64767
16276         #wrapping whole catalog
16277         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
16278
16279         createmany -o $DIR/$tdir/$tfile_ 64700
16280         for (( i = 0; i < 64700; i = i + 2 ))
16281         do
16282                 rm $DIR/$tdir/$tfile_$i &
16283                 rm $DIR/$tdir/$tfile_$((i + 1)) &
16284                 local pid=$!
16285                 wait $pid
16286         done
16287
16288         #waiting osp synchronization
16289         wait_delete_completed
16290 }
16291 run_test 135 "Race catalog processing"
16292
16293 test_136() {
16294         remote_mds_nodsh && skip "remote MDS with nodsh"
16295         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
16296                 skip "Need MDS version at least 2.13.50"
16297         local fname
16298
16299         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
16300         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
16301         #set only one record at plain llog
16302 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
16303         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
16304
16305         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
16306
16307         #fill already existed 2 plain llogs each 64767
16308         #wrapping whole catalog
16309         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
16310         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
16311         wait_delete_completed
16312
16313         createmany -o $DIR/$tdir/$tfile_ 10
16314         sleep 25
16315
16316         do_facet $SINGLEMDS $LCTL set_param fail_val=3
16317         for (( i = 0; i < 10; i = i + 3 ))
16318         do
16319                 rm $DIR/$tdir/$tfile_$i &
16320                 rm $DIR/$tdir/$tfile_$((i + 1)) &
16321                 local pid=$!
16322                 wait $pid
16323                 sleep 7
16324                 rm $DIR/$tdir/$tfile_$((i + 2)) &
16325         done
16326
16327         #waiting osp synchronization
16328         wait_delete_completed
16329 }
16330 run_test 136 "Race catalog processing 2"
16331
16332 test_140() { #bug-17379
16333         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16334
16335         test_mkdir $DIR/$tdir
16336         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
16337         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
16338
16339         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
16340         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
16341         local i=0
16342         while i=$((i + 1)); do
16343                 test_mkdir $i
16344                 cd $i || error "Changing to $i"
16345                 ln -s ../stat stat || error "Creating stat symlink"
16346                 # Read the symlink until ELOOP present,
16347                 # not LBUGing the system is considered success,
16348                 # we didn't overrun the stack.
16349                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
16350                 if [ $ret -ne 0 ]; then
16351                         if [ $ret -eq 40 ]; then
16352                                 break  # -ELOOP
16353                         else
16354                                 error "Open stat symlink"
16355                                         return
16356                         fi
16357                 fi
16358         done
16359         i=$((i - 1))
16360         echo "The symlink depth = $i"
16361         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
16362                 error "Invalid symlink depth"
16363
16364         # Test recursive symlink
16365         ln -s symlink_self symlink_self
16366         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
16367         echo "open symlink_self returns $ret"
16368         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
16369 }
16370 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
16371
16372 test_150a() {
16373         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16374
16375         local TF="$TMP/$tfile"
16376
16377         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16378         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16379         cp $TF $DIR/$tfile
16380         cancel_lru_locks $OSC
16381         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
16382         remount_client $MOUNT
16383         df -P $MOUNT
16384         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
16385
16386         $TRUNCATE $TF 6000
16387         $TRUNCATE $DIR/$tfile 6000
16388         cancel_lru_locks $OSC
16389         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
16390
16391         echo "12345" >>$TF
16392         echo "12345" >>$DIR/$tfile
16393         cancel_lru_locks $OSC
16394         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
16395
16396         echo "12345" >>$TF
16397         echo "12345" >>$DIR/$tfile
16398         cancel_lru_locks $OSC
16399         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
16400 }
16401 run_test 150a "truncate/append tests"
16402
16403 test_150b() {
16404         check_set_fallocate_or_skip
16405         local out
16406
16407         touch $DIR/$tfile
16408         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16409         out=$(check_fallocate $DIR/$tfile 2>&1) ||
16410                 skip_eopnotsupp "$out|check_fallocate failed"
16411 }
16412 run_test 150b "Verify fallocate (prealloc) functionality"
16413
16414 test_150bb() {
16415         check_set_fallocate_or_skip
16416
16417         touch $DIR/$tfile
16418         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16419         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
16420         > $DIR/$tfile
16421         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
16422         # precomputed md5sum for 20MB of zeroes
16423         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
16424         local sum=($(md5sum $DIR/$tfile))
16425
16426         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
16427
16428         check_set_fallocate 1
16429
16430         > $DIR/$tfile
16431         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
16432         sum=($(md5sum $DIR/$tfile))
16433
16434         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
16435 }
16436 run_test 150bb "Verify fallocate modes both zero space"
16437
16438 test_150c() {
16439         check_set_fallocate_or_skip
16440         local striping="-c2"
16441
16442         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16443         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
16444         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
16445         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
16446         local want=$((OSTCOUNT * 1048576))
16447
16448         # Must allocate all requested space, not more than 5% extra
16449         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16450                 error "bytes $bytes is not $want"
16451
16452         rm -f $DIR/$tfile
16453
16454         echo "verify fallocate on PFL file"
16455
16456         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
16457
16458         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
16459                 error "Create $DIR/$tfile failed"
16460         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
16461         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
16462         want=$((512 * 1048576))
16463
16464         # Must allocate all requested space, not more than 5% extra
16465         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16466                 error "bytes $bytes is not $want"
16467 }
16468 run_test 150c "Verify fallocate Size and Blocks"
16469
16470 test_150d() {
16471         check_set_fallocate_or_skip
16472         local striping="-c2"
16473
16474         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
16475
16476         stack_trap "rm -f $DIR/$tdir; wait_delete_completed"
16477         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
16478                 error "setstripe failed"
16479         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
16480         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
16481         local want=$((OSTCOUNT * 1048576))
16482
16483         # Must allocate all requested space, not more than 5% extra
16484         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16485                 error "bytes $bytes is not $want"
16486 }
16487 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
16488
16489 test_150e() {
16490         check_set_fallocate_or_skip
16491
16492         echo "df before:"
16493         $LFS df
16494         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16495         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16496                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16497
16498         # Find OST with Minimum Size
16499         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16500                        sort -un | head -1)
16501
16502         # Get 100MB per OST of the available space to reduce run time
16503         # else 60% of the available space if we are running SLOW tests
16504         if [ $SLOW == "no" ]; then
16505                 local space=$((1024 * 100 * OSTCOUNT))
16506         else
16507                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
16508         fi
16509
16510         fallocate -l${space}k $DIR/$tfile ||
16511                 error "fallocate ${space}k $DIR/$tfile failed"
16512         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
16513
16514         # get size immediately after fallocate. This should be correctly
16515         # updated
16516         local size=$(stat -c '%s' $DIR/$tfile)
16517         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
16518
16519         # Sleep for a while for statfs to get updated. And not pull from cache.
16520         sleep 2
16521
16522         echo "df after fallocate:"
16523         $LFS df
16524
16525         (( size / 1024 == space )) || error "size $size != requested $space"
16526         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
16527                 error "used $used < space $space"
16528
16529         rm $DIR/$tfile || error "rm failed"
16530         sync
16531         wait_delete_completed
16532
16533         echo "df after unlink:"
16534         $LFS df
16535 }
16536 run_test 150e "Verify 60% of available OST space consumed by fallocate"
16537
16538 test_150f() {
16539         local size
16540         local blocks
16541         local want_size_before=20480 # in bytes
16542         local want_blocks_before=40 # 512 sized blocks
16543         local want_blocks_after=24  # 512 sized blocks
16544         local length=$(((want_blocks_before - want_blocks_after) * 512))
16545
16546         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16547                 skip "need at least 2.14.0 for fallocate punch"
16548
16549         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16550                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16551         fi
16552
16553         check_set_fallocate_or_skip
16554         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16555
16556         [[ "x$DOM" == "xyes" ]] &&
16557                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
16558
16559         echo "Verify fallocate punch: Range within the file range"
16560         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16561                 error "dd failed for bs 4096 and count 5"
16562
16563         # Call fallocate with punch range which is within the file range
16564         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
16565                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
16566         # client must see changes immediately after fallocate
16567         size=$(stat -c '%s' $DIR/$tfile)
16568         blocks=$(stat -c '%b' $DIR/$tfile)
16569
16570         # Verify punch worked.
16571         (( blocks == want_blocks_after )) ||
16572                 error "punch failed: blocks $blocks != $want_blocks_after"
16573
16574         (( size == want_size_before )) ||
16575                 error "punch failed: size $size != $want_size_before"
16576
16577         # Verify there is hole in file
16578         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
16579         # precomputed md5sum
16580         local expect="4a9a834a2db02452929c0a348273b4aa"
16581
16582         cksum=($(md5sum $DIR/$tfile))
16583         [[ "${cksum[0]}" == "$expect" ]] ||
16584                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16585
16586         # Start second sub-case for fallocate punch.
16587         echo "Verify fallocate punch: Range overlapping and less than blocksize"
16588         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16589                 error "dd failed for bs 4096 and count 5"
16590
16591         # Punch range less than block size will have no change in block count
16592         want_blocks_after=40  # 512 sized blocks
16593
16594         # Punch overlaps two blocks and less than blocksize
16595         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
16596                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
16597         size=$(stat -c '%s' $DIR/$tfile)
16598         blocks=$(stat -c '%b' $DIR/$tfile)
16599
16600         # Verify punch worked.
16601         (( blocks == want_blocks_after )) ||
16602                 error "punch failed: blocks $blocks != $want_blocks_after"
16603
16604         (( size == want_size_before )) ||
16605                 error "punch failed: size $size != $want_size_before"
16606
16607         # Verify if range is really zero'ed out. We expect Zeros.
16608         # precomputed md5sum
16609         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
16610         cksum=($(md5sum $DIR/$tfile))
16611         [[ "${cksum[0]}" == "$expect" ]] ||
16612                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16613 }
16614 run_test 150f "Verify fallocate punch functionality"
16615
16616 test_150g() {
16617         local space
16618         local size
16619         local blocks
16620         local blocks_after
16621         local size_after
16622         local BS=4096 # Block size in bytes
16623
16624         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16625                 skip "need at least 2.14.0 for fallocate punch"
16626
16627         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16628                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16629         fi
16630
16631         check_set_fallocate_or_skip
16632         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16633
16634         if [[ "x$DOM" == "xyes" ]]; then
16635                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
16636                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
16637         else
16638                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16639                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16640         fi
16641
16642         # Get 100MB per OST of the available space to reduce run time
16643         # else 60% of the available space if we are running SLOW tests
16644         if [ $SLOW == "no" ]; then
16645                 space=$((1024 * 100 * OSTCOUNT))
16646         else
16647                 # Find OST with Minimum Size
16648                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16649                         sort -un | head -1)
16650                 echo "min size OST: $space"
16651                 space=$(((space * 60)/100 * OSTCOUNT))
16652         fi
16653         # space in 1k units, round to 4k blocks
16654         local blkcount=$((space * 1024 / $BS))
16655
16656         echo "Verify fallocate punch: Very large Range"
16657         fallocate -l${space}k $DIR/$tfile ||
16658                 error "fallocate ${space}k $DIR/$tfile failed"
16659         # write 1M at the end, start and in the middle
16660         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
16661                 error "dd failed: bs $BS count 256"
16662         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
16663                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
16664         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
16665                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
16666
16667         # Gather stats.
16668         size=$(stat -c '%s' $DIR/$tfile)
16669
16670         # gather punch length.
16671         local punch_size=$((size - (BS * 2)))
16672
16673         echo "punch_size = $punch_size"
16674         echo "size - punch_size: $((size - punch_size))"
16675         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
16676
16677         # Call fallocate to punch all except 2 blocks. We leave the
16678         # first and the last block
16679         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
16680         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
16681                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
16682
16683         size_after=$(stat -c '%s' $DIR/$tfile)
16684         blocks_after=$(stat -c '%b' $DIR/$tfile)
16685
16686         # Verify punch worked.
16687         # Size should be kept
16688         (( size == size_after )) ||
16689                 error "punch failed: size $size != $size_after"
16690
16691         # two 4k data blocks to remain plus possible 1 extra extent block
16692         (( blocks_after <= ((BS / 512) * 3) )) ||
16693                 error "too many blocks remains: $blocks_after"
16694
16695         # Verify that file has hole between the first and the last blocks
16696         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
16697         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
16698
16699         echo "Hole at [$hole_start, $hole_end)"
16700         (( hole_start == BS )) ||
16701                 error "no hole at offset $BS after punch"
16702
16703         (( hole_end == BS + punch_size )) ||
16704                 error "data at offset $hole_end < $((BS + punch_size))"
16705 }
16706 run_test 150g "Verify fallocate punch on large range"
16707
16708 test_150h() {
16709         local file=$DIR/$tfile
16710         local size
16711
16712         check_set_fallocate_or_skip
16713         statx_supported || skip_env "Test must be statx() syscall supported"
16714
16715         # fallocate() does not update the size information on the MDT
16716         fallocate -l 16K $file || error "failed to fallocate $file"
16717         cancel_lru_locks $OSC
16718         # STATX with cached-always mode will not send glimpse RPCs to OST,
16719         # it uses the caching attrs on the client side as much as possible.
16720         size=$($STATX --cached=always -c %s $file)
16721         [ $size == 16384 ] ||
16722                 error "size after fallocate() is $size, expected 16384"
16723 }
16724 run_test 150h "Verify extend fallocate updates the file size"
16725
16726 #LU-2902 roc_hit was not able to read all values from lproc
16727 function roc_hit_init() {
16728         local list=$(comma_list $(osts_nodes))
16729         local dir=$DIR/$tdir-check
16730         local file=$dir/$tfile
16731         local BEFORE
16732         local AFTER
16733         local idx
16734
16735         test_mkdir $dir
16736         #use setstripe to do a write to every ost
16737         for i in $(seq 0 $((OSTCOUNT-1))); do
16738                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
16739                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
16740                 idx=$(printf %04x $i)
16741                 BEFORE=$(get_osd_param $list *OST*$idx stats |
16742                         awk '$1 == "cache_access" {sum += $7}
16743                                 END { printf("%0.0f", sum) }')
16744
16745                 cancel_lru_locks osc
16746                 cat $file >/dev/null
16747
16748                 AFTER=$(get_osd_param $list *OST*$idx stats |
16749                         awk '$1 == "cache_access" {sum += $7}
16750                                 END { printf("%0.0f", sum) }')
16751
16752                 echo BEFORE:$BEFORE AFTER:$AFTER
16753                 if ! let "AFTER - BEFORE == 4"; then
16754                         rm -rf $dir
16755                         error "roc_hit is not safe to use"
16756                 fi
16757                 rm $file
16758         done
16759
16760         rm -rf $dir
16761 }
16762
16763 function roc_hit() {
16764         local list=$(comma_list $(osts_nodes))
16765         echo $(get_osd_param $list '' stats |
16766                 awk '$1 == "cache_hit" {sum += $7}
16767                         END { printf("%0.0f", sum) }')
16768 }
16769
16770 function set_cache() {
16771         local on=1
16772
16773         if [ "$2" == "off" ]; then
16774                 on=0;
16775         fi
16776         local list=$(comma_list $(osts_nodes))
16777         set_osd_param $list '' $1_cache_enable $on
16778
16779         cancel_lru_locks osc
16780 }
16781
16782 test_151() {
16783         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16784         remote_ost_nodsh && skip "remote OST with nodsh"
16785         (( CLIENT_VERSION == OST1_VERSION )) ||
16786                 skip "LU-13081: no interop testing for OSS cache"
16787
16788         local CPAGES=3
16789         local list=$(comma_list $(osts_nodes))
16790
16791         # check whether obdfilter is cache capable at all
16792         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
16793                 skip "not cache-capable obdfilter"
16794         fi
16795
16796         # check cache is enabled on all obdfilters
16797         if get_osd_param $list '' read_cache_enable | grep 0; then
16798                 skip "oss cache is disabled"
16799         fi
16800
16801         set_osd_param $list '' writethrough_cache_enable 1
16802
16803         # check write cache is enabled on all obdfilters
16804         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
16805                 skip "oss write cache is NOT enabled"
16806         fi
16807
16808         roc_hit_init
16809
16810         #define OBD_FAIL_OBD_NO_LRU  0x609
16811         do_nodes $list $LCTL set_param fail_loc=0x609
16812
16813         # pages should be in the case right after write
16814         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
16815                 error "dd failed"
16816
16817         local BEFORE=$(roc_hit)
16818         cancel_lru_locks osc
16819         cat $DIR/$tfile >/dev/null
16820         local AFTER=$(roc_hit)
16821
16822         do_nodes $list $LCTL set_param fail_loc=0
16823
16824         if ! let "AFTER - BEFORE == CPAGES"; then
16825                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
16826         fi
16827
16828         cancel_lru_locks osc
16829         # invalidates OST cache
16830         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
16831         set_osd_param $list '' read_cache_enable 0
16832         cat $DIR/$tfile >/dev/null
16833
16834         # now data shouldn't be found in the cache
16835         BEFORE=$(roc_hit)
16836         cancel_lru_locks osc
16837         cat $DIR/$tfile >/dev/null
16838         AFTER=$(roc_hit)
16839         if let "AFTER - BEFORE != 0"; then
16840                 error "IN CACHE: before: $BEFORE, after: $AFTER"
16841         fi
16842
16843         set_osd_param $list '' read_cache_enable 1
16844         rm -f $DIR/$tfile
16845 }
16846 run_test 151 "test cache on oss and controls ==============================="
16847
16848 test_152() {
16849         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16850
16851         local TF="$TMP/$tfile"
16852
16853         # simulate ENOMEM during write
16854 #define OBD_FAIL_OST_NOMEM      0x226
16855         lctl set_param fail_loc=0x80000226
16856         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16857         cp $TF $DIR/$tfile
16858         sync || error "sync failed"
16859         lctl set_param fail_loc=0
16860
16861         # discard client's cache
16862         cancel_lru_locks osc
16863
16864         # simulate ENOMEM during read
16865         lctl set_param fail_loc=0x80000226
16866         cmp $TF $DIR/$tfile || error "cmp failed"
16867         lctl set_param fail_loc=0
16868
16869         rm -f $TF
16870 }
16871 run_test 152 "test read/write with enomem ============================"
16872
16873 test_153() {
16874         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
16875 }
16876 run_test 153 "test if fdatasync does not crash ======================="
16877
16878 dot_lustre_fid_permission_check() {
16879         local fid=$1
16880         local ffid=$MOUNT/.lustre/fid/$fid
16881         local test_dir=$2
16882
16883         echo "stat fid $fid"
16884         stat $ffid || error "stat $ffid failed."
16885         echo "touch fid $fid"
16886         touch $ffid || error "touch $ffid failed."
16887         echo "write to fid $fid"
16888         cat /etc/hosts > $ffid || error "write $ffid failed."
16889         echo "read fid $fid"
16890         diff /etc/hosts $ffid || error "read $ffid failed."
16891         echo "append write to fid $fid"
16892         cat /etc/hosts >> $ffid || error "append write $ffid failed."
16893         echo "rename fid $fid"
16894         mv $ffid $test_dir/$tfile.1 &&
16895                 error "rename $ffid to $tfile.1 should fail."
16896         touch $test_dir/$tfile.1
16897         mv $test_dir/$tfile.1 $ffid &&
16898                 error "rename $tfile.1 to $ffid should fail."
16899         rm -f $test_dir/$tfile.1
16900         echo "truncate fid $fid"
16901         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
16902         echo "link fid $fid"
16903         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
16904         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
16905                 id $USER0 || skip_env "missing user $USER0"
16906                 echo "setfacl fid $fid"
16907                 setfacl -R -m u:$USER0:rwx $ffid ||
16908                         error "setfacl $ffid failed"
16909                 echo "getfacl fid $fid"
16910                 getfacl $ffid || error "getfacl $ffid failed."
16911         fi
16912         echo "unlink fid $fid"
16913         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
16914         echo "mknod fid $fid"
16915         mknod $ffid c 1 3 && error "mknod $ffid should fail."
16916
16917         fid=[0xf00000400:0x1:0x0]
16918         ffid=$MOUNT/.lustre/fid/$fid
16919
16920         echo "stat non-exist fid $fid"
16921         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
16922         echo "write to non-exist fid $fid"
16923         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
16924         echo "link new fid $fid"
16925         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
16926
16927         mkdir -p $test_dir/$tdir
16928         touch $test_dir/$tdir/$tfile
16929         fid=$($LFS path2fid $test_dir/$tdir)
16930         rc=$?
16931         [ $rc -ne 0 ] &&
16932                 error "error: could not get fid for $test_dir/$dir/$tfile."
16933
16934         ffid=$MOUNT/.lustre/fid/$fid
16935
16936         echo "ls $fid"
16937         ls $ffid || error "ls $ffid failed."
16938         echo "touch $fid/$tfile.1"
16939         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
16940
16941         echo "touch $MOUNT/.lustre/fid/$tfile"
16942         touch $MOUNT/.lustre/fid/$tfile && \
16943                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
16944
16945         echo "setxattr to $MOUNT/.lustre/fid"
16946         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
16947
16948         echo "listxattr for $MOUNT/.lustre/fid"
16949         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
16950
16951         echo "delxattr from $MOUNT/.lustre/fid"
16952         setfattr -x trusted.name1 $MOUNT/.lustre/fid
16953
16954         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
16955         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
16956                 error "touch invalid fid should fail."
16957
16958         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
16959         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
16960                 error "touch non-normal fid should fail."
16961
16962         echo "rename $tdir to $MOUNT/.lustre/fid"
16963         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
16964                 error "rename to $MOUNT/.lustre/fid should fail."
16965
16966         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
16967         then            # LU-3547
16968                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
16969                 local new_obf_mode=777
16970
16971                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
16972                 chmod $new_obf_mode $DIR/.lustre/fid ||
16973                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
16974
16975                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
16976                 [ $obf_mode -eq $new_obf_mode ] ||
16977                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
16978
16979                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
16980                 chmod $old_obf_mode $DIR/.lustre/fid ||
16981                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
16982         fi
16983
16984         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
16985         fid=$($LFS path2fid $test_dir/$tfile-2)
16986
16987         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
16988         then # LU-5424
16989                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
16990                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
16991                         error "create lov data thru .lustre failed"
16992         fi
16993         echo "cp /etc/passwd $test_dir/$tfile-2"
16994         cp /etc/passwd $test_dir/$tfile-2 ||
16995                 error "copy to $test_dir/$tfile-2 failed."
16996         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
16997         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
16998                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
16999
17000         rm -rf $test_dir/tfile.lnk
17001         rm -rf $test_dir/$tfile-2
17002 }
17003
17004 test_154A() {
17005         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
17006                 skip "Need MDS version at least 2.4.1"
17007
17008         local tf=$DIR/$tfile
17009         touch $tf
17010
17011         local fid=$($LFS path2fid $tf)
17012         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
17013
17014         # check that we get the same pathname back
17015         local rootpath
17016         local found
17017         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
17018                 echo "$rootpath $fid"
17019                 found=$($LFS fid2path $rootpath "$fid")
17020                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
17021                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
17022         done
17023
17024         # check wrong root path format
17025         rootpath=$MOUNT"_wrong"
17026         found=$($LFS fid2path $rootpath "$fid")
17027         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
17028 }
17029 run_test 154A "lfs path2fid and fid2path basic checks"
17030
17031 test_154B() {
17032         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
17033                 skip "Need MDS version at least 2.4.1"
17034
17035         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
17036         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
17037         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
17038         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
17039
17040         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
17041         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
17042
17043         # check that we get the same pathname
17044         echo "PFID: $PFID, name: $name"
17045         local FOUND=$($LFS fid2path $MOUNT "$PFID")
17046         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
17047         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
17048                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
17049
17050         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
17051 }
17052 run_test 154B "verify the ll_decode_linkea tool"
17053
17054 test_154a() {
17055         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17056         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17057         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
17058                 skip "Need MDS version at least 2.2.51"
17059         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
17060
17061         cp /etc/hosts $DIR/$tfile
17062
17063         fid=$($LFS path2fid $DIR/$tfile)
17064         rc=$?
17065         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
17066
17067         dot_lustre_fid_permission_check "$fid" $DIR ||
17068                 error "dot lustre permission check $fid failed"
17069
17070         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
17071
17072         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
17073
17074         touch $MOUNT/.lustre/file &&
17075                 error "creation is not allowed under .lustre"
17076
17077         mkdir $MOUNT/.lustre/dir &&
17078                 error "mkdir is not allowed under .lustre"
17079
17080         rm -rf $DIR/$tfile
17081 }
17082 run_test 154a "Open-by-FID"
17083
17084 test_154b() {
17085         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17086         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17087         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17088         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
17089                 skip "Need MDS version at least 2.2.51"
17090
17091         local remote_dir=$DIR/$tdir/remote_dir
17092         local MDTIDX=1
17093         local rc=0
17094
17095         mkdir -p $DIR/$tdir
17096         $LFS mkdir -i $MDTIDX $remote_dir ||
17097                 error "create remote directory failed"
17098
17099         cp /etc/hosts $remote_dir/$tfile
17100
17101         fid=$($LFS path2fid $remote_dir/$tfile)
17102         rc=$?
17103         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
17104
17105         dot_lustre_fid_permission_check "$fid" $remote_dir ||
17106                 error "dot lustre permission check $fid failed"
17107         rm -rf $DIR/$tdir
17108 }
17109 run_test 154b "Open-by-FID for remote directory"
17110
17111 test_154c() {
17112         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
17113                 skip "Need MDS version at least 2.4.1"
17114
17115         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
17116         local FID1=$($LFS path2fid $DIR/$tfile.1)
17117         local FID2=$($LFS path2fid $DIR/$tfile.2)
17118         local FID3=$($LFS path2fid $DIR/$tfile.3)
17119
17120         local N=1
17121         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
17122                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
17123                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
17124                 local want=FID$N
17125                 [ "$FID" = "${!want}" ] ||
17126                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
17127                 N=$((N + 1))
17128         done
17129
17130         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
17131         do
17132                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
17133                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
17134                 N=$((N + 1))
17135         done
17136 }
17137 run_test 154c "lfs path2fid and fid2path multiple arguments"
17138
17139 test_154d() {
17140         remote_mds_nodsh && skip "remote MDS with nodsh"
17141         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
17142                 skip "Need MDS version at least 2.5.53"
17143
17144         if remote_mds; then
17145                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
17146         else
17147                 nid="0@lo"
17148         fi
17149         local proc_ofile="mdt.*.exports.'$nid'.open_files"
17150         local fd
17151         local cmd
17152
17153         rm -f $DIR/$tfile
17154         touch $DIR/$tfile
17155
17156         local fid=$($LFS path2fid $DIR/$tfile)
17157         # Open the file
17158         fd=$(free_fd)
17159         cmd="exec $fd<$DIR/$tfile"
17160         eval $cmd
17161         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
17162         echo "$fid_list" | grep "$fid"
17163         rc=$?
17164
17165         cmd="exec $fd>/dev/null"
17166         eval $cmd
17167         if [ $rc -ne 0 ]; then
17168                 error "FID $fid not found in open files list $fid_list"
17169         fi
17170 }
17171 run_test 154d "Verify open file fid"
17172
17173 test_154e()
17174 {
17175         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
17176                 skip "Need MDS version at least 2.6.50"
17177
17178         if ls -a $MOUNT | grep -q '^\.lustre$'; then
17179                 error ".lustre returned by readdir"
17180         fi
17181 }
17182 run_test 154e ".lustre is not returned by readdir"
17183
17184 test_154f() {
17185         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17186
17187         # create parent directory on a single MDT to avoid cross-MDT hardlinks
17188         mkdir_on_mdt0 $DIR/$tdir
17189         # test dirs inherit from its stripe
17190         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
17191         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
17192         cp /etc/hosts $DIR/$tdir/foo1/$tfile
17193         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
17194         touch $DIR/f
17195
17196         # get fid of parents
17197         local FID0=$($LFS path2fid $DIR/$tdir)
17198         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
17199         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
17200         local FID3=$($LFS path2fid $DIR)
17201
17202         # check that path2fid --parents returns expected <parent_fid>/name
17203         # 1) test for a directory (single parent)
17204         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
17205         [ "$parent" == "$FID0/foo1" ] ||
17206                 error "expected parent: $FID0/foo1, got: $parent"
17207
17208         # 2) test for a file with nlink > 1 (multiple parents)
17209         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
17210         echo "$parent" | grep -F "$FID1/$tfile" ||
17211                 error "$FID1/$tfile not returned in parent list"
17212         echo "$parent" | grep -F "$FID2/link" ||
17213                 error "$FID2/link not returned in parent list"
17214
17215         # 3) get parent by fid
17216         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
17217         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17218         echo "$parent" | grep -F "$FID1/$tfile" ||
17219                 error "$FID1/$tfile not returned in parent list (by fid)"
17220         echo "$parent" | grep -F "$FID2/link" ||
17221                 error "$FID2/link not returned in parent list (by fid)"
17222
17223         # 4) test for entry in root directory
17224         parent=$($LFS path2fid --parents $DIR/f)
17225         echo "$parent" | grep -F "$FID3/f" ||
17226                 error "$FID3/f not returned in parent list"
17227
17228         # 5) test it on root directory
17229         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
17230                 error "$MOUNT should not have parents"
17231
17232         # enable xattr caching and check that linkea is correctly updated
17233         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
17234         save_lustre_params client "llite.*.xattr_cache" > $save
17235         lctl set_param llite.*.xattr_cache 1
17236
17237         # 6.1) linkea update on rename
17238         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
17239
17240         # get parents by fid
17241         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17242         # foo1 should no longer be returned in parent list
17243         echo "$parent" | grep -F "$FID1" &&
17244                 error "$FID1 should no longer be in parent list"
17245         # the new path should appear
17246         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
17247                 error "$FID2/$tfile.moved is not in parent list"
17248
17249         # 6.2) linkea update on unlink
17250         rm -f $DIR/$tdir/foo2/link
17251         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17252         # foo2/link should no longer be returned in parent list
17253         echo "$parent" | grep -F "$FID2/link" &&
17254                 error "$FID2/link should no longer be in parent list"
17255         true
17256
17257         rm -f $DIR/f
17258         restore_lustre_params < $save
17259         rm -f $save
17260 }
17261 run_test 154f "get parent fids by reading link ea"
17262
17263 test_154g()
17264 {
17265         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
17266            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
17267                 skip "Need MDS version at least 2.6.92"
17268
17269         mkdir_on_mdt0 $DIR/$tdir
17270         llapi_fid_test -d $DIR/$tdir
17271 }
17272 run_test 154g "various llapi FID tests"
17273
17274 test_154h()
17275 {
17276         (( $CLIENT_VERSION >= $(version_code 2.15.55.1) )) ||
17277                 skip "Need client at least version 2.15.55.1"
17278
17279         # Create an empty file
17280         touch $DIR/$tfile
17281
17282         # Get FID (interactive mode) and save under $TMP/$tfile.log
17283         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
17284                 path2fid $DIR/$tfile
17285         EOF
17286
17287         fid=$(cat $TMP/$tfile.log)
17288         # $fid should not be empty
17289         [[ ! -z $fid ]] || error "FID is empty"
17290         $LFS rmfid $DIR "$fid" || error "rmfid failed for $fid"
17291 }
17292 run_test 154h "Verify interactive path2fid"
17293
17294 test_155_small_load() {
17295     local temp=$TMP/$tfile
17296     local file=$DIR/$tfile
17297
17298     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
17299         error "dd of=$temp bs=6096 count=1 failed"
17300     cp $temp $file
17301     cancel_lru_locks $OSC
17302     cmp $temp $file || error "$temp $file differ"
17303
17304     $TRUNCATE $temp 6000
17305     $TRUNCATE $file 6000
17306     cmp $temp $file || error "$temp $file differ (truncate1)"
17307
17308     echo "12345" >>$temp
17309     echo "12345" >>$file
17310     cmp $temp $file || error "$temp $file differ (append1)"
17311
17312     echo "12345" >>$temp
17313     echo "12345" >>$file
17314     cmp $temp $file || error "$temp $file differ (append2)"
17315
17316     rm -f $temp $file
17317     true
17318 }
17319
17320 test_155_big_load() {
17321         remote_ost_nodsh && skip "remote OST with nodsh"
17322
17323         local temp=$TMP/$tfile
17324         local file=$DIR/$tfile
17325
17326         free_min_max
17327         local cache_size=$(do_facet ost$((MAXI+1)) \
17328                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
17329
17330         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
17331         # pre-set value
17332         if [ -z "$cache_size" ]; then
17333                 cache_size=256
17334         fi
17335         local large_file_size=$((cache_size * 2))
17336
17337         echo "OSS cache size: $cache_size KB"
17338         echo "Large file size: $large_file_size KB"
17339
17340         [ $MAXV -le $large_file_size ] &&
17341                 skip_env "max available OST size needs > $large_file_size KB"
17342
17343         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
17344
17345         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
17346                 error "dd of=$temp bs=$large_file_size count=1k failed"
17347         cp $temp $file
17348         ls -lh $temp $file
17349         cancel_lru_locks osc
17350         cmp $temp $file || error "$temp $file differ"
17351
17352         rm -f $temp $file
17353         true
17354 }
17355
17356 save_writethrough() {
17357         local facets=$(get_facets OST)
17358
17359         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
17360 }
17361
17362 test_155a() {
17363         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17364
17365         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17366
17367         save_writethrough $p
17368
17369         set_cache read on
17370         set_cache writethrough on
17371         test_155_small_load
17372         restore_lustre_params < $p
17373         rm -f $p
17374 }
17375 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
17376
17377 test_155b() {
17378         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17379
17380         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17381
17382         save_writethrough $p
17383
17384         set_cache read on
17385         set_cache writethrough off
17386         test_155_small_load
17387         restore_lustre_params < $p
17388         rm -f $p
17389 }
17390 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
17391
17392 test_155c() {
17393         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17394
17395         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17396
17397         save_writethrough $p
17398
17399         set_cache read off
17400         set_cache writethrough on
17401         test_155_small_load
17402         restore_lustre_params < $p
17403         rm -f $p
17404 }
17405 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
17406
17407 test_155d() {
17408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17409
17410         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17411
17412         save_writethrough $p
17413
17414         set_cache read off
17415         set_cache writethrough off
17416         test_155_small_load
17417         restore_lustre_params < $p
17418         rm -f $p
17419 }
17420 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
17421
17422 test_155e() {
17423         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17424
17425         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17426
17427         save_writethrough $p
17428
17429         set_cache read on
17430         set_cache writethrough on
17431         test_155_big_load
17432         restore_lustre_params < $p
17433         rm -f $p
17434 }
17435 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
17436
17437 test_155f() {
17438         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17439
17440         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17441
17442         save_writethrough $p
17443
17444         set_cache read on
17445         set_cache writethrough off
17446         test_155_big_load
17447         restore_lustre_params < $p
17448         rm -f $p
17449 }
17450 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
17451
17452 test_155g() {
17453         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17454
17455         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17456
17457         save_writethrough $p
17458
17459         set_cache read off
17460         set_cache writethrough on
17461         test_155_big_load
17462         restore_lustre_params < $p
17463         rm -f $p
17464 }
17465 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
17466
17467 test_155h() {
17468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17469
17470         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17471
17472         save_writethrough $p
17473
17474         set_cache read off
17475         set_cache writethrough off
17476         test_155_big_load
17477         restore_lustre_params < $p
17478         rm -f $p
17479 }
17480 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
17481
17482 test_156() {
17483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17484         remote_ost_nodsh && skip "remote OST with nodsh"
17485         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
17486                 skip "stats not implemented on old servers"
17487         [ "$ost1_FSTYPE" = "zfs" ] &&
17488                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
17489         (( CLIENT_VERSION == OST1_VERSION )) ||
17490                 skip "LU-13081: no interop testing for OSS cache"
17491
17492         local CPAGES=3
17493         local BEFORE
17494         local AFTER
17495         local file="$DIR/$tfile"
17496         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17497
17498         save_writethrough $p
17499         roc_hit_init
17500
17501         log "Turn on read and write cache"
17502         set_cache read on
17503         set_cache writethrough on
17504
17505         log "Write data and read it back."
17506         log "Read should be satisfied from the cache."
17507         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17508         BEFORE=$(roc_hit)
17509         cancel_lru_locks osc
17510         cat $file >/dev/null
17511         AFTER=$(roc_hit)
17512         if ! let "AFTER - BEFORE == CPAGES"; then
17513                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
17514         else
17515                 log "cache hits: before: $BEFORE, after: $AFTER"
17516         fi
17517
17518         log "Read again; it should be satisfied from the cache."
17519         BEFORE=$AFTER
17520         cancel_lru_locks osc
17521         cat $file >/dev/null
17522         AFTER=$(roc_hit)
17523         if ! let "AFTER - BEFORE == CPAGES"; then
17524                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
17525         else
17526                 log "cache hits:: before: $BEFORE, after: $AFTER"
17527         fi
17528
17529         log "Turn off the read cache and turn on the write cache"
17530         set_cache read off
17531         set_cache writethrough on
17532
17533         log "Read again; it should be satisfied from the cache."
17534         BEFORE=$(roc_hit)
17535         cancel_lru_locks osc
17536         cat $file >/dev/null
17537         AFTER=$(roc_hit)
17538         if ! let "AFTER - BEFORE == CPAGES"; then
17539                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
17540         else
17541                 log "cache hits:: before: $BEFORE, after: $AFTER"
17542         fi
17543
17544         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17545                 # > 2.12.56 uses pagecache if cached
17546                 log "Read again; it should not be satisfied from the cache."
17547                 BEFORE=$AFTER
17548                 cancel_lru_locks osc
17549                 cat $file >/dev/null
17550                 AFTER=$(roc_hit)
17551                 if ! let "AFTER - BEFORE == 0"; then
17552                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
17553                 else
17554                         log "cache hits:: before: $BEFORE, after: $AFTER"
17555                 fi
17556         fi
17557
17558         log "Write data and read it back."
17559         log "Read should be satisfied from the cache."
17560         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17561         BEFORE=$(roc_hit)
17562         cancel_lru_locks osc
17563         cat $file >/dev/null
17564         AFTER=$(roc_hit)
17565         if ! let "AFTER - BEFORE == CPAGES"; then
17566                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
17567         else
17568                 log "cache hits:: before: $BEFORE, after: $AFTER"
17569         fi
17570
17571         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17572                 # > 2.12.56 uses pagecache if cached
17573                 log "Read again; it should not be satisfied from the cache."
17574                 BEFORE=$AFTER
17575                 cancel_lru_locks osc
17576                 cat $file >/dev/null
17577                 AFTER=$(roc_hit)
17578                 if ! let "AFTER - BEFORE == 0"; then
17579                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
17580                 else
17581                         log "cache hits:: before: $BEFORE, after: $AFTER"
17582                 fi
17583         fi
17584
17585         log "Turn off read and write cache"
17586         set_cache read off
17587         set_cache writethrough off
17588
17589         log "Write data and read it back"
17590         log "It should not be satisfied from the cache."
17591         rm -f $file
17592         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17593         cancel_lru_locks osc
17594         BEFORE=$(roc_hit)
17595         cat $file >/dev/null
17596         AFTER=$(roc_hit)
17597         if ! let "AFTER - BEFORE == 0"; then
17598                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
17599         else
17600                 log "cache hits:: before: $BEFORE, after: $AFTER"
17601         fi
17602
17603         log "Turn on the read cache and turn off the write cache"
17604         set_cache read on
17605         set_cache writethrough off
17606
17607         log "Write data and read it back"
17608         log "It should not be satisfied from the cache."
17609         rm -f $file
17610         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17611         BEFORE=$(roc_hit)
17612         cancel_lru_locks osc
17613         cat $file >/dev/null
17614         AFTER=$(roc_hit)
17615         if ! let "AFTER - BEFORE == 0"; then
17616                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
17617         else
17618                 log "cache hits:: before: $BEFORE, after: $AFTER"
17619         fi
17620
17621         log "Read again; it should be satisfied from the cache."
17622         BEFORE=$(roc_hit)
17623         cancel_lru_locks osc
17624         cat $file >/dev/null
17625         AFTER=$(roc_hit)
17626         if ! let "AFTER - BEFORE == CPAGES"; then
17627                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
17628         else
17629                 log "cache hits:: before: $BEFORE, after: $AFTER"
17630         fi
17631
17632         restore_lustre_params < $p
17633         rm -f $p $file
17634 }
17635 run_test 156 "Verification of tunables"
17636
17637 test_160a() {
17638         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17639         remote_mds_nodsh && skip "remote MDS with nodsh"
17640         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17641                 skip "Need MDS version at least 2.2.0"
17642
17643         changelog_register || error "changelog_register failed"
17644         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17645         changelog_users $SINGLEMDS | grep -q $cl_user ||
17646                 error "User $cl_user not found in changelog_users"
17647
17648         mkdir_on_mdt0 $DIR/$tdir
17649
17650         # change something
17651         test_mkdir -p $DIR/$tdir/pics/2008/zachy
17652         changelog_clear 0 || error "changelog_clear failed"
17653         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
17654         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
17655         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17656         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17657         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17658         rm $DIR/$tdir/pics/desktop.jpg
17659
17660         echo "verifying changelog mask"
17661         changelog_chmask "-MKDIR"
17662         changelog_chmask "-CLOSE"
17663
17664         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
17665         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
17666
17667         changelog_chmask "+MKDIR"
17668         changelog_chmask "+CLOSE"
17669
17670         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
17671         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
17672
17673         MKDIRS=$(changelog_dump | grep -c "MKDIR")
17674         CLOSES=$(changelog_dump | grep -c "CLOSE")
17675         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
17676         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
17677
17678         # verify contents
17679         echo "verifying target fid"
17680         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
17681         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
17682         [ "$fidc" == "$fidf" ] ||
17683                 error "changelog '$tfile' fid $fidc != file fid $fidf"
17684         echo "verifying parent fid"
17685         # The FID returned from the Changelog may be the directory shard on
17686         # a different MDT, and not the FID returned by path2fid on the parent.
17687         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
17688         # since this is what will matter when recreating this file in the tree.
17689         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
17690         local pathp=$($LFS fid2path $MOUNT "$fidp")
17691         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
17692                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
17693
17694         echo "getting records for $cl_user"
17695         changelog_users $SINGLEMDS
17696         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
17697         local nclr=3
17698         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
17699                 error "changelog_clear failed"
17700         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
17701         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
17702         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
17703                 error "user index expect $user_rec1 + $nclr != $user_rec2"
17704
17705         local min0_rec=$(changelog_users $SINGLEMDS |
17706                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
17707         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
17708                           awk '{ print $1; exit; }')
17709
17710         changelog_dump | tail -n 5
17711         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
17712         [ $first_rec == $((min0_rec + 1)) ] ||
17713                 error "first index should be $min0_rec + 1 not $first_rec"
17714
17715         # LU-3446 changelog index reset on MDT restart
17716         local cur_rec1=$(changelog_users $SINGLEMDS |
17717                          awk '/^current.index:/ { print $NF }')
17718         changelog_clear 0 ||
17719                 error "clear all changelog records for $cl_user failed"
17720         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
17721         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
17722                 error "Fail to start $SINGLEMDS"
17723         local cur_rec2=$(changelog_users $SINGLEMDS |
17724                          awk '/^current.index:/ { print $NF }')
17725         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
17726         [ $cur_rec1 == $cur_rec2 ] ||
17727                 error "current index should be $cur_rec1 not $cur_rec2"
17728
17729         echo "verifying users from this test are deregistered"
17730         changelog_deregister || error "changelog_deregister failed"
17731         changelog_users $SINGLEMDS | grep -q $cl_user &&
17732                 error "User '$cl_user' still in changelog_users"
17733
17734         # lctl get_param -n mdd.*.changelog_users
17735         # current_index: 144
17736         # ID    index (idle seconds)
17737         # cl3   144   (2) mask=<list>
17738         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
17739                 # this is the normal case where all users were deregistered
17740                 # make sure no new records are added when no users are present
17741                 local last_rec1=$(changelog_users $SINGLEMDS |
17742                                   awk '/^current.index:/ { print $NF }')
17743                 touch $DIR/$tdir/chloe
17744                 local last_rec2=$(changelog_users $SINGLEMDS |
17745                                   awk '/^current.index:/ { print $NF }')
17746                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
17747                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
17748         else
17749                 # any changelog users must be leftovers from a previous test
17750                 changelog_users $SINGLEMDS
17751                 echo "other changelog users; can't verify off"
17752         fi
17753 }
17754 run_test 160a "changelog sanity"
17755
17756 test_160b() { # LU-3587
17757         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17758         remote_mds_nodsh && skip "remote MDS with nodsh"
17759         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17760                 skip "Need MDS version at least 2.2.0"
17761
17762         changelog_register || error "changelog_register failed"
17763         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17764         changelog_users $SINGLEMDS | grep -q $cl_user ||
17765                 error "User '$cl_user' not found in changelog_users"
17766
17767         local longname1=$(str_repeat a 255)
17768         local longname2=$(str_repeat b 255)
17769
17770         cd $DIR
17771         echo "creating very long named file"
17772         touch $longname1 || error "create of '$longname1' failed"
17773         echo "renaming very long named file"
17774         mv $longname1 $longname2
17775
17776         changelog_dump | grep RENME | tail -n 5
17777         rm -f $longname2
17778 }
17779 run_test 160b "Verify that very long rename doesn't crash in changelog"
17780
17781 test_160c() {
17782         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17783         remote_mds_nodsh && skip "remote MDS with nodsh"
17784
17785         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
17786                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
17787                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
17788                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
17789
17790         local rc=0
17791
17792         # Registration step
17793         changelog_register || error "changelog_register failed"
17794
17795         rm -rf $DIR/$tdir
17796         mkdir -p $DIR/$tdir
17797         $MCREATE $DIR/$tdir/foo_160c
17798         changelog_chmask "-TRUNC"
17799         $TRUNCATE $DIR/$tdir/foo_160c 200
17800         changelog_chmask "+TRUNC"
17801         $TRUNCATE $DIR/$tdir/foo_160c 199
17802         changelog_dump | tail -n 5
17803         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
17804         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
17805 }
17806 run_test 160c "verify that changelog log catch the truncate event"
17807
17808 test_160d() {
17809         remote_mds_nodsh && skip "remote MDS with nodsh"
17810         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17812         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
17813                 skip "Need MDS version at least 2.7.60"
17814
17815         # Registration step
17816         changelog_register || error "changelog_register failed"
17817
17818         mkdir -p $DIR/$tdir/migrate_dir
17819         changelog_clear 0 || error "changelog_clear failed"
17820
17821         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
17822         changelog_dump | tail -n 5
17823         local migrates=$(changelog_dump | grep -c "MIGRT")
17824         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
17825 }
17826 run_test 160d "verify that changelog log catch the migrate event"
17827
17828 test_160e() {
17829         remote_mds_nodsh && skip "remote MDS with nodsh"
17830
17831         # Create a user
17832         changelog_register || error "changelog_register failed"
17833
17834         local MDT0=$(facet_svc $SINGLEMDS)
17835         local rc
17836
17837         # No user (expect fail)
17838         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
17839         rc=$?
17840         if [ $rc -eq 0 ]; then
17841                 error "Should fail without user"
17842         elif [ $rc -ne 4 ]; then
17843                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
17844         fi
17845
17846         # Delete a future user (expect fail)
17847         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
17848         rc=$?
17849         if [ $rc -eq 0 ]; then
17850                 error "Deleted non-existant user cl77"
17851         elif [ $rc -ne 2 ]; then
17852                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
17853         fi
17854
17855         # Clear to a bad index (1 billion should be safe)
17856         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
17857         rc=$?
17858
17859         if [ $rc -eq 0 ]; then
17860                 error "Successfully cleared to invalid CL index"
17861         elif [ $rc -ne 22 ]; then
17862                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
17863         fi
17864 }
17865 run_test 160e "changelog negative testing (should return errors)"
17866
17867 test_160f() {
17868         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17869         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17870                 skip "Need MDS version at least 2.10.56"
17871
17872         local mdts=$(comma_list $(mdts_nodes))
17873
17874         # Create a user
17875         changelog_register || error "first changelog_register failed"
17876         changelog_register || error "second changelog_register failed"
17877         local cl_users
17878         declare -A cl_user1
17879         declare -A cl_user2
17880         local user_rec1
17881         local user_rec2
17882         local i
17883
17884         # generate some changelog records to accumulate on each MDT
17885         # use all_char because created files should be evenly distributed
17886         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17887                 error "test_mkdir $tdir failed"
17888         log "$(date +%s): creating first files"
17889         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17890                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
17891                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
17892         done
17893
17894         # check changelogs have been generated
17895         local start=$SECONDS
17896         local idle_time=$((MDSCOUNT * 5 + 5))
17897         local nbcl=$(changelog_dump | wc -l)
17898         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17899
17900         for param in "changelog_max_idle_time=$idle_time" \
17901                      "changelog_gc=1" \
17902                      "changelog_min_gc_interval=2" \
17903                      "changelog_min_free_cat_entries=3"; do
17904                 local MDT0=$(facet_svc $SINGLEMDS)
17905                 local var="${param%=*}"
17906                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17907
17908                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17909                 do_nodes $mdts $LCTL set_param mdd.*.$param
17910         done
17911
17912         # force cl_user2 to be idle (1st part), but also cancel the
17913         # cl_user1 records so that it is not evicted later in the test.
17914         local sleep1=$((idle_time / 2))
17915         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
17916         sleep $sleep1
17917
17918         # simulate changelog catalog almost full
17919         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
17920         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
17921
17922         for i in $(seq $MDSCOUNT); do
17923                 cl_users=(${CL_USERS[mds$i]})
17924                 cl_user1[mds$i]="${cl_users[0]}"
17925                 cl_user2[mds$i]="${cl_users[1]}"
17926
17927                 [ -n "${cl_user1[mds$i]}" ] ||
17928                         error "mds$i: no user registered"
17929                 [ -n "${cl_user2[mds$i]}" ] ||
17930                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17931
17932                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17933                 [ -n "$user_rec1" ] ||
17934                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17935                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17936                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17937                 [ -n "$user_rec2" ] ||
17938                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17939                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17940                      "$user_rec1 + 2 == $user_rec2"
17941                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17942                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17943                               "$user_rec1 + 2, but is $user_rec2"
17944                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17945                 [ -n "$user_rec2" ] ||
17946                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17947                 [ $user_rec1 == $user_rec2 ] ||
17948                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17949                               "$user_rec1, but is $user_rec2"
17950         done
17951
17952         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
17953         local sleep2=$((idle_time - (SECONDS - start) + 1))
17954         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
17955         sleep $sleep2
17956
17957         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17958         # cl_user1 should be OK because it recently processed records.
17959         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
17960         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17961                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
17962                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
17963         done
17964
17965         # ensure gc thread is done
17966         for i in $(mdts_nodes); do
17967                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17968                         error "$i: GC-thread not done"
17969         done
17970
17971         local first_rec
17972         for (( i = 1; i <= MDSCOUNT; i++ )); do
17973                 # check cl_user1 still registered
17974                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17975                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17976                 # check cl_user2 unregistered
17977                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17978                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17979
17980                 # check changelogs are present and starting at $user_rec1 + 1
17981                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17982                 [ -n "$user_rec1" ] ||
17983                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17984                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17985                             awk '{ print $1; exit; }')
17986
17987                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17988                 [ $((user_rec1 + 1)) == $first_rec ] ||
17989                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17990         done
17991 }
17992 run_test 160f "changelog garbage collect (timestamped users)"
17993
17994 test_160g() {
17995         remote_mds_nodsh && skip "remote MDS with nodsh"
17996         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
17997                 skip "Need MDS version at least 2.14.55"
17998
17999         local mdts=$(comma_list $(mdts_nodes))
18000
18001         # Create a user
18002         changelog_register || error "first changelog_register failed"
18003         changelog_register || error "second changelog_register failed"
18004         local cl_users
18005         declare -A cl_user1
18006         declare -A cl_user2
18007         local user_rec1
18008         local user_rec2
18009         local i
18010
18011         # generate some changelog records to accumulate on each MDT
18012         # use all_char because created files should be evenly distributed
18013         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18014                 error "test_mkdir $tdir failed"
18015         for ((i = 0; i < MDSCOUNT; i++)); do
18016                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18017                         error "create $DIR/$tdir/d$i.1 failed"
18018         done
18019
18020         # check changelogs have been generated
18021         local nbcl=$(changelog_dump | wc -l)
18022         (( $nbcl > 0 )) || error "no changelogs found"
18023
18024         # reduce the max_idle_indexes value to make sure we exceed it
18025         for param in "changelog_max_idle_indexes=2" \
18026                      "changelog_gc=1" \
18027                      "changelog_min_gc_interval=2"; 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                         error "unable to set mdd.*.$param"
18035         done
18036
18037         local start=$SECONDS
18038         for i in $(seq $MDSCOUNT); do
18039                 cl_users=(${CL_USERS[mds$i]})
18040                 cl_user1[mds$i]="${cl_users[0]}"
18041                 cl_user2[mds$i]="${cl_users[1]}"
18042
18043                 [ -n "${cl_user1[mds$i]}" ] ||
18044                         error "mds$i: user1 is not registered"
18045                 [ -n "${cl_user2[mds$i]}" ] ||
18046                         error "mds$i: only ${cl_user1[mds$i]} is registered"
18047
18048                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18049                 [ -n "$user_rec1" ] ||
18050                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
18051                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
18052                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18053                 [ -n "$user_rec2" ] ||
18054                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
18055                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
18056                      "$user_rec1 + 2 == $user_rec2"
18057                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
18058                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
18059                               "expected $user_rec1 + 2, but is $user_rec2"
18060                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
18061                 [ -n "$user_rec2" ] ||
18062                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
18063                 [ $user_rec1 == $user_rec2 ] ||
18064                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
18065                               "expected $user_rec1, but is $user_rec2"
18066         done
18067
18068         # ensure we are past the previous changelog_min_gc_interval set above
18069         local sleep2=$((start + 2 - SECONDS))
18070         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18071         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
18072         # cl_user1 should be OK because it recently processed records.
18073         for ((i = 0; i < MDSCOUNT; i++)); do
18074                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
18075                         error "create $DIR/$tdir/d$i.3 failed"
18076         done
18077
18078         # ensure gc thread is done
18079         for i in $(mdts_nodes); do
18080                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
18081                         error "$i: GC-thread not done"
18082         done
18083
18084         local first_rec
18085         for (( i = 1; i <= MDSCOUNT; i++ )); do
18086                 # check cl_user1 still registered
18087                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
18088                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
18089                 # check cl_user2 unregistered
18090                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
18091                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
18092
18093                 # check changelogs are present and starting at $user_rec1 + 1
18094                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18095                 [ -n "$user_rec1" ] ||
18096                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
18097                 first_rec=$($LFS changelog $(facet_svc mds$i) |
18098                             awk '{ print $1; exit; }')
18099
18100                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
18101                 [ $((user_rec1 + 1)) == $first_rec ] ||
18102                         error "mds$i: rec $first_rec != $user_rec1 + 1"
18103         done
18104 }
18105 run_test 160g "changelog garbage collect on idle records"
18106
18107 test_160h() {
18108         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18109         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
18110                 skip "Need MDS version at least 2.10.56"
18111
18112         local mdts=$(comma_list $(mdts_nodes))
18113
18114         # Create a user
18115         changelog_register || error "first changelog_register failed"
18116         changelog_register || error "second changelog_register failed"
18117         local cl_users
18118         declare -A cl_user1
18119         declare -A cl_user2
18120         local user_rec1
18121         local user_rec2
18122         local i
18123
18124         # generate some changelog records to accumulate on each MDT
18125         # use all_char because created files should be evenly distributed
18126         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18127                 error "test_mkdir $tdir failed"
18128         for ((i = 0; i < MDSCOUNT; i++)); do
18129                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18130                         error "create $DIR/$tdir/d$i.1 failed"
18131         done
18132
18133         # check changelogs have been generated
18134         local nbcl=$(changelog_dump | wc -l)
18135         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18136
18137         for param in "changelog_max_idle_time=10" \
18138                      "changelog_gc=1" \
18139                      "changelog_min_gc_interval=2"; do
18140                 local MDT0=$(facet_svc $SINGLEMDS)
18141                 local var="${param%=*}"
18142                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18143
18144                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18145                 do_nodes $mdts $LCTL set_param mdd.*.$param
18146         done
18147
18148         # force cl_user2 to be idle (1st part)
18149         sleep 9
18150
18151         for i in $(seq $MDSCOUNT); do
18152                 cl_users=(${CL_USERS[mds$i]})
18153                 cl_user1[mds$i]="${cl_users[0]}"
18154                 cl_user2[mds$i]="${cl_users[1]}"
18155
18156                 [ -n "${cl_user1[mds$i]}" ] ||
18157                         error "mds$i: no user registered"
18158                 [ -n "${cl_user2[mds$i]}" ] ||
18159                         error "mds$i: only ${cl_user2[mds$i]} is registered"
18160
18161                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18162                 [ -n "$user_rec1" ] ||
18163                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18164                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
18165                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18166                 [ -n "$user_rec2" ] ||
18167                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18168                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
18169                      "$user_rec1 + 2 == $user_rec2"
18170                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
18171                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
18172                               "$user_rec1 + 2, but is $user_rec2"
18173                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
18174                 [ -n "$user_rec2" ] ||
18175                         error "mds$i: User ${cl_user2[mds$i]} not registered"
18176                 [ $user_rec1 == $user_rec2 ] ||
18177                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
18178                               "$user_rec1, but is $user_rec2"
18179         done
18180
18181         # force cl_user2 to be idle (2nd part) and to reach
18182         # changelog_max_idle_time
18183         sleep 2
18184
18185         # force each GC-thread start and block then
18186         # one per MDT/MDD, set fail_val accordingly
18187         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
18188         do_nodes $mdts $LCTL set_param fail_loc=0x1316
18189
18190         # generate more changelogs to trigger fail_loc
18191         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
18192                 error "create $DIR/$tdir/${tfile}bis failed"
18193
18194         # stop MDT to stop GC-thread, should be done in back-ground as it will
18195         # block waiting for the thread to be released and exit
18196         declare -A stop_pids
18197         for i in $(seq $MDSCOUNT); do
18198                 stop mds$i &
18199                 stop_pids[mds$i]=$!
18200         done
18201
18202         for i in $(mdts_nodes); do
18203                 local facet
18204                 local nb=0
18205                 local facets=$(facets_up_on_host $i)
18206
18207                 for facet in ${facets//,/ }; do
18208                         if [[ $facet == mds* ]]; then
18209                                 nb=$((nb + 1))
18210                         fi
18211                 done
18212                 # ensure each MDS's gc threads are still present and all in "R"
18213                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
18214                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
18215                         error "$i: expected $nb GC-thread"
18216                 wait_update $i \
18217                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
18218                         "R" 20 ||
18219                         error "$i: GC-thread not found in R-state"
18220                 # check umounts of each MDT on MDS have reached kthread_stop()
18221                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
18222                         error "$i: expected $nb umount"
18223                 wait_update $i \
18224                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
18225                         error "$i: umount not found in D-state"
18226         done
18227
18228         # release all GC-threads
18229         do_nodes $mdts $LCTL set_param fail_loc=0
18230
18231         # wait for MDT stop to complete
18232         for i in $(seq $MDSCOUNT); do
18233                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
18234         done
18235
18236         # XXX
18237         # may try to check if any orphan changelog records are present
18238         # via ldiskfs/zfs and llog_reader...
18239
18240         # re-start/mount MDTs
18241         for i in $(seq $MDSCOUNT); do
18242                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
18243                         error "Fail to start mds$i"
18244         done
18245
18246         local first_rec
18247         for i in $(seq $MDSCOUNT); do
18248                 # check cl_user1 still registered
18249                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
18250                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18251                 # check cl_user2 unregistered
18252                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
18253                         error "mds$i: User ${cl_user2[mds$i]} still registered"
18254
18255                 # check changelogs are present and starting at $user_rec1 + 1
18256                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18257                 [ -n "$user_rec1" ] ||
18258                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18259                 first_rec=$($LFS changelog $(facet_svc mds$i) |
18260                             awk '{ print $1; exit; }')
18261
18262                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
18263                 [ $((user_rec1 + 1)) == $first_rec ] ||
18264                         error "mds$i: first index should be $user_rec1 + 1, " \
18265                               "but is $first_rec"
18266         done
18267 }
18268 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
18269               "during mount"
18270
18271 test_160i() {
18272
18273         local mdts=$(comma_list $(mdts_nodes))
18274
18275         changelog_register || error "first changelog_register failed"
18276
18277         # generate some changelog records to accumulate on each MDT
18278         # use all_char because created files should be evenly distributed
18279         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18280                 error "test_mkdir $tdir failed"
18281         for ((i = 0; i < MDSCOUNT; i++)); do
18282                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18283                         error "create $DIR/$tdir/d$i.1 failed"
18284         done
18285
18286         # check changelogs have been generated
18287         local nbcl=$(changelog_dump | wc -l)
18288         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18289
18290         # simulate race between register and unregister
18291         # XXX as fail_loc is set per-MDS, with DNE configs the race
18292         # simulation will only occur for one MDT per MDS and for the
18293         # others the normal race scenario will take place
18294         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
18295         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
18296         do_nodes $mdts $LCTL set_param fail_val=1
18297
18298         # unregister 1st user
18299         changelog_deregister &
18300         local pid1=$!
18301         # wait some time for deregister work to reach race rdv
18302         sleep 2
18303         # register 2nd user
18304         changelog_register || error "2nd user register failed"
18305
18306         wait $pid1 || error "1st user deregister failed"
18307
18308         local i
18309         local last_rec
18310         declare -A LAST_REC
18311         for i in $(seq $MDSCOUNT); do
18312                 if changelog_users mds$i | grep "^cl"; then
18313                         # make sure new records are added with one user present
18314                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
18315                                           awk '/^current.index:/ { print $NF }')
18316                 else
18317                         error "mds$i has no user registered"
18318                 fi
18319         done
18320
18321         # generate more changelog records to accumulate on each MDT
18322         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
18323                 error "create $DIR/$tdir/${tfile}bis failed"
18324
18325         for i in $(seq $MDSCOUNT); do
18326                 last_rec=$(changelog_users $SINGLEMDS |
18327                            awk '/^current.index:/ { print $NF }')
18328                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
18329                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
18330                         error "changelogs are off on mds$i"
18331         done
18332 }
18333 run_test 160i "changelog user register/unregister race"
18334
18335 test_160j() {
18336         remote_mds_nodsh && skip "remote MDS with nodsh"
18337         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
18338                 skip "Need MDS version at least 2.12.56"
18339
18340         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
18341         stack_trap "umount $MOUNT2" EXIT
18342
18343         changelog_register || error "first changelog_register failed"
18344         stack_trap "changelog_deregister" EXIT
18345
18346         # generate some changelog
18347         # use all_char because created files should be evenly distributed
18348         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18349                 error "mkdir $tdir failed"
18350         for ((i = 0; i < MDSCOUNT; i++)); do
18351                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18352                         error "create $DIR/$tdir/d$i.1 failed"
18353         done
18354
18355         # open the changelog device
18356         exec 3>/dev/changelog-$FSNAME-MDT0000
18357         stack_trap "exec 3>&-" EXIT
18358         exec 4</dev/changelog-$FSNAME-MDT0000
18359         stack_trap "exec 4<&-" EXIT
18360
18361         # umount the first lustre mount
18362         umount $MOUNT
18363         stack_trap "mount_client $MOUNT" EXIT
18364
18365         # read changelog, which may or may not fail, but should not crash
18366         cat <&4 >/dev/null
18367
18368         # clear changelog
18369         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18370         changelog_users $SINGLEMDS | grep -q $cl_user ||
18371                 error "User $cl_user not found in changelog_users"
18372
18373         printf 'clear:'$cl_user':0' >&3
18374 }
18375 run_test 160j "client can be umounted while its chanangelog is being used"
18376
18377 test_160k() {
18378         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18379         remote_mds_nodsh && skip "remote MDS with nodsh"
18380
18381         mkdir -p $DIR/$tdir/1/1
18382
18383         changelog_register || error "changelog_register failed"
18384         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18385
18386         changelog_users $SINGLEMDS | grep -q $cl_user ||
18387                 error "User '$cl_user' not found in changelog_users"
18388 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
18389         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
18390         rmdir $DIR/$tdir/1/1 & sleep 1
18391         mkdir $DIR/$tdir/2
18392         touch $DIR/$tdir/2/2
18393         rm -rf $DIR/$tdir/2
18394
18395         wait
18396         sleep 4
18397
18398         changelog_dump | grep rmdir || error "rmdir not recorded"
18399 }
18400 run_test 160k "Verify that changelog records are not lost"
18401
18402 # Verifies that a file passed as a parameter has recently had an operation
18403 # performed on it that has generated an MTIME changelog which contains the
18404 # correct parent FID. As files might reside on a different MDT from the
18405 # parent directory in DNE configurations, the FIDs are translated to paths
18406 # before being compared, which should be identical
18407 compare_mtime_changelog() {
18408         local file="${1}"
18409         local mdtidx
18410         local mtime
18411         local cl_fid
18412         local pdir
18413         local dir
18414
18415         mdtidx=$($LFS getstripe --mdt-index $file)
18416         mdtidx=$(printf "%04x" $mdtidx)
18417
18418         # Obtain the parent FID from the MTIME changelog
18419         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
18420         [ -z "$mtime" ] && error "MTIME changelog not recorded"
18421
18422         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
18423         [ -z "$cl_fid" ] && error "parent FID not present"
18424
18425         # Verify that the path for the parent FID is the same as the path for
18426         # the test directory
18427         pdir=$($LFS fid2path $MOUNT "$cl_fid")
18428
18429         dir=$(dirname $1)
18430
18431         [[ "${pdir%/}" == "$dir" ]] ||
18432                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
18433 }
18434
18435 test_160l() {
18436         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18437
18438         remote_mds_nodsh && skip "remote MDS with nodsh"
18439         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
18440                 skip "Need MDS version at least 2.13.55"
18441
18442         local cl_user
18443
18444         changelog_register || error "changelog_register failed"
18445         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18446
18447         changelog_users $SINGLEMDS | grep -q $cl_user ||
18448                 error "User '$cl_user' not found in changelog_users"
18449
18450         # Clear some types so that MTIME changelogs are generated
18451         changelog_chmask "-CREAT"
18452         changelog_chmask "-CLOSE"
18453
18454         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
18455
18456         # Test CL_MTIME during setattr
18457         touch $DIR/$tdir/$tfile
18458         compare_mtime_changelog $DIR/$tdir/$tfile
18459
18460         # Test CL_MTIME during close
18461         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
18462         compare_mtime_changelog $DIR/$tdir/${tfile}_2
18463 }
18464 run_test 160l "Verify that MTIME changelog records contain the parent FID"
18465
18466 test_160m() {
18467         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18468         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18469                 skip "Need MDS version at least 2.14.51"
18470         local cl_users
18471         local cl_user1
18472         local cl_user2
18473         local pid1
18474
18475         # Create a user
18476         changelog_register || error "first changelog_register failed"
18477         changelog_register || error "second changelog_register failed"
18478
18479         cl_users=(${CL_USERS[mds1]})
18480         cl_user1="${cl_users[0]}"
18481         cl_user2="${cl_users[1]}"
18482         # generate some changelog records to accumulate on MDT0
18483         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18484         createmany -m $DIR/$tdir/$tfile 50 ||
18485                 error "create $DIR/$tdir/$tfile failed"
18486         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18487         rm -f $DIR/$tdir
18488
18489         # check changelogs have been generated
18490         local nbcl=$(changelog_dump | wc -l)
18491         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18492
18493 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
18494         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
18495
18496         __changelog_clear mds1 $cl_user1 +10
18497         __changelog_clear mds1 $cl_user2 0 &
18498         pid1=$!
18499         sleep 2
18500         __changelog_clear mds1 $cl_user1 0 ||
18501                 error "fail to cancel record for $cl_user1"
18502         wait $pid1
18503         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
18504 }
18505 run_test 160m "Changelog clear race"
18506
18507 test_160n() {
18508         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18509         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18510                 skip "Need MDS version at least 2.14.51"
18511         local cl_users
18512         local cl_user1
18513         local cl_user2
18514         local pid1
18515         local first_rec
18516         local last_rec=0
18517
18518         # Create a user
18519         changelog_register || error "first changelog_register failed"
18520
18521         cl_users=(${CL_USERS[mds1]})
18522         cl_user1="${cl_users[0]}"
18523
18524         # generate some changelog records to accumulate on MDT0
18525         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18526         first_rec=$(changelog_users $SINGLEMDS |
18527                         awk '/^current.index:/ { print $NF }')
18528         while (( last_rec < (( first_rec + 65000)) )); do
18529                 createmany -m $DIR/$tdir/$tfile 10000 ||
18530                         error "create $DIR/$tdir/$tfile failed"
18531
18532                 for i in $(seq 0 10000); do
18533                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
18534                                 > /dev/null
18535                 done
18536
18537                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
18538                         error "unlinkmany failed unlink"
18539                 last_rec=$(changelog_users $SINGLEMDS |
18540                         awk '/^current.index:/ { print $NF }')
18541                 echo last record $last_rec
18542                 (( last_rec == 0 )) && error "no changelog found"
18543         done
18544
18545 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
18546         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
18547
18548         __changelog_clear mds1 $cl_user1 0 &
18549         pid1=$!
18550         sleep 2
18551         __changelog_clear mds1 $cl_user1 0 ||
18552                 error "fail to cancel record for $cl_user1"
18553         wait $pid1
18554         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
18555 }
18556 run_test 160n "Changelog destroy race"
18557
18558 test_160o() {
18559         local mdt="$(facet_svc $SINGLEMDS)"
18560
18561         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18562         remote_mds_nodsh && skip "remote MDS with nodsh"
18563         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
18564                 skip "Need MDS version at least 2.14.52"
18565
18566         changelog_register --user test_160o -m unlnk+close+open ||
18567                 error "changelog_register failed"
18568
18569         do_facet $SINGLEMDS $LCTL --device $mdt \
18570                                 changelog_register -u "Tt3_-#" &&
18571                 error "bad symbols in name should fail"
18572
18573         do_facet $SINGLEMDS $LCTL --device $mdt \
18574                                 changelog_register -u test_160o &&
18575                 error "the same name registration should fail"
18576
18577         do_facet $SINGLEMDS $LCTL --device $mdt \
18578                         changelog_register -u test_160toolongname &&
18579                 error "too long name registration should fail"
18580
18581         changelog_chmask "MARK+HSM"
18582         lctl get_param mdd.*.changelog*mask
18583         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18584         changelog_users $SINGLEMDS | grep -q $cl_user ||
18585                 error "User $cl_user not found in changelog_users"
18586         #verify username
18587         echo $cl_user | grep -q test_160o ||
18588                 error "User $cl_user has no specific name 'test160o'"
18589
18590         # change something
18591         changelog_clear 0 || error "changelog_clear failed"
18592         # generate some changelog records to accumulate on MDT0
18593         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18594         touch $DIR/$tdir/$tfile                 # open 1
18595
18596         OPENS=$(changelog_dump | grep -c "OPEN")
18597         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
18598
18599         # must be no MKDIR it wasn't set as user mask
18600         MKDIR=$(changelog_dump | grep -c "MKDIR")
18601         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
18602
18603         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
18604                                 mdd.$mdt.changelog_current_mask -n)
18605         # register maskless user
18606         changelog_register || error "changelog_register failed"
18607         # effective mask should be not changed because it is not minimal
18608         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18609                                 mdd.$mdt.changelog_current_mask -n)
18610         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
18611         # set server mask to minimal value
18612         changelog_chmask "MARK"
18613         # check effective mask again, should be treated as DEFMASK now
18614         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18615                                 mdd.$mdt.changelog_current_mask -n)
18616         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18617
18618         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
18619                 # set server mask back to some value
18620                 changelog_chmask "CLOSE,UNLNK"
18621                 # check effective mask again, should not remain as DEFMASK
18622                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
18623                                 mdd.$mdt.changelog_current_mask -n)
18624                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
18625         fi
18626
18627         do_facet $SINGLEMDS $LCTL --device $mdt \
18628                                 changelog_deregister -u test_160o ||
18629                 error "cannot deregister by name"
18630 }
18631 run_test 160o "changelog user name and mask"
18632
18633 test_160p() {
18634         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18635         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18636                 skip "Need MDS version at least 2.14.51"
18637         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
18638         local cl_users
18639         local cl_user1
18640         local entry_count
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         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18649         createmany -m $DIR/$tdir/$tfile 50 ||
18650                 error "create $DIR/$tdir/$tfile failed"
18651         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18652         rm -rf $DIR/$tdir
18653
18654         # check changelogs have been generated
18655         entry_count=$(changelog_dump | wc -l)
18656         ((entry_count != 0)) || error "no changelog entries found"
18657
18658         # remove changelog_users and check that orphan entries are removed
18659         stop mds1
18660         local dev=$(mdsdevname 1)
18661         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
18662         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
18663         entry_count=$(changelog_dump | wc -l)
18664         ((entry_count == 0)) ||
18665                 error "found $entry_count changelog entries, expected none"
18666 }
18667 run_test 160p "Changelog orphan cleanup with no users"
18668
18669 test_160q() {
18670         local mdt="$(facet_svc $SINGLEMDS)"
18671         local clu
18672
18673         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18674         remote_mds_nodsh && skip "remote MDS with nodsh"
18675         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
18676                 skip "Need MDS version at least 2.14.54"
18677
18678         # set server mask to minimal value like server init does
18679         changelog_chmask "MARK"
18680         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
18681                 error "changelog_register failed"
18682         # check effective mask again, should be treated as DEFMASK now
18683         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18684                                 mdd.$mdt.changelog_current_mask -n)
18685         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
18686                 error "changelog_deregister failed"
18687         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18688 }
18689 run_test 160q "changelog effective mask is DEFMASK if not set"
18690
18691 test_160s() {
18692         remote_mds_nodsh && skip "remote MDS with nodsh"
18693         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
18694                 skip "Need MDS version at least 2.14.55"
18695
18696         local mdts=$(comma_list $(mdts_nodes))
18697
18698         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
18699         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
18700                                        fail_val=$((24 * 3600 * 10))
18701
18702         # Create a user which is 10 days old
18703         changelog_register || error "first changelog_register failed"
18704         local cl_users
18705         declare -A cl_user1
18706         local i
18707
18708         # generate some changelog records to accumulate on each MDT
18709         # use all_char because created files should be evenly distributed
18710         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18711                 error "test_mkdir $tdir failed"
18712         for ((i = 0; i < MDSCOUNT; i++)); do
18713                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18714                         error "create $DIR/$tdir/d$i.1 failed"
18715         done
18716
18717         # check changelogs have been generated
18718         local nbcl=$(changelog_dump | wc -l)
18719         (( nbcl > 0 )) || error "no changelogs found"
18720
18721         # reduce the max_idle_indexes value to make sure we exceed it
18722         for param in "changelog_max_idle_indexes=2097446912" \
18723                      "changelog_max_idle_time=2592000" \
18724                      "changelog_gc=1" \
18725                      "changelog_min_gc_interval=2"; do
18726                 local MDT0=$(facet_svc $SINGLEMDS)
18727                 local var="${param%=*}"
18728                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18729
18730                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18731                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
18732                         error "unable to set mdd.*.$param"
18733         done
18734
18735         local start=$SECONDS
18736         for i in $(seq $MDSCOUNT); do
18737                 cl_users=(${CL_USERS[mds$i]})
18738                 cl_user1[mds$i]="${cl_users[0]}"
18739
18740                 [[ -n "${cl_user1[mds$i]}" ]] ||
18741                         error "mds$i: no user registered"
18742         done
18743
18744         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
18745         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
18746
18747         # ensure we are past the previous changelog_min_gc_interval set above
18748         local sleep2=$((start + 2 - SECONDS))
18749         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18750
18751         # Generate one more changelog to trigger GC
18752         for ((i = 0; i < MDSCOUNT; i++)); do
18753                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
18754                         error "create $DIR/$tdir/d$i.3 failed"
18755         done
18756
18757         # ensure gc thread is done
18758         for node in $(mdts_nodes); do
18759                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
18760                         error "$node: GC-thread not done"
18761         done
18762
18763         do_nodes $mdts $LCTL set_param fail_loc=0
18764
18765         for (( i = 1; i <= MDSCOUNT; i++ )); do
18766                 # check cl_user1 is purged
18767                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
18768                         error "mds$i: User ${cl_user1[mds$i]} is registered"
18769         done
18770         return 0
18771 }
18772 run_test 160s "changelog garbage collect on idle records * time"
18773
18774 test_160t() {
18775         remote_mds_nodsh && skip "remote MDS with nodsh"
18776         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
18777                 skip "Need MDS version at least 2.15.50"
18778
18779         local MDT0=$(facet_svc $SINGLEMDS)
18780         local cl_users
18781         local cl_user1
18782         local cl_user2
18783         local start
18784
18785         changelog_register --user user1 -m all ||
18786                 error "user1 failed to register"
18787
18788         mkdir_on_mdt0 $DIR/$tdir
18789         # create default overstripe to maximize changelog size
18790         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
18791         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
18792         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18793
18794         # user2 consumes less records so less space
18795         changelog_register --user user2 || error "user2 failed to register"
18796         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
18797         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18798
18799         # check changelogs have been generated
18800         local nbcl=$(changelog_dump | wc -l)
18801         (( nbcl > 0 )) || error "no changelogs found"
18802
18803         # reduce the changelog_min_gc_interval to force check
18804         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
18805                 local var="${param%=*}"
18806                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18807
18808                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
18809                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
18810                         error "unable to set mdd.*.$param"
18811         done
18812
18813         start=$SECONDS
18814         cl_users=(${CL_USERS[mds1]})
18815         cl_user1="${cl_users[0]}"
18816         cl_user2="${cl_users[1]}"
18817
18818         [[ -n $cl_user1 ]] ||
18819                 error "mds1: user #1 isn't registered"
18820         [[ -n $cl_user2 ]] ||
18821                 error "mds1: user #2 isn't registered"
18822
18823         # ensure we are past the previous changelog_min_gc_interval set above
18824         local sleep2=$((start + 2 - SECONDS))
18825         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18826
18827         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
18828         do_facet mds1 $LCTL set_param fail_loc=0x018c \
18829                         fail_val=$(((llog_size1 + llog_size2) / 2))
18830
18831         # Generate more changelog to trigger GC
18832         createmany -o $DIR/$tdir/u3_ 4 ||
18833                 error "create failed for more files"
18834
18835         # ensure gc thread is done
18836         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
18837                 error "mds1: GC-thread not done"
18838
18839         do_facet mds1 $LCTL set_param fail_loc=0
18840
18841         # check cl_user1 is purged
18842         changelog_users mds1 | grep -q "$cl_user1" &&
18843                 error "User $cl_user1 is registered"
18844         # check cl_user2 is not purged
18845         changelog_users mds1 | grep -q "$cl_user2" ||
18846                 error "User $cl_user2 is not registered"
18847 }
18848 run_test 160t "changelog garbage collect on lack of space"
18849
18850 test_160u() { # LU-17400
18851         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18852         remote_mds_nodsh && skip "remote MDS with nodsh"
18853         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
18854                 skip "Need MDS version at least 2.2.0"
18855
18856         cd $DIR || error "cd $DIR failed"
18857
18858         # ensure changelog has a clean view if tests are run multiple times
18859         [ -d rename ] && rm -rf rename
18860
18861         changelog_register || error "changelog_register failed"
18862         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18863
18864         changelog_users $SINGLEMDS | grep -q $cl_user ||
18865                 error "User '$cl_user' not found in changelog_users"
18866
18867         local longname1=$(str_repeat a 255)
18868
18869         echo "creating simple directory tree"
18870         mkdir -p rename/a || error "create of simple directory tree failed"
18871         echo "creating rename/hw file"
18872         echo "hello world" > rename/hw || error "create of rename/hw failed"
18873         echo "creating very long named file"
18874         touch rename/$longname1 || error "create of 'rename/$longname1' failed"
18875         echo "move rename/hw to rename/a/a.hw"
18876         mv rename/hw rename/a/a.hw || error "mv failed"
18877
18878         RENME=($(changelog_dump | grep "RENME"))
18879         #declare -p RENME # for debugging captured value with indexes
18880
18881         [[ "${RENME[11]}" == "a.hw" && "${RENME[14]}" == "hw" ]] ||
18882                 error "changelog rename record type name/sname error"
18883 }
18884 run_test 160u "changelog rename record type name and sname strings are correct"
18885
18886 test_161a() {
18887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18888
18889         test_mkdir -c1 $DIR/$tdir
18890         cp /etc/hosts $DIR/$tdir/$tfile
18891         test_mkdir -c1 $DIR/$tdir/foo1
18892         test_mkdir -c1 $DIR/$tdir/foo2
18893         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
18894         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
18895         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
18896         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
18897         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
18898         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18899                 $LFS fid2path $DIR $FID
18900                 error "bad link ea"
18901         fi
18902         # middle
18903         rm $DIR/$tdir/foo2/zachary
18904         # last
18905         rm $DIR/$tdir/foo2/thor
18906         # first
18907         rm $DIR/$tdir/$tfile
18908         # rename
18909         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
18910         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
18911                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
18912         rm $DIR/$tdir/foo2/maggie
18913
18914         # overflow the EA
18915         local longname=$tfile.avg_len_is_thirty_two_
18916         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
18917                 error_noexit 'failed to unlink many hardlinks'" EXIT
18918         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
18919                 error "failed to hardlink many files"
18920         links=$($LFS fid2path $DIR $FID | wc -l)
18921         echo -n "${links}/1000 links in link EA"
18922         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
18923 }
18924 run_test 161a "link ea sanity"
18925
18926 test_161b() {
18927         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18928         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
18929
18930         local MDTIDX=1
18931         local remote_dir=$DIR/$tdir/remote_dir
18932
18933         mkdir -p $DIR/$tdir
18934         $LFS mkdir -i $MDTIDX $remote_dir ||
18935                 error "create remote directory failed"
18936
18937         cp /etc/hosts $remote_dir/$tfile
18938         mkdir -p $remote_dir/foo1
18939         mkdir -p $remote_dir/foo2
18940         ln $remote_dir/$tfile $remote_dir/foo1/sofia
18941         ln $remote_dir/$tfile $remote_dir/foo2/zachary
18942         ln $remote_dir/$tfile $remote_dir/foo1/luna
18943         ln $remote_dir/$tfile $remote_dir/foo2/thor
18944
18945         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
18946                      tr -d ']')
18947         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18948                 $LFS fid2path $DIR $FID
18949                 error "bad link ea"
18950         fi
18951         # middle
18952         rm $remote_dir/foo2/zachary
18953         # last
18954         rm $remote_dir/foo2/thor
18955         # first
18956         rm $remote_dir/$tfile
18957         # rename
18958         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
18959         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
18960         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
18961                 $LFS fid2path $DIR $FID
18962                 error "bad link rename"
18963         fi
18964         rm $remote_dir/foo2/maggie
18965
18966         # overflow the EA
18967         local longname=filename_avg_len_is_thirty_two_
18968         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
18969                 error "failed to hardlink many files"
18970         links=$($LFS fid2path $DIR $FID | wc -l)
18971         echo -n "${links}/1000 links in link EA"
18972         [[ ${links} -gt 60 ]] ||
18973                 error "expected at least 60 links in link EA"
18974         unlinkmany $remote_dir/foo2/$longname 1000 ||
18975         error "failed to unlink many hardlinks"
18976 }
18977 run_test 161b "link ea sanity under remote directory"
18978
18979 test_161c() {
18980         remote_mds_nodsh && skip "remote MDS with nodsh"
18981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18982         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
18983                 skip "Need MDS version at least 2.1.5"
18984
18985         # define CLF_RENAME_LAST 0x0001
18986         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
18987         changelog_register || error "changelog_register failed"
18988
18989         rm -rf $DIR/$tdir
18990         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
18991         touch $DIR/$tdir/foo_161c
18992         touch $DIR/$tdir/bar_161c
18993         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18994         changelog_dump | grep RENME | tail -n 5
18995         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18996         changelog_clear 0 || error "changelog_clear failed"
18997         if [ x$flags != "x0x1" ]; then
18998                 error "flag $flags is not 0x1"
18999         fi
19000
19001         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
19002         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
19003         touch $DIR/$tdir/foo_161c
19004         touch $DIR/$tdir/bar_161c
19005         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
19006         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
19007         changelog_dump | grep RENME | tail -n 5
19008         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
19009         changelog_clear 0 || error "changelog_clear failed"
19010         if [ x$flags != "x0x0" ]; then
19011                 error "flag $flags is not 0x0"
19012         fi
19013         echo "rename overwrite a target having nlink > 1," \
19014                 "changelog record has flags of $flags"
19015
19016         # rename doesn't overwrite a target (changelog flag 0x0)
19017         touch $DIR/$tdir/foo_161c
19018         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
19019         changelog_dump | grep RENME | tail -n 5
19020         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
19021         changelog_clear 0 || error "changelog_clear failed"
19022         if [ x$flags != "x0x0" ]; then
19023                 error "flag $flags is not 0x0"
19024         fi
19025         echo "rename doesn't overwrite a target," \
19026                 "changelog record has flags of $flags"
19027
19028         # define CLF_UNLINK_LAST 0x0001
19029         # unlink a file having nlink = 1 (changelog flag 0x1)
19030         rm -f $DIR/$tdir/foo2_161c
19031         changelog_dump | grep UNLNK | tail -n 5
19032         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
19033         changelog_clear 0 || error "changelog_clear failed"
19034         if [ x$flags != "x0x1" ]; then
19035                 error "flag $flags is not 0x1"
19036         fi
19037         echo "unlink a file having nlink = 1," \
19038                 "changelog record has flags of $flags"
19039
19040         # unlink a file having nlink > 1 (changelog flag 0x0)
19041         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
19042         rm -f $DIR/$tdir/foobar_161c
19043         changelog_dump | grep UNLNK | tail -n 5
19044         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
19045         changelog_clear 0 || error "changelog_clear failed"
19046         if [ x$flags != "x0x0" ]; then
19047                 error "flag $flags is not 0x0"
19048         fi
19049         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
19050 }
19051 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
19052
19053 test_161d() {
19054         remote_mds_nodsh && skip "remote MDS with nodsh"
19055         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
19056
19057         local pid
19058         local fid
19059
19060         changelog_register || error "changelog_register failed"
19061
19062         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
19063         # interfer with $MOUNT/.lustre/fid/ access
19064         mkdir $DIR/$tdir
19065         [[ $? -eq 0 ]] || error "mkdir failed"
19066
19067         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | CFS_FAIL_ONCE
19068         $LCTL set_param fail_loc=0x8000140c
19069         # 5s pause
19070         $LCTL set_param fail_val=5
19071
19072         # create file
19073         echo foofoo > $DIR/$tdir/$tfile &
19074         pid=$!
19075
19076         # wait for create to be delayed
19077         sleep 2
19078
19079         ps -p $pid
19080         [[ $? -eq 0 ]] || error "create should be blocked"
19081
19082         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
19083         stack_trap "rm -f $tempfile"
19084         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
19085         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
19086         # some delay may occur during ChangeLog publishing and file read just
19087         # above, that could allow file write to happen finally
19088         [[ -s $tempfile ]] && echo "file should be empty"
19089
19090         $LCTL set_param fail_loc=0
19091
19092         wait $pid
19093         [[ $? -eq 0 ]] || error "create failed"
19094 }
19095 run_test 161d "create with concurrent .lustre/fid access"
19096
19097 check_path() {
19098         local expected="$1"
19099         shift
19100         local fid="$2"
19101
19102         local path
19103         path=$($LFS fid2path "$@")
19104         local rc=$?
19105
19106         if [ $rc -ne 0 ]; then
19107                 error "path looked up of '$expected' failed: rc=$rc"
19108         elif [ "$path" != "$expected" ]; then
19109                 error "path looked up '$path' instead of '$expected'"
19110         else
19111                 echo "FID '$fid' resolves to path '$path' as expected"
19112         fi
19113 }
19114
19115 test_162a() { # was test_162
19116         test_mkdir -p -c1 $DIR/$tdir/d2
19117         touch $DIR/$tdir/d2/$tfile
19118         touch $DIR/$tdir/d2/x1
19119         touch $DIR/$tdir/d2/x2
19120         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
19121         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
19122         # regular file
19123         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
19124         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
19125
19126         # softlink
19127         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
19128         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
19129         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
19130
19131         # softlink to wrong file
19132         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
19133         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
19134         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
19135
19136         # hardlink
19137         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
19138         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
19139         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
19140         # fid2path dir/fsname should both work
19141         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
19142         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
19143
19144         # hardlink count: check that there are 2 links
19145         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
19146         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
19147
19148         # hardlink indexing: remove the first link
19149         rm $DIR/$tdir/d2/p/q/r/hlink
19150         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
19151 }
19152 run_test 162a "path lookup sanity"
19153
19154 test_162b() {
19155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19156         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19157
19158         mkdir $DIR/$tdir
19159         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19160                                 error "create striped dir failed"
19161
19162         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
19163                                         tail -n 1 | awk '{print $2}')
19164         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
19165
19166         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
19167         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
19168
19169         # regular file
19170         for ((i=0;i<5;i++)); do
19171                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
19172                         error "get fid for f$i failed"
19173                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
19174
19175                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
19176                         error "get fid for d$i failed"
19177                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
19178         done
19179
19180         return 0
19181 }
19182 run_test 162b "striped directory path lookup sanity"
19183
19184 # LU-4239: Verify fid2path works with paths 100 or more directories deep
19185 test_162c() {
19186         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
19187                 skip "Need MDS version at least 2.7.51"
19188
19189         local lpath=$tdir.local
19190         local rpath=$tdir.remote
19191
19192         test_mkdir $DIR/$lpath
19193         test_mkdir $DIR/$rpath
19194
19195         for ((i = 0; i <= 101; i++)); do
19196                 lpath="$lpath/$i"
19197                 mkdir $DIR/$lpath
19198                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
19199                         error "get fid for local directory $DIR/$lpath failed"
19200                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
19201
19202                 rpath="$rpath/$i"
19203                 test_mkdir $DIR/$rpath
19204                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
19205                         error "get fid for remote directory $DIR/$rpath failed"
19206                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
19207         done
19208
19209         return 0
19210 }
19211 run_test 162c "fid2path works with paths 100 or more directories deep"
19212
19213 oalr_event_count() {
19214         local event="${1}"
19215         local trace="${2}"
19216
19217         awk -v name="${FSNAME}-OST0000" \
19218             -v event="${event}" \
19219             '$1 == "TRACE" && $2 == event && $3 == name' \
19220             "${trace}" |
19221         wc -l
19222 }
19223
19224 oalr_expect_event_count() {
19225         local event="${1}"
19226         local trace="${2}"
19227         local expect="${3}"
19228         local count
19229
19230         count=$(oalr_event_count "${event}" "${trace}")
19231         if ((count == expect)); then
19232                 return 0
19233         fi
19234
19235         error_noexit "${event} event count was '${count}', expected ${expect}"
19236         cat "${trace}" >&2
19237         exit 1
19238 }
19239
19240 cleanup_165() {
19241         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
19242         stop ost1
19243         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
19244 }
19245
19246 setup_165() {
19247         sync # Flush previous IOs so we can count log entries.
19248         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
19249         stack_trap cleanup_165 EXIT
19250 }
19251
19252 test_165a() {
19253         local trace="/tmp/${tfile}.trace"
19254         local rc
19255         local count
19256
19257         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19258                 skip "OFD access log unsupported"
19259
19260         setup_165
19261         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19262         sleep 5
19263
19264         do_facet ost1 ofd_access_log_reader --list
19265         stop ost1
19266
19267         do_facet ost1 killall -TERM ofd_access_log_reader
19268         wait
19269         rc=$?
19270
19271         if ((rc != 0)); then
19272                 error "ofd_access_log_reader exited with rc = '${rc}'"
19273         fi
19274
19275         # Parse trace file for discovery events:
19276         oalr_expect_event_count alr_log_add "${trace}" 1
19277         oalr_expect_event_count alr_log_eof "${trace}" 1
19278         oalr_expect_event_count alr_log_free "${trace}" 1
19279 }
19280 run_test 165a "ofd access log discovery"
19281
19282 test_165b() {
19283         local trace="/tmp/${tfile}.trace"
19284         local file="${DIR}/${tfile}"
19285         local pfid1
19286         local pfid2
19287         local -a entry
19288         local rc
19289         local count
19290         local size
19291         local flags
19292
19293         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19294                 skip "OFD access log unsupported"
19295
19296         setup_165
19297         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19298         sleep 5
19299
19300         do_facet ost1 ofd_access_log_reader --list
19301
19302         lfs setstripe -c 1 -i 0 "${file}"
19303         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19304                 error "cannot create '${file}'"
19305
19306         sleep 5
19307         do_facet ost1 killall -TERM ofd_access_log_reader
19308         wait
19309         rc=$?
19310
19311         if ((rc != 0)); then
19312                 error "ofd_access_log_reader exited with rc = '${rc}'"
19313         fi
19314
19315         oalr_expect_event_count alr_log_entry "${trace}" 1
19316
19317         pfid1=$($LFS path2fid "${file}")
19318
19319         # 1     2             3   4    5     6   7    8    9     10
19320         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
19321         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
19322
19323         echo "entry = '${entry[*]}'" >&2
19324
19325         pfid2=${entry[4]}
19326         if [[ "${pfid1}" != "${pfid2}" ]]; then
19327                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
19328         fi
19329
19330         size=${entry[8]}
19331         if ((size != 1048576)); then
19332                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
19333         fi
19334
19335         flags=${entry[10]}
19336         if [[ "${flags}" != "w" ]]; then
19337                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
19338         fi
19339
19340         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19341         sleep 5
19342
19343         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
19344                 error "cannot read '${file}'"
19345         sleep 5
19346
19347         do_facet ost1 killall -TERM ofd_access_log_reader
19348         wait
19349         rc=$?
19350
19351         if ((rc != 0)); then
19352                 error "ofd_access_log_reader exited with rc = '${rc}'"
19353         fi
19354
19355         oalr_expect_event_count alr_log_entry "${trace}" 1
19356
19357         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
19358         echo "entry = '${entry[*]}'" >&2
19359
19360         pfid2=${entry[4]}
19361         if [[ "${pfid1}" != "${pfid2}" ]]; then
19362                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
19363         fi
19364
19365         size=${entry[8]}
19366         if ((size != 524288)); then
19367                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
19368         fi
19369
19370         flags=${entry[10]}
19371         if [[ "${flags}" != "r" ]]; then
19372                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
19373         fi
19374 }
19375 run_test 165b "ofd access log entries are produced and consumed"
19376
19377 test_165c() {
19378         local trace="/tmp/${tfile}.trace"
19379         local file="${DIR}/${tdir}/${tfile}"
19380
19381         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19382                 skip "OFD access log unsupported"
19383
19384         test_mkdir "${DIR}/${tdir}"
19385
19386         setup_165
19387         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19388         sleep 5
19389
19390         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
19391
19392         # 4096 / 64 = 64. Create twice as many entries.
19393         for ((i = 0; i < 128; i++)); do
19394                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
19395                         error "cannot create file"
19396         done
19397
19398         sync
19399
19400         do_facet ost1 killall -TERM ofd_access_log_reader
19401         wait
19402         rc=$?
19403         if ((rc != 0)); then
19404                 error "ofd_access_log_reader exited with rc = '${rc}'"
19405         fi
19406
19407         unlinkmany  "${file}-%d" 128
19408 }
19409 run_test 165c "full ofd access logs do not block IOs"
19410
19411 oal_get_read_count() {
19412         local stats="$1"
19413
19414         # STATS lustre-OST0001 alr_read_count 1
19415
19416         do_facet ost1 cat "${stats}" |
19417         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
19418              END { print count; }'
19419 }
19420
19421 oal_expect_read_count() {
19422         local stats="$1"
19423         local count
19424         local expect="$2"
19425
19426         # Ask ofd_access_log_reader to write stats.
19427         do_facet ost1 killall -USR1 ofd_access_log_reader
19428
19429         # Allow some time for things to happen.
19430         sleep 1
19431
19432         count=$(oal_get_read_count "${stats}")
19433         if ((count == expect)); then
19434                 return 0
19435         fi
19436
19437         error_noexit "bad read count, got ${count}, expected ${expect}"
19438         do_facet ost1 cat "${stats}" >&2
19439         exit 1
19440 }
19441
19442 test_165d() {
19443         local stats="/tmp/${tfile}.stats"
19444         local file="${DIR}/${tdir}/${tfile}"
19445         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
19446
19447         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19448                 skip "OFD access log unsupported"
19449
19450         test_mkdir "${DIR}/${tdir}"
19451
19452         setup_165
19453         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
19454         sleep 5
19455
19456         lfs setstripe -c 1 -i 0 "${file}"
19457
19458         do_facet ost1 lctl set_param "${param}=rw"
19459         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19460                 error "cannot create '${file}'"
19461         oal_expect_read_count "${stats}" 1
19462
19463         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19464                 error "cannot read '${file}'"
19465         oal_expect_read_count "${stats}" 2
19466
19467         do_facet ost1 lctl set_param "${param}=r"
19468         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19469                 error "cannot create '${file}'"
19470         oal_expect_read_count "${stats}" 2
19471
19472         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19473                 error "cannot read '${file}'"
19474         oal_expect_read_count "${stats}" 3
19475
19476         do_facet ost1 lctl set_param "${param}=w"
19477         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19478                 error "cannot create '${file}'"
19479         oal_expect_read_count "${stats}" 4
19480
19481         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19482                 error "cannot read '${file}'"
19483         oal_expect_read_count "${stats}" 4
19484
19485         do_facet ost1 lctl set_param "${param}=0"
19486         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19487                 error "cannot create '${file}'"
19488         oal_expect_read_count "${stats}" 4
19489
19490         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19491                 error "cannot read '${file}'"
19492         oal_expect_read_count "${stats}" 4
19493
19494         do_facet ost1 killall -TERM ofd_access_log_reader
19495         wait
19496         rc=$?
19497         if ((rc != 0)); then
19498                 error "ofd_access_log_reader exited with rc = '${rc}'"
19499         fi
19500 }
19501 run_test 165d "ofd_access_log mask works"
19502
19503 test_165e() {
19504         local stats="/tmp/${tfile}.stats"
19505         local file0="${DIR}/${tdir}-0/${tfile}"
19506         local file1="${DIR}/${tdir}-1/${tfile}"
19507
19508         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19509                 skip "OFD access log unsupported"
19510
19511         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
19512
19513         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
19514         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
19515
19516         lfs setstripe -c 1 -i 0 "${file0}"
19517         lfs setstripe -c 1 -i 0 "${file1}"
19518
19519         setup_165
19520         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
19521         sleep 5
19522
19523         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
19524                 error "cannot create '${file0}'"
19525         sync
19526         oal_expect_read_count "${stats}" 0
19527
19528         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
19529                 error "cannot create '${file1}'"
19530         sync
19531         oal_expect_read_count "${stats}" 1
19532
19533         do_facet ost1 killall -TERM ofd_access_log_reader
19534         wait
19535         rc=$?
19536         if ((rc != 0)); then
19537                 error "ofd_access_log_reader exited with rc = '${rc}'"
19538         fi
19539 }
19540 run_test 165e "ofd_access_log MDT index filter works"
19541
19542 test_165f() {
19543         local trace="/tmp/${tfile}.trace"
19544         local rc
19545         local count
19546
19547         setup_165
19548         do_facet ost1 timeout 60 ofd_access_log_reader \
19549                 --exit-on-close --debug=- --trace=- > "${trace}" &
19550         sleep 5
19551         stop ost1
19552
19553         wait
19554         rc=$?
19555
19556         if ((rc != 0)); then
19557                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
19558                 cat "${trace}"
19559                 exit 1
19560         fi
19561 }
19562 run_test 165f "ofd_access_log_reader --exit-on-close works"
19563
19564 test_169() {
19565         # do directio so as not to populate the page cache
19566         log "creating a 10 Mb file"
19567         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
19568                 error "multiop failed while creating a file"
19569         log "starting reads"
19570         dd if=$DIR/$tfile of=/dev/null bs=4096 &
19571         log "truncating the file"
19572         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
19573                 error "multiop failed while truncating the file"
19574         log "killing dd"
19575         kill %+ || true # reads might have finished
19576         echo "wait until dd is finished"
19577         wait
19578         log "removing the temporary file"
19579         rm -rf $DIR/$tfile || error "tmp file removal failed"
19580 }
19581 run_test 169 "parallel read and truncate should not deadlock"
19582
19583 test_170() {
19584         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19585
19586         $LCTL clear     # bug 18514
19587         $LCTL debug_daemon start $TMP/${tfile}_log_good
19588         touch $DIR/$tfile
19589         $LCTL debug_daemon stop
19590         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
19591                 error "sed failed to read log_good"
19592
19593         $LCTL debug_daemon start $TMP/${tfile}_log_good
19594         rm -rf $DIR/$tfile
19595         $LCTL debug_daemon stop
19596
19597         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
19598                error "lctl df log_bad failed"
19599
19600         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19601         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19602
19603         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
19604         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
19605
19606         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
19607                 error "bad_line good_line1 good_line2 are empty"
19608
19609         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19610         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
19611         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19612
19613         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
19614         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19615         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19616
19617         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
19618                 error "bad_line_new good_line_new are empty"
19619
19620         local expected_good=$((good_line1 + good_line2*2))
19621
19622         rm -f $TMP/${tfile}*
19623         # LU-231, short malformed line may not be counted into bad lines
19624         if [ $bad_line -ne $bad_line_new ] &&
19625                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
19626                 error "expected $bad_line bad lines, but got $bad_line_new"
19627                 return 1
19628         fi
19629
19630         if [ $expected_good -ne $good_line_new ]; then
19631                 error "expected $expected_good good lines, but got $good_line_new"
19632                 return 2
19633         fi
19634         true
19635 }
19636 run_test 170 "test lctl df to handle corrupted log ====================="
19637
19638 test_171() { # bug20592
19639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19640
19641         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
19642         $LCTL set_param fail_loc=0x50e
19643         $LCTL set_param fail_val=3000
19644         multiop_bg_pause $DIR/$tfile O_s || true
19645         local MULTIPID=$!
19646         kill -USR1 $MULTIPID
19647         # cause log dump
19648         sleep 3
19649         wait $MULTIPID
19650         if dmesg | grep "recursive fault"; then
19651                 error "caught a recursive fault"
19652         fi
19653         $LCTL set_param fail_loc=0
19654         true
19655 }
19656 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
19657
19658 test_172() {
19659
19660         #define OBD_FAIL_OBD_CLEANUP  0x60e
19661         $LCTL set_param fail_loc=0x60e
19662         umount $MOUNT || error "umount $MOUNT failed"
19663         stack_trap "mount_client $MOUNT"
19664
19665         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
19666                 error "no client OBDs are remained"
19667
19668         $LCTL dl | while read devno state type name foo; do
19669                 case $type in
19670                 lov|osc|lmv|mdc)
19671                         $LCTL --device $name cleanup
19672                         $LCTL --device $name detach
19673                         ;;
19674                 *)
19675                         # skip server devices
19676                         ;;
19677                 esac
19678         done
19679
19680         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
19681                 $LCTL dl | egrep " osc | lov | lmv | mdc "
19682                 error "some client OBDs are still remained"
19683         fi
19684
19685 }
19686 run_test 172 "manual device removal with lctl cleanup/detach ======"
19687
19688 # it would be good to share it with obdfilter-survey/iokit-libecho code
19689 setup_obdecho_osc () {
19690         local rc=0
19691         local ost_nid=$1
19692         local obdfilter_name=$2
19693         echo "Creating new osc for $obdfilter_name on $ost_nid"
19694         # make sure we can find loopback nid
19695         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
19696
19697         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
19698                            ${obdfilter_name}_osc_UUID || rc=2; }
19699         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
19700                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
19701         return $rc
19702 }
19703
19704 cleanup_obdecho_osc () {
19705         local obdfilter_name=$1
19706         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
19707         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
19708         return 0
19709 }
19710
19711 obdecho_test() {
19712         local OBD=$1
19713         local node=$2
19714         local pages=${3:-64}
19715         local rc=0
19716         local id
19717
19718         local count=10
19719         local obd_size=$(get_obd_size $node $OBD)
19720         local page_size=$(get_page_size $node)
19721         if [[ -n "$obd_size" ]]; then
19722                 local new_count=$((obd_size / (pages * page_size / 1024)))
19723                 [[ $new_count -ge $count ]] || count=$new_count
19724         fi
19725
19726         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
19727         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
19728                            rc=2; }
19729         if [ $rc -eq 0 ]; then
19730             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
19731             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
19732         fi
19733         echo "New object id is $id"
19734         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
19735                            rc=4; }
19736         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
19737                            "test_brw $count w v $pages $id" || rc=4; }
19738         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
19739                            rc=4; }
19740         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
19741                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
19742         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
19743                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
19744         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
19745         return $rc
19746 }
19747
19748 test_180a() {
19749         skip "obdecho on osc is no longer supported"
19750 }
19751 run_test 180a "test obdecho on osc"
19752
19753 test_180b() {
19754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19755         remote_ost_nodsh && skip "remote OST with nodsh"
19756
19757         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19758                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19759                 error "failed to load module obdecho"
19760
19761         local target=$(do_facet ost1 $LCTL dl |
19762                        awk '/obdfilter/ { print $4; exit; }')
19763
19764         if [ -n "$target" ]; then
19765                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
19766         else
19767                 do_facet ost1 $LCTL dl
19768                 error "there is no obdfilter target on ost1"
19769         fi
19770 }
19771 run_test 180b "test obdecho directly on obdfilter"
19772
19773 test_180c() { # LU-2598
19774         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19775         remote_ost_nodsh && skip "remote OST with nodsh"
19776         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
19777                 skip "Need MDS version at least 2.4.0"
19778
19779         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19780                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19781                 error "failed to load module obdecho"
19782
19783         local target=$(do_facet ost1 $LCTL dl |
19784                        awk '/obdfilter/ { print $4; exit; }')
19785
19786         if [ -n "$target" ]; then
19787                 local pages=16384 # 64MB bulk I/O RPC size
19788
19789                 obdecho_test "$target" ost1 "$pages" ||
19790                         error "obdecho_test with pages=$pages failed with $?"
19791         else
19792                 do_facet ost1 $LCTL dl
19793                 error "there is no obdfilter target on ost1"
19794         fi
19795 }
19796 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
19797
19798 test_181() { # bug 22177
19799         test_mkdir $DIR/$tdir
19800         # create enough files to index the directory
19801         createmany -o $DIR/$tdir/foobar 4000
19802         # print attributes for debug purpose
19803         lsattr -d .
19804         # open dir
19805         multiop_bg_pause $DIR/$tdir D_Sc || return 1
19806         MULTIPID=$!
19807         # remove the files & current working dir
19808         unlinkmany $DIR/$tdir/foobar 4000
19809         rmdir $DIR/$tdir
19810         kill -USR1 $MULTIPID
19811         wait $MULTIPID
19812         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
19813         return 0
19814 }
19815 run_test 181 "Test open-unlinked dir ========================"
19816
19817 test_182a() {
19818         local fcount=1000
19819         local tcount=10
19820
19821         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19822
19823         $LCTL set_param mdc.*.rpc_stats=clear
19824
19825         for (( i = 0; i < $tcount; i++ )) ; do
19826                 mkdir $DIR/$tdir/$i
19827         done
19828
19829         for (( i = 0; i < $tcount; i++ )) ; do
19830                 createmany -o $DIR/$tdir/$i/f- $fcount &
19831         done
19832         wait
19833
19834         for (( i = 0; i < $tcount; i++ )) ; do
19835                 unlinkmany $DIR/$tdir/$i/f- $fcount &
19836         done
19837         wait
19838
19839         $LCTL get_param mdc.*.rpc_stats
19840
19841         rm -rf $DIR/$tdir
19842 }
19843 run_test 182a "Test parallel modify metadata operations from mdc"
19844
19845 test_182b() {
19846         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19847         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19848         local dcount=1000
19849         local tcount=10
19850         local stime
19851         local etime
19852         local delta
19853
19854         do_facet mds1 $LCTL list_param \
19855                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
19856                 skip "MDS lacks parallel RPC handling"
19857
19858         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19859
19860         rpc_count=$(do_facet mds1 $LCTL get_param -n \
19861                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
19862
19863         stime=$(date +%s)
19864         createmany -i 0 -d $DIR/$tdir/t- $tcount
19865
19866         for (( i = 0; i < $tcount; i++ )) ; do
19867                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19868         done
19869         wait
19870         etime=$(date +%s)
19871         delta=$((etime - stime))
19872         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
19873
19874         stime=$(date +%s)
19875         for (( i = 0; i < $tcount; i++ )) ; do
19876                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
19877         done
19878         wait
19879         etime=$(date +%s)
19880         delta=$((etime - stime))
19881         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
19882
19883         rm -rf $DIR/$tdir
19884
19885         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19886
19887         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
19888
19889         stime=$(date +%s)
19890         createmany -i 0 -d $DIR/$tdir/t- $tcount
19891
19892         for (( i = 0; i < $tcount; i++ )) ; do
19893                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19894         done
19895         wait
19896         etime=$(date +%s)
19897         delta=$((etime - stime))
19898         echo "Time for file creation $delta sec for 1 RPC sent at a time"
19899
19900         stime=$(date +%s)
19901         for (( i = 0; i < $tcount; i++ )) ; do
19902                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
19903         done
19904         wait
19905         etime=$(date +%s)
19906         delta=$((etime - stime))
19907         echo "Time for file removal $delta sec for 1 RPC sent at a time"
19908
19909         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
19910 }
19911 run_test 182b "Test parallel modify metadata operations from osp"
19912
19913 test_183() { # LU-2275
19914         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19915         remote_mds_nodsh && skip "remote MDS with nodsh"
19916         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
19917                 skip "Need MDS version at least 2.3.56"
19918
19919         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19920         echo aaa > $DIR/$tdir/$tfile
19921
19922 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
19923         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
19924
19925         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
19926         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
19927
19928         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19929
19930         # Flush negative dentry cache
19931         touch $DIR/$tdir/$tfile
19932
19933         # We are not checking for any leaked references here, they'll
19934         # become evident next time we do cleanup with module unload.
19935         rm -rf $DIR/$tdir
19936 }
19937 run_test 183 "No crash or request leak in case of strange dispositions ========"
19938
19939 # test suite 184 is for LU-2016, LU-2017
19940 test_184a() {
19941         check_swap_layouts_support
19942
19943         dir0=$DIR/$tdir/$testnum
19944         test_mkdir -p -c1 $dir0
19945         ref1=/etc/passwd
19946         ref2=/etc/group
19947         file1=$dir0/f1
19948         file2=$dir0/f2
19949         $LFS setstripe -c1 $file1
19950         cp $ref1 $file1
19951         $LFS setstripe -c2 $file2
19952         cp $ref2 $file2
19953         gen1=$($LFS getstripe -g $file1)
19954         gen2=$($LFS getstripe -g $file2)
19955
19956         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
19957         gen=$($LFS getstripe -g $file1)
19958         [[ $gen1 != $gen ]] ||
19959                 error "Layout generation on $file1 does not change"
19960         gen=$($LFS getstripe -g $file2)
19961         [[ $gen2 != $gen ]] ||
19962                 error "Layout generation on $file2 does not change"
19963
19964         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
19965         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19966
19967         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
19968 }
19969 run_test 184a "Basic layout swap"
19970
19971 test_184b() {
19972         check_swap_layouts_support
19973
19974         dir0=$DIR/$tdir/$testnum
19975         mkdir -p $dir0 || error "creating dir $dir0"
19976         file1=$dir0/f1
19977         file2=$dir0/f2
19978         file3=$dir0/f3
19979         dir1=$dir0/d1
19980         dir2=$dir0/d2
19981         mkdir $dir1 $dir2
19982         $LFS setstripe -c1 $file1
19983         $LFS setstripe -c2 $file2
19984         $LFS setstripe -c1 $file3
19985         chown $RUNAS_ID $file3
19986         gen1=$($LFS getstripe -g $file1)
19987         gen2=$($LFS getstripe -g $file2)
19988
19989         $LFS swap_layouts $dir1 $dir2 &&
19990                 error "swap of directories layouts should fail"
19991         $LFS swap_layouts $dir1 $file1 &&
19992                 error "swap of directory and file layouts should fail"
19993         $RUNAS $LFS swap_layouts $file1 $file2 &&
19994                 error "swap of file we cannot write should fail"
19995         $LFS swap_layouts $file1 $file3 &&
19996                 error "swap of file with different owner should fail"
19997         /bin/true # to clear error code
19998 }
19999 run_test 184b "Forbidden layout swap (will generate errors)"
20000
20001 test_184c() {
20002         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
20003         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
20004         check_swap_layouts_support
20005         check_swap_layout_no_dom $DIR
20006
20007         local dir0=$DIR/$tdir/$testnum
20008         mkdir -p $dir0 || error "creating dir $dir0"
20009
20010         local ref1=$dir0/ref1
20011         local ref2=$dir0/ref2
20012         local file1=$dir0/file1
20013         local file2=$dir0/file2
20014         # create a file large enough for the concurrent test
20015         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
20016         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
20017         echo "ref file size: ref1($(stat -c %s $ref1))," \
20018              "ref2($(stat -c %s $ref2))"
20019
20020         cp $ref2 $file2
20021         dd if=$ref1 of=$file1 bs=16k &
20022         local DD_PID=$!
20023
20024         # Make sure dd starts to copy file, but wait at most 5 seconds
20025         local loops=0
20026         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
20027
20028         $LFS swap_layouts $file1 $file2
20029         local rc=$?
20030         wait $DD_PID
20031         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
20032         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
20033
20034         # how many bytes copied before swapping layout
20035         local copied=$(stat -c %s $file2)
20036         local remaining=$(stat -c %s $ref1)
20037         remaining=$((remaining - copied))
20038         echo "Copied $copied bytes before swapping layout..."
20039
20040         cmp -n $copied $file1 $ref2 | grep differ &&
20041                 error "Content mismatch [0, $copied) of ref2 and file1"
20042         cmp -n $copied $file2 $ref1 ||
20043                 error "Content mismatch [0, $copied) of ref1 and file2"
20044         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
20045                 error "Content mismatch [$copied, EOF) of ref1 and file1"
20046
20047         # clean up
20048         rm -f $ref1 $ref2 $file1 $file2
20049 }
20050 run_test 184c "Concurrent write and layout swap"
20051
20052 test_184d() {
20053         check_swap_layouts_support
20054         check_swap_layout_no_dom $DIR
20055         [ -z "$(which getfattr 2>/dev/null)" ] &&
20056                 skip_env "no getfattr command"
20057
20058         local file1=$DIR/$tdir/$tfile-1
20059         local file2=$DIR/$tdir/$tfile-2
20060         local file3=$DIR/$tdir/$tfile-3
20061         local lovea1
20062         local lovea2
20063
20064         mkdir -p $DIR/$tdir
20065         touch $file1 || error "create $file1 failed"
20066         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
20067                 error "create $file2 failed"
20068         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
20069                 error "create $file3 failed"
20070         lovea1=$(get_layout_param $file1)
20071
20072         $LFS swap_layouts $file2 $file3 ||
20073                 error "swap $file2 $file3 layouts failed"
20074         $LFS swap_layouts $file1 $file2 ||
20075                 error "swap $file1 $file2 layouts failed"
20076
20077         lovea2=$(get_layout_param $file2)
20078         echo "$lovea1"
20079         echo "$lovea2"
20080         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
20081
20082         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
20083         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
20084 }
20085 run_test 184d "allow stripeless layouts swap"
20086
20087 test_184e() {
20088         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
20089                 skip "Need MDS version at least 2.6.94"
20090         check_swap_layouts_support
20091         check_swap_layout_no_dom $DIR
20092         [ -z "$(which getfattr 2>/dev/null)" ] &&
20093                 skip_env "no getfattr command"
20094
20095         local file1=$DIR/$tdir/$tfile-1
20096         local file2=$DIR/$tdir/$tfile-2
20097         local file3=$DIR/$tdir/$tfile-3
20098         local lovea
20099
20100         mkdir -p $DIR/$tdir
20101         touch $file1 || error "create $file1 failed"
20102         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
20103                 error "create $file2 failed"
20104         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
20105                 error "create $file3 failed"
20106
20107         $LFS swap_layouts $file1 $file2 ||
20108                 error "swap $file1 $file2 layouts failed"
20109
20110         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
20111         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
20112
20113         echo 123 > $file1 || error "Should be able to write into $file1"
20114
20115         $LFS swap_layouts $file1 $file3 ||
20116                 error "swap $file1 $file3 layouts failed"
20117
20118         echo 123 > $file1 || error "Should be able to write into $file1"
20119
20120         rm -rf $file1 $file2 $file3
20121 }
20122 run_test 184e "Recreate layout after stripeless layout swaps"
20123
20124 test_184f() {
20125         # Create a file with name longer than sizeof(struct stat) ==
20126         # 144 to see if we can get chars from the file name to appear
20127         # in the returned striping. Note that 'f' == 0x66.
20128         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
20129
20130         mkdir -p $DIR/$tdir
20131         mcreate $DIR/$tdir/$file
20132         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
20133                 error "IOC_MDC_GETFILEINFO returned garbage striping"
20134         fi
20135 }
20136 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
20137
20138 test_185() { # LU-2441
20139         # LU-3553 - no volatile file support in old servers
20140         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
20141                 skip "Need MDS version at least 2.3.60"
20142
20143         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
20144         touch $DIR/$tdir/spoo
20145         local mtime1=$(stat -c "%Y" $DIR/$tdir)
20146         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
20147                 error "cannot create/write a volatile file"
20148         [ "$FILESET" == "" ] &&
20149         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
20150                 error "FID is still valid after close"
20151
20152         multiop_bg_pause $DIR/$tdir Vw4096_c
20153         local multi_pid=$!
20154
20155         local OLD_IFS=$IFS
20156         IFS=":"
20157         local fidv=($fid)
20158         IFS=$OLD_IFS
20159         # assume that the next FID for this client is sequential, since stdout
20160         # is unfortunately eaten by multiop_bg_pause
20161         local n=$((${fidv[1]} + 1))
20162         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
20163         if [ "$FILESET" == "" ]; then
20164                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
20165                         error "FID is missing before close"
20166         fi
20167         kill -USR1 $multi_pid
20168         # 1 second delay, so if mtime change we will see it
20169         sleep 1
20170         local mtime2=$(stat -c "%Y" $DIR/$tdir)
20171         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
20172 }
20173 run_test 185 "Volatile file support"
20174
20175 function create_check_volatile() {
20176         local idx=$1
20177         local tgt
20178
20179         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
20180         local PID=$!
20181         sleep 1
20182         local FID=$(cat /tmp/${tfile}.fid)
20183         [ "$FID" == "" ] && error "can't get FID for volatile"
20184         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
20185         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
20186         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
20187         kill -USR1 $PID
20188         wait
20189         sleep 1
20190         cancel_lru_locks mdc # flush opencache
20191         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
20192         return 0
20193 }
20194
20195 test_185a(){
20196         # LU-12516 - volatile creation via .lustre
20197         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
20198                 skip "Need MDS version at least 2.3.55"
20199
20200         create_check_volatile 0
20201         [ $MDSCOUNT -lt 2 ] && return 0
20202
20203         # DNE case
20204         create_check_volatile 1
20205
20206         return 0
20207 }
20208 run_test 185a "Volatile file creation in .lustre/fid/"
20209
20210 test_187a() {
20211         remote_mds_nodsh && skip "remote MDS with nodsh"
20212         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
20213                 skip "Need MDS version at least 2.3.0"
20214
20215         local dir0=$DIR/$tdir/$testnum
20216         mkdir -p $dir0 || error "creating dir $dir0"
20217
20218         local file=$dir0/file1
20219         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
20220         stack_trap "rm -f $file"
20221         local dv1=$($LFS data_version $file)
20222         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
20223         local dv2=$($LFS data_version $file)
20224         [[ $dv1 != $dv2 ]] ||
20225                 error "data version did not change on write $dv1 == $dv2"
20226 }
20227 run_test 187a "Test data version change"
20228
20229 test_187b() {
20230         remote_mds_nodsh && skip "remote MDS with nodsh"
20231         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
20232                 skip "Need MDS version at least 2.3.0"
20233
20234         local dir0=$DIR/$tdir/$testnum
20235         mkdir -p $dir0 || error "creating dir $dir0"
20236
20237         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
20238         [[ ${DV[0]} != ${DV[1]} ]] ||
20239                 error "data version did not change on write"\
20240                       " ${DV[0]} == ${DV[1]}"
20241
20242         # clean up
20243         rm -f $file1
20244 }
20245 run_test 187b "Test data version change on volatile file"
20246
20247 test_200() {
20248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20249         remote_mgs_nodsh && skip "remote MGS with nodsh"
20250         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
20251
20252         local POOL=${POOL:-cea1}
20253         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
20254         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
20255         # Pool OST targets
20256         local first_ost=0
20257         local last_ost=$(($OSTCOUNT - 1))
20258         local ost_step=2
20259         local ost_list=$(seq $first_ost $ost_step $last_ost)
20260         local ost_range="$first_ost $last_ost $ost_step"
20261         local test_path=$POOL_ROOT/$POOL_DIR_NAME
20262         local file_dir=$POOL_ROOT/file_tst
20263         local subdir=$test_path/subdir
20264         local rc=0
20265
20266         while : ; do
20267                 # former test_200a test_200b
20268                 pool_add $POOL                          || { rc=$? ; break; }
20269                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
20270                 # former test_200c test_200d
20271                 mkdir -p $test_path
20272                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
20273                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
20274                 mkdir -p $subdir
20275                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
20276                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
20277                                                         || { rc=$? ; break; }
20278                 # former test_200e test_200f
20279                 local files=$((OSTCOUNT*3))
20280                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
20281                                                         || { rc=$? ; break; }
20282                 pool_create_files $POOL $file_dir $files "$ost_list" \
20283                                                         || { rc=$? ; break; }
20284                 # former test_200g test_200h
20285                 pool_lfs_df $POOL                       || { rc=$? ; break; }
20286                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
20287
20288                 # former test_201a test_201b test_201c
20289                 pool_remove_first_target $POOL          || { rc=$? ; break; }
20290
20291                 local f=$test_path/$tfile
20292                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
20293                 pool_remove $POOL $f                    || { rc=$? ; break; }
20294                 break
20295         done
20296
20297         destroy_test_pools
20298
20299         return $rc
20300 }
20301 run_test 200 "OST pools"
20302
20303 # usage: default_attr <count | size | offset>
20304 default_attr() {
20305         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
20306 }
20307
20308 # usage: check_default_stripe_attr
20309 check_default_stripe_attr() {
20310         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
20311         case $1 in
20312         --stripe-count|-c)
20313                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
20314         --stripe-size|-S)
20315                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
20316         --stripe-index|-i)
20317                 EXPECTED=-1;;
20318         *)
20319                 error "unknown getstripe attr '$1'"
20320         esac
20321
20322         [ $ACTUAL == $EXPECTED ] ||
20323                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
20324 }
20325
20326 test_204a() {
20327         test_mkdir $DIR/$tdir
20328         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
20329
20330         check_default_stripe_attr --stripe-count
20331         check_default_stripe_attr --stripe-size
20332         check_default_stripe_attr --stripe-index
20333 }
20334 run_test 204a "Print default stripe attributes"
20335
20336 test_204b() {
20337         test_mkdir $DIR/$tdir
20338         $LFS setstripe --stripe-count 1 $DIR/$tdir
20339
20340         check_default_stripe_attr --stripe-size
20341         check_default_stripe_attr --stripe-index
20342 }
20343 run_test 204b "Print default stripe size and offset"
20344
20345 test_204c() {
20346         test_mkdir $DIR/$tdir
20347         $LFS setstripe --stripe-size 65536 $DIR/$tdir
20348
20349         check_default_stripe_attr --stripe-count
20350         check_default_stripe_attr --stripe-index
20351 }
20352 run_test 204c "Print default stripe count and offset"
20353
20354 test_204d() {
20355         test_mkdir $DIR/$tdir
20356         $LFS setstripe --stripe-index 0 $DIR/$tdir
20357
20358         check_default_stripe_attr --stripe-count
20359         check_default_stripe_attr --stripe-size
20360 }
20361 run_test 204d "Print default stripe count and size"
20362
20363 test_204e() {
20364         test_mkdir $DIR/$tdir
20365         $LFS setstripe -d $DIR/$tdir
20366
20367         # LU-16904 check if root is set as PFL layout
20368         local numcomp=$($LFS getstripe --component-count $MOUNT)
20369
20370         if [[ $numcomp -gt 0 ]]; then
20371                 check_default_stripe_attr --stripe-count
20372         else
20373                 check_default_stripe_attr --stripe-count --raw
20374         fi
20375         check_default_stripe_attr --stripe-size --raw
20376         check_default_stripe_attr --stripe-index --raw
20377 }
20378 run_test 204e "Print raw stripe attributes"
20379
20380 test_204f() {
20381         test_mkdir $DIR/$tdir
20382         $LFS setstripe --stripe-count 1 $DIR/$tdir
20383
20384         check_default_stripe_attr --stripe-size --raw
20385         check_default_stripe_attr --stripe-index --raw
20386 }
20387 run_test 204f "Print raw stripe size and offset"
20388
20389 test_204g() {
20390         test_mkdir $DIR/$tdir
20391         $LFS setstripe --stripe-size 65536 $DIR/$tdir
20392
20393         check_default_stripe_attr --stripe-count --raw
20394         check_default_stripe_attr --stripe-index --raw
20395 }
20396 run_test 204g "Print raw stripe count and offset"
20397
20398 test_204h() {
20399         test_mkdir $DIR/$tdir
20400         $LFS setstripe --stripe-index 0 $DIR/$tdir
20401
20402         check_default_stripe_attr --stripe-count --raw
20403         check_default_stripe_attr --stripe-size --raw
20404 }
20405 run_test 204h "Print raw stripe count and size"
20406
20407 # Figure out which job scheduler is being used, if any,
20408 # or use a fake one
20409 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
20410         JOBENV=SLURM_JOB_ID
20411 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
20412         JOBENV=LSB_JOBID
20413 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
20414         JOBENV=PBS_JOBID
20415 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
20416         JOBENV=LOADL_STEP_ID
20417 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
20418         JOBENV=JOB_ID
20419 else
20420         $LCTL list_param jobid_name > /dev/null 2>&1
20421         if [ $? -eq 0 ]; then
20422                 JOBENV=nodelocal
20423         else
20424                 JOBENV=FAKE_JOBID
20425         fi
20426 fi
20427 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
20428
20429 verify_jobstats() {
20430         local cmd=($1)
20431         shift
20432         local facets="$@"
20433
20434 # we don't really need to clear the stats for this test to work, since each
20435 # command has a unique jobid, but it makes debugging easier if needed.
20436 #       for facet in $facets; do
20437 #               local dev=$(convert_facet2label $facet)
20438 #               # clear old jobstats
20439 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
20440 #       done
20441
20442         # use a new JobID for each test, or we might see an old one
20443         [ "$JOBENV" = "FAKE_JOBID" ] &&
20444                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
20445
20446         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
20447
20448         [ "$JOBENV" = "nodelocal" ] && {
20449                 FAKE_JOBID=id.$testnum.%e.$RANDOM
20450                 $LCTL set_param jobid_name=$FAKE_JOBID
20451                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
20452         }
20453
20454         log "Test: ${cmd[*]}"
20455         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
20456
20457         if [ $JOBENV = "FAKE_JOBID" ]; then
20458                 FAKE_JOBID=$JOBVAL ${cmd[*]}
20459         else
20460                 ${cmd[*]}
20461         fi
20462
20463         # all files are created on OST0000
20464         for facet in $facets; do
20465                 local stats="*.$(convert_facet2label $facet).job_stats"
20466
20467                 # strip out libtool wrappers for in-tree executables
20468                 if (( $(do_facet $facet lctl get_param $stats |
20469                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
20470                         do_facet $facet lctl get_param $stats
20471                         error "No jobstats for $JOBVAL found on $facet::$stats"
20472                 fi
20473         done
20474 }
20475
20476 jobstats_set() {
20477         local new_jobenv=$1
20478
20479         set_persistent_param_and_check client "jobid_var" \
20480                 "$FSNAME.sys.jobid_var" $new_jobenv
20481 }
20482
20483 test_205a() { # Job stats
20484         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20485         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
20486                 skip "Need MDS version with at least 2.7.1"
20487         remote_mgs_nodsh && skip "remote MGS with nodsh"
20488         remote_mds_nodsh && skip "remote MDS with nodsh"
20489         remote_ost_nodsh && skip "remote OST with nodsh"
20490         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
20491                 skip "Server doesn't support jobstats"
20492         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
20493
20494         local old_jobenv=$($LCTL get_param -n jobid_var)
20495         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
20496         stack_trap "jobstats_set $old_jobenv" EXIT
20497
20498         changelog_register
20499
20500         local old_jobid_name=$($LCTL get_param jobid_name)
20501         stack_trap "$LCTL set_param $old_jobid_name" EXIT
20502
20503         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
20504                                 mdt.*.job_cleanup_interval | head -n 1)
20505         local new_interval=5
20506         do_facet $SINGLEMDS \
20507                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
20508         stack_trap "do_facet $SINGLEMDS \
20509                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
20510         local start=$SECONDS
20511
20512         local cmd
20513         # mkdir
20514         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
20515         verify_jobstats "$cmd" "$SINGLEMDS"
20516         # rmdir
20517         cmd="rmdir $DIR/$tdir"
20518         verify_jobstats "$cmd" "$SINGLEMDS"
20519         # mkdir on secondary MDT
20520         if [ $MDSCOUNT -gt 1 ]; then
20521                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
20522                 verify_jobstats "$cmd" "mds2"
20523         fi
20524         # mknod
20525         cmd="mknod $DIR/$tfile c 1 3"
20526         verify_jobstats "$cmd" "$SINGLEMDS"
20527         # unlink
20528         cmd="rm -f $DIR/$tfile"
20529         verify_jobstats "$cmd" "$SINGLEMDS"
20530         # create all files on OST0000 so verify_jobstats can find OST stats
20531         # open & close
20532         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
20533         verify_jobstats "$cmd" "$SINGLEMDS"
20534         # setattr
20535         cmd="touch $DIR/$tfile"
20536         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20537         # write
20538         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
20539         verify_jobstats "$cmd" "ost1"
20540         # read
20541         cancel_lru_locks osc
20542         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
20543         verify_jobstats "$cmd" "ost1"
20544         # truncate
20545         cmd="$TRUNCATE $DIR/$tfile 0"
20546         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20547         # rename
20548         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
20549         verify_jobstats "$cmd" "$SINGLEMDS"
20550         # jobstats expiry - sleep until old stats should be expired
20551         local left=$((new_interval + 5 - (SECONDS - start)))
20552         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
20553                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
20554                         "0" $left
20555         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
20556         verify_jobstats "$cmd" "$SINGLEMDS"
20557         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
20558             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
20559
20560         # Ensure that jobid are present in changelog (if supported by MDS)
20561         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
20562                 changelog_dump | tail -10
20563                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
20564                 [ $jobids -eq 9 ] ||
20565                         error "Wrong changelog jobid count $jobids != 9"
20566
20567                 # LU-5862
20568                 JOBENV="disable"
20569                 jobstats_set $JOBENV
20570                 touch $DIR/$tfile
20571                 changelog_dump | grep $tfile
20572                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
20573                 [ $jobids -eq 0 ] ||
20574                         error "Unexpected jobids when jobid_var=$JOBENV"
20575         fi
20576
20577         # test '%j' access to environment variable - if supported
20578         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
20579                 JOBENV="JOBCOMPLEX"
20580                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20581
20582                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20583         fi
20584
20585         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
20586                 JOBENV="JOBCOMPLEX"
20587                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
20588
20589                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20590         fi
20591
20592         # test '%j' access to per-session jobid - if supported
20593         if lctl list_param jobid_this_session > /dev/null 2>&1
20594         then
20595                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
20596                 lctl set_param jobid_this_session=$USER
20597
20598                 JOBENV="JOBCOMPLEX"
20599                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20600
20601                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20602         fi
20603 }
20604 run_test 205a "Verify job stats"
20605
20606 # LU-13117, LU-13597, LU-16599
20607 test_205b() {
20608         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
20609                 skip "Need MDS version at least 2.13.54.91"
20610
20611         local job_stats="mdt.*.job_stats"
20612         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
20613
20614         do_facet mds1 $LCTL set_param $job_stats=clear
20615
20616         # Setting jobid_var to USER might not be supported
20617         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
20618         $LCTL set_param jobid_var=USER || true
20619         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
20620         $LCTL set_param jobid_name="%j.%e.%u"
20621
20622         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
20623         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
20624                 { do_facet mds1 $LCTL get_param $job_stats;
20625                   error "Unexpected jobid found"; }
20626         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
20627                 { do_facet mds1 $LCTL get_param $job_stats;
20628                   error "wrong job_stats format found"; }
20629
20630         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
20631                 echo "MDS does not yet escape jobid" && return 0
20632
20633         mkdir_on_mdt0 $DIR/$tdir
20634         $LCTL set_param jobid_var=TEST205b
20635         env -i TEST205b="has sp" touch $DIR/$tdir/$tfile.2
20636         local jobid=$(do_facet mds1 $LCTL get_param $job_stats |
20637                       awk '/has\\x20sp/ {print $3}')
20638         [[ -n "$jobid" ]] || { do_facet mds1 $LCTL get_param $job_stats;
20639                   error "jobid not escaped"; }
20640
20641         if (( $MDS1_VERSION >= $(version_code 2.15.53.139) )); then
20642                 # need to run such a command on mds1:
20643                 # lctl set_param mdt.$FSNAME-MDT0000.job_stats='"has\x20sp.touch.0"'
20644                 #
20645                 # there might be multiple MDTs on single mds server, so need to
20646                 # specifiy MDT0000. Or the command will fail due to other MDTs
20647                 do_facet_vp mds1 $LCTL set_param mdt.$FSNAME-MDT0000.job_stats=$jobid ||
20648                         error "cannot clear escaped jobid in job_stats";
20649         else
20650                 echo "MDS does not support clearing escaped jobid"
20651         fi
20652 }
20653 run_test 205b "Verify job stats jobid and output format"
20654
20655 # LU-13733
20656 test_205c() {
20657         $LCTL set_param llite.*.stats=0
20658         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
20659         $LCTL get_param llite.*.stats
20660         $LCTL get_param llite.*.stats | grep \
20661                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
20662                         error "wrong client stats format found"
20663 }
20664 run_test 205c "Verify client stats format"
20665
20666 test_205d() {
20667         local file=$DIR/$tdir/$tfile
20668
20669         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20670                 skip "need lustre >= 2.15.53 for lljobstat"
20671         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20672                 skip "need lustre >= 2.15.53 for lljobstat"
20673         verify_yaml_available || skip_env "YAML verification not installed"
20674
20675         test_mkdir -i 0 $DIR/$tdir
20676         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
20677         stack_trap "rm -rf $DIR/$tdir"
20678
20679         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
20680                 error "failed to write data to $file"
20681         mv $file $file.2
20682
20683         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
20684         echo -n 'verify rename_stats...'
20685         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
20686                 verify_yaml || error "rename_stats is not valid YAML"
20687         echo " OK"
20688
20689         echo -n 'verify mdt job_stats...'
20690         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
20691                 verify_yaml || error "job_stats on mds1 is not valid YAML"
20692         echo " OK"
20693
20694         echo -n 'verify ost job_stats...'
20695         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
20696                 verify_yaml || error "job_stats on ost1 is not valid YAML"
20697         echo " OK"
20698 }
20699 run_test 205d "verify the format of some stats files"
20700
20701 test_205e() {
20702         local ops_comma
20703         local file=$DIR/$tdir/$tfile
20704         local -a cli_params
20705
20706         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20707                 skip "need lustre >= 2.15.53 for lljobstat"
20708         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20709                 skip "need lustre >= 2.15.53 for lljobstat"
20710         verify_yaml_available || skip_env "YAML verification not installed"
20711
20712         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20713         $LCTL set_param jobid_var=nodelocal jobid_name=205e.%e.%u
20714         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20715
20716         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
20717         stack_trap "rm -rf $DIR/$tdir"
20718
20719         $LFS setstripe -E EOF -i 0 -c 1 $file ||
20720                 error "failed to create $file on ost1"
20721         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
20722                 error "failed to write data to $file"
20723
20724         do_facet mds1 "$LCTL get_param *.*.job_stats"
20725         do_facet ost1 "$LCTL get_param *.*.job_stats"
20726
20727         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
20728         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
20729                 error "The output of lljobstat is not an valid YAML"
20730
20731         # verify that job dd.0 does exist and has some ops on ost1
20732         # typically this line is like:
20733         # - 205e.dd.0:            {ops: 20, ...}
20734         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
20735                     awk '$2=="205e.dd.0:" {print $4}')
20736
20737         (( ${ops_comma%,} >= 10 )) ||
20738                 error "cannot find job 205e.dd.0 with ops >= 10"
20739 }
20740 run_test 205e "verify the output of lljobstat"
20741
20742 test_205f() {
20743         verify_yaml_available || skip_env "YAML verification not installed"
20744
20745         # check both qos_ost_weights and qos_mdt_weights
20746         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
20747         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
20748                 error "qos_ost_weights is not valid YAML"
20749 }
20750 run_test 205f "verify qos_ost_weights YAML format "
20751
20752 __test_205_jobstats_dump() {
20753         local -a pids
20754         local nbr_instance=$1
20755
20756         while true; do
20757                 if (( ${#pids[@]} >= nbr_instance )); then
20758                         wait ${pids[@]}
20759                         pids=()
20760                 fi
20761
20762                 do_facet mds1 "$LCTL get_param mdt.*.job_stats > /dev/null" &
20763                 pids+=( $! )
20764         done
20765 }
20766
20767 __test_205_cleanup() {
20768         kill $@
20769         # Clear all job entries
20770         do_facet mds1 "$LCTL set_param mdt.*.job_stats=clear"
20771 }
20772
20773 test_205g() {
20774         local -a mds1_params
20775         local -a cli_params
20776         local pids
20777         local interval=5
20778
20779         mds1_params=( $(do_facet mds1 $LCTL get_param mdt.*.job_cleanup_interval) )
20780         do_facet mds1 $LCTL set_param mdt.*.job_cleanup_interval=$interval
20781         stack_trap "do_facet mds1 $LCTL set_param ${mds1_params[*]}" EXIT
20782
20783         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20784         $LCTL set_param jobid_var=TEST205G_ID jobid_name=%j.%p
20785         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20786
20787         # start jobs loop
20788         export TEST205G_ID=205g
20789         stack_trap "unset TEST205G_ID" EXIT
20790         while true; do
20791                 printf $DIR/$tfile.{0001..1000} | xargs -P10 -n1 touch
20792         done & pids="$! "
20793
20794         __test_205_jobstats_dump 4 & pids+="$! "
20795         stack_trap "__test_205_cleanup $pids" EXIT INT
20796
20797         [[ $SLOW == "no" ]] && sleep 90 || sleep 240
20798 }
20799 run_test 205g "stress test for job_stats procfile"
20800
20801 test_205h() {
20802         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
20803                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
20804         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
20805
20806         local dir=$DIR/$tdir
20807         local f=$dir/$tfile
20808         local f2=$dir/$tfile-2
20809         local f3=$dir/$tfile-3
20810         local subdir=$DIR/dir
20811         local val
20812
20813         local mdts=$(comma_list $(mdts_nodes))
20814         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20815         local client_saved=$($LCTL get_param -n jobid_var)
20816
20817         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20818         stack_trap "$LCTL set_param jobid_var=$client_saved" EXIT
20819
20820         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job ||
20821                 error "failed to set job_xattr parameter to user.job"
20822         $LCTL set_param jobid_var=procname.uid ||
20823                 error "failed to set jobid_var parameter"
20824
20825         test_mkdir $dir
20826
20827         touch $f
20828         val=$(getfattr -n user.job $f | grep user.job)
20829         [[ $val = user.job=\"touch.0\" ]] ||
20830                 error "expected user.job=\"touch.0\", got '$val'"
20831
20832         mkdir $subdir
20833         val=$(getfattr -n user.job $subdir | grep user.job)
20834         [[ $val = user.job=\"mkdir.0\" ]] ||
20835                 error "expected user.job=\"mkdir.0\", got '$val'"
20836
20837         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE ||
20838                 error "failed to set job_xattr parameter to NONE"
20839
20840         touch $f2
20841         val=$(getfattr -d $f2)
20842         [[ -z $val ]] ||
20843                 error "expected no user xattr, got '$val'"
20844
20845         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=trusted.job ||
20846                 error "failed to set job_xattr parameter to trusted.job"
20847
20848         touch $f3
20849         val=$(getfattr -n trusted.job $f3 | grep trusted.job)
20850         [[ $val = trusted.job=\"touch.0\" ]] ||
20851                 error "expected trusted.job=\"touch.0\", got '$val'"
20852 }
20853 run_test 205h "check jobid xattr is stored correctly"
20854
20855 test_205i() {
20856         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
20857                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
20858
20859         local mdts=$(comma_list $(mdts_nodes))
20860         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20861
20862         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20863
20864         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.1234567 ||
20865                 error "failed to set mdt.*.job_xattr to user.1234567"
20866
20867         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.12345678 &&
20868                 error "failed to reject too long job_xattr name"
20869
20870         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=userjob &&
20871                 error "failed to reject job_xattr name in bad format"
20872
20873         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job/ &&
20874                 error "failed to reject job_xattr name with invalid character"
20875
20876         do_nodes $mdts "printf 'mdt.*.job_xattr=user.job\x80' |
20877                         xargs $LCTL set_param" &&
20878                 error "failed to reject job_xattr name with non-ascii character"
20879
20880         return 0
20881 }
20882 run_test 205i "check job_xattr parameter accepts and rejects values correctly"
20883
20884 # LU-1480, LU-1773 and LU-1657
20885 test_206() {
20886         mkdir -p $DIR/$tdir
20887         $LFS setstripe -c -1 $DIR/$tdir
20888 #define OBD_FAIL_LOV_INIT 0x1403
20889         $LCTL set_param fail_loc=0xa0001403
20890         $LCTL set_param fail_val=1
20891         touch $DIR/$tdir/$tfile || true
20892 }
20893 run_test 206 "fail lov_init_raid0() doesn't lbug"
20894
20895 test_207a() {
20896         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20897         local fsz=`stat -c %s $DIR/$tfile`
20898         cancel_lru_locks mdc
20899
20900         # do not return layout in getattr intent
20901 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
20902         $LCTL set_param fail_loc=0x170
20903         local sz=`stat -c %s $DIR/$tfile`
20904
20905         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
20906
20907         rm -rf $DIR/$tfile
20908 }
20909 run_test 207a "can refresh layout at glimpse"
20910
20911 test_207b() {
20912         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20913         local cksum=`md5sum $DIR/$tfile`
20914         local fsz=`stat -c %s $DIR/$tfile`
20915         cancel_lru_locks mdc
20916         cancel_lru_locks osc
20917
20918         # do not return layout in getattr intent
20919 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
20920         $LCTL set_param fail_loc=0x171
20921
20922         # it will refresh layout after the file is opened but before read issues
20923         echo checksum is "$cksum"
20924         echo "$cksum" |md5sum -c --quiet || error "file differs"
20925
20926         rm -rf $DIR/$tfile
20927 }
20928 run_test 207b "can refresh layout at open"
20929
20930 test_208() {
20931         # FIXME: in this test suite, only RD lease is used. This is okay
20932         # for now as only exclusive open is supported. After generic lease
20933         # is done, this test suite should be revised. - Jinshan
20934
20935         remote_mds_nodsh && skip "remote MDS with nodsh"
20936         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
20937                 skip "Need MDS version at least 2.4.52"
20938
20939         echo "==== test 1: verify get lease work"
20940         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
20941
20942         echo "==== test 2: verify lease can be broken by upcoming open"
20943         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20944         local PID=$!
20945         sleep 2
20946
20947         $MULTIOP $DIR/$tfile oO_RDWR:c
20948         kill -USR1 $PID && wait $PID || error "break lease error"
20949
20950         echo "==== test 3: verify lease can't be granted if an open already exists"
20951         $MULTIOP $DIR/$tfile oO_RDWR:_c &
20952         local PID=$!
20953         sleep 2
20954
20955         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
20956         kill -USR1 $PID && wait $PID || error "open file error"
20957
20958         echo "==== test 4: lease can sustain over recovery"
20959         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
20960         PID=$!
20961         sleep 2
20962
20963         fail mds1
20964
20965         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
20966
20967         echo "==== test 5: lease broken can't be regained by replay"
20968         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20969         PID=$!
20970         sleep 2
20971
20972         # open file to break lease and then recovery
20973         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
20974         fail mds1
20975
20976         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
20977
20978         rm -f $DIR/$tfile
20979 }
20980 run_test 208 "Exclusive open"
20981
20982 test_209() {
20983         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
20984                 skip_env "must have disp_stripe"
20985
20986         touch $DIR/$tfile
20987         sync; sleep 5; sync;
20988
20989         echo 3 > /proc/sys/vm/drop_caches
20990         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20991                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20992         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20993
20994         # open/close 500 times
20995         for i in $(seq 500); do
20996                 cat $DIR/$tfile
20997         done
20998
20999         echo 3 > /proc/sys/vm/drop_caches
21000         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
21001                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
21002         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
21003
21004         echo "before: $req_before, after: $req_after"
21005         [ $((req_after - req_before)) -ge 300 ] &&
21006                 error "open/close requests are not freed"
21007         return 0
21008 }
21009 run_test 209 "read-only open/close requests should be freed promptly"
21010
21011 test_210() {
21012         local pid
21013
21014         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
21015         pid=$!
21016         sleep 1
21017
21018         $LFS getstripe $DIR/$tfile
21019         kill -USR1 $pid
21020         wait $pid || error "multiop failed"
21021
21022         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
21023         pid=$!
21024         sleep 1
21025
21026         $LFS getstripe $DIR/$tfile
21027         kill -USR1 $pid
21028         wait $pid || error "multiop failed"
21029 }
21030 run_test 210 "lfs getstripe does not break leases"
21031
21032 function test_211() {
21033         local PID
21034         local id
21035         local rc
21036
21037         stack_trap "rm -f $DIR/$tfile" EXIT
21038         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=10 oflag=direct ||
21039                 error "can't create file"
21040         $LFS mirror extend -N $DIR/$tfile ||
21041                 error "can't create a replica"
21042         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
21043         $LFS getstripe $DIR/$tfile
21044         stale=$($LFS getstripe $DIR/$tfile | grep stale | wc -l)
21045         (( $stale != 1 )) && error "expected 1 stale, found $stale"
21046
21047         $MULTIOP $DIR/$tfile OeW_E+eUc &
21048         PID=$!
21049         sleep 0.3
21050
21051         id=$($LFS getstripe $DIR/$tfile |
21052                 awk '/lcme_mirror_id:/{id=$2}/lcme_flags.*init$/{print id}')
21053         $LFS mirror split -d --mirror-id $id $DIR/$tfile &&
21054                 error "removed last in-sync replica?"
21055
21056         kill -USR1 $PID
21057         wait $PID
21058         (( $? == 0 )) || error "failed split broke the lease"
21059 }
21060 run_test 211 "failed mirror split doesn't break write lease"
21061
21062 test_212() {
21063         size=`date +%s`
21064         size=$((size % 8192 + 1))
21065         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
21066         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
21067         rm -f $DIR/f212 $DIR/f212.xyz
21068 }
21069 run_test 212 "Sendfile test ============================================"
21070
21071 test_213() {
21072         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
21073         cancel_lru_locks osc
21074         lctl set_param fail_loc=0x8000040f
21075         # generate a read lock
21076         cat $DIR/$tfile > /dev/null
21077         # write to the file, it will try to cancel the above read lock.
21078         cat /etc/hosts >> $DIR/$tfile
21079 }
21080 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
21081
21082 test_214() { # for bug 20133
21083         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
21084         for (( i=0; i < 340; i++ )) ; do
21085                 touch $DIR/$tdir/d214c/a$i
21086         done
21087
21088         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
21089         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
21090         ls $DIR/d214c || error "ls $DIR/d214c failed"
21091         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
21092         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
21093 }
21094 run_test 214 "hash-indexed directory test - bug 20133"
21095
21096 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
21097 create_lnet_proc_files() {
21098         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
21099 }
21100
21101 # counterpart of create_lnet_proc_files
21102 remove_lnet_proc_files() {
21103         rm -f $TMP/lnet_$1.sys
21104 }
21105
21106 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
21107 # 3rd arg as regexp for body
21108 check_lnet_proc_stats() {
21109         local l=$(cat "$TMP/lnet_$1" |wc -l)
21110         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
21111
21112         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
21113 }
21114
21115 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
21116 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
21117 # optional and can be regexp for 2nd line (lnet.routes case)
21118 check_lnet_proc_entry() {
21119         local blp=2          # blp stands for 'position of 1st line of body'
21120         [ -z "$5" ] || blp=3 # lnet.routes case
21121
21122         local l=$(cat "$TMP/lnet_$1" |wc -l)
21123         # subtracting one from $blp because the body can be empty
21124         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
21125
21126         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
21127                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
21128
21129         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
21130                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
21131
21132         # bail out if any unexpected line happened
21133         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
21134         [ "$?" != 0 ] || error "$2 misformatted"
21135 }
21136
21137 test_215() { # for bugs 18102, 21079, 21517
21138         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21139
21140         local N='(0|[1-9][0-9]*)'       # non-negative numeric
21141         local P='[1-9][0-9]*'           # positive numeric
21142         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
21143         local NET='[a-z][a-z0-9]*'      # LNet net like o2ib2
21144         local ADDR='[0-9.]+'            # LNet addr like 10.0.0.1
21145         local ADDR6='([0-9a-f]{0,4}:){2,7}[0-9a-f]{0,4}' # IPv6 LNet addr
21146         local NID="$ADDR@$NET"          # LNet nid like 10.0.0.1@o2ib2
21147         local NID6="$ADDR6@$NET"        # LNet nid like 2601:8c1:c180::cbdd@tcp
21148
21149         local L1 # regexp for 1st line
21150         local L2 # regexp for 2nd line (optional)
21151         local BR # regexp for the rest (body)
21152
21153         # lnet.stats should look as 11 space-separated non-negative numerics
21154         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
21155         create_lnet_proc_files "stats"
21156         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
21157         remove_lnet_proc_files "stats"
21158
21159         # lnet.routes should look like this:
21160         # Routing disabled/enabled
21161         # net hops priority state router
21162         # where net is a string like tcp0, hops > 0, priority >= 0,
21163         # state is up/down,
21164         # router is a string like 192.168.1.1@tcp2
21165         L1="^Routing (disabled|enabled)$"
21166         L2="^net +hops +priority +state +router$"
21167         BR="^$NET +$N +(0|1) +(up|down) +($NID|$NID6)$"
21168         create_lnet_proc_files "routes"
21169         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
21170         remove_lnet_proc_files "routes"
21171
21172         # lnet.routers should look like this:
21173         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
21174         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
21175         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
21176         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
21177         L1="^ref +rtr_ref +alive +router$"
21178         BR="^$P +$P +(up|down) +($NID|$NID6)$"
21179         create_lnet_proc_files "routers"
21180         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
21181         remove_lnet_proc_files "routers"
21182
21183         # lnet.peers should look like this:
21184         # nid refs state last max rtr min tx min queue
21185         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
21186         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
21187         # numeric (0 or >0 or <0), queue >= 0.
21188         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
21189         BR="^($NID|$NID6) +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
21190         create_lnet_proc_files "peers"
21191         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
21192         remove_lnet_proc_files "peers"
21193
21194         # lnet.buffers  should look like this:
21195         # pages count credits min
21196         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
21197         L1="^pages +count +credits +min$"
21198         BR="^ +$N +$N +$I +$I$"
21199         create_lnet_proc_files "buffers"
21200         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
21201         remove_lnet_proc_files "buffers"
21202
21203         # lnet.nis should look like this:
21204         # nid status alive refs peer rtr max tx min
21205         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
21206         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
21207         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
21208         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
21209         BR="^($NID|$NID6) +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
21210         create_lnet_proc_files "nis"
21211         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
21212         remove_lnet_proc_files "nis"
21213
21214         # can we successfully write to lnet.stats?
21215         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
21216 }
21217 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
21218
21219 test_216() { # bug 20317
21220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21221         remote_ost_nodsh && skip "remote OST with nodsh"
21222
21223         local node
21224         local facets=$(get_facets OST)
21225         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
21226
21227         save_lustre_params client "osc.*.contention_seconds" > $p
21228         save_lustre_params $facets \
21229                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
21230         save_lustre_params $facets \
21231                 "ldlm.namespaces.filter-*.contended_locks" >> $p
21232         save_lustre_params $facets \
21233                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
21234         clear_stats osc.*.osc_stats
21235
21236         # agressive lockless i/o settings
21237         do_nodes $(comma_list $(osts_nodes)) \
21238                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
21239                         ldlm.namespaces.filter-*.contended_locks=0 \
21240                         ldlm.namespaces.filter-*.contention_seconds=60"
21241         lctl set_param -n osc.*.contention_seconds=60
21242
21243         $DIRECTIO write $DIR/$tfile 0 10 4096
21244         $CHECKSTAT -s 40960 $DIR/$tfile
21245
21246         # disable lockless i/o
21247         do_nodes $(comma_list $(osts_nodes)) \
21248                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
21249                         ldlm.namespaces.filter-*.contended_locks=32 \
21250                         ldlm.namespaces.filter-*.contention_seconds=0"
21251         lctl set_param -n osc.*.contention_seconds=0
21252         clear_stats osc.*.osc_stats
21253
21254         dd if=/dev/zero of=$DIR/$tfile count=0
21255         $CHECKSTAT -s 0 $DIR/$tfile
21256
21257         restore_lustre_params <$p
21258         rm -f $p
21259         rm $DIR/$tfile
21260 }
21261 run_test 216 "check lockless direct write updates file size and kms correctly"
21262
21263 test_217() { # bug 22430
21264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21265
21266         local node
21267
21268         for node in $(nodes_list); do
21269                 local nid=$(host_nids_address $node $NETTYPE)
21270                 local node_ip=$(do_node $node getent ahostsv4 $node |
21271                                 awk '{ print $1; exit; }')
21272
21273                 echo "node: '$node', nid: '$nid', node_ip='$node_ip'"
21274                 # if hostname matches any NID, use hostname for better testing
21275                 if [[ -z "$nid" || "$nid" =~ "$node_ip" ]]; then
21276                         echo "lctl ping node $node@$NETTYPE"
21277                         lctl ping $node@$NETTYPE ||
21278                                 error "ping $node@$NETTYPE failed rc=$?"
21279                 else # otherwise, at least test 'lctl ping' is working
21280                         echo "lctl ping nid $(h2nettype $nid)"
21281                         lctl ping $(h2nettype $nid) ||
21282                                 error "ping $(h2nettype $nid) failed rc=$?"
21283                         echo "skipping $node (no hyphen detected)"
21284                 fi
21285         done
21286
21287         return 0
21288 }
21289 run_test 217 "check lctl ping for hostnames with embedded hyphen ('-')"
21290
21291 test_218() {
21292         # do directio so as not to populate the page cache
21293         log "creating a 10 Mb file"
21294         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
21295                 error "multiop failed while creating a file"
21296         log "starting reads"
21297         dd if=$DIR/$tfile of=/dev/null bs=4096 &
21298         log "truncating the file"
21299         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
21300                 error "multiop failed while truncating the file"
21301         log "killing dd"
21302         kill %+ || true # reads might have finished
21303         echo "wait until dd is finished"
21304         wait
21305         log "removing the temporary file"
21306         rm -rf $DIR/$tfile || error "tmp file removal failed"
21307 }
21308 run_test 218 "parallel read and truncate should not deadlock"
21309
21310 test_219() {
21311         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21312
21313         # write one partial page
21314         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
21315         # set no grant so vvp_io_commit_write will do sync write
21316         $LCTL set_param fail_loc=0x411
21317         # write a full page at the end of file
21318         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
21319
21320         $LCTL set_param fail_loc=0
21321         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
21322         $LCTL set_param fail_loc=0x411
21323         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
21324
21325         # LU-4201
21326         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
21327         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
21328 }
21329 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
21330
21331 test_220() { #LU-325
21332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21333         remote_ost_nodsh && skip "remote OST with nodsh"
21334         remote_mds_nodsh && skip "remote MDS with nodsh"
21335         remote_mgs_nodsh && skip "remote MGS with nodsh"
21336
21337         local OSTIDX=0
21338
21339         # create on MDT0000 so the last_id and next_id are correct
21340         mkdir_on_mdt0 $DIR/$tdir
21341         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
21342         OST=${OST%_UUID}
21343
21344         # on the mdt's osc
21345         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
21346         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
21347                         osp.$mdtosc_proc1.prealloc_last_id)
21348         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
21349                         osp.$mdtosc_proc1.prealloc_next_id)
21350
21351         $LFS df -i
21352
21353         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
21354         #define OBD_FAIL_OST_ENOINO              0x229
21355         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
21356         create_pool $FSNAME.$TESTNAME || return 1
21357         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
21358
21359         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
21360
21361         MDSOBJS=$((last_id - next_id))
21362         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
21363
21364         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
21365         echo "OST still has $count kbytes free"
21366
21367         echo "create $MDSOBJS files @next_id..."
21368         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
21369
21370         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
21371                         osp.$mdtosc_proc1.prealloc_last_id)
21372         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
21373                         osp.$mdtosc_proc1.prealloc_next_id)
21374
21375         echo "after creation, last_id=$last_id2, next_id=$next_id2"
21376         $LFS df -i
21377
21378         echo "cleanup..."
21379
21380         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
21381         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
21382
21383         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
21384                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
21385         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
21386                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
21387         echo "unlink $MDSOBJS files @$next_id..."
21388         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
21389 }
21390 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
21391
21392 test_221() {
21393         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21394
21395         dd if=`which date` of=$MOUNT/date oflag=sync
21396         chmod +x $MOUNT/date
21397
21398         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
21399         $LCTL set_param fail_loc=0x80001401
21400
21401         $MOUNT/date > /dev/null
21402         rm -f $MOUNT/date
21403 }
21404 run_test 221 "make sure fault and truncate race to not cause OOM"
21405
21406 test_222a () {
21407         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21408
21409         rm -rf $DIR/$tdir
21410         test_mkdir $DIR/$tdir
21411         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21412         createmany -o $DIR/$tdir/$tfile 10
21413         cancel_lru_locks mdc
21414         cancel_lru_locks osc
21415         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21416         $LCTL set_param fail_loc=0x31a
21417         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
21418         $LCTL set_param fail_loc=0
21419         rm -r $DIR/$tdir
21420 }
21421 run_test 222a "AGL for ls should not trigger CLIO lock failure"
21422
21423 test_222b () {
21424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21425
21426         rm -rf $DIR/$tdir
21427         test_mkdir $DIR/$tdir
21428         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21429         createmany -o $DIR/$tdir/$tfile 10
21430         cancel_lru_locks mdc
21431         cancel_lru_locks osc
21432         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21433         $LCTL set_param fail_loc=0x31a
21434         rm -r $DIR/$tdir || error "AGL for rmdir failed"
21435         $LCTL set_param fail_loc=0
21436 }
21437 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
21438
21439 test_223 () {
21440         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21441
21442         rm -rf $DIR/$tdir
21443         test_mkdir $DIR/$tdir
21444         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21445         createmany -o $DIR/$tdir/$tfile 10
21446         cancel_lru_locks mdc
21447         cancel_lru_locks osc
21448         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
21449         $LCTL set_param fail_loc=0x31b
21450         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
21451         $LCTL set_param fail_loc=0
21452         rm -r $DIR/$tdir
21453 }
21454 run_test 223 "osc reenqueue if without AGL lock granted ======================="
21455
21456 test_224a() { # LU-1039, MRP-303
21457         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21458         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
21459         $LCTL set_param fail_loc=0x508
21460         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
21461         $LCTL set_param fail_loc=0
21462         df $DIR
21463 }
21464 run_test 224a "Don't panic on bulk IO failure"
21465
21466 test_224bd_sub() { # LU-1039, MRP-303
21467         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21468         local timeout=$1
21469
21470         shift
21471         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
21472
21473         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21474
21475         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
21476         cancel_lru_locks osc
21477         set_checksums 0
21478         stack_trap "set_checksums $ORIG_CSUM" EXIT
21479         local at_max_saved=0
21480
21481         # adaptive timeouts may prevent seeing the issue
21482         if at_is_enabled; then
21483                 at_max_saved=$(at_max_get mds)
21484                 at_max_set 0 mds client
21485                 stack_trap "at_max_set $at_max_saved mds client" EXIT
21486         fi
21487
21488         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
21489         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
21490         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
21491
21492         do_facet ost1 $LCTL set_param fail_loc=0
21493         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
21494         df $DIR
21495 }
21496
21497 test_224b() {
21498         test_224bd_sub 3 error "dd failed"
21499 }
21500 run_test 224b "Don't panic on bulk IO failure"
21501
21502 test_224c() { # LU-6441
21503         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21504         remote_mds_nodsh && skip "remote MDS with nodsh"
21505
21506         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
21507         save_writethrough $p
21508         set_cache writethrough on
21509
21510         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
21511         local at_max=$($LCTL get_param -n at_max)
21512         local timeout=$($LCTL get_param -n timeout)
21513         local test_at="at_max"
21514         local param_at="$FSNAME.sys.at_max"
21515         local test_timeout="timeout"
21516         local param_timeout="$FSNAME.sys.timeout"
21517
21518         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
21519
21520         set_persistent_param_and_check client "$test_at" "$param_at" 0
21521         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
21522
21523         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
21524         do_facet ost1 "$LCTL set_param fail_loc=0x520"
21525         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21526         stack_trap "rm -f $DIR/$tfile"
21527         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
21528         sync
21529         do_facet ost1 "$LCTL set_param fail_loc=0"
21530
21531         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
21532         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
21533                 $timeout
21534
21535         $LCTL set_param -n $pages_per_rpc
21536         restore_lustre_params < $p
21537         rm -f $p
21538 }
21539 run_test 224c "Don't hang if one of md lost during large bulk RPC"
21540
21541 test_224d() { # LU-11169
21542         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
21543 }
21544 run_test 224d "Don't corrupt data on bulk IO timeout"
21545
21546 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
21547 test_225a () {
21548         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21549         if [ -z ${MDSSURVEY} ]; then
21550                 skip_env "mds-survey not found"
21551         fi
21552         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21553                 skip "Need MDS version at least 2.2.51"
21554
21555         local mds=$(facet_host $SINGLEMDS)
21556         local target=$(do_nodes $mds 'lctl dl' |
21557                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21558
21559         local cmd1="file_count=1000 thrhi=4"
21560         local cmd2="dir_count=2 layer=mdd stripe_count=0"
21561         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21562         local cmd="$cmd1 $cmd2 $cmd3"
21563
21564         rm -f ${TMP}/mds_survey*
21565         echo + $cmd
21566         eval $cmd || error "mds-survey with zero-stripe failed"
21567         cat ${TMP}/mds_survey*
21568         rm -f ${TMP}/mds_survey*
21569 }
21570 run_test 225a "Metadata survey sanity with zero-stripe"
21571
21572 test_225b () {
21573         if [ -z ${MDSSURVEY} ]; then
21574                 skip_env "mds-survey not found"
21575         fi
21576         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21577                 skip "Need MDS version at least 2.2.51"
21578         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21579         remote_mds_nodsh && skip "remote MDS with nodsh"
21580         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
21581                 skip_env "Need to mount OST to test"
21582         fi
21583
21584         local mds=$(facet_host $SINGLEMDS)
21585         local target=$(do_nodes $mds 'lctl dl' |
21586                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21587
21588         local cmd1="file_count=1000 thrhi=4"
21589         local cmd2="dir_count=2 layer=mdd stripe_count=1"
21590         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21591         local cmd="$cmd1 $cmd2 $cmd3"
21592
21593         rm -f ${TMP}/mds_survey*
21594         echo + $cmd
21595         eval $cmd || error "mds-survey with stripe_count failed"
21596         cat ${TMP}/mds_survey*
21597         rm -f ${TMP}/mds_survey*
21598 }
21599 run_test 225b "Metadata survey sanity with stripe_count = 1"
21600
21601 mcreate_path2fid () {
21602         local mode=$1
21603         local major=$2
21604         local minor=$3
21605         local name=$4
21606         local desc=$5
21607         local path=$DIR/$tdir/$name
21608         local fid
21609         local rc
21610         local fid_path
21611
21612         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
21613                 error "cannot create $desc"
21614
21615         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
21616         rc=$?
21617         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
21618
21619         fid_path=$($LFS fid2path $MOUNT $fid)
21620         rc=$?
21621         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
21622
21623         [ "$path" == "$fid_path" ] ||
21624                 error "fid2path returned $fid_path, expected $path"
21625
21626         echo "pass with $path and $fid"
21627 }
21628
21629 test_226a () {
21630         rm -rf $DIR/$tdir
21631         mkdir -p $DIR/$tdir
21632
21633         mcreate_path2fid 0010666 0 0 fifo "FIFO"
21634         mcreate_path2fid 0020666 1 3 null "character special file (null)"
21635         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
21636         mcreate_path2fid 0040666 0 0 dir "directory"
21637         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
21638         mcreate_path2fid 0100666 0 0 file "regular file"
21639         mcreate_path2fid 0120666 0 0 link "symbolic link"
21640         mcreate_path2fid 0140666 0 0 sock "socket"
21641 }
21642 run_test 226a "call path2fid and fid2path on files of all type"
21643
21644 test_226b () {
21645         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21646
21647         local MDTIDX=1
21648
21649         rm -rf $DIR/$tdir
21650         mkdir -p $DIR/$tdir
21651         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
21652                 error "create remote directory failed"
21653         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
21654         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
21655                                 "character special file (null)"
21656         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
21657                                 "character special file (no device)"
21658         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
21659         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
21660                                 "block special file (loop)"
21661         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
21662         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
21663         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
21664 }
21665 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
21666
21667 test_226c () {
21668         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21669         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
21670                 skip "Need MDS version at least 2.13.55"
21671
21672         local submnt=/mnt/submnt
21673         local srcfile=/etc/passwd
21674         local dstfile=$submnt/passwd
21675         local path
21676         local fid
21677
21678         rm -rf $DIR/$tdir
21679         rm -rf $submnt
21680         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
21681                 error "create remote directory failed"
21682         mkdir -p $submnt || error "create $submnt failed"
21683         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
21684                 error "mount $submnt failed"
21685         stack_trap "umount $submnt" EXIT
21686
21687         cp $srcfile $dstfile
21688         fid=$($LFS path2fid $dstfile)
21689         path=$($LFS fid2path $submnt "$fid")
21690         [ "$path" = "$dstfile" ] ||
21691                 error "fid2path $submnt $fid failed ($path != $dstfile)"
21692 }
21693 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
21694
21695 test_226d () {
21696         (( $CLIENT_VERSION >= $(version_code 2.15.57) )) ||
21697                 skip "Need client at least version 2.15.57"
21698
21699         # Define First test dataset
21700         local testdirs_01=$DIR/$tdir
21701         local testdata_01=$testdirs_01/${tdir}_01
21702         local testresult_01=${tdir}_01
21703         # Define Second test dataset
21704         local testdirs_02=$DIR/$tdir/$tdir
21705         local testdata_02=$testdirs_02/${tdir}_02
21706         local testresult_02=${tdir}_02
21707         # Define third test dataset (top level)
21708         local testdata_03=$DIR/${tdir}_03
21709         local testresult_03=${tdir}_03
21710
21711         # Create first test dataset
21712         mkdir -p $testdirs_01 || error "cannot create dir $testdirs_01"
21713         touch $testdata_01 || error "cannot create file $testdata_01"
21714
21715         # Create second test dataset
21716         mkdir -p $testdirs_02 || error "cannot create dir $testdirs_02"
21717         touch $testdata_02 || error "cannot create file $testdata_02"
21718
21719         # Create third test dataset
21720         touch $testdata_03 || error "cannot create file $testdata_03"
21721
21722         local fid01=$($LFS getstripe -F "$testdata_01") ||
21723                 error "getstripe failed on $testdata_01"
21724         local fid02=$($LFS getstripe -F "$testdata_02") ||
21725                 error "getstripe failed on $testdata_01"
21726         local fid03=$($LFS getstripe -F "$testdata_03") ||
21727                 error "getstripe failed on $testdata_03"
21728
21729         # Verify only -n option
21730         local out1=$($LFS fid2path -n $DIR $fid01) ||
21731                 error "fid2path failed on $fid01"
21732         local out2=$($LFS fid2path -n $DIR $fid02) ||
21733                 error "fid2path failed on $fid02"
21734         local out3=$($LFS fid2path -n $DIR $fid03) ||
21735                 error "fid2path failed on $fid03"
21736
21737         [[ "$out1" == "$testresult_01" ]] ||
21738                 error "fid2path failed: Expected $testresult_01 got $out1"
21739         [[ "$out2" == "$testresult_02" ]] ||
21740                 error "fid2path failed: Expected $testresult_02 got $out2"
21741         [[ "$out3" == "$testresult_03" ]] ||
21742                 error "fid2path failed: Expected $testresult_03 got $out3"
21743
21744         # Verify with option -fn together
21745         out1=$($LFS fid2path -fn $DIR $fid01) ||
21746                 error "fid2path -fn failed on $fid01"
21747         out2=$($LFS fid2path -fn $DIR $fid02) ||
21748                 error "fid2path -fn failed on $fid02"
21749         out3=$($LFS fid2path -fn $DIR $fid03) ||
21750                 error "fid2path -fn failed on $fid03"
21751
21752         local tmpout=$(echo $out1 | cut -d" " -f2)
21753         [[ "$tmpout" == "$testresult_01" ]] ||
21754                 error "fid2path -fn failed: Expected $testresult_01 got $out1"
21755
21756         tmpout=$(echo $out2 | cut -d" " -f2)
21757         [[ "$tmpout" == "$testresult_02" ]] ||
21758                 error "fid2path -fn failed: Expected $testresult_02 got $out2"
21759
21760         tmpout=$(echo $out3 | cut -d" " -f2)
21761         [[ "$tmpout" == "$testresult_03" ]] ||
21762                 error "fid2path -fn failed: Expected $testresult_03 got $out3"
21763 }
21764 run_test 226d "verify fid2path with -n and -fn option"
21765
21766 test_226e () {
21767         (( $CLIENT_VERSION >= $(version_code 2.15.56) )) ||
21768                 skip "Need client at least version 2.15.56"
21769
21770         # Define filename with 'newline' and a space
21771         local testfile="Test"$'\n'"file 01"
21772         # Define link name with multiple 'newline' and a space
21773         local linkfile="Link"$'\n'"file "$'\n'"01"
21774         # Remove prior hard link
21775         rm -f $DIR/"$linkfile"
21776
21777         # Create file
21778         touch $DIR/"$testfile"
21779         # Create link
21780         ln $DIR/"$testfile" $DIR/"$linkfile"
21781
21782         local fid=$($LFS getstripe -F "$DIR/$testfile") ||
21783                 error "getstripe failed on $DIR/$testfile"
21784
21785         # Call with -0 option
21786         local out1=$($LFS fid2path -0 $DIR $fid | xargs --null -n1 \
21787                 echo "FILE:" | grep -c "FILE:")
21788
21789         # With -0 option the output should be exactly 2 lines.
21790         (( $out1 == 2 )) || error "fid2path -0 failed on $fid, $out1"
21791 }
21792 run_test 226e "Verify path2fid -0 option with newline and space"
21793
21794 # LU-1299 Executing or running ldd on a truncated executable does not
21795 # cause an out-of-memory condition.
21796 test_227() {
21797         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21798         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
21799
21800         dd if=$(which date) of=$MOUNT/date bs=1k count=1
21801         chmod +x $MOUNT/date
21802
21803         $MOUNT/date > /dev/null
21804         ldd $MOUNT/date > /dev/null
21805         rm -f $MOUNT/date
21806 }
21807 run_test 227 "running truncated executable does not cause OOM"
21808
21809 # LU-1512 try to reuse idle OI blocks
21810 test_228a() {
21811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21812         remote_mds_nodsh && skip "remote MDS with nodsh"
21813         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21814
21815         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21816         local myDIR=$DIR/$tdir
21817
21818         mkdir -p $myDIR
21819         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21820         $LCTL set_param fail_loc=0x80001002
21821         createmany -o $myDIR/t- 10000
21822         $LCTL set_param fail_loc=0
21823         # The guard is current the largest FID holder
21824         touch $myDIR/guard
21825         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21826                     tr -d '[')
21827         local IDX=$(($SEQ % 64))
21828
21829         do_facet $SINGLEMDS sync
21830         # Make sure journal flushed.
21831         sleep 6
21832         local blk1=$(do_facet $SINGLEMDS \
21833                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21834                      grep Blockcount | awk '{print $4}')
21835
21836         # Remove old files, some OI blocks will become idle.
21837         unlinkmany $myDIR/t- 10000
21838         # Create new files, idle OI blocks should be reused.
21839         createmany -o $myDIR/t- 2000
21840         do_facet $SINGLEMDS sync
21841         # Make sure journal flushed.
21842         sleep 6
21843         local blk2=$(do_facet $SINGLEMDS \
21844                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21845                      grep Blockcount | awk '{print $4}')
21846
21847         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21848 }
21849 run_test 228a "try to reuse idle OI blocks"
21850
21851 test_228b() {
21852         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21853         remote_mds_nodsh && skip "remote MDS with nodsh"
21854         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21855
21856         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21857         local myDIR=$DIR/$tdir
21858
21859         mkdir -p $myDIR
21860         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21861         $LCTL set_param fail_loc=0x80001002
21862         createmany -o $myDIR/t- 10000
21863         $LCTL set_param fail_loc=0
21864         # The guard is current the largest FID holder
21865         touch $myDIR/guard
21866         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21867                     tr -d '[')
21868         local IDX=$(($SEQ % 64))
21869
21870         do_facet $SINGLEMDS sync
21871         # Make sure journal flushed.
21872         sleep 6
21873         local blk1=$(do_facet $SINGLEMDS \
21874                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21875                      grep Blockcount | awk '{print $4}')
21876
21877         # Remove old files, some OI blocks will become idle.
21878         unlinkmany $myDIR/t- 10000
21879
21880         # stop the MDT
21881         stop $SINGLEMDS || error "Fail to stop MDT."
21882         # remount the MDT
21883         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
21884                 error "Fail to start MDT."
21885
21886         client_up || error "Fail to df."
21887         # Create new files, idle OI blocks should be reused.
21888         createmany -o $myDIR/t- 2000
21889         do_facet $SINGLEMDS sync
21890         # Make sure journal flushed.
21891         sleep 6
21892         local blk2=$(do_facet $SINGLEMDS \
21893                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21894                      grep Blockcount | awk '{print $4}')
21895
21896         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21897 }
21898 run_test 228b "idle OI blocks can be reused after MDT restart"
21899
21900 #LU-1881
21901 test_228c() {
21902         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21903         remote_mds_nodsh && skip "remote MDS with nodsh"
21904         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21905
21906         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21907         local myDIR=$DIR/$tdir
21908
21909         mkdir -p $myDIR
21910         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21911         $LCTL set_param fail_loc=0x80001002
21912         # 20000 files can guarantee there are index nodes in the OI file
21913         createmany -o $myDIR/t- 20000
21914         $LCTL set_param fail_loc=0
21915         # The guard is current the largest FID holder
21916         touch $myDIR/guard
21917         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21918                     tr -d '[')
21919         local IDX=$(($SEQ % 64))
21920
21921         do_facet $SINGLEMDS sync
21922         # Make sure journal flushed.
21923         sleep 6
21924         local blk1=$(do_facet $SINGLEMDS \
21925                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21926                      grep Blockcount | awk '{print $4}')
21927
21928         # Remove old files, some OI blocks will become idle.
21929         unlinkmany $myDIR/t- 20000
21930         rm -f $myDIR/guard
21931         # The OI file should become empty now
21932
21933         # Create new files, idle OI blocks should be reused.
21934         createmany -o $myDIR/t- 2000
21935         do_facet $SINGLEMDS sync
21936         # Make sure journal flushed.
21937         sleep 6
21938         local blk2=$(do_facet $SINGLEMDS \
21939                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21940                      grep Blockcount | awk '{print $4}')
21941
21942         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21943 }
21944 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
21945
21946 test_229() { # LU-2482, LU-3448
21947         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21948         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
21949         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
21950                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
21951
21952         rm -f $DIR/$tfile
21953
21954         # Create a file with a released layout and stripe count 2.
21955         $MULTIOP $DIR/$tfile H2c ||
21956                 error "failed to create file with released layout"
21957
21958         $LFS getstripe -v $DIR/$tfile
21959
21960         local pattern=$($LFS getstripe -L $DIR/$tfile)
21961         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
21962
21963         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
21964                 error "getstripe"
21965         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
21966         stat $DIR/$tfile || error "failed to stat released file"
21967
21968         chown $RUNAS_ID $DIR/$tfile ||
21969                 error "chown $RUNAS_ID $DIR/$tfile failed"
21970
21971         chgrp $RUNAS_ID $DIR/$tfile ||
21972                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
21973
21974         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
21975         rm $DIR/$tfile || error "failed to remove released file"
21976 }
21977 run_test 229 "getstripe/stat/rm/attr changes work on released files"
21978
21979 test_230a() {
21980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21981         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21982         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21983                 skip "Need MDS version at least 2.11.52"
21984
21985         local MDTIDX=1
21986
21987         test_mkdir $DIR/$tdir
21988         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
21989         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
21990         [ $mdt_idx -ne 0 ] &&
21991                 error "create local directory on wrong MDT $mdt_idx"
21992
21993         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
21994                         error "create remote directory failed"
21995         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
21996         [ $mdt_idx -ne $MDTIDX ] &&
21997                 error "create remote directory on wrong MDT $mdt_idx"
21998
21999         createmany -o $DIR/$tdir/test_230/t- 10 ||
22000                 error "create files on remote directory failed"
22001         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
22002         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
22003         rm -r $DIR/$tdir || error "unlink remote directory failed"
22004 }
22005 run_test 230a "Create remote directory and files under the remote directory"
22006
22007 test_230b() {
22008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22009         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22010         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22011                 skip "Need MDS version at least 2.11.52"
22012
22013         local MDTIDX=1
22014         local mdt_index
22015         local i
22016         local file
22017         local pid
22018         local stripe_count
22019         local migrate_dir=$DIR/$tdir/migrate_dir
22020         local other_dir=$DIR/$tdir/other_dir
22021
22022         test_mkdir $DIR/$tdir
22023         test_mkdir -i0 -c1 $migrate_dir
22024         test_mkdir -i0 -c1 $other_dir
22025         for ((i=0; i<10; i++)); do
22026                 mkdir -p $migrate_dir/dir_${i}
22027                 createmany -o $migrate_dir/dir_${i}/f 10 ||
22028                         error "create files under remote dir failed $i"
22029         done
22030
22031         cp /etc/passwd $migrate_dir/$tfile
22032         cp /etc/passwd $other_dir/$tfile
22033         chattr +SAD $migrate_dir
22034         chattr +SAD $migrate_dir/$tfile
22035
22036         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
22037         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
22038         local old_dir_mode=$(stat -c%f $migrate_dir)
22039         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
22040
22041         mkdir -p $migrate_dir/dir_default_stripe2
22042         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
22043         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
22044
22045         mkdir -p $other_dir
22046         ln $migrate_dir/$tfile $other_dir/luna
22047         ln $migrate_dir/$tfile $migrate_dir/sofia
22048         ln $other_dir/$tfile $migrate_dir/david
22049         ln -s $migrate_dir/$tfile $other_dir/zachary
22050         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
22051         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
22052
22053         local len
22054         local lnktgt
22055
22056         # inline symlink
22057         for len in 58 59 60; do
22058                 lnktgt=$(str_repeat 'l' $len)
22059                 touch $migrate_dir/$lnktgt
22060                 ln -s $lnktgt $migrate_dir/${len}char_ln
22061         done
22062
22063         # PATH_MAX
22064         for len in 4094 4095; do
22065                 lnktgt=$(str_repeat 'l' $len)
22066                 ln -s $lnktgt $migrate_dir/${len}char_ln
22067         done
22068
22069         # NAME_MAX
22070         for len in 254 255; do
22071                 touch $migrate_dir/$(str_repeat 'l' $len)
22072         done
22073
22074         $LFS migrate -m $MDTIDX $migrate_dir ||
22075                 error "fails on migrating remote dir to MDT1"
22076
22077         echo "migratate to MDT1, then checking.."
22078         for ((i = 0; i < 10; i++)); do
22079                 for file in $(find $migrate_dir/dir_${i}); do
22080                         mdt_index=$($LFS getstripe -m $file)
22081                         # broken symlink getstripe will fail
22082                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
22083                                 error "$file is not on MDT${MDTIDX}"
22084                 done
22085         done
22086
22087         # the multiple link file should still in MDT0
22088         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
22089         [ $mdt_index == 0 ] ||
22090                 error "$file is not on MDT${MDTIDX}"
22091
22092         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
22093         [ "$old_dir_flag" = "$new_dir_flag" ] ||
22094                 error " expect $old_dir_flag get $new_dir_flag"
22095
22096         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
22097         [ "$old_file_flag" = "$new_file_flag" ] ||
22098                 error " expect $old_file_flag get $new_file_flag"
22099
22100         local new_dir_mode=$(stat -c%f $migrate_dir)
22101         [ "$old_dir_mode" = "$new_dir_mode" ] ||
22102                 error "expect mode $old_dir_mode get $new_dir_mode"
22103
22104         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
22105         [ "$old_file_mode" = "$new_file_mode" ] ||
22106                 error "expect mode $old_file_mode get $new_file_mode"
22107
22108         diff /etc/passwd $migrate_dir/$tfile ||
22109                 error "$tfile different after migration"
22110
22111         diff /etc/passwd $other_dir/luna ||
22112                 error "luna different after migration"
22113
22114         diff /etc/passwd $migrate_dir/sofia ||
22115                 error "sofia different after migration"
22116
22117         diff /etc/passwd $migrate_dir/david ||
22118                 error "david different after migration"
22119
22120         diff /etc/passwd $other_dir/zachary ||
22121                 error "zachary different after migration"
22122
22123         diff /etc/passwd $migrate_dir/${tfile}_ln ||
22124                 error "${tfile}_ln different after migration"
22125
22126         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
22127                 error "${tfile}_ln_other different after migration"
22128
22129         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
22130         [ $stripe_count = 2 ] ||
22131                 error "dir strpe_count $d != 2 after migration."
22132
22133         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
22134         [ $stripe_count = 2 ] ||
22135                 error "file strpe_count $d != 2 after migration."
22136
22137         #migrate back to MDT0
22138         MDTIDX=0
22139
22140         $LFS migrate -m $MDTIDX $migrate_dir ||
22141                 error "fails on migrating remote dir to MDT0"
22142
22143         echo "migrate back to MDT0, checking.."
22144         for file in $(find $migrate_dir); do
22145                 mdt_index=$($LFS getstripe -m $file)
22146                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
22147                         error "$file is not on MDT${MDTIDX}"
22148         done
22149
22150         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
22151         [ "$old_dir_flag" = "$new_dir_flag" ] ||
22152                 error " expect $old_dir_flag get $new_dir_flag"
22153
22154         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
22155         [ "$old_file_flag" = "$new_file_flag" ] ||
22156                 error " expect $old_file_flag get $new_file_flag"
22157
22158         local new_dir_mode=$(stat -c%f $migrate_dir)
22159         [ "$old_dir_mode" = "$new_dir_mode" ] ||
22160                 error "expect mode $old_dir_mode get $new_dir_mode"
22161
22162         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
22163         [ "$old_file_mode" = "$new_file_mode" ] ||
22164                 error "expect mode $old_file_mode get $new_file_mode"
22165
22166         diff /etc/passwd ${migrate_dir}/$tfile ||
22167                 error "$tfile different after migration"
22168
22169         diff /etc/passwd ${other_dir}/luna ||
22170                 error "luna different after migration"
22171
22172         diff /etc/passwd ${migrate_dir}/sofia ||
22173                 error "sofia different after migration"
22174
22175         diff /etc/passwd ${other_dir}/zachary ||
22176                 error "zachary different after migration"
22177
22178         diff /etc/passwd $migrate_dir/${tfile}_ln ||
22179                 error "${tfile}_ln different after migration"
22180
22181         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
22182                 error "${tfile}_ln_other different after migration"
22183
22184         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
22185         [ $stripe_count = 2 ] ||
22186                 error "dir strpe_count $d != 2 after migration."
22187
22188         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
22189         [ $stripe_count = 2 ] ||
22190                 error "file strpe_count $d != 2 after migration."
22191
22192         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22193 }
22194 run_test 230b "migrate directory"
22195
22196 test_230c() {
22197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22198         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22199         remote_mds_nodsh && skip "remote MDS with nodsh"
22200         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22201                 skip "Need MDS version at least 2.11.52"
22202
22203         local MDTIDX=1
22204         local total=3
22205         local mdt_index
22206         local file
22207         local migrate_dir=$DIR/$tdir/migrate_dir
22208
22209         #If migrating directory fails in the middle, all entries of
22210         #the directory is still accessiable.
22211         test_mkdir $DIR/$tdir
22212         test_mkdir -i0 -c1 $migrate_dir
22213         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
22214         stat $migrate_dir
22215         createmany -o $migrate_dir/f $total ||
22216                 error "create files under ${migrate_dir} failed"
22217
22218         # fail after migrating top dir, and this will fail only once, so the
22219         # first sub file migration will fail (currently f3), others succeed.
22220         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
22221         do_facet mds1 lctl set_param fail_loc=0x1801
22222         local t=$(ls $migrate_dir | wc -l)
22223         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
22224                 error "migrate should fail"
22225         local u=$(ls $migrate_dir | wc -l)
22226         [ "$u" == "$t" ] || error "$u != $t during migration"
22227
22228         # add new dir/file should succeed
22229         mkdir $migrate_dir/dir ||
22230                 error "mkdir failed under migrating directory"
22231         touch $migrate_dir/file ||
22232                 error "create file failed under migrating directory"
22233
22234         # add file with existing name should fail
22235         for file in $migrate_dir/f*; do
22236                 stat $file > /dev/null || error "stat $file failed"
22237                 $OPENFILE -f O_CREAT:O_EXCL $file &&
22238                         error "open(O_CREAT|O_EXCL) $file should fail"
22239                 $MULTIOP $file m && error "create $file should fail"
22240                 touch $DIR/$tdir/remote_dir/$tfile ||
22241                         error "touch $tfile failed"
22242                 ln $DIR/$tdir/remote_dir/$tfile $file &&
22243                         error "link $file should fail"
22244                 mdt_index=$($LFS getstripe -m $file)
22245                 if [ $mdt_index == 0 ]; then
22246                         # file failed to migrate is not allowed to rename to
22247                         mv $DIR/$tdir/remote_dir/$tfile $file &&
22248                                 error "rename to $file should fail"
22249                 else
22250                         mv $DIR/$tdir/remote_dir/$tfile $file ||
22251                                 error "rename to $file failed"
22252                 fi
22253                 echo hello >> $file || error "write $file failed"
22254         done
22255
22256         # resume migration with different options should fail
22257         $LFS migrate -m 0 $migrate_dir &&
22258                 error "migrate -m 0 $migrate_dir should fail"
22259
22260         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
22261                 error "migrate -c 2 $migrate_dir should fail"
22262
22263         # resume migration should succeed
22264         $LFS migrate -m $MDTIDX $migrate_dir ||
22265                 error "migrate $migrate_dir failed"
22266
22267         echo "Finish migration, then checking.."
22268         for file in $(find $migrate_dir); do
22269                 mdt_index=$($LFS getstripe -m $file)
22270                 [ $mdt_index == $MDTIDX ] ||
22271                         error "$file is not on MDT${MDTIDX}"
22272         done
22273
22274         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22275 }
22276 run_test 230c "check directory accessiblity if migration failed"
22277
22278 test_230d() {
22279         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22280         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22281         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22282                 skip "Need MDS version at least 2.11.52"
22283         # LU-11235
22284         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
22285
22286         local migrate_dir=$DIR/$tdir/migrate_dir
22287         local old_index
22288         local new_index
22289         local old_count
22290         local new_count
22291         local new_hash
22292         local mdt_index
22293         local i
22294         local j
22295
22296         old_index=$((RANDOM % MDSCOUNT))
22297         old_count=$((MDSCOUNT - old_index))
22298         new_index=$((RANDOM % MDSCOUNT))
22299         new_count=$((MDSCOUNT - new_index))
22300         new_hash=1 # for all_char
22301
22302         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
22303         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
22304
22305         test_mkdir $DIR/$tdir
22306         test_mkdir -i $old_index -c $old_count $migrate_dir
22307
22308         for ((i=0; i<100; i++)); do
22309                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
22310                 createmany -o $migrate_dir/dir_${i}/f 100 ||
22311                         error "create files under remote dir failed $i"
22312         done
22313
22314         echo -n "Migrate from MDT$old_index "
22315         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
22316         echo -n "to MDT$new_index"
22317         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
22318         echo
22319
22320         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
22321         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
22322                 error "migrate remote dir error"
22323
22324         echo "Finish migration, then checking.."
22325         for file in $(find $migrate_dir -maxdepth 1); do
22326                 mdt_index=$($LFS getstripe -m $file)
22327                 if [ $mdt_index -lt $new_index ] ||
22328                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
22329                         error "$file is on MDT$mdt_index"
22330                 fi
22331         done
22332
22333         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22334 }
22335 run_test 230d "check migrate big directory"
22336
22337 test_230e() {
22338         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22339         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22340         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22341                 skip "Need MDS version at least 2.11.52"
22342
22343         local i
22344         local j
22345         local a_fid
22346         local b_fid
22347
22348         mkdir_on_mdt0 $DIR/$tdir
22349         mkdir $DIR/$tdir/migrate_dir
22350         mkdir $DIR/$tdir/other_dir
22351         touch $DIR/$tdir/migrate_dir/a
22352         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
22353         ls $DIR/$tdir/other_dir
22354
22355         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22356                 error "migrate dir fails"
22357
22358         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
22359         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
22360
22361         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22362         [ $mdt_index == 0 ] || error "a is not on MDT0"
22363
22364         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
22365                 error "migrate dir fails"
22366
22367         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
22368         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
22369
22370         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22371         [ $mdt_index == 1 ] || error "a is not on MDT1"
22372
22373         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
22374         [ $mdt_index == 1 ] || error "b is not on MDT1"
22375
22376         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
22377         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
22378
22379         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
22380
22381         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22382 }
22383 run_test 230e "migrate mulitple local link files"
22384
22385 test_230f() {
22386         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22387         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22388         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22389                 skip "Need MDS version at least 2.11.52"
22390
22391         local a_fid
22392         local ln_fid
22393
22394         mkdir -p $DIR/$tdir
22395         mkdir $DIR/$tdir/migrate_dir
22396         $LFS mkdir -i1 $DIR/$tdir/other_dir
22397         touch $DIR/$tdir/migrate_dir/a
22398         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
22399         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
22400         ls $DIR/$tdir/other_dir
22401
22402         # a should be migrated to MDT1, since no other links on MDT0
22403         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22404                 error "#1 migrate dir fails"
22405         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
22406         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
22407         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22408         [ $mdt_index == 1 ] || error "a is not on MDT1"
22409
22410         # a should stay on MDT1, because it is a mulitple link file
22411         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22412                 error "#2 migrate dir fails"
22413         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22414         [ $mdt_index == 1 ] || error "a is not on MDT1"
22415
22416         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22417                 error "#3 migrate dir fails"
22418
22419         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
22420         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
22421         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
22422
22423         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
22424         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
22425
22426         # a should be migrated to MDT0, since no other links on MDT1
22427         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22428                 error "#4 migrate dir fails"
22429         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22430         [ $mdt_index == 0 ] || error "a is not on MDT0"
22431
22432         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22433 }
22434 run_test 230f "migrate mulitple remote link files"
22435
22436 test_230g() {
22437         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22438         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22439         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22440                 skip "Need MDS version at least 2.11.52"
22441
22442         mkdir -p $DIR/$tdir/migrate_dir
22443
22444         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
22445                 error "migrating dir to non-exist MDT succeeds"
22446         true
22447 }
22448 run_test 230g "migrate dir to non-exist MDT"
22449
22450 test_230h() {
22451         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22452         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22453         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22454                 skip "Need MDS version at least 2.11.52"
22455
22456         local mdt_index
22457
22458         mkdir -p $DIR/$tdir/migrate_dir
22459
22460         $LFS migrate -m1 $DIR &&
22461                 error "migrating mountpoint1 should fail"
22462
22463         $LFS migrate -m1 $DIR/$tdir/.. &&
22464                 error "migrating mountpoint2 should fail"
22465
22466         # same as mv
22467         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
22468                 error "migrating $tdir/migrate_dir/.. should fail"
22469
22470         true
22471 }
22472 run_test 230h "migrate .. and root"
22473
22474 test_230i() {
22475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22476         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22477         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22478                 skip "Need MDS version at least 2.11.52"
22479
22480         mkdir -p $DIR/$tdir/migrate_dir
22481
22482         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
22483                 error "migration fails with a tailing slash"
22484
22485         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
22486                 error "migration fails with two tailing slashes"
22487 }
22488 run_test 230i "lfs migrate -m tolerates trailing slashes"
22489
22490 test_230j() {
22491         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22492         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
22493                 skip "Need MDS version at least 2.11.52"
22494
22495         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22496         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
22497                 error "create $tfile failed"
22498         cat /etc/passwd > $DIR/$tdir/$tfile
22499
22500         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22501
22502         cmp /etc/passwd $DIR/$tdir/$tfile ||
22503                 error "DoM file mismatch after migration"
22504 }
22505 run_test 230j "DoM file data not changed after dir migration"
22506
22507 test_230k() {
22508         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
22509         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22510                 skip "Need MDS version at least 2.11.56"
22511
22512         local total=20
22513         local files_on_starting_mdt=0
22514
22515         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
22516         $LFS getdirstripe $DIR/$tdir
22517         for i in $(seq $total); do
22518                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
22519                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22520                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22521         done
22522
22523         echo "$files_on_starting_mdt files on MDT0"
22524
22525         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
22526         $LFS getdirstripe $DIR/$tdir
22527
22528         files_on_starting_mdt=0
22529         for i in $(seq $total); do
22530                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22531                         error "file $tfile.$i mismatch after migration"
22532                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
22533                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22534         done
22535
22536         echo "$files_on_starting_mdt files on MDT1 after migration"
22537         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
22538
22539         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
22540         $LFS getdirstripe $DIR/$tdir
22541
22542         files_on_starting_mdt=0
22543         for i in $(seq $total); do
22544                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22545                         error "file $tfile.$i mismatch after 2nd migration"
22546                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22547                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22548         done
22549
22550         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
22551         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
22552
22553         true
22554 }
22555 run_test 230k "file data not changed after dir migration"
22556
22557 test_230l() {
22558         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22559         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22560                 skip "Need MDS version at least 2.11.56"
22561
22562         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
22563         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
22564                 error "create files under remote dir failed $i"
22565         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22566 }
22567 run_test 230l "readdir between MDTs won't crash"
22568
22569 test_230m() {
22570         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22571         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22572                 skip "Need MDS version at least 2.11.56"
22573
22574         local MDTIDX=1
22575         local mig_dir=$DIR/$tdir/migrate_dir
22576         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
22577         local shortstr="b"
22578         local val
22579
22580         echo "Creating files and dirs with xattrs"
22581         test_mkdir $DIR/$tdir
22582         test_mkdir -i0 -c1 $mig_dir
22583         mkdir $mig_dir/dir
22584         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
22585                 error "cannot set xattr attr1 on dir"
22586         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
22587                 error "cannot set xattr attr2 on dir"
22588         touch $mig_dir/dir/f0
22589         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
22590                 error "cannot set xattr attr1 on file"
22591         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
22592                 error "cannot set xattr attr2 on file"
22593         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22594         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22595         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
22596         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22597         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
22598         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22599         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
22600         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22601         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
22602
22603         echo "Migrating to MDT1"
22604         $LFS migrate -m $MDTIDX $mig_dir ||
22605                 error "fails on migrating dir to MDT1"
22606
22607         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22608         echo "Checking xattrs"
22609         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22610         [ "$val" = $longstr ] ||
22611                 error "expecting xattr1 $longstr on dir, found $val"
22612         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22613         [ "$val" = $shortstr ] ||
22614                 error "expecting xattr2 $shortstr on dir, found $val"
22615         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22616         [ "$val" = $longstr ] ||
22617                 error "expecting xattr1 $longstr on file, found $val"
22618         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22619         [ "$val" = $shortstr ] ||
22620                 error "expecting xattr2 $shortstr on file, found $val"
22621 }
22622 run_test 230m "xattrs not changed after dir migration"
22623
22624 test_230n() {
22625         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22626         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22627                 skip "Need MDS version at least 2.13.53"
22628
22629         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
22630         cat /etc/hosts > $DIR/$tdir/$tfile
22631         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
22632         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
22633
22634         cmp /etc/hosts $DIR/$tdir/$tfile ||
22635                 error "File data mismatch after migration"
22636 }
22637 run_test 230n "Dir migration with mirrored file"
22638
22639 test_230o() {
22640         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
22641         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22642                 skip "Need MDS version at least 2.13.52"
22643
22644         local mdts=$(comma_list $(mdts_nodes))
22645         local timeout=100
22646         local restripe_status
22647         local delta
22648         local i
22649
22650         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22651
22652         # in case "crush" hash type is not set
22653         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22654
22655         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22656                            mdt.*MDT0000.enable_dir_restripe)
22657         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22658         stack_trap "do_nodes $mdts $LCTL set_param \
22659                     mdt.*.enable_dir_restripe=$restripe_status"
22660
22661         mkdir $DIR/$tdir
22662         createmany -m $DIR/$tdir/f 100 ||
22663                 error "create files under remote dir failed $i"
22664         createmany -d $DIR/$tdir/d 100 ||
22665                 error "create dirs under remote dir failed $i"
22666
22667         for i in $(seq 2 $MDSCOUNT); do
22668                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22669                 $LFS setdirstripe -c $i $DIR/$tdir ||
22670                         error "split -c $i $tdir failed"
22671                 wait_update $HOSTNAME \
22672                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
22673                         error "dir split not finished"
22674                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22675                         awk '/migrate/ {sum += $2} END { print sum }')
22676                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
22677                 # delta is around total_files/stripe_count
22678                 (( $delta < 200 / (i - 1) + 4 )) ||
22679                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
22680         done
22681 }
22682 run_test 230o "dir split"
22683
22684 test_230p() {
22685         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22686         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22687                 skip "Need MDS version at least 2.13.52"
22688
22689         local mdts=$(comma_list $(mdts_nodes))
22690         local timeout=100
22691         local restripe_status
22692         local delta
22693         local c
22694
22695         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22696
22697         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22698
22699         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22700                            mdt.*MDT0000.enable_dir_restripe)
22701         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22702         stack_trap "do_nodes $mdts $LCTL set_param \
22703                     mdt.*.enable_dir_restripe=$restripe_status"
22704
22705         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
22706         createmany -m $DIR/$tdir/f 100 ||
22707                 error "create files under remote dir failed"
22708         createmany -d $DIR/$tdir/d 100 ||
22709                 error "create dirs under remote dir failed"
22710
22711         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
22712                 local mdt_hash="crush"
22713
22714                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22715                 $LFS setdirstripe -c $c $DIR/$tdir ||
22716                         error "split -c $c $tdir failed"
22717                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
22718                         mdt_hash="$mdt_hash,fixed"
22719                 elif [ $c -eq 1 ]; then
22720                         mdt_hash="none"
22721                 fi
22722                 wait_update $HOSTNAME \
22723                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
22724                         error "dir merge not finished"
22725                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22726                         awk '/migrate/ {sum += $2} END { print sum }')
22727                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
22728                 # delta is around total_files/stripe_count
22729                 (( delta < 200 / c + 4 )) ||
22730                         error "$delta files migrated >= $((200 / c + 4))"
22731         done
22732 }
22733 run_test 230p "dir merge"
22734
22735 test_230q() {
22736         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
22737         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22738                 skip "Need MDS version at least 2.13.52"
22739
22740         local mdts=$(comma_list $(mdts_nodes))
22741         local saved_threshold=$(do_facet mds1 \
22742                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
22743         local saved_delta=$(do_facet mds1 \
22744                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
22745         local threshold=100
22746         local delta=2
22747         local total=0
22748         local stripe_count=0
22749         local stripe_index
22750         local nr_files
22751         local create
22752
22753         # test with fewer files on ZFS
22754         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
22755
22756         stack_trap "do_nodes $mdts $LCTL set_param \
22757                     mdt.*.dir_split_count=$saved_threshold"
22758         stack_trap "do_nodes $mdts $LCTL set_param \
22759                     mdt.*.dir_split_delta=$saved_delta"
22760         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
22761         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
22762         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
22763         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
22764         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
22765         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22766
22767         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22768         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22769
22770         create=$((threshold * 3 / 2))
22771         while [ $stripe_count -lt $MDSCOUNT ]; do
22772                 createmany -m $DIR/$tdir/f $total $create ||
22773                         error "create sub files failed"
22774                 stat $DIR/$tdir > /dev/null
22775                 total=$((total + create))
22776                 stripe_count=$((stripe_count + delta))
22777                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
22778
22779                 wait_update $HOSTNAME \
22780                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
22781                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
22782
22783                 wait_update $HOSTNAME \
22784                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
22785                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
22786
22787                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
22788                 echo "$nr_files/$total files on MDT$stripe_index after split"
22789                 # allow 10% margin of imbalance with crush hash
22790                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
22791                         error "$nr_files files on MDT$stripe_index after split"
22792
22793                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
22794                 [ $nr_files -eq $total ] ||
22795                         error "total sub files $nr_files != $total"
22796         done
22797
22798         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
22799
22800         echo "fixed layout directory won't auto split"
22801         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
22802         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
22803                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
22804         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
22805                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
22806 }
22807 run_test 230q "dir auto split"
22808
22809 test_230r() {
22810         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
22811         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
22812         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
22813                 skip "Need MDS version at least 2.13.54"
22814
22815         # maximum amount of local locks:
22816         # parent striped dir - 2 locks
22817         # new stripe in parent to migrate to - 1 lock
22818         # source and target - 2 locks
22819         # Total 5 locks for regular file
22820         mkdir -p $DIR/$tdir
22821         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
22822         touch $DIR/$tdir/dir1/eee
22823
22824         # create 4 hardlink for 4 more locks
22825         # Total: 9 locks > RS_MAX_LOCKS (8)
22826         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
22827         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
22828         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
22829         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
22830         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
22831         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
22832         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
22833         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
22834
22835         cancel_lru_locks mdc
22836
22837         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
22838                 error "migrate dir fails"
22839
22840         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22841 }
22842 run_test 230r "migrate with too many local locks"
22843
22844 test_230s() {
22845         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
22846                 skip "Need MDS version at least 2.14.52"
22847
22848         local mdts=$(comma_list $(mdts_nodes))
22849         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
22850                                 mdt.*MDT0000.enable_dir_restripe)
22851
22852         stack_trap "do_nodes $mdts $LCTL set_param \
22853                     mdt.*.enable_dir_restripe=$restripe_status"
22854
22855         local st
22856         for st in 0 1; do
22857                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
22858                 test_mkdir $DIR/$tdir
22859                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
22860                         error "$LFS mkdir should return EEXIST if target exists"
22861                 rmdir $DIR/$tdir
22862         done
22863 }
22864 run_test 230s "lfs mkdir should return -EEXIST if target exists"
22865
22866 test_230t()
22867 {
22868         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
22869         (( $MDS1_VERSION >= $(version_code 2.14.50) )) ||
22870                 skip "Need MDS version at least 2.14.50"
22871
22872         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
22873         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
22874         $LFS project -p 1 -s $DIR/$tdir ||
22875                 error "set $tdir project id failed"
22876         $LFS project -p 2 -s $DIR/$tdir/subdir ||
22877                 error "set subdir project id failed"
22878         local pbefore="$($LFS project -d $DIR/$tdir)"
22879         local sbefore="$($LFS project -d $DIR/$tdir/subdir)"
22880         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
22881
22882         local pafter="$($LFS project -d $DIR/$tdir)"
22883         local safter="$($LFS project -d $DIR/$tdir/subdir)"
22884         [[ "$pbefore" == "$pafter" ]] || error "projid '$pbefore' != '$pafter'"
22885         [[ "$sbefore" == "$safter" ]] || error "projid '$sbefore' != '$safter'"
22886
22887         (( $MDS1_VERSION >= $(version_code 2.15.59.107) )) ||
22888                 { echo "Need MDS >= 2.15.59.107 for projid rename"; return 0; }
22889
22890         # check rename works, even if source parent projid differs (LU-17016)
22891         test_mkdir $DIR/$tdir.2 || error "mkdir $tdir.2 failed"
22892         local fid_before=$($LFS path2fid $DIR/$tdir/subdir)
22893
22894         $LFS project -p 2 -s $DIR/$tdir.2 || error "set $tdir.2 projid failed"
22895         mrename $DIR/$tdir/subdir $DIR/$tdir.2/subdir ||
22896                 error "subdir failed rename for different source parent projid"
22897         local fid_after=$($LFS path2fid $DIR/$tdir.2/subdir)
22898
22899         [[ "$fid_before" == "$fid_after" ]] ||
22900                 error "fid before '$fid_before' != after '$fid_after'"
22901 }
22902 run_test 230t "migrate directory with project ID set"
22903
22904 test_230u()
22905 {
22906         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22907         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22908                 skip "Need MDS version at least 2.14.53"
22909
22910         local count
22911
22912         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22913         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22914         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
22915         for i in $(seq 0 $((MDSCOUNT - 1))); do
22916                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22917                 echo "$count dirs migrated to MDT$i"
22918         done
22919         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22920         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
22921 }
22922 run_test 230u "migrate directory by QOS"
22923
22924 test_230v()
22925 {
22926         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22927         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22928                 skip "Need MDS version at least 2.14.53"
22929
22930         local count
22931
22932         mkdir $DIR/$tdir || error "mkdir $tdir failed"
22933         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22934         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
22935         for i in $(seq 0 $((MDSCOUNT - 1))); do
22936                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22937                 echo "$count subdirs migrated to MDT$i"
22938                 (( i == 3 )) && (( count > 0 )) &&
22939                         error "subdir shouldn't be migrated to MDT3"
22940         done
22941         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22942         (( count == 3 )) || error "dirs migrated to $count MDTs"
22943 }
22944 run_test 230v "subdir migrated to the MDT where its parent is located"
22945
22946 test_230w() {
22947         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22948         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22949                 skip "Need MDS version at least 2.15.0"
22950
22951         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
22952         createmany -o $DIR/$tdir/f 10 || error "create files failed"
22953         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
22954
22955         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
22956                 error "migrate failed"
22957
22958         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
22959                 error "$tdir stripe count mismatch"
22960
22961         for i in $(seq 0 9); do
22962                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
22963                         error "d$i is striped"
22964         done
22965 }
22966 run_test 230w "non-recursive mode dir migration"
22967
22968 test_230x() {
22969         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22970         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22971                 skip "Need MDS version at least 2.15.0"
22972
22973         mkdir -p $DIR/$tdir || error "mkdir failed"
22974         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
22975
22976         local mdt_name=$(mdtname_from_index 0)
22977         local low=$(do_facet mds2 $LCTL get_param -n \
22978                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
22979         local high=$(do_facet mds2 $LCTL get_param -n \
22980                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
22981         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
22982         local maxage=$(do_facet mds2 $LCTL get_param -n \
22983                 osp.*$mdt_name-osp-MDT0001.maxage)
22984
22985         stack_trap "do_facet mds2 $LCTL set_param -n \
22986                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
22987                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
22988         stack_trap "do_facet mds2 $LCTL set_param -n \
22989                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
22990
22991         do_facet mds2 $LCTL set_param -n \
22992                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
22993         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
22994         sleep 4
22995         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
22996                 error "migrate $tdir should fail"
22997
22998         do_facet mds2 $LCTL set_param -n \
22999                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
23000         do_facet mds2 $LCTL set_param -n \
23001                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
23002         sleep 4
23003         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
23004                 error "migrate failed"
23005         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
23006                 error "$tdir stripe count mismatch"
23007 }
23008 run_test 230x "dir migration check space"
23009
23010 test_230y() {
23011         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23012         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
23013                 skip "Need MDS version at least 2.15.55.45"
23014
23015         local pid
23016
23017         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
23018         $LFS getdirstripe $DIR/$tdir
23019         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
23020         $LFS migrate -m 1 -c 2 $DIR/$tdir &
23021         pid=$!
23022         sleep 1
23023
23024         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
23025         do_facet mds2 lctl set_param fail_loc=0x1802
23026
23027         wait $pid
23028         do_facet mds2 lctl set_param fail_loc=0
23029         $LFS getdirstripe $DIR/$tdir
23030         unlinkmany -d $DIR/$tdir/d 100 || error "unlinkmany failed"
23031         rmdir $DIR/$tdir || error "rmdir $tdir failed"
23032 }
23033 run_test 230y "unlink dir with bad hash type"
23034
23035 test_230z() {
23036         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23037         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
23038                 skip "Need MDS version at least 2.15.55.45"
23039
23040         local pid
23041
23042         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
23043         $LFS getdirstripe $DIR/$tdir
23044         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
23045         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir &
23046         pid=$!
23047         sleep 1
23048
23049         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
23050         do_facet mds2 lctl set_param fail_loc=0x1802
23051
23052         wait $pid
23053         do_facet mds2 lctl set_param fail_loc=0
23054         $LFS getdirstripe $DIR/$tdir
23055
23056         # resume migration
23057         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir ||
23058                 error "resume migration failed"
23059         $LFS getdirstripe $DIR/$tdir
23060         [ $($LFS getdirstripe -H $DIR/$tdir) == "fnv_1a_64,fixed" ] ||
23061                 error "migration is not finished"
23062 }
23063 run_test 230z "resume dir migration with bad hash type"
23064
23065 test_231a()
23066 {
23067         # For simplicity this test assumes that max_pages_per_rpc
23068         # is the same across all OSCs
23069         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
23070         local bulk_size=$((max_pages * PAGE_SIZE))
23071         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
23072                                        head -n 1)
23073
23074         mkdir -p $DIR/$tdir
23075         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
23076                 error "failed to set stripe with -S ${brw_size}M option"
23077         stack_trap "rm -rf $DIR/$tdir"
23078
23079         # clear the OSC stats
23080         $LCTL set_param osc.*.stats=0 &>/dev/null
23081         stop_writeback
23082
23083         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
23084         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
23085                 oflag=direct &>/dev/null || error "dd failed"
23086
23087         sync; sleep 1; sync # just to be safe
23088         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
23089         if [ x$nrpcs != "x1" ]; then
23090                 $LCTL get_param osc.*.stats
23091                 error "found $nrpcs ost_write RPCs, not 1 as expected"
23092         fi
23093
23094         start_writeback
23095         # Drop the OSC cache, otherwise we will read from it
23096         cancel_lru_locks osc
23097
23098         # clear the OSC stats
23099         $LCTL set_param osc.*.stats=0 &>/dev/null
23100
23101         # Client reads $bulk_size.
23102         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
23103                 iflag=direct &>/dev/null || error "dd failed"
23104
23105         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
23106         if [ x$nrpcs != "x1" ]; then
23107                 $LCTL get_param osc.*.stats
23108                 error "found $nrpcs ost_read RPCs, not 1 as expected"
23109         fi
23110 }
23111 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
23112
23113 test_231b() {
23114         mkdir -p $DIR/$tdir
23115         stack_trap "rm -rf $DIR/$tdir"
23116         local i
23117         for i in {0..1023}; do
23118                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
23119                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
23120                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
23121         done
23122         sync
23123 }
23124 run_test 231b "must not assert on fully utilized OST request buffer"
23125
23126 test_232a() {
23127         mkdir -p $DIR/$tdir
23128         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
23129
23130         #define OBD_FAIL_LDLM_OST_LVB            0x31c
23131         do_facet ost1 $LCTL set_param fail_loc=0x31c
23132
23133         # ignore dd failure
23134         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
23135         stack_trap "rm -f $DIR/$tdir/$tfile"
23136
23137         do_facet ost1 $LCTL set_param fail_loc=0
23138         umount_client $MOUNT || error "umount failed"
23139         mount_client $MOUNT || error "mount failed"
23140         stop ost1 || error "cannot stop ost1"
23141         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23142 }
23143 run_test 232a "failed lock should not block umount"
23144
23145 test_232b() {
23146         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
23147                 skip "Need MDS version at least 2.10.58"
23148
23149         mkdir -p $DIR/$tdir
23150         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
23151         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
23152         stack_trap "rm -f $DIR/$tdir/$tfile"
23153         sync
23154         cancel_lru_locks osc
23155
23156         #define OBD_FAIL_LDLM_OST_LVB            0x31c
23157         do_facet ost1 $LCTL set_param fail_loc=0x31c
23158
23159         # ignore failure
23160         $LFS data_version $DIR/$tdir/$tfile || true
23161
23162         do_facet ost1 $LCTL set_param fail_loc=0
23163         umount_client $MOUNT || error "umount failed"
23164         mount_client $MOUNT || error "mount failed"
23165         stop ost1 || error "cannot stop ost1"
23166         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23167 }
23168 run_test 232b "failed data version lock should not block umount"
23169
23170 test_233a() {
23171         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
23172                 skip "Need MDS version at least 2.3.64"
23173         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
23174
23175         local fid=$($LFS path2fid $MOUNT)
23176
23177         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23178                 error "cannot access $MOUNT using its FID '$fid'"
23179 }
23180 run_test 233a "checking that OBF of the FS root succeeds"
23181
23182 test_233b() {
23183         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
23184                 skip "Need MDS version at least 2.5.90"
23185         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
23186
23187         local fid=$($LFS path2fid $MOUNT/.lustre)
23188
23189         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23190                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
23191
23192         fid=$($LFS path2fid $MOUNT/.lustre/fid)
23193         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23194                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
23195 }
23196 run_test 233b "checking that OBF of the FS .lustre succeeds"
23197
23198 test_234() {
23199         local p="$TMP/sanityN-$TESTNAME.parameters"
23200         save_lustre_params client "llite.*.xattr_cache" > $p
23201         lctl set_param llite.*.xattr_cache 1 ||
23202                 skip_env "xattr cache is not supported"
23203
23204         mkdir -p $DIR/$tdir || error "mkdir failed"
23205         touch $DIR/$tdir/$tfile || error "touch failed"
23206         # OBD_FAIL_LLITE_XATTR_ENOMEM
23207         $LCTL set_param fail_loc=0x1405
23208         getfattr -n user.attr $DIR/$tdir/$tfile &&
23209                 error "getfattr should have failed with ENOMEM"
23210         $LCTL set_param fail_loc=0x0
23211         rm -rf $DIR/$tdir
23212
23213         restore_lustre_params < $p
23214         rm -f $p
23215 }
23216 run_test 234 "xattr cache should not crash on ENOMEM"
23217
23218 test_235() {
23219         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
23220                 skip "Need MDS version at least 2.4.52"
23221
23222         flock_deadlock $DIR/$tfile
23223         local RC=$?
23224         case $RC in
23225                 0)
23226                 ;;
23227                 124) error "process hangs on a deadlock"
23228                 ;;
23229                 *) error "error executing flock_deadlock $DIR/$tfile"
23230                 ;;
23231         esac
23232 }
23233 run_test 235 "LU-1715: flock deadlock detection does not work properly"
23234
23235 #LU-2935
23236 test_236() {
23237         check_swap_layouts_support
23238
23239         local ref1=/etc/passwd
23240         local ref2=/etc/group
23241         local file1=$DIR/$tdir/f1
23242         local file2=$DIR/$tdir/f2
23243
23244         test_mkdir -c1 $DIR/$tdir
23245         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
23246         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
23247         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
23248         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
23249         local fd=$(free_fd)
23250         local cmd="exec $fd<>$file2"
23251         eval $cmd
23252         rm $file2
23253         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
23254                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
23255         cmd="exec $fd>&-"
23256         eval $cmd
23257         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
23258
23259         #cleanup
23260         rm -rf $DIR/$tdir
23261 }
23262 run_test 236 "Layout swap on open unlinked file"
23263
23264 # LU-4659 linkea consistency
23265 test_238() {
23266         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
23267                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
23268                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
23269                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
23270
23271         touch $DIR/$tfile
23272         ln $DIR/$tfile $DIR/$tfile.lnk
23273         touch $DIR/$tfile.new
23274         mv $DIR/$tfile.new $DIR/$tfile
23275         local fid1=$($LFS path2fid $DIR/$tfile)
23276         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
23277         local path1=$($LFS fid2path $FSNAME "$fid1")
23278         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
23279         local path2=$($LFS fid2path $FSNAME "$fid2")
23280         [ $tfile.lnk == $path2 ] ||
23281                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
23282         rm -f $DIR/$tfile*
23283 }
23284 run_test 238 "Verify linkea consistency"
23285
23286 test_239A() { # was test_239
23287         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
23288                 skip "Need MDS version at least 2.5.60"
23289
23290         local list=$(comma_list $(mdts_nodes))
23291
23292         mkdir -p $DIR/$tdir
23293         createmany -o $DIR/$tdir/f- 5000
23294         unlinkmany $DIR/$tdir/f- 5000
23295         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
23296                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
23297         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
23298                         osp.*MDT*.sync_in_flight" | calc_sum)
23299         [ "$changes" -eq 0 ] || error "$changes not synced"
23300 }
23301 run_test 239A "osp_sync test"
23302
23303 test_239a() { #LU-5297
23304         remote_mds_nodsh && skip "remote MDS with nodsh"
23305
23306         touch $DIR/$tfile
23307         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
23308         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
23309         chgrp $RUNAS_GID $DIR/$tfile
23310         wait_delete_completed
23311 }
23312 run_test 239a "process invalid osp sync record correctly"
23313
23314 test_239b() { #LU-5297
23315         remote_mds_nodsh && skip "remote MDS with nodsh"
23316
23317         touch $DIR/$tfile1
23318         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
23319         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
23320         chgrp $RUNAS_GID $DIR/$tfile1
23321         wait_delete_completed
23322         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
23323         touch $DIR/$tfile2
23324         chgrp $RUNAS_GID $DIR/$tfile2
23325         wait_delete_completed
23326 }
23327 run_test 239b "process osp sync record with ENOMEM error correctly"
23328
23329 test_240() {
23330         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23331         remote_mds_nodsh && skip "remote MDS with nodsh"
23332
23333         mkdir -p $DIR/$tdir
23334
23335         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
23336                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
23337         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
23338                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
23339
23340         umount_client $MOUNT || error "umount failed"
23341         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
23342         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
23343         mount_client $MOUNT || error "failed to mount client"
23344
23345         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
23346         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
23347 }
23348 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
23349
23350 test_241_bio() {
23351         local count=$1
23352         local bsize=$2
23353
23354         for LOOP in $(seq $count); do
23355                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
23356                 cancel_lru_locks $OSC || true
23357         done
23358 }
23359
23360 test_241_dio() {
23361         local count=$1
23362         local bsize=$2
23363
23364         for LOOP in $(seq $1); do
23365                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
23366                         2>/dev/null
23367         done
23368 }
23369
23370 test_241a() { # was test_241
23371         local bsize=$PAGE_SIZE
23372
23373         (( bsize < 40960 )) && bsize=40960
23374         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
23375         ls -la $DIR/$tfile
23376         cancel_lru_locks $OSC
23377         test_241_bio 1000 $bsize &
23378         PID=$!
23379         test_241_dio 1000 $bsize
23380         wait $PID
23381 }
23382 run_test 241a "bio vs dio"
23383
23384 test_241b() {
23385         local bsize=$PAGE_SIZE
23386
23387         (( bsize < 40960 )) && bsize=40960
23388         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
23389         ls -la $DIR/$tfile
23390         test_241_dio 1000 $bsize &
23391         PID=$!
23392         test_241_dio 1000 $bsize
23393         wait $PID
23394 }
23395 run_test 241b "dio vs dio"
23396
23397 test_242() {
23398         remote_mds_nodsh && skip "remote MDS with nodsh"
23399
23400         mkdir_on_mdt0 $DIR/$tdir
23401         touch $DIR/$tdir/$tfile
23402
23403         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
23404         do_facet mds1 lctl set_param fail_loc=0x105
23405         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
23406
23407         do_facet mds1 lctl set_param fail_loc=0
23408         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
23409 }
23410 run_test 242 "mdt_readpage failure should not cause directory unreadable"
23411
23412 test_243()
23413 {
23414         test_mkdir $DIR/$tdir
23415         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
23416 }
23417 run_test 243 "various group lock tests"
23418
23419 test_244a()
23420 {
23421         test_mkdir $DIR/$tdir
23422         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
23423         sendfile_grouplock $DIR/$tdir/$tfile || \
23424                 error "sendfile+grouplock failed"
23425         rm -rf $DIR/$tdir
23426 }
23427 run_test 244a "sendfile with group lock tests"
23428
23429 test_244b()
23430 {
23431         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23432
23433         local threads=50
23434         local size=$((1024*1024))
23435
23436         test_mkdir $DIR/$tdir
23437         for i in $(seq 1 $threads); do
23438                 local file=$DIR/$tdir/file_$((i / 10))
23439                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
23440                 local pids[$i]=$!
23441         done
23442         for i in $(seq 1 $threads); do
23443                 wait ${pids[$i]}
23444         done
23445 }
23446 run_test 244b "multi-threaded write with group lock"
23447
23448 test_245a() {
23449         local flagname="multi_mod_rpcs"
23450         local connect_data_name="max_mod_rpcs"
23451         local out
23452
23453         # check if multiple modify RPCs flag is set
23454         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
23455                 grep "connect_flags:")
23456         echo "$out"
23457
23458         echo "$out" | grep -qw $flagname
23459         if [ $? -ne 0 ]; then
23460                 echo "connect flag $flagname is not set"
23461                 return
23462         fi
23463
23464         # check if multiple modify RPCs data is set
23465         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
23466         echo "$out"
23467
23468         echo "$out" | grep -qw $connect_data_name ||
23469                 error "import should have connect data $connect_data_name"
23470 }
23471 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
23472
23473 test_245b() {
23474         local flagname="multi_mod_rpcs"
23475         local connect_data_name="max_mod_rpcs"
23476         local out
23477
23478         remote_mds_nodsh && skip "remote MDS with nodsh"
23479         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
23480
23481         # check if multiple modify RPCs flag is set
23482         out=$(do_facet mds1 \
23483               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
23484               grep "connect_flags:")
23485         echo "$out"
23486
23487         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
23488
23489         # check if multiple modify RPCs data is set
23490         out=$(do_facet mds1 \
23491               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
23492
23493         [[ "$out" =~ $connect_data_name ]] ||
23494                 {
23495                         echo "$out"
23496                         error "missing connect data $connect_data_name"
23497                 }
23498 }
23499 run_test 245b "check osp connection flag/data: multiple modify RPCs"
23500
23501 cleanup_247() {
23502         local submount=$1
23503
23504         trap 0
23505         umount_client $submount
23506         rmdir $submount
23507 }
23508
23509 test_247a() {
23510         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23511                 grep -q subtree ||
23512                 skip_env "Fileset feature is not supported"
23513
23514         local submount=${MOUNT}_$tdir
23515
23516         mkdir $MOUNT/$tdir
23517         mkdir -p $submount || error "mkdir $submount failed"
23518         FILESET="$FILESET/$tdir" mount_client $submount ||
23519                 error "mount $submount failed"
23520         trap "cleanup_247 $submount" EXIT
23521         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
23522         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
23523                 error "read $MOUNT/$tdir/$tfile failed"
23524         cleanup_247 $submount
23525 }
23526 run_test 247a "mount subdir as fileset"
23527
23528 test_247b() {
23529         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23530                 skip_env "Fileset feature is not supported"
23531
23532         local submount=${MOUNT}_$tdir
23533
23534         rm -rf $MOUNT/$tdir
23535         mkdir -p $submount || error "mkdir $submount failed"
23536         SKIP_FILESET=1
23537         FILESET="$FILESET/$tdir" mount_client $submount &&
23538                 error "mount $submount should fail"
23539         rmdir $submount
23540 }
23541 run_test 247b "mount subdir that dose not exist"
23542
23543 test_247c() {
23544         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23545                 skip_env "Fileset feature is not supported"
23546
23547         local submount=${MOUNT}_$tdir
23548
23549         mkdir -p $MOUNT/$tdir/dir1
23550         mkdir -p $submount || error "mkdir $submount failed"
23551         trap "cleanup_247 $submount" EXIT
23552         FILESET="$FILESET/$tdir" mount_client $submount ||
23553                 error "mount $submount failed"
23554         local fid=$($LFS path2fid $MOUNT/)
23555         $LFS fid2path $submount $fid && error "fid2path should fail"
23556         cleanup_247 $submount
23557 }
23558 run_test 247c "running fid2path outside subdirectory root"
23559
23560 test_247d() {
23561         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23562                 skip "Fileset feature is not supported"
23563
23564         local submount=${MOUNT}_$tdir
23565
23566         mkdir -p $MOUNT/$tdir/dir1
23567         mkdir -p $submount || error "mkdir $submount failed"
23568         FILESET="$FILESET/$tdir" mount_client $submount ||
23569                 error "mount $submount failed"
23570         trap "cleanup_247 $submount" EXIT
23571
23572         local td=$submount/dir1
23573         local fid=$($LFS path2fid $td)
23574         [ -z "$fid" ] && error "path2fid unable to get $td FID"
23575
23576         # check that we get the same pathname back
23577         local rootpath
23578         local found
23579         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
23580                 echo "$rootpath $fid"
23581                 found=$($LFS fid2path $rootpath "$fid")
23582                 [ -n "$found" ] || error "fid2path should succeed"
23583                 [ "$found" == "$td" ] || error "fid2path $found != $td"
23584         done
23585         # check wrong root path format
23586         rootpath=$submount"_wrong"
23587         found=$($LFS fid2path $rootpath "$fid")
23588         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
23589
23590         cleanup_247 $submount
23591 }
23592 run_test 247d "running fid2path inside subdirectory root"
23593
23594 # LU-8037
23595 test_247e() {
23596         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23597                 grep -q subtree ||
23598                 skip "Fileset feature is not supported"
23599
23600         local submount=${MOUNT}_$tdir
23601
23602         mkdir $MOUNT/$tdir
23603         mkdir -p $submount || error "mkdir $submount failed"
23604         FILESET="$FILESET/.." mount_client $submount &&
23605                 error "mount $submount should fail"
23606         rmdir $submount
23607 }
23608 run_test 247e "mount .. as fileset"
23609
23610 test_247f() {
23611         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
23612         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
23613                 skip "Need at least version 2.14.50.162"
23614         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23615                 skip "Fileset feature is not supported"
23616
23617         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
23618         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
23619                 error "mkdir remote failed"
23620         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
23621                 error "mkdir remote/subdir failed"
23622         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
23623                 error "mkdir striped failed"
23624         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
23625
23626         local submount=${MOUNT}_$tdir
23627
23628         mkdir -p $submount || error "mkdir $submount failed"
23629         stack_trap "rmdir $submount"
23630
23631         local dir
23632         local fileset=$FILESET
23633         local mdts=$(comma_list $(mdts_nodes))
23634
23635         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
23636         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
23637                 $tdir/striped/subdir $tdir/striped/.; do
23638                 FILESET="$fileset/$dir" mount_client $submount ||
23639                         error "mount $dir failed"
23640                 umount_client $submount
23641         done
23642 }
23643 run_test 247f "mount striped or remote directory as fileset"
23644
23645 test_subdir_mount_lock()
23646 {
23647         local testdir=$1
23648         local submount=${MOUNT}_$(basename $testdir)
23649
23650         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
23651
23652         mkdir -p $submount || error "mkdir $submount failed"
23653         stack_trap "rmdir $submount"
23654
23655         FILESET="$fileset/$testdir" mount_client $submount ||
23656                 error "mount $FILESET failed"
23657         stack_trap "umount $submount"
23658
23659         local mdts=$(comma_list $(mdts_nodes))
23660
23661         local nrpcs
23662
23663         stat $submount > /dev/null || error "stat $submount failed"
23664         cancel_lru_locks $MDC
23665         stat $submount > /dev/null || error "stat $submount failed"
23666         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23667         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
23668         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23669         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
23670                 awk '/getattr/ {sum += $2} END {print sum}')
23671
23672         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
23673 }
23674
23675 test_247g() {
23676         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23677
23678         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
23679                 error "mkdir $tdir failed"
23680         test_subdir_mount_lock $tdir
23681 }
23682 run_test 247g "striped directory submount revalidate ROOT from cache"
23683
23684 test_247h() {
23685         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23686         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
23687                 skip "Need MDS version at least 2.15.51"
23688
23689         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23690         test_subdir_mount_lock $tdir
23691         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
23692         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
23693                 error "mkdir $tdir.1 failed"
23694         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
23695 }
23696 run_test 247h "remote directory submount revalidate ROOT from cache"
23697
23698 test_248a() {
23699         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
23700         [ -z "$fast_read_sav" ] && skip "no fast read support"
23701
23702         # create a large file for fast read verification
23703         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
23704
23705         # make sure the file is created correctly
23706         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
23707                 { rm -f $DIR/$tfile; skip "file creation error"; }
23708
23709         echo "Test 1: verify that fast read is 4 times faster on cache read"
23710
23711         # small read with fast read enabled
23712         $LCTL set_param -n llite.*.fast_read=1
23713         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23714                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23715                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23716         # small read with fast read disabled
23717         $LCTL set_param -n llite.*.fast_read=0
23718         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23719                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23720                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23721
23722         # verify that fast read is 4 times faster for cache read
23723         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
23724                 error_not_in_vm "fast read was not 4 times faster: " \
23725                            "$t_fast vs $t_slow"
23726
23727         echo "Test 2: verify the performance between big and small read"
23728         $LCTL set_param -n llite.*.fast_read=1
23729
23730         # 1k non-cache read
23731         cancel_lru_locks osc
23732         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23733                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23734                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23735
23736         # 1M non-cache read
23737         cancel_lru_locks osc
23738         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23739                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23740                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23741
23742         # verify that big IO is not 4 times faster than small IO
23743         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
23744                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
23745
23746         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
23747         rm -f $DIR/$tfile
23748 }
23749 run_test 248a "fast read verification"
23750
23751 test_248b() {
23752         # Default short_io_bytes=16384, try both smaller and larger sizes.
23753         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
23754         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
23755         echo "bs=53248 count=113 normal buffered write"
23756         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
23757                 error "dd of initial data file failed"
23758         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
23759
23760         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
23761         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
23762                 error "dd with sync normal writes failed"
23763         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
23764
23765         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
23766         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
23767                 error "dd with sync small writes failed"
23768         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
23769
23770         cancel_lru_locks osc
23771
23772         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
23773         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
23774         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
23775         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
23776                 iflag=direct || error "dd with O_DIRECT small read failed"
23777         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
23778         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
23779                 error "compare $TMP/$tfile.1 failed"
23780
23781         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
23782         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
23783
23784         # just to see what the maximum tunable value is, and test parsing
23785         echo "test invalid parameter 2MB"
23786         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
23787                 error "too-large short_io_bytes allowed"
23788         echo "test maximum parameter 512KB"
23789         # if we can set a larger short_io_bytes, run test regardless of version
23790         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
23791                 # older clients may not allow setting it this large, that's OK
23792                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
23793                         skip "Need at least client version 2.13.50"
23794                 error "medium short_io_bytes failed"
23795         fi
23796         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23797         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
23798
23799         echo "test large parameter 64KB"
23800         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
23801         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23802
23803         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
23804         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
23805                 error "dd with sync large writes failed"
23806         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
23807
23808         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
23809         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
23810         num=$((113 * 4096 / PAGE_SIZE))
23811         echo "bs=$size count=$num oflag=direct large write $tfile.3"
23812         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
23813                 error "dd with O_DIRECT large writes failed"
23814         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
23815                 error "compare $DIR/$tfile.3 failed"
23816
23817         cancel_lru_locks osc
23818
23819         echo "bs=$size count=$num iflag=direct large read $tfile.2"
23820         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
23821                 error "dd with O_DIRECT large read failed"
23822         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
23823                 error "compare $TMP/$tfile.2 failed"
23824
23825         echo "bs=$size count=$num iflag=direct large read $tfile.3"
23826         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
23827                 error "dd with O_DIRECT large read failed"
23828         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
23829                 error "compare $TMP/$tfile.3 failed"
23830 }
23831 run_test 248b "test short_io read and write for both small and large sizes"
23832
23833 test_248c() {
23834         $LCTL set_param llite.*.read_ahead_stats=c
23835         # This test compares whole file readahead to non-whole file readahead
23836         # The performance should be consistently slightly faster for whole file,
23837         # and the bug caused whole file readahead to be 80-100x slower, but to
23838         # account for possible test system lag, we require whole file to be
23839         # <= 1.5xnon-whole file, and require 3 failures in a row to fail the
23840         # test
23841         local time1
23842         local time2
23843         local whole_mb=$($LCTL get_param -n llite.*.max_read_ahead_whole_mb)
23844         stack_trap "$LCTL set_param llite.*.max_read_ahead_whole_mb=$whole_mb" EXIT
23845         counter=0
23846
23847         while [ $counter -lt 3 ]; do
23848                 # Increment the counter
23849                 ((counter++))
23850
23851                 $LCTL set_param llite.*.max_read_ahead_whole_mb=64
23852                 rm -f $DIR/$tfile
23853                 touch $DIR/$tfile || error "(0) failed to create file"
23854                 # 64 MiB
23855                 $TRUNCATE $DIR/$tfile 67108864 || error "(1) failed to truncate file"
23856                 time1=$(dd if=$DIR/$tfile bs=4K of=/dev/null 2>&1 | awk '/bytes/ {print $8}')
23857                 echo "whole file readahead of 64 MiB took $time1 seconds"
23858                 $LCTL get_param llite.*.read_ahead_stats
23859
23860                 $LCTL set_param llite.*.read_ahead_stats=c
23861                 $LCTL set_param llite.*.max_read_ahead_whole_mb=8
23862                 rm -f $DIR/$tfile
23863                 touch $DIR/$tfile || error "(2) failed to create file"
23864                 # 64 MiB
23865                 $TRUNCATE $DIR/$tfile 67108864 || error "(3) failed to create file"
23866                 time2=$(dd if=$DIR/$tfile bs=4K of=/dev/null 2>&1 | awk '/bytes/ {print $8}')
23867                 echo "non-whole file readahead of 64 MiB took $time2 seconds"
23868                 $LCTL get_param llite.*.read_ahead_stats
23869
23870                 # Check if time1 is not more than 1.5 times2
23871                 timecheck=$(echo "$time1 <= (1.5 * $time2)" | bc -l)
23872
23873                 if [[ $timecheck -eq 1 ]]; then
23874                         echo "Test passed on attempt $counter"
23875                         # Exit the loop
23876                         counter=4
23877                 else
23878                         echo "Attempt $counter failed: whole file readahead took: $time1, greater than non: $time2"
23879                 fi
23880         done
23881         if [ $counter -eq 3 ]; then
23882                 error "whole file readahead check failed 3 times in a row, probably not just VM lag"
23883         fi
23884
23885 }
23886 run_test 248c "verify whole file read behavior"
23887
23888 test_249() { # LU-7890
23889         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
23890                 skip "Need at least version 2.8.54"
23891
23892         rm -f $DIR/$tfile
23893         $LFS setstripe -c 1 $DIR/$tfile
23894         # Offset 2T == 4k * 512M
23895         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
23896                 error "dd to 2T offset failed"
23897 }
23898 run_test 249 "Write above 2T file size"
23899
23900 test_250() {
23901         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
23902          && skip "no 16TB file size limit on ZFS"
23903
23904         $LFS setstripe -c 1 $DIR/$tfile
23905         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
23906         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
23907         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
23908         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
23909                 conv=notrunc,fsync && error "append succeeded"
23910         return 0
23911 }
23912 run_test 250 "Write above 16T limit"
23913
23914 test_251a() {
23915         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
23916
23917         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
23918         #Skip once - writing the first stripe will succeed
23919         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23920         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
23921                 error "short write happened"
23922
23923         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23924         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
23925                 error "short read happened"
23926
23927         rm -f $DIR/$tfile
23928 }
23929 run_test 251a "Handling short read and write correctly"
23930
23931 test_251b() {
23932         dd if=/dev/zero of=$DIR/$tfile bs=1k count=4 ||
23933                 error "write $tfile failed"
23934
23935         sleep 2 && echo 12345 >> $DIR/$tfile &
23936
23937         #define OBD_FAIL_LLITE_READ_PAUSE 0x1431
23938         $LCTL set_param fail_loc=0x1431 fail_val=5
23939         # seek to 4096, 2 seconds later, file size expand to 4102, and after
23940         # 5 seconds, read 10 bytes, the short read should
23941         # report:
23942         #                start ->+ read_len -> offset_after_read read_count
23943         #     short read: 4096 ->+ 10 -> 4096 0
23944         # not:
23945         #     short read: 4096 ->+ 10 -> 4102 0
23946         local off=$($MULTIOP $DIR/$tfile oO_RDONLY:z4096r10c 2>&1 | \
23947                         awk '/short read/ { print $7 }')
23948         (( off == 4096 )) ||
23949                 error "short read should set offset at 4096, not $off"
23950 }
23951 run_test 251b "short read restore offset correctly"
23952
23953 test_252() {
23954         remote_mds_nodsh && skip "remote MDS with nodsh"
23955         remote_ost_nodsh && skip "remote OST with nodsh"
23956         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
23957                 skip_env "ldiskfs only test"
23958         fi
23959
23960         local tgt
23961         local dev
23962         local out
23963         local uuid
23964         local num
23965         local gen
23966
23967         # check lr_reader on OST0000
23968         tgt=ost1
23969         dev=$(facet_device $tgt)
23970         out=$(do_facet $tgt $LR_READER $dev)
23971         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23972         echo "$out"
23973         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
23974         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
23975                 error "Invalid uuid returned by $LR_READER on target $tgt"
23976         echo -e "uuid returned by $LR_READER is '$uuid'\n"
23977
23978         # check lr_reader -c on MDT0000
23979         tgt=mds1
23980         dev=$(facet_device $tgt)
23981         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
23982                 skip "$LR_READER does not support additional options"
23983         fi
23984         out=$(do_facet $tgt $LR_READER -c $dev)
23985         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23986         echo "$out"
23987         num=$(echo "$out" | grep -c "mdtlov")
23988         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
23989                 error "Invalid number of mdtlov clients returned by $LR_READER"
23990         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
23991
23992         # check lr_reader -cr on MDT0000
23993         out=$(do_facet $tgt $LR_READER -cr $dev)
23994         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23995         echo "$out"
23996         echo "$out" | grep -q "^reply_data:$" ||
23997                 error "$LR_READER should have returned 'reply_data' section"
23998         num=$(echo "$out" | grep -c "client_generation")
23999         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
24000 }
24001 run_test 252 "check lr_reader tool"
24002
24003 test_253() {
24004         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24005         remote_mds_nodsh && skip "remote MDS with nodsh"
24006         remote_mgs_nodsh && skip "remote MGS with nodsh"
24007         check_set_fallocate_or_skip
24008
24009         local ostidx=0
24010         local rc=0
24011         local ost_name=$(ostname_from_index $ostidx)
24012
24013         # on the mdt's osc
24014         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
24015         do_facet $SINGLEMDS $LCTL get_param -n \
24016                 osp.$mdtosc_proc1.reserved_mb_high ||
24017                 skip  "remote MDS does not support reserved_mb_high"
24018
24019         rm -rf $DIR/$tdir
24020         wait_mds_ost_sync
24021         wait_delete_completed
24022         mkdir $DIR/$tdir
24023         stack_trap "rm -rf $DIR/$tdir"
24024
24025         pool_add $TESTNAME || error "Pool creation failed"
24026         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
24027
24028         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
24029                 error "Setstripe failed"
24030
24031         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
24032
24033         local wms=$(ost_watermarks_get $ostidx)
24034
24035         ost_watermarks_set $ostidx 60 50
24036         stack_trap "ost_watermarks_set $ostidx $wms"
24037
24038         local free_kb=$($LFS df $MOUNT | awk "/$ost_name/ { print \$4 }")
24039         local size=$((free_kb * 1024))
24040
24041         fallocate -l $size $DIR/$tdir/fill_ost$ostidx ||
24042                 error "fallocate failed"
24043         sleep_maxage
24044
24045         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
24046                         osp.$mdtosc_proc1.prealloc_status)
24047         echo "prealloc_status $oa_status"
24048
24049         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
24050                 error "File creation should fail"
24051
24052         #object allocation was stopped, but we still able to append files
24053         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
24054                 oflag=append || error "Append failed"
24055
24056         rm -f $DIR/$tdir/$tfile.0
24057         rm -f $DIR/$tdir/fill_ost$ostidx
24058
24059         wait_delete_completed
24060         sleep_maxage
24061
24062         for i in $(seq 10 12); do
24063                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
24064                         2>/dev/null || error "File creation failed after rm"
24065         done
24066
24067         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
24068                         osp.$mdtosc_proc1.prealloc_status)
24069         echo "prealloc_status $oa_status"
24070
24071         if (( oa_status != 0 )); then
24072                 error "Object allocation still disable after rm"
24073         fi
24074 }
24075 run_test 253 "Check object allocation limit"
24076
24077 test_254() {
24078         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24079         remote_mds_nodsh && skip "remote MDS with nodsh"
24080
24081         local mdt=$(facet_svc $SINGLEMDS)
24082
24083         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
24084                 skip "MDS does not support changelog_size"
24085
24086         local cl_user
24087
24088         changelog_register || error "changelog_register failed"
24089
24090         changelog_clear 0 || error "changelog_clear failed"
24091
24092         local size1=$(do_facet $SINGLEMDS \
24093                       $LCTL get_param -n mdd.$mdt.changelog_size)
24094         echo "Changelog size $size1"
24095
24096         rm -rf $DIR/$tdir
24097         $LFS mkdir -i 0 $DIR/$tdir
24098         # change something
24099         mkdir -p $DIR/$tdir/pics/2008/zachy
24100         touch $DIR/$tdir/pics/2008/zachy/timestamp
24101         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
24102         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
24103         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
24104         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
24105         rm $DIR/$tdir/pics/desktop.jpg
24106
24107         local size2=$(do_facet $SINGLEMDS \
24108                       $LCTL get_param -n mdd.$mdt.changelog_size)
24109         echo "Changelog size after work $size2"
24110
24111         (( $size2 > $size1 )) ||
24112                 error "new Changelog size=$size2 less than old size=$size1"
24113 }
24114 run_test 254 "Check changelog size"
24115
24116 ladvise_no_type()
24117 {
24118         local type=$1
24119         local file=$2
24120
24121         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
24122                 awk -F: '{print $2}' | grep $type > /dev/null
24123         if [ $? -ne 0 ]; then
24124                 return 0
24125         fi
24126         return 1
24127 }
24128
24129 ladvise_no_ioctl()
24130 {
24131         local file=$1
24132
24133         lfs ladvise -a willread $file > /dev/null 2>&1
24134         if [ $? -eq 0 ]; then
24135                 return 1
24136         fi
24137
24138         lfs ladvise -a willread $file 2>&1 |
24139                 grep "Inappropriate ioctl for device" > /dev/null
24140         if [ $? -eq 0 ]; then
24141                 return 0
24142         fi
24143         return 1
24144 }
24145
24146 percent() {
24147         bc <<<"scale=2; ($1 - $2) * 100 / $2"
24148 }
24149
24150 # run a random read IO workload
24151 # usage: random_read_iops <filename> <filesize> <iosize>
24152 random_read_iops() {
24153         local file=$1
24154         local fsize=$2
24155         local iosize=${3:-4096}
24156
24157         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
24158                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
24159 }
24160
24161 drop_file_oss_cache() {
24162         local file="$1"
24163         local nodes="$2"
24164
24165         $LFS ladvise -a dontneed $file 2>/dev/null ||
24166                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
24167 }
24168
24169 ladvise_willread_performance()
24170 {
24171         local repeat=10
24172         local average_origin=0
24173         local average_cache=0
24174         local average_ladvise=0
24175
24176         for ((i = 1; i <= $repeat; i++)); do
24177                 echo "Iter $i/$repeat: reading without willread hint"
24178                 cancel_lru_locks osc
24179                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
24180                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
24181                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
24182                 average_origin=$(bc <<<"$average_origin + $speed_origin")
24183
24184                 cancel_lru_locks osc
24185                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
24186                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
24187                 average_cache=$(bc <<<"$average_cache + $speed_cache")
24188
24189                 cancel_lru_locks osc
24190                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
24191                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
24192                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
24193                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
24194                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
24195         done
24196         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
24197         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
24198         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
24199
24200         speedup_cache=$(percent $average_cache $average_origin)
24201         speedup_ladvise=$(percent $average_ladvise $average_origin)
24202
24203         echo "Average uncached read: $average_origin"
24204         echo "Average speedup with OSS cached read:" \
24205                 "$average_cache = +$speedup_cache%"
24206         echo "Average speedup with ladvise willread:" \
24207                 "$average_ladvise = +$speedup_ladvise%"
24208
24209         local lowest_speedup=20
24210         if (( ${speedup_cache%.*} < $lowest_speedup )); then
24211                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
24212                      "got $speedup_cache%. Skipping ladvise willread check."
24213                 return 0
24214         fi
24215
24216         # the test won't work on ZFS until it supports 'ladvise dontneed', but
24217         # it is still good to run until then to exercise 'ladvise willread'
24218         ! $LFS ladvise -a dontneed $DIR/$tfile &&
24219                 [ "$ost1_FSTYPE" = "zfs" ] &&
24220                 echo "osd-zfs does not support dontneed or drop_caches" &&
24221                 return 0
24222
24223         lowest_speedup=$(bc <<<"scale=2; $speedup_cache / 2")
24224         (( ${speedup_ladvise%.*} > ${lowest_speedup%.*} )) ||
24225                 error_not_in_vm "Speedup with willread is less than " \
24226                         "$lowest_speedup%, got $speedup_ladvise%"
24227 }
24228
24229 test_255a() {
24230         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
24231                 skip "lustre < 2.8.54 does not support ladvise "
24232         remote_ost_nodsh && skip "remote OST with nodsh"
24233
24234         stack_trap "rm -f $DIR/$tfile"
24235         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
24236
24237         ladvise_no_type willread $DIR/$tfile &&
24238                 skip "willread ladvise is not supported"
24239
24240         ladvise_no_ioctl $DIR/$tfile &&
24241                 skip "ladvise ioctl is not supported"
24242
24243         local size_mb=100
24244         local size=$((size_mb * 1048576))
24245         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
24246                 error "dd to $DIR/$tfile failed"
24247
24248         lfs ladvise -a willread $DIR/$tfile ||
24249                 error "Ladvise failed with no range argument"
24250
24251         lfs ladvise -a willread -s 0 $DIR/$tfile ||
24252                 error "Ladvise failed with no -l or -e argument"
24253
24254         lfs ladvise -a willread -e 1 $DIR/$tfile ||
24255                 error "Ladvise failed with only -e argument"
24256
24257         lfs ladvise -a willread -l 1 $DIR/$tfile ||
24258                 error "Ladvise failed with only -l argument"
24259
24260         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
24261                 error "End offset should not be smaller than start offset"
24262
24263         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
24264                 error "End offset should not be equal to start offset"
24265
24266         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
24267                 error "Ladvise failed with overflowing -s argument"
24268
24269         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
24270                 error "Ladvise failed with overflowing -e argument"
24271
24272         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
24273                 error "Ladvise failed with overflowing -l argument"
24274
24275         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
24276                 error "Ladvise succeeded with conflicting -l and -e arguments"
24277
24278         echo "Synchronous ladvise should wait"
24279         local delay=8
24280 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
24281         do_nodes $(comma_list $(osts_nodes)) \
24282                 $LCTL set_param fail_val=$delay fail_loc=0x237
24283         stack_trap "do_nodes $(comma_list $(osts_nodes)) \
24284                 $LCTL set_param fail_loc=0"
24285
24286         local start_ts=$SECONDS
24287         lfs ladvise -a willread $DIR/$tfile ||
24288                 error "Ladvise failed with no range argument"
24289         local end_ts=$SECONDS
24290         local inteval_ts=$((end_ts - start_ts))
24291
24292         if [ $inteval_ts -lt $(($delay - 1)) ]; then
24293                 error "Synchronous advice didn't wait reply"
24294         fi
24295
24296         echo "Asynchronous ladvise shouldn't wait"
24297         local start_ts=$SECONDS
24298         lfs ladvise -a willread -b $DIR/$tfile ||
24299                 error "Ladvise failed with no range argument"
24300         local end_ts=$SECONDS
24301         local inteval_ts=$((end_ts - start_ts))
24302
24303         if [ $inteval_ts -gt $(($delay / 2)) ]; then
24304                 error "Asynchronous advice blocked"
24305         fi
24306
24307         ladvise_willread_performance
24308 }
24309 run_test 255a "check 'lfs ladvise -a willread'"
24310
24311 facet_meminfo() {
24312         local facet=$1
24313         local info=$2
24314
24315         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
24316 }
24317
24318 test_255b() {
24319         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
24320                 skip "lustre < 2.8.54 does not support ladvise "
24321         remote_ost_nodsh && skip "remote OST with nodsh"
24322
24323         stack_trap "rm -f $DIR/$tfile"
24324         lfs setstripe -c 1 -i 0 $DIR/$tfile
24325
24326         ladvise_no_type dontneed $DIR/$tfile &&
24327                 skip "dontneed ladvise is not supported"
24328
24329         ladvise_no_ioctl $DIR/$tfile &&
24330                 skip "ladvise ioctl is not supported"
24331
24332         ! $LFS ladvise -a dontneed $DIR/$tfile &&
24333                 [ "$ost1_FSTYPE" = "zfs" ] &&
24334                 skip "zfs-osd does not support 'ladvise dontneed'"
24335
24336         local size_mb=100
24337         local size=$((size_mb * 1048576))
24338         # In order to prevent disturbance of other processes, only check 3/4
24339         # of the memory usage
24340         local kibibytes=$((size_mb * 1024 * 3 / 4))
24341
24342         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
24343                 error "dd to $DIR/$tfile failed"
24344
24345         #force write to complete before dropping OST cache & checking memory
24346         sync
24347
24348         local total=$(facet_meminfo ost1 MemTotal)
24349         echo "Total memory: $total KiB"
24350
24351         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
24352         local before_read=$(facet_meminfo ost1 Cached)
24353         echo "Cache used before read: $before_read KiB"
24354
24355         lfs ladvise -a willread $DIR/$tfile ||
24356                 error "Ladvise willread failed"
24357         local after_read=$(facet_meminfo ost1 Cached)
24358         echo "Cache used after read: $after_read KiB"
24359
24360         lfs ladvise -a dontneed $DIR/$tfile ||
24361                 error "Ladvise dontneed again failed"
24362         local no_read=$(facet_meminfo ost1 Cached)
24363         echo "Cache used after dontneed ladvise: $no_read KiB"
24364
24365         if [ $total -lt $((before_read + kibibytes)) ]; then
24366                 echo "Memory is too small, abort checking"
24367                 return 0
24368         fi
24369
24370         if [ $((before_read + kibibytes)) -gt $after_read ]; then
24371                 error "Ladvise willread should use more memory" \
24372                         "than $kibibytes KiB"
24373         fi
24374
24375         if [ $((no_read + kibibytes)) -gt $after_read ]; then
24376                 error "Ladvise dontneed should release more memory" \
24377                         "than $kibibytes KiB"
24378         fi
24379 }
24380 run_test 255b "check 'lfs ladvise -a dontneed'"
24381
24382 test_255c() {
24383         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
24384                 skip "lustre < 2.10.50 does not support lockahead"
24385
24386         local ost1_imp=$(get_osc_import_name client ost1)
24387         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24388                          cut -d'.' -f2)
24389         local count
24390         local new_count
24391         local difference
24392         local i
24393         local rc
24394
24395         test_mkdir -p $DIR/$tdir
24396         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24397
24398         #test 10 returns only success/failure
24399         i=10
24400         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24401         rc=$?
24402         if [ $rc -eq 255 ]; then
24403                 error "Ladvise test${i} failed, ${rc}"
24404         fi
24405
24406         #test 11 counts lock enqueue requests, all others count new locks
24407         i=11
24408         count=$(do_facet ost1 \
24409                 $LCTL get_param -n ost.OSS.ost.stats)
24410         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
24411
24412         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24413         rc=$?
24414         if [ $rc -eq 255 ]; then
24415                 error "Ladvise test${i} failed, ${rc}"
24416         fi
24417
24418         new_count=$(do_facet ost1 \
24419                 $LCTL get_param -n ost.OSS.ost.stats)
24420         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
24421                    awk '{ print $2 }')
24422
24423         difference="$((new_count - count))"
24424         if [ $difference -ne $rc ]; then
24425                 error "Ladvise test${i}, bad enqueue count, returned " \
24426                       "${rc}, actual ${difference}"
24427         fi
24428
24429         for i in $(seq 12 21); do
24430                 # If we do not do this, we run the risk of having too many
24431                 # locks and starting lock cancellation while we are checking
24432                 # lock counts.
24433                 cancel_lru_locks osc
24434
24435                 count=$($LCTL get_param -n \
24436                        ldlm.namespaces.$imp_name.lock_unused_count)
24437
24438                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
24439                 rc=$?
24440                 if [ $rc -eq 255 ]; then
24441                         error "Ladvise test ${i} failed, ${rc}"
24442                 fi
24443
24444                 new_count=$($LCTL get_param -n \
24445                        ldlm.namespaces.$imp_name.lock_unused_count)
24446                 difference="$((new_count - count))"
24447
24448                 # Test 15 output is divided by 100 to map down to valid return
24449                 if [ $i -eq 15 ]; then
24450                         rc="$((rc * 100))"
24451                 fi
24452
24453                 if [ $difference -ne $rc ]; then
24454                         error "Ladvise test ${i}, bad lock count, returned " \
24455                               "${rc}, actual ${difference}"
24456                 fi
24457         done
24458
24459         #test 22 returns only success/failure
24460         i=22
24461         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24462         rc=$?
24463         if [ $rc -eq 255 ]; then
24464                 error "Ladvise test${i} failed, ${rc}"
24465         fi
24466 }
24467 run_test 255c "suite of ladvise lockahead tests"
24468
24469 test_256() {
24470         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24471         remote_mds_nodsh && skip "remote MDS with nodsh"
24472         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
24473         changelog_users $SINGLEMDS | grep "^cl" &&
24474                 skip "active changelog user"
24475
24476         local cl_user
24477         local cat_sl
24478         local mdt_dev
24479
24480         mdt_dev=$(facet_device $SINGLEMDS)
24481         echo $mdt_dev
24482
24483         changelog_register || error "changelog_register failed"
24484
24485         rm -rf $DIR/$tdir
24486         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
24487
24488         changelog_clear 0 || error "changelog_clear failed"
24489
24490         # change something
24491         touch $DIR/$tdir/{1..10}
24492
24493         # stop the MDT
24494         stop $SINGLEMDS || error "Fail to stop MDT"
24495
24496         # remount the MDT
24497         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
24498                 error "Fail to start MDT"
24499
24500         #after mount new plainllog is used
24501         touch $DIR/$tdir/{11..19}
24502         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
24503         stack_trap "rm -f $tmpfile"
24504         cat_sl=$(do_facet $SINGLEMDS "sync; \
24505                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24506                  llog_reader $tmpfile | grep -c type=1064553b")
24507         do_facet $SINGLEMDS llog_reader $tmpfile
24508
24509         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
24510
24511         changelog_clear 0 || error "changelog_clear failed"
24512
24513         cat_sl=$(do_facet $SINGLEMDS "sync; \
24514                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24515                  llog_reader $tmpfile | grep -c type=1064553b")
24516
24517         if (( cat_sl == 2 )); then
24518                 error "Empty plain llog was not deleted from changelog catalog"
24519         elif (( cat_sl != 1 )); then
24520                 error "Active plain llog shouldn't be deleted from catalog"
24521         fi
24522 }
24523 run_test 256 "Check llog delete for empty and not full state"
24524
24525 test_257() {
24526         remote_mds_nodsh && skip "remote MDS with nodsh"
24527         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
24528                 skip "Need MDS version at least 2.8.55"
24529
24530         test_mkdir $DIR/$tdir
24531
24532         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
24533                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
24534         stat $DIR/$tdir
24535
24536 #define OBD_FAIL_MDS_XATTR_REP                  0x161
24537         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
24538         local facet=mds$((mdtidx + 1))
24539         set_nodes_failloc $(facet_active_host $facet) 0x80000161
24540         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
24541
24542         stop $facet || error "stop MDS failed"
24543         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
24544                 error "start MDS fail"
24545         wait_recovery_complete $facet
24546 }
24547 run_test 257 "xattr locks are not lost"
24548
24549 # Verify we take the i_mutex when security requires it
24550 test_258a() {
24551 #define OBD_FAIL_IMUTEX_SEC 0x141c
24552         $LCTL set_param fail_loc=0x141c
24553         touch $DIR/$tfile
24554         chmod u+s $DIR/$tfile
24555         chmod a+rwx $DIR/$tfile
24556         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24557         RC=$?
24558         if [ $RC -ne 0 ]; then
24559                 error "error, failed to take i_mutex, rc=$?"
24560         fi
24561         rm -f $DIR/$tfile
24562 }
24563 run_test 258a "verify i_mutex security behavior when suid attributes is set"
24564
24565 # Verify we do NOT take the i_mutex in the normal case
24566 test_258b() {
24567 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
24568         $LCTL set_param fail_loc=0x141d
24569         touch $DIR/$tfile
24570         chmod a+rwx $DIR
24571         chmod a+rw $DIR/$tfile
24572         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24573         RC=$?
24574         if [ $RC -ne 0 ]; then
24575                 error "error, took i_mutex unnecessarily, rc=$?"
24576         fi
24577         rm -f $DIR/$tfile
24578
24579 }
24580 run_test 258b "verify i_mutex security behavior"
24581
24582 test_259() {
24583         local file=$DIR/$tfile
24584         local before
24585         local after
24586
24587         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
24588
24589         stack_trap "rm -f $file" EXIT
24590
24591         wait_delete_completed
24592         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24593         echo "before: $before"
24594
24595         $LFS setstripe -i 0 -c 1 $file
24596         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
24597         sync_all_data
24598         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24599         echo "after write: $after"
24600
24601 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
24602         do_facet ost1 $LCTL set_param fail_loc=0x2301
24603         $TRUNCATE $file 0
24604         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24605         echo "after truncate: $after"
24606
24607         stop ost1
24608         do_facet ost1 $LCTL set_param fail_loc=0
24609         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
24610         sleep 2
24611         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24612         echo "after restart: $after"
24613         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
24614                 error "missing truncate?"
24615
24616         return 0
24617 }
24618 run_test 259 "crash at delayed truncate"
24619
24620 test_260() {
24621 #define OBD_FAIL_MDC_CLOSE               0x806
24622         $LCTL set_param fail_loc=0x80000806
24623         touch $DIR/$tfile
24624
24625 }
24626 run_test 260 "Check mdc_close fail"
24627
24628 ### Data-on-MDT sanity tests ###
24629 test_270a() {
24630         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24631                 skip "Need MDS version at least 2.10.55 for DoM"
24632
24633         # create DoM file
24634         local dom=$DIR/$tdir/dom_file
24635         local tmp=$DIR/$tdir/tmp_file
24636
24637         mkdir_on_mdt0 $DIR/$tdir
24638
24639         # basic checks for DoM component creation
24640         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
24641                 error "Can set MDT layout to non-first entry"
24642
24643         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
24644                 error "Can define multiple entries as MDT layout"
24645
24646         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
24647
24648         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
24649         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
24650         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
24651
24652         local mdtidx=$($LFS getstripe -m $dom)
24653         local mdtname=MDT$(printf %04x $mdtidx)
24654         local facet=mds$((mdtidx + 1))
24655         local space_check=1
24656
24657         # Skip free space checks with ZFS
24658         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
24659
24660         # write
24661         sync
24662         local size_tmp=$((65536 * 3))
24663         local mdtfree1=$(do_facet $facet \
24664                          lctl get_param -n osd*.*$mdtname.kbytesfree)
24665
24666         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24667         # check also direct IO along write
24668         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
24669         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24670         sync
24671         cmp $tmp $dom || error "file data is different"
24672         [ $(stat -c%s $dom) == $size_tmp ] ||
24673                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24674         if [ $space_check == 1 ]; then
24675                 local mdtfree2=$(do_facet $facet \
24676                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
24677
24678                 # increase in usage from by $size_tmp
24679                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24680                         error "MDT free space wrong after write: " \
24681                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24682         fi
24683
24684         # truncate
24685         local size_dom=10000
24686
24687         $TRUNCATE $dom $size_dom
24688         [ $(stat -c%s $dom) == $size_dom ] ||
24689                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
24690         if [ $space_check == 1 ]; then
24691                 mdtfree1=$(do_facet $facet \
24692                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24693                 # decrease in usage from $size_tmp to new $size_dom
24694                 [ $(($mdtfree1 - $mdtfree2)) -ge \
24695                   $(((size_tmp - size_dom) / 1024)) ] ||
24696                         error "MDT free space is wrong after truncate: " \
24697                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
24698         fi
24699
24700         # append
24701         cat $tmp >> $dom
24702         sync
24703         size_dom=$((size_dom + size_tmp))
24704         [ $(stat -c%s $dom) == $size_dom ] ||
24705                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
24706         if [ $space_check == 1 ]; then
24707                 mdtfree2=$(do_facet $facet \
24708                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24709                 # increase in usage by $size_tmp from previous
24710                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24711                         error "MDT free space is wrong after append: " \
24712                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24713         fi
24714
24715         # delete
24716         rm $dom
24717         if [ $space_check == 1 ]; then
24718                 mdtfree1=$(do_facet $facet \
24719                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24720                 # decrease in usage by $size_dom from previous
24721                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
24722                         error "MDT free space is wrong after removal: " \
24723                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
24724         fi
24725
24726         # combined striping
24727         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
24728                 error "Can't create DoM + OST striping"
24729
24730         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
24731         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24732         # check also direct IO along write
24733         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24734         sync
24735         cmp $tmp $dom || error "file data is different"
24736         [ $(stat -c%s $dom) == $size_tmp ] ||
24737                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24738         rm $dom $tmp
24739
24740         return 0
24741 }
24742 run_test 270a "DoM: basic functionality tests"
24743
24744 test_270b() {
24745         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24746                 skip "Need MDS version at least 2.10.55"
24747
24748         local dom=$DIR/$tdir/dom_file
24749         local max_size=1048576
24750
24751         mkdir -p $DIR/$tdir
24752         $LFS setstripe -E $max_size -L mdt $dom
24753
24754         # truncate over the limit
24755         $TRUNCATE $dom $(($max_size + 1)) &&
24756                 error "successful truncate over the maximum size"
24757         # write over the limit
24758         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
24759                 error "successful write over the maximum size"
24760         # append over the limit
24761         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
24762         echo "12345" >> $dom && error "successful append over the maximum size"
24763         rm $dom
24764
24765         return 0
24766 }
24767 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
24768
24769 test_270c() {
24770         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24771                 skip "Need MDS version at least 2.10.55"
24772
24773         mkdir -p $DIR/$tdir
24774         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24775
24776         # check files inherit DoM EA
24777         touch $DIR/$tdir/first
24778         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
24779                 error "bad pattern"
24780         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
24781                 error "bad stripe count"
24782         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
24783                 error "bad stripe size"
24784
24785         # check directory inherits DoM EA and uses it as default
24786         mkdir $DIR/$tdir/subdir
24787         touch $DIR/$tdir/subdir/second
24788         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
24789                 error "bad pattern in sub-directory"
24790         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
24791                 error "bad stripe count in sub-directory"
24792         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
24793                 error "bad stripe size in sub-directory"
24794         return 0
24795 }
24796 run_test 270c "DoM: DoM EA inheritance tests"
24797
24798 test_270d() {
24799         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24800                 skip "Need MDS version at least 2.10.55"
24801
24802         mkdir -p $DIR/$tdir
24803         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24804
24805         # inherit default DoM striping
24806         mkdir $DIR/$tdir/subdir
24807         touch $DIR/$tdir/subdir/f1
24808
24809         # change default directory striping
24810         $LFS setstripe -c 1 $DIR/$tdir/subdir
24811         touch $DIR/$tdir/subdir/f2
24812         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
24813                 error "wrong default striping in file 2"
24814         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
24815                 error "bad pattern in file 2"
24816         return 0
24817 }
24818 run_test 270d "DoM: change striping from DoM to RAID0"
24819
24820 test_270e() {
24821         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24822                 skip "Need MDS version at least 2.10.55"
24823
24824         mkdir -p $DIR/$tdir/dom
24825         mkdir -p $DIR/$tdir/norm
24826         DOMFILES=20
24827         NORMFILES=10
24828         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
24829         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
24830
24831         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
24832         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
24833
24834         # find DoM files by layout
24835         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
24836         [ $NUM -eq  $DOMFILES ] ||
24837                 error "lfs find -L: found $NUM, expected $DOMFILES"
24838         echo "Test 1: lfs find 20 DOM files by layout: OK"
24839
24840         # there should be 1 dir with default DOM striping
24841         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
24842         [ $NUM -eq  1 ] ||
24843                 error "lfs find -L: found $NUM, expected 1 dir"
24844         echo "Test 2: lfs find 1 DOM dir by layout: OK"
24845
24846         # find DoM files by stripe size
24847         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
24848         [ $NUM -eq  $DOMFILES ] ||
24849                 error "lfs find -S: found $NUM, expected $DOMFILES"
24850         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
24851
24852         # find files by stripe offset except DoM files
24853         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
24854         [ $NUM -eq  $NORMFILES ] ||
24855                 error "lfs find -i: found $NUM, expected $NORMFILES"
24856         echo "Test 5: lfs find no DOM files by stripe index: OK"
24857         return 0
24858 }
24859 run_test 270e "DoM: lfs find with DoM files test"
24860
24861 test_270f() {
24862         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24863                 skip "Need MDS version at least 2.10.55"
24864
24865         local mdtname=${FSNAME}-MDT0000-mdtlov
24866         local dom=$DIR/$tdir/dom_file
24867         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
24868                                                 lod.$mdtname.dom_stripesize)
24869         local dom_limit=131072
24870
24871         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
24872         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24873                                                 lod.$mdtname.dom_stripesize)
24874         [ ${dom_limit} -eq ${dom_current} ] ||
24875                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
24876
24877         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24878         $LFS setstripe -d $DIR/$tdir
24879         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
24880                 error "Can't set directory default striping"
24881
24882         # exceed maximum stripe size
24883         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24884                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
24885         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
24886                 error "Able to create DoM component size more than LOD limit"
24887
24888         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24889         dom_current=$(do_facet mds1 $LCTL get_param -n \
24890                                                 lod.$mdtname.dom_stripesize)
24891         [ 0 -eq ${dom_current} ] ||
24892                 error "Can't set zero DoM stripe limit"
24893         rm $dom
24894
24895         # attempt to create DoM file on server with disabled DoM should
24896         # remove DoM entry from layout and be succeed
24897         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
24898                 error "Can't create DoM file (DoM is disabled)"
24899         [ $($LFS getstripe -L $dom) == "mdt" ] &&
24900                 error "File has DoM component while DoM is disabled"
24901         rm $dom
24902
24903         # attempt to create DoM file with only DoM stripe should return error
24904         $LFS setstripe -E $dom_limit -L mdt $dom &&
24905                 error "Able to create DoM-only file while DoM is disabled"
24906
24907         # too low values to be aligned with smallest stripe size 64K
24908         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
24909         dom_current=$(do_facet mds1 $LCTL get_param -n \
24910                                                 lod.$mdtname.dom_stripesize)
24911         [ 30000 -eq ${dom_current} ] &&
24912                 error "Can set too small DoM stripe limit"
24913
24914         # 64K is a minimal stripe size in Lustre, expect limit of that size
24915         [ 65536 -eq ${dom_current} ] ||
24916                 error "Limit is not set to 64K but ${dom_current}"
24917
24918         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
24919         dom_current=$(do_facet mds1 $LCTL get_param -n \
24920                                                 lod.$mdtname.dom_stripesize)
24921         echo $dom_current
24922         [ 2147483648 -eq ${dom_current} ] &&
24923                 error "Can set too large DoM stripe limit"
24924
24925         do_facet mds1 $LCTL set_param -n \
24926                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
24927         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24928                 error "Can't create DoM component size after limit change"
24929         do_facet mds1 $LCTL set_param -n \
24930                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
24931         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
24932                 error "Can't create DoM file after limit decrease"
24933         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
24934                 error "Can create big DoM component after limit decrease"
24935         touch ${dom}_def ||
24936                 error "Can't create file with old default layout"
24937
24938         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
24939         return 0
24940 }
24941 run_test 270f "DoM: maximum DoM stripe size checks"
24942
24943 test_270g() {
24944         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
24945                 skip "Need MDS version at least 2.13.52"
24946         local dom=$DIR/$tdir/$tfile
24947
24948         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24949         local lodname=${FSNAME}-MDT0000-mdtlov
24950
24951         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24952         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
24953         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
24954         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24955
24956         local dom_limit=1024
24957         local dom_threshold="50%"
24958
24959         $LFS setstripe -d $DIR/$tdir
24960         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
24961                 error "Can't set directory default striping"
24962
24963         do_facet mds1 $LCTL set_param -n \
24964                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
24965         # set 0 threshold and create DOM file to change tunable stripesize
24966         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
24967         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
24968                 error "Failed to create $dom file"
24969         # now tunable dom_cur_stripesize should reach maximum
24970         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24971                                         lod.${lodname}.dom_stripesize_cur_kb)
24972         [[ $dom_current == $dom_limit ]] ||
24973                 error "Current DOM stripesize is not maximum"
24974         rm $dom
24975
24976         # set threshold for further tests
24977         do_facet mds1 $LCTL set_param -n \
24978                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
24979         echo "DOM threshold is $dom_threshold free space"
24980         local dom_def
24981         local dom_set
24982         # Spoof bfree to exceed threshold
24983         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
24984         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
24985         for spfree in 40 20 0 15 30 55; do
24986                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
24987                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
24988                         error "Failed to create $dom file"
24989                 dom_def=$(do_facet mds1 $LCTL get_param -n \
24990                                         lod.${lodname}.dom_stripesize_cur_kb)
24991                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
24992                 [[ $dom_def != $dom_current ]] ||
24993                         error "Default stripe size was not changed"
24994                 if (( spfree > 0 )) ; then
24995                         dom_set=$($LFS getstripe -S $dom)
24996                         (( dom_set == dom_def * 1024 )) ||
24997                                 error "DOM component size is still old"
24998                 else
24999                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
25000                                 error "DoM component is set with no free space"
25001                 fi
25002                 rm $dom
25003                 dom_current=$dom_def
25004         done
25005 }
25006 run_test 270g "DoM: default DoM stripe size depends on free space"
25007
25008 test_270h() {
25009         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
25010                 skip "Need MDS version at least 2.13.53"
25011
25012         local mdtname=${FSNAME}-MDT0000-mdtlov
25013         local dom=$DIR/$tdir/$tfile
25014         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25015
25016         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
25017         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25018
25019         $LFS mkdir -i 0 -c 1 $DIR/$tdir
25020         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
25021                 error "can't create OST file"
25022         # mirrored file with DOM entry in the second mirror
25023         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
25024                 error "can't create mirror with DoM component"
25025
25026         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
25027
25028         # DOM component in the middle and has other enries in the same mirror,
25029         # should succeed but lost DoM component
25030         $LFS setstripe --copy=${dom}_1 $dom ||
25031                 error "Can't create file from OST|DOM mirror layout"
25032         # check new file has no DoM layout after all
25033         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
25034                 error "File has DoM component while DoM is disabled"
25035 }
25036 run_test 270h "DoM: DoM stripe removal when disabled on server"
25037
25038 test_270i() {
25039         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
25040                 skip "Need MDS version at least 2.14.54"
25041
25042         mkdir $DIR/$tdir
25043         # DoM with plain layout
25044         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
25045                 error "default plain layout with DoM must fail"
25046         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
25047                 error "setstripe plain file layout with DoM must fail"
25048         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
25049                 error "default DoM layout with bad striping must fail"
25050         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
25051                 error "setstripe to DoM layout with bad striping must fail"
25052         return 0
25053 }
25054 run_test 270i "DoM: setting invalid DoM striping should fail"
25055
25056 test_270j() {
25057         (( $MDS1_VERSION >= $(version_code 2.15.55.203) )) ||
25058                 skip "Need MDS version at least 2.15.55.203"
25059
25060         local dom=$DIR/$tdir/$tfile
25061         local odv
25062         local ndv
25063
25064         mkdir -p $DIR/$tdir
25065
25066         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25067
25068         odv=$($LFS data_version $dom)
25069         chmod 666 $dom
25070         mv $dom ${dom}_moved
25071         link ${dom}_moved $dom
25072         setfattr -n user.attrx -v "some_attr" $dom
25073         ndv=$($LFS data_version $dom)
25074         (( $ndv == $odv )) ||
25075                 error "data version was changed by metadata operations"
25076
25077         dd if=/dev/urandom of=$dom bs=1M count=1 ||
25078                 error "failed to write data into $dom"
25079         cancel_lru_locks mdc
25080         ndv=$($LFS data_version $dom)
25081         (( $ndv != $odv )) ||
25082                 error "data version wasn't changed on write"
25083
25084         odv=$ndv
25085         $TRUNCATE $dom 1000 || error "failed to truncate $dom"
25086         ndv=$($LFS data_version $dom)
25087         (( $ndv != $odv )) ||
25088                 error "data version wasn't changed on truncate down"
25089
25090         odv=$ndv
25091         $TRUNCATE $dom 25000
25092         ndv=$($LFS data_version $dom)
25093         (( $ndv != $odv )) ||
25094                 error "data version wasn't changed on truncate up"
25095
25096         # check also fallocate for ldiskfs
25097         if [[ "$mds1_FSTYPE" == ldiskfs ]]; then
25098                 odv=$ndv
25099                 fallocate -l 1048576 $dom
25100                 ndv=$($LFS data_version $dom)
25101                 (( $ndv != $odv )) ||
25102                         error "data version wasn't changed on fallocate"
25103
25104                 odv=$ndv
25105                 fallocate -p --offset 4096 -l 4096 $dom
25106                 ndv=$($LFS data_version $dom)
25107                 (( $ndv != $odv )) ||
25108                         error "data version wasn't changed on fallocate punch"
25109         fi
25110 }
25111 run_test 270j "DoM migration: DOM file to the OST-striped file (plain)"
25112
25113 test_271a() {
25114         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25115                 skip "Need MDS version at least 2.10.55"
25116
25117         local dom=$DIR/$tdir/dom
25118
25119         mkdir -p $DIR/$tdir
25120
25121         $LFS setstripe -E 1024K -L mdt $dom
25122
25123         lctl set_param -n mdc.*.stats=clear
25124         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
25125         cat $dom > /dev/null
25126         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
25127         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
25128         ls $dom
25129         rm -f $dom
25130 }
25131 run_test 271a "DoM: data is cached for read after write"
25132
25133 test_271b() {
25134         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25135                 skip "Need MDS version at least 2.10.55"
25136
25137         local dom=$DIR/$tdir/dom
25138
25139         mkdir -p $DIR/$tdir
25140
25141         $LFS setstripe -E 1024K -L mdt -E EOF $dom
25142
25143         lctl set_param -n mdc.*.stats=clear
25144         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
25145         cancel_lru_locks mdc
25146         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
25147         # second stat to check size is cached on client
25148         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
25149         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
25150         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
25151         rm -f $dom
25152 }
25153 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
25154
25155 test_271ba() {
25156         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25157                 skip "Need MDS version at least 2.10.55"
25158
25159         local dom=$DIR/$tdir/dom
25160
25161         mkdir -p $DIR/$tdir
25162
25163         $LFS setstripe -E 1024K -L mdt -E EOF $dom
25164
25165         lctl set_param -n mdc.*.stats=clear
25166         lctl set_param -n osc.*.stats=clear
25167         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
25168         cancel_lru_locks mdc
25169         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
25170         # second stat to check size is cached on client
25171         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
25172         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
25173         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
25174         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
25175         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
25176         rm -f $dom
25177 }
25178 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
25179
25180
25181 get_mdc_stats() {
25182         local mdtidx=$1
25183         local param=$2
25184         local mdt=MDT$(printf %04x $mdtidx)
25185
25186         if [ -z $param ]; then
25187                 lctl get_param -n mdc.*$mdt*.stats
25188         else
25189                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
25190         fi
25191 }
25192
25193 test_271c() {
25194         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25195                 skip "Need MDS version at least 2.10.55"
25196
25197         local dom=$DIR/$tdir/dom
25198
25199         mkdir -p $DIR/$tdir
25200
25201         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25202
25203         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
25204         local facet=mds$((mdtidx + 1))
25205
25206         cancel_lru_locks mdc
25207         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
25208         createmany -o $dom 1000
25209         lctl set_param -n mdc.*.stats=clear
25210         smalliomany -w $dom 1000 200
25211         get_mdc_stats $mdtidx
25212         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
25213         # Each file has 1 open, 1 IO enqueues, total 2000
25214         # but now we have also +1 getxattr for security.capability, total 3000
25215         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
25216         unlinkmany $dom 1000
25217
25218         cancel_lru_locks mdc
25219         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
25220         createmany -o $dom 1000
25221         lctl set_param -n mdc.*.stats=clear
25222         smalliomany -w $dom 1000 200
25223         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
25224         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
25225         # for OPEN and IO lock.
25226         [ $((enq - enq_2)) -ge 1000 ] ||
25227                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
25228         unlinkmany $dom 1000
25229         return 0
25230 }
25231 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
25232
25233 cleanup_271def_tests() {
25234         trap 0
25235         rm -f $1
25236 }
25237
25238 test_271d() {
25239         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
25240                 skip "Need MDS version at least 2.10.57"
25241
25242         local dom=$DIR/$tdir/dom
25243         local tmp=$TMP/$tfile
25244         trap "cleanup_271def_tests $tmp" EXIT
25245
25246         mkdir -p $DIR/$tdir
25247
25248         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25249
25250         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
25251
25252         cancel_lru_locks mdc
25253         dd if=/dev/urandom of=$tmp bs=1000 count=1
25254         dd if=$tmp of=$dom bs=1000 count=1
25255         cancel_lru_locks mdc
25256
25257         cat /etc/hosts >> $tmp
25258         lctl set_param -n mdc.*.stats=clear
25259
25260         # append data to the same file it should update local page
25261         echo "Append to the same page"
25262         cat /etc/hosts >> $dom
25263         local num=$(get_mdc_stats $mdtidx ost_read)
25264         local ra=$(get_mdc_stats $mdtidx req_active)
25265         local rw=$(get_mdc_stats $mdtidx req_waittime)
25266
25267         [ -z $num ] || error "$num READ RPC occured"
25268         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25269         echo "... DONE"
25270
25271         # compare content
25272         cmp $tmp $dom || error "file miscompare"
25273
25274         cancel_lru_locks mdc
25275         lctl set_param -n mdc.*.stats=clear
25276
25277         echo "Open and read file"
25278         cat $dom > /dev/null
25279         local num=$(get_mdc_stats $mdtidx ost_read)
25280         local ra=$(get_mdc_stats $mdtidx req_active)
25281         local rw=$(get_mdc_stats $mdtidx req_waittime)
25282
25283         [ -z $num ] || error "$num READ RPC occured"
25284         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25285         echo "... DONE"
25286
25287         # compare content
25288         cmp $tmp $dom || error "file miscompare"
25289
25290         return 0
25291 }
25292 run_test 271d "DoM: read on open (1K file in reply buffer)"
25293
25294 test_271f() {
25295         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
25296                 skip "Need MDS version at least 2.10.57"
25297
25298         local dom=$DIR/$tdir/dom
25299         local tmp=$TMP/$tfile
25300         trap "cleanup_271def_tests $tmp" EXIT
25301
25302         mkdir -p $DIR/$tdir
25303
25304         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25305
25306         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
25307
25308         cancel_lru_locks mdc
25309         dd if=/dev/urandom of=$tmp bs=265000 count=1
25310         dd if=$tmp of=$dom bs=265000 count=1
25311         cancel_lru_locks mdc
25312         cat /etc/hosts >> $tmp
25313         lctl set_param -n mdc.*.stats=clear
25314
25315         echo "Append to the same page"
25316         cat /etc/hosts >> $dom
25317         local num=$(get_mdc_stats $mdtidx ost_read)
25318         local ra=$(get_mdc_stats $mdtidx req_active)
25319         local rw=$(get_mdc_stats $mdtidx req_waittime)
25320
25321         [ -z $num ] || error "$num READ RPC occured"
25322         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25323         echo "... DONE"
25324
25325         # compare content
25326         cmp $tmp $dom || error "file miscompare"
25327
25328         cancel_lru_locks mdc
25329         lctl set_param -n mdc.*.stats=clear
25330
25331         echo "Open and read file"
25332         cat $dom > /dev/null
25333         local num=$(get_mdc_stats $mdtidx ost_read)
25334         local ra=$(get_mdc_stats $mdtidx req_active)
25335         local rw=$(get_mdc_stats $mdtidx req_waittime)
25336
25337         [ -z $num ] && num=0
25338         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
25339         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25340         echo "... DONE"
25341
25342         # compare content
25343         cmp $tmp $dom || error "file miscompare"
25344
25345         return 0
25346 }
25347 run_test 271f "DoM: read on open (200K file and read tail)"
25348
25349 test_271g() {
25350         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
25351                 skip "Skipping due to old client or server version"
25352
25353         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
25354         # to get layout
25355         $CHECKSTAT -t file $DIR1/$tfile
25356
25357         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
25358         MULTIOP_PID=$!
25359         sleep 1
25360         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
25361         $LCTL set_param fail_loc=0x80000314
25362         rm $DIR1/$tfile || error "Unlink fails"
25363         RC=$?
25364         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
25365         [ $RC -eq 0 ] || error "Failed write to stale object"
25366 }
25367 run_test 271g "Discard DoM data vs client flush race"
25368
25369 test_272a() {
25370         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25371                 skip "Need MDS version at least 2.11.50"
25372
25373         local dom=$DIR/$tdir/dom
25374         mkdir -p $DIR/$tdir
25375
25376         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
25377         dd if=/dev/urandom of=$dom bs=512K count=1 ||
25378                 error "failed to write data into $dom"
25379         local old_md5=$(md5sum $dom)
25380
25381         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
25382                 error "failed to migrate to the same DoM component"
25383
25384         local new_md5=$(md5sum $dom)
25385
25386         [ "$old_md5" == "$new_md5" ] ||
25387                 error "md5sum differ: $old_md5, $new_md5"
25388
25389         [ $($LFS getstripe -c $dom) -eq 2 ] ||
25390                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
25391 }
25392 run_test 272a "DoM migration: new layout with the same DOM component"
25393
25394 test_272b() {
25395         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25396                 skip "Need MDS version at least 2.11.50"
25397
25398         local dom=$DIR/$tdir/dom
25399         mkdir -p $DIR/$tdir
25400         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25401         stack_trap "rm -rf $DIR/$tdir"
25402
25403         local mdtidx=$($LFS getstripe -m $dom)
25404         local mdtname=MDT$(printf %04x $mdtidx)
25405         local facet=mds$((mdtidx + 1))
25406
25407         local mdtfree1=$(do_facet $facet \
25408                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25409         dd if=/dev/urandom of=$dom bs=2M count=1 ||
25410                 error "failed to write data into $dom"
25411         local old_md5=$(md5sum $dom)
25412         cancel_lru_locks mdc
25413         local mdtfree1=$(do_facet $facet \
25414                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25415
25416         $LFS migrate -c2 $dom ||
25417                 error "failed to migrate to the new composite layout"
25418         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
25419                 error "MDT stripe was not removed"
25420         ! getfattr -n trusted.dataver $dom &> /dev/null ||
25421                 error "$dir1 shouldn't have DATAVER EA"
25422
25423         cancel_lru_locks mdc
25424         local new_md5=$(md5sum $dom)
25425         [ "$old_md5" == "$new_md5" ] ||
25426                 error "$old_md5 != $new_md5"
25427
25428         # Skip free space checks with ZFS
25429         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25430                 local mdtfree2=$(do_facet $facet \
25431                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25432                 [ $mdtfree2 -gt $mdtfree1 ] ||
25433                         error "MDT space is not freed after migration"
25434         fi
25435         return 0
25436 }
25437 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
25438
25439 test_272c() {
25440         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25441                 skip "Need MDS version at least 2.11.50"
25442
25443         local dom=$DIR/$tdir/$tfile
25444         mkdir -p $DIR/$tdir
25445         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25446         stack_trap "rm -rf $DIR/$tdir"
25447
25448         local mdtidx=$($LFS getstripe -m $dom)
25449         local mdtname=MDT$(printf %04x $mdtidx)
25450         local facet=mds$((mdtidx + 1))
25451
25452         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25453                 error "failed to write data into $dom"
25454         local old_md5=$(md5sum $dom)
25455         cancel_lru_locks mdc
25456         local mdtfree1=$(do_facet $facet \
25457                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25458
25459         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
25460                 error "failed to migrate to the new composite layout"
25461         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
25462                 error "MDT stripe was not removed"
25463
25464         cancel_lru_locks mdc
25465         local new_md5=$(md5sum $dom)
25466         [ "$old_md5" == "$new_md5" ] ||
25467                 error "$old_md5 != $new_md5"
25468
25469         # Skip free space checks with ZFS
25470         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25471                 local mdtfree2=$(do_facet $facet \
25472                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25473                 [ $mdtfree2 -gt $mdtfree1 ] ||
25474                         error "MDS space is not freed after migration"
25475         fi
25476         return 0
25477 }
25478 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
25479
25480 test_272d() {
25481         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25482                 skip "Need MDS version at least 2.12.55"
25483
25484         local dom=$DIR/$tdir/$tfile
25485         mkdir -p $DIR/$tdir
25486         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25487
25488         local mdtidx=$($LFS getstripe -m $dom)
25489         local mdtname=MDT$(printf %04x $mdtidx)
25490         local facet=mds$((mdtidx + 1))
25491
25492         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25493                 error "failed to write data into $dom"
25494         local old_md5=$(md5sum $dom)
25495         cancel_lru_locks mdc
25496         local mdtfree1=$(do_facet $facet \
25497                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25498
25499         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
25500                 error "failed mirroring to the new composite layout"
25501         $LFS mirror resync $dom ||
25502                 error "failed mirror resync"
25503         $LFS mirror split --mirror-id 1 -d $dom ||
25504                 error "failed mirror split"
25505
25506         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
25507                 error "MDT stripe was not removed"
25508
25509         cancel_lru_locks mdc
25510         local new_md5=$(md5sum $dom)
25511         [ "$old_md5" == "$new_md5" ] ||
25512                 error "$old_md5 != $new_md5"
25513
25514         # Skip free space checks with ZFS
25515         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25516                 local mdtfree2=$(do_facet $facet \
25517                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25518                 [ $mdtfree2 -gt $mdtfree1 ] ||
25519                         error "MDS space is not freed after DOM mirror deletion"
25520         fi
25521         return 0
25522 }
25523 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
25524
25525 test_272e() {
25526         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25527                 skip "Need MDS version at least 2.12.55"
25528
25529         local dom=$DIR/$tdir/$tfile
25530         mkdir -p $DIR/$tdir
25531         $LFS setstripe -c 2 $dom
25532
25533         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25534                 error "failed to write data into $dom"
25535         local old_md5=$(md5sum $dom)
25536         cancel_lru_locks
25537
25538         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
25539                 error "failed mirroring to the DOM layout"
25540         $LFS mirror resync $dom ||
25541                 error "failed mirror resync"
25542         $LFS mirror split --mirror-id 1 -d $dom ||
25543                 error "failed mirror split"
25544
25545         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25546                 error "MDT stripe wasn't set"
25547
25548         cancel_lru_locks
25549         local new_md5=$(md5sum $dom)
25550         [ "$old_md5" == "$new_md5" ] ||
25551                 error "$old_md5 != $new_md5"
25552
25553         return 0
25554 }
25555 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
25556
25557 test_272f() {
25558         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25559                 skip "Need MDS version at least 2.12.55"
25560
25561         local dom=$DIR/$tdir/$tfile
25562         mkdir -p $DIR/$tdir
25563         $LFS setstripe -c 2 $dom
25564
25565         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25566                 error "failed to write data into $dom"
25567         local old_md5=$(md5sum $dom)
25568         cancel_lru_locks
25569
25570         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
25571                 error "failed migrating to the DOM file"
25572
25573         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25574                 error "MDT stripe wasn't set"
25575
25576         cancel_lru_locks
25577         local new_md5=$(md5sum $dom)
25578         [ "$old_md5" != "$new_md5" ] &&
25579                 error "$old_md5 != $new_md5"
25580
25581         return 0
25582 }
25583 run_test 272f "DoM migration: OST-striped file to DOM file"
25584
25585 test_273a() {
25586         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25587                 skip "Need MDS version at least 2.11.50"
25588
25589         # Layout swap cannot be done if either file has DOM component,
25590         # this will never be supported, migration should be used instead
25591
25592         local dom=$DIR/$tdir/$tfile
25593         mkdir -p $DIR/$tdir
25594
25595         $LFS setstripe -c2 ${dom}_plain
25596         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
25597         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
25598                 error "can swap layout with DoM component"
25599         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
25600                 error "can swap layout with DoM component"
25601
25602         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
25603         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
25604                 error "can swap layout with DoM component"
25605         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
25606                 error "can swap layout with DoM component"
25607         return 0
25608 }
25609 run_test 273a "DoM: layout swapping should fail with DOM"
25610
25611 test_273b() {
25612         mkdir -p $DIR/$tdir
25613         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
25614
25615 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
25616         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
25617
25618         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25619 }
25620 run_test 273b "DoM: race writeback and object destroy"
25621
25622 test_273c() {
25623         mkdir -p $DIR/$tdir
25624         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
25625
25626         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
25627         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
25628
25629         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25630 }
25631 run_test 273c "race writeback and object destroy"
25632
25633 test_275() {
25634         remote_ost_nodsh && skip "remote OST with nodsh"
25635         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
25636                 skip "Need OST version >= 2.10.57"
25637
25638         local file=$DIR/$tfile
25639         local oss
25640
25641         oss=$(comma_list $(osts_nodes))
25642
25643         dd if=/dev/urandom of=$file bs=1M count=2 ||
25644                 error "failed to create a file"
25645         stack_trap "rm -f $file"
25646         cancel_lru_locks osc
25647
25648         #lock 1
25649         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25650                 error "failed to read a file"
25651
25652 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
25653         $LCTL set_param fail_loc=0x8000031f
25654
25655         cancel_lru_locks osc &
25656         sleep 1
25657
25658 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
25659         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
25660         #IO takes another lock, but matches the PENDING one
25661         #and places it to the IO RPC
25662         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25663                 error "failed to read a file with PENDING lock"
25664 }
25665 run_test 275 "Read on a canceled duplicate lock"
25666
25667 test_276() {
25668         remote_ost_nodsh && skip "remote OST with nodsh"
25669         local pid
25670
25671         do_facet ost1 "(while true; do \
25672                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
25673                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
25674         pid=$!
25675
25676         for LOOP in $(seq 20); do
25677                 stop ost1
25678                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
25679         done
25680         kill -9 $pid
25681         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
25682                 rm $TMP/sanity_276_pid"
25683 }
25684 run_test 276 "Race between mount and obd_statfs"
25685
25686 test_277() {
25687         $LCTL set_param ldlm.namespaces.*.lru_size=0
25688         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25689         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25690                           awk '/^used_mb/ { print $2 }')
25691         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
25692         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
25693                 oflag=direct conv=notrunc
25694         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25695                     awk '/^used_mb/ { print $2 }')
25696         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
25697 }
25698 run_test 277 "Direct IO shall drop page cache"
25699
25700 test_278() {
25701         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
25702         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25703         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
25704                 skip "needs the same host for mdt1 mdt2" && return
25705
25706         local pid1
25707         local pid2
25708
25709 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
25710         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
25711         stop mds2 &
25712         pid2=$!
25713
25714         stop mds1
25715
25716         echo "Starting MDTs"
25717         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
25718         wait $pid2
25719 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
25720 #will return NULL
25721         do_facet mds2 $LCTL set_param fail_loc=0
25722
25723         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
25724         wait_recovery_complete mds2
25725 }
25726 run_test 278 "Race starting MDS between MDTs stop/start"
25727
25728 test_280() {
25729         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
25730                 skip "Need MGS version at least 2.13.52"
25731         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25732         combined_mgs_mds || skip "needs combined MGS/MDT"
25733
25734         umount_client $MOUNT
25735 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
25736         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
25737
25738         mount_client $MOUNT &
25739         sleep 1
25740         stop mgs || error "stop mgs failed"
25741         #for a race mgs would crash
25742         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
25743         # make sure we unmount client before remounting
25744         wait
25745         umount_client $MOUNT
25746         mount_client $MOUNT || error "mount client failed"
25747 }
25748 run_test 280 "Race between MGS umount and client llog processing"
25749
25750 cleanup_test_300() {
25751         trap 0
25752         umask $SAVE_UMASK
25753 }
25754
25755 test_striped_dir() {
25756         local mdt_index=$1
25757         local stripe_count=$2
25758         local overstriping=$3
25759         local stripe_index
25760         local getstripe_count
25761
25762         mkdir -p $DIR/$tdir
25763
25764         SAVE_UMASK=$(umask)
25765         trap cleanup_test_300 RETURN EXIT
25766
25767         if [ -z $overstriping ]; then
25768                 $LFS setdirstripe -i $mdt_index -c $stripe_count -H all_char \
25769                                         -o 755 $DIR/$tdir/striped_dir ||
25770                         error "set striped dir error"
25771         else
25772                 $LFS setdirstripe -i $mdt_index -C $stripe_count -H all_char \
25773                                         -o 755 $DIR/$tdir/striped_dir ||
25774                         error "set striped dir error"
25775         fi
25776
25777         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
25778         [ "$mode" = "755" ] || error "expect 755 got $mode"
25779
25780         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
25781                 error "getdirstripe failed"
25782         getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
25783         if [ "$getstripe_count" != "$stripe_count" ]; then
25784                 error "1:stripe_count is $getstripe_count, expect $stripe_count"
25785         fi
25786         getstripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
25787         if [ "$getstripe_count" != "$stripe_count" ]; then
25788                 error "2:stripe_count is $getstripe_count, expect $stripe_count"
25789         fi
25790
25791         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
25792         if [ "$stripe_index" != "$mdt_index" ]; then
25793                 error "stripe_index is $stripe_index, expect $mdt_index"
25794         fi
25795
25796         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25797                 error "nlink error after create striped dir"
25798
25799         mkdir $DIR/$tdir/striped_dir/a
25800         mkdir $DIR/$tdir/striped_dir/b
25801
25802         stat $DIR/$tdir/striped_dir/a ||
25803                 error "create dir under striped dir failed"
25804         stat $DIR/$tdir/striped_dir/b ||
25805                 error "create dir under striped dir failed"
25806
25807         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
25808                 error "nlink error after mkdir"
25809
25810         rmdir $DIR/$tdir/striped_dir/a
25811         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
25812                 error "nlink error after rmdir"
25813
25814         rmdir $DIR/$tdir/striped_dir/b
25815         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25816                 error "nlink error after rmdir"
25817
25818         chattr +i $DIR/$tdir/striped_dir
25819         createmany -o $DIR/$tdir/striped_dir/f 10 &&
25820                 error "immutable flags not working under striped dir!"
25821         chattr -i $DIR/$tdir/striped_dir
25822
25823         rmdir $DIR/$tdir/striped_dir ||
25824                 error "rmdir striped dir error"
25825
25826         cleanup_test_300
25827
25828         true
25829 }
25830
25831 test_300a() {
25832         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25833                 skip "skipped for lustre < 2.7.0"
25834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25835         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25836
25837         test_striped_dir 0 2 || error "failed on striped dir on MDT0"
25838         test_striped_dir 1 2 || error "failed on striped dir on MDT0"
25839 }
25840 run_test 300a "basic striped dir sanity test"
25841
25842 test_300b() {
25843         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25844                 skip "skipped for lustre < 2.7.0"
25845         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25846         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25847
25848         local i
25849         local mtime1
25850         local mtime2
25851         local mtime3
25852
25853         test_mkdir $DIR/$tdir || error "mkdir fail"
25854         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25855                 error "set striped dir error"
25856         for i in {0..9}; do
25857                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
25858                 sleep 1
25859                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
25860                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
25861                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
25862                 sleep 1
25863                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
25864                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
25865                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
25866         done
25867         true
25868 }
25869 run_test 300b "check ctime/mtime for striped dir"
25870
25871 test_300c() {
25872         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25873                 skip "skipped for lustre < 2.7.0"
25874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25875         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25876
25877         local file_count
25878
25879         mkdir_on_mdt0 $DIR/$tdir
25880         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
25881                 error "set striped dir error"
25882
25883         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
25884                 error "chown striped dir failed"
25885
25886         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
25887                 error "create 5k files failed"
25888
25889         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
25890
25891         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
25892
25893         rm -rf $DIR/$tdir
25894 }
25895 run_test 300c "chown && check ls under striped directory"
25896
25897 test_300d() {
25898         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25899                 skip "skipped for lustre < 2.7.0"
25900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25901         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25902
25903         local stripe_count
25904         local file
25905
25906         mkdir -p $DIR/$tdir
25907         $LFS setstripe -c 2 $DIR/$tdir
25908
25909         #local striped directory
25910         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25911                 error "set striped dir error"
25912         #look at the directories for debug purposes
25913         ls -l $DIR/$tdir
25914         $LFS getdirstripe $DIR/$tdir
25915         ls -l $DIR/$tdir/striped_dir
25916         $LFS getdirstripe $DIR/$tdir/striped_dir
25917         createmany -o $DIR/$tdir/striped_dir/f 10 ||
25918                 error "create 10 files failed"
25919
25920         #remote striped directory
25921         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
25922                 error "set striped dir error"
25923         #look at the directories for debug purposes
25924         ls -l $DIR/$tdir
25925         $LFS getdirstripe $DIR/$tdir
25926         ls -l $DIR/$tdir/remote_striped_dir
25927         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
25928         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
25929                 error "create 10 files failed"
25930
25931         for file in $(find $DIR/$tdir); do
25932                 stripe_count=$($LFS getstripe -c $file)
25933                 [ $stripe_count -eq 2 ] ||
25934                         error "wrong stripe $stripe_count for $file"
25935         done
25936
25937         rm -rf $DIR/$tdir
25938 }
25939 run_test 300d "check default stripe under striped directory"
25940
25941 test_300e() {
25942         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25943                 skip "Need MDS version at least 2.7.55"
25944         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25945         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25946
25947         local stripe_count
25948         local file
25949
25950         mkdir -p $DIR/$tdir
25951
25952         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25953                 error "set striped dir error"
25954
25955         touch $DIR/$tdir/striped_dir/a
25956         touch $DIR/$tdir/striped_dir/b
25957         touch $DIR/$tdir/striped_dir/c
25958
25959         mkdir $DIR/$tdir/striped_dir/dir_a
25960         mkdir $DIR/$tdir/striped_dir/dir_b
25961         mkdir $DIR/$tdir/striped_dir/dir_c
25962
25963         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
25964                 error "set striped adir under striped dir error"
25965
25966         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
25967                 error "set striped bdir under striped dir error"
25968
25969         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
25970                 error "set striped cdir under striped dir error"
25971
25972         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
25973                 error "rename dir under striped dir fails"
25974
25975         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
25976                 error "rename dir under different stripes fails"
25977
25978         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
25979                 error "rename file under striped dir should succeed"
25980
25981         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
25982                 error "rename dir under striped dir should succeed"
25983
25984         rm -rf $DIR/$tdir
25985 }
25986 run_test 300e "check rename under striped directory"
25987
25988 test_300f() {
25989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25990         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25991         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25992                 skip "Need MDS version at least 2.7.55"
25993
25994         local stripe_count
25995         local file
25996
25997         rm -rf $DIR/$tdir
25998         mkdir -p $DIR/$tdir
25999
26000         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
26001                 error "set striped dir error"
26002
26003         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
26004                 error "set striped dir error"
26005
26006         touch $DIR/$tdir/striped_dir/a
26007         mkdir $DIR/$tdir/striped_dir/dir_a
26008         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
26009                 error "create striped dir under striped dir fails"
26010
26011         touch $DIR/$tdir/striped_dir1/b
26012         mkdir $DIR/$tdir/striped_dir1/dir_b
26013         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
26014                 error "create striped dir under striped dir fails"
26015
26016         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
26017                 error "rename dir under different striped dir should fail"
26018
26019         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
26020                 error "rename striped dir under diff striped dir should fail"
26021
26022         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
26023                 error "rename file under diff striped dirs fails"
26024
26025         rm -rf $DIR/$tdir
26026 }
26027 run_test 300f "check rename cross striped directory"
26028
26029 test_300_check_default_striped_dir()
26030 {
26031         local dirname=$1
26032         local default_count=$2
26033         local default_index=$3
26034         local stripe_count
26035         local stripe_index
26036         local dir_stripe_index
26037         local dir
26038
26039         echo "checking $dirname $default_count $default_index"
26040         $LFS setdirstripe -D -c $default_count -i $default_index \
26041                                 -H all_char $DIR/$tdir/$dirname ||
26042                 error "set default stripe on striped dir error"
26043         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
26044         [ $stripe_count -eq $default_count ] ||
26045                 error "expect $default_count get $stripe_count for $dirname"
26046
26047         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
26048         [ $stripe_index -eq $default_index ] ||
26049                 error "expect $default_index get $stripe_index for $dirname"
26050
26051         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
26052                                                 error "create dirs failed"
26053
26054         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
26055         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
26056         for dir in $(find $DIR/$tdir/$dirname/*); do
26057                 stripe_count=$($LFS getdirstripe -c $dir)
26058                 (( $stripe_count == $default_count )) ||
26059                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
26060                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
26061                 error "stripe count $default_count != $stripe_count for $dir"
26062
26063                 stripe_index=$($LFS getdirstripe -i $dir)
26064                 [ $default_index -eq -1 ] ||
26065                         [ $stripe_index -eq $default_index ] ||
26066                         error "$stripe_index != $default_index for $dir"
26067
26068                 #check default stripe
26069                 stripe_count=$($LFS getdirstripe -D -c $dir)
26070                 [ $stripe_count -eq $default_count ] ||
26071                 error "default count $default_count != $stripe_count for $dir"
26072
26073                 stripe_index=$($LFS getdirstripe -D -i $dir)
26074                 [ $stripe_index -eq $default_index ] ||
26075                 error "default index $default_index != $stripe_index for $dir"
26076         done
26077         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
26078 }
26079
26080 test_300g() {
26081         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26082         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26083                 skip "Need MDS version at least 2.7.55"
26084
26085         local dir
26086         local stripe_count
26087         local stripe_index
26088
26089         mkdir_on_mdt0 $DIR/$tdir
26090         mkdir $DIR/$tdir/normal_dir
26091
26092         #Checking when client cache stripe index
26093         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26094         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
26095                 error "create striped_dir failed"
26096
26097         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
26098                 error "create dir0 fails"
26099         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
26100         [ $stripe_index -eq 0 ] ||
26101                 error "dir0 expect index 0 got $stripe_index"
26102
26103         mkdir $DIR/$tdir/striped_dir/dir1 ||
26104                 error "create dir1 fails"
26105         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
26106         [ $stripe_index -eq 1 ] ||
26107                 error "dir1 expect index 1 got $stripe_index"
26108
26109         #check default stripe count/stripe index
26110         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
26111         test_300_check_default_striped_dir normal_dir 1 0
26112         test_300_check_default_striped_dir normal_dir -1 1
26113         test_300_check_default_striped_dir normal_dir 2 -1
26114
26115         #delete default stripe information
26116         echo "delete default stripeEA"
26117         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
26118                 error "set default stripe on striped dir error"
26119
26120         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
26121         for dir in $(find $DIR/$tdir/normal_dir/*); do
26122                 stripe_count=$($LFS getdirstripe -c $dir)
26123                 [ $stripe_count -eq 0 ] ||
26124                         error "expect 1 get $stripe_count for $dir"
26125         done
26126 }
26127 run_test 300g "check default striped directory for normal directory"
26128
26129 test_300h() {
26130         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26131         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26132                 skip "Need MDS version at least 2.7.55"
26133
26134         local dir
26135         local stripe_count
26136
26137         mkdir $DIR/$tdir
26138         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
26139                 error "set striped dir error"
26140
26141         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
26142         test_300_check_default_striped_dir striped_dir 1 0
26143         test_300_check_default_striped_dir striped_dir -1 1
26144         test_300_check_default_striped_dir striped_dir 2 -1
26145
26146         #delete default stripe information
26147         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
26148                 error "set default stripe on striped dir error"
26149
26150         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
26151         for dir in $(find $DIR/$tdir/striped_dir/*); do
26152                 stripe_count=$($LFS getdirstripe -c $dir)
26153                 [ $stripe_count -eq 0 ] ||
26154                         error "expect 1 get $stripe_count for $dir"
26155         done
26156 }
26157 run_test 300h "check default striped directory for striped directory"
26158
26159 test_300i() {
26160         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
26161         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
26162         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
26163                 skip "Need MDS version at least 2.7.55"
26164
26165         local stripe_count
26166         local file
26167
26168         mkdir $DIR/$tdir
26169
26170         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
26171                 error "set striped dir error"
26172
26173         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
26174                 error "create files under striped dir failed"
26175
26176         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
26177                 error "set striped hashdir error"
26178
26179         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
26180                 error "create dir0 under hash dir failed"
26181         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
26182                 error "create dir1 under hash dir failed"
26183         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
26184                 error "create dir2 under hash dir failed"
26185
26186         # unfortunately, we need to umount to clear dir layout cache for now
26187         # once we fully implement dir layout, we can drop this
26188         umount_client $MOUNT || error "umount failed"
26189         mount_client $MOUNT || error "mount failed"
26190
26191         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
26192         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
26193         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
26194
26195         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
26196                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
26197                         error "create crush2 dir $tdir/hashdir/d3 failed"
26198                 $LFS find -H crush2 $DIR/$tdir/hashdir
26199                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
26200                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
26201
26202                 # mkdir with an invalid hash type (hash=fail_val) from client
26203                 # should be replaced on MDS with a valid (default) hash type
26204                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
26205                 $LCTL set_param fail_loc=0x1901 fail_val=99
26206                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
26207
26208                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
26209                 local expect=$(do_facet mds1 \
26210                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
26211                 [[ $hash == $expect ]] ||
26212                         error "d99 hash '$hash' != expected hash '$expect'"
26213         fi
26214
26215         #set the stripe to be unknown hash type on read
26216         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
26217         $LCTL set_param fail_loc=0x1901 fail_val=99
26218         for ((i = 0; i < 10; i++)); do
26219                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
26220                         error "stat f-$i failed"
26221                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
26222         done
26223
26224         touch $DIR/$tdir/striped_dir/f0 &&
26225                 error "create under striped dir with unknown hash should fail"
26226
26227         $LCTL set_param fail_loc=0
26228
26229         umount_client $MOUNT || error "umount failed"
26230         mount_client $MOUNT || error "mount failed"
26231
26232         return 0
26233 }
26234 run_test 300i "client handle unknown hash type striped directory"
26235
26236 test_300j() {
26237         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26238         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26239         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26240                 skip "Need MDS version at least 2.7.55"
26241
26242         local stripe_count
26243         local file
26244
26245         mkdir $DIR/$tdir
26246
26247         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
26248         $LCTL set_param fail_loc=0x1702
26249         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
26250                 error "set striped dir error"
26251
26252         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
26253                 error "create files under striped dir failed"
26254
26255         $LCTL set_param fail_loc=0
26256
26257         rm -rf $DIR/$tdir || error "unlink striped dir fails"
26258
26259         return 0
26260 }
26261 run_test 300j "test large update record"
26262
26263 test_300k() {
26264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26265         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26266         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26267                 skip "Need MDS version at least 2.7.55"
26268
26269         # this test needs a huge transaction
26270         local kb
26271         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
26272              osd*.$FSNAME-MDT0000.kbytestotal")
26273         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
26274
26275         local stripe_count
26276         local file
26277
26278         mkdir $DIR/$tdir
26279
26280         #define OBD_FAIL_LARGE_STRIPE   0x1703
26281         $LCTL set_param fail_loc=0x1703
26282         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
26283                 error "set striped dir error"
26284         $LCTL set_param fail_loc=0
26285
26286         $LFS getdirstripe $DIR/$tdir/striped_dir ||
26287                 error "getstripeddir fails"
26288         rm -rf $DIR/$tdir/striped_dir ||
26289                 error "unlink striped dir fails"
26290
26291         return 0
26292 }
26293 run_test 300k "test large striped directory"
26294
26295 test_300l() {
26296         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26297         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26298         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26299                 skip "Need MDS version at least 2.7.55"
26300
26301         local stripe_index
26302
26303         test_mkdir -p $DIR/$tdir/striped_dir
26304         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
26305                         error "chown $RUNAS_ID failed"
26306         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
26307                 error "set default striped dir failed"
26308
26309         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
26310         $LCTL set_param fail_loc=0x80000158
26311         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
26312
26313         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
26314         [ $stripe_index -eq 1 ] ||
26315                 error "expect 1 get $stripe_index for $dir"
26316 }
26317 run_test 300l "non-root user to create dir under striped dir with stale layout"
26318
26319 test_300m() {
26320         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26321         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
26322         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26323                 skip "Need MDS version at least 2.7.55"
26324
26325         mkdir -p $DIR/$tdir/striped_dir
26326         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
26327                 error "set default stripes dir error"
26328
26329         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
26330
26331         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
26332         [ $stripe_count -eq 0 ] ||
26333                         error "expect 0 get $stripe_count for a"
26334
26335         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
26336                 error "set default stripes dir error"
26337
26338         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
26339
26340         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
26341         [ $stripe_count -eq 0 ] ||
26342                         error "expect 0 get $stripe_count for b"
26343
26344         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
26345                 error "set default stripes dir error"
26346
26347         mkdir $DIR/$tdir/striped_dir/c &&
26348                 error "default stripe_index is invalid, mkdir c should fails"
26349
26350         rm -rf $DIR/$tdir || error "rmdir fails"
26351 }
26352 run_test 300m "setstriped directory on single MDT FS"
26353
26354 cleanup_300n() {
26355         local list=$(comma_list $(mdts_nodes))
26356
26357         trap 0
26358         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26359 }
26360
26361 test_300n() {
26362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26363         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26364         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26365                 skip "Need MDS version at least 2.7.55"
26366         remote_mds_nodsh && skip "remote MDS with nodsh"
26367
26368         local stripe_index
26369         local list=$(comma_list $(mdts_nodes))
26370
26371         trap cleanup_300n RETURN EXIT
26372         mkdir -p $DIR/$tdir
26373         chmod 777 $DIR/$tdir
26374         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
26375                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
26376                 error "create striped dir succeeds with gid=0"
26377
26378         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
26379         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
26380                 error "create striped dir fails with gid=-1"
26381
26382         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26383         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
26384                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
26385                 error "set default striped dir succeeds with gid=0"
26386
26387
26388         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
26389         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
26390                 error "set default striped dir fails with gid=-1"
26391
26392
26393         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26394         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
26395                                         error "create test_dir fails"
26396         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
26397                                         error "create test_dir1 fails"
26398         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
26399                                         error "create test_dir2 fails"
26400         cleanup_300n
26401 }
26402 run_test 300n "non-root user to create dir under striped dir with default EA"
26403
26404 test_300o() {
26405         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26406         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26407         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26408                 skip "Need MDS version at least 2.7.55"
26409
26410         local numfree1
26411         local numfree2
26412
26413         mkdir -p $DIR/$tdir
26414
26415         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
26416         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
26417         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
26418                 skip "not enough free inodes $numfree1 $numfree2"
26419         fi
26420
26421         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
26422         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
26423         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
26424                 skip "not enough free space $numfree1 $numfree2"
26425         fi
26426
26427         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
26428                 error "setdirstripe fails"
26429
26430         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
26431                 error "create dirs fails"
26432
26433         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
26434         ls $DIR/$tdir/striped_dir > /dev/null ||
26435                 error "ls striped dir fails"
26436         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
26437                 error "unlink big striped dir fails"
26438 }
26439 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
26440
26441 test_300p() {
26442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26443         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26444         remote_mds_nodsh && skip "remote MDS with nodsh"
26445
26446         mkdir_on_mdt0 $DIR/$tdir
26447
26448         #define OBD_FAIL_OUT_ENOSPC     0x1704
26449         do_facet mds2 lctl set_param fail_loc=0x80001704
26450         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
26451                  && error "create striped directory should fail"
26452
26453         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
26454
26455         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
26456         true
26457 }
26458 run_test 300p "create striped directory without space"
26459
26460 test_300q() {
26461         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26462         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26463
26464         local fd=$(free_fd)
26465         local cmd="exec $fd<$tdir"
26466         cd $DIR
26467         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
26468         eval $cmd
26469         cmd="exec $fd<&-"
26470         trap "eval $cmd" EXIT
26471         cd $tdir || error "cd $tdir fails"
26472         rmdir  ../$tdir || error "rmdir $tdir fails"
26473         mkdir local_dir && error "create dir succeeds"
26474         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
26475         eval $cmd
26476         return 0
26477 }
26478 run_test 300q "create remote directory under orphan directory"
26479
26480 test_300r() {
26481         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26482                 skip "Need MDS version at least 2.7.55" && return
26483         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
26484
26485         mkdir $DIR/$tdir
26486
26487         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
26488                 error "set striped dir error"
26489
26490         $LFS getdirstripe $DIR/$tdir/striped_dir ||
26491                 error "getstripeddir fails"
26492
26493         local stripe_count
26494         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
26495                       awk '/lmv_stripe_count:/ { print $2 }')
26496
26497         [ $MDSCOUNT -ne $stripe_count ] &&
26498                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
26499
26500         rm -rf $DIR/$tdir/striped_dir ||
26501                 error "unlink striped dir fails"
26502 }
26503 run_test 300r "test -1 striped directory"
26504
26505 test_300s_helper() {
26506         local count=$1
26507
26508         local stripe_dir=$DIR/$tdir/striped_dir.$count
26509
26510         $LFS mkdir -c $count $stripe_dir ||
26511                 error "lfs mkdir -c error"
26512
26513         $LFS getdirstripe $stripe_dir ||
26514                 error "lfs getdirstripe fails"
26515
26516         local stripe_count
26517         stripe_count=$($LFS getdirstripe $stripe_dir |
26518                       awk '/lmv_stripe_count:/ { print $2 }')
26519
26520         [ $count -ne $stripe_count ] &&
26521                 error_noexit "bad stripe count $stripe_count expected $count"
26522
26523         local dupe_stripes
26524         dupe_stripes=$($LFS getdirstripe $stripe_dir |
26525                 awk '/0x/ {count[$1] += 1}; END {
26526                         for (idx in count) {
26527                                 if (count[idx]>1) {
26528                                         print "index " idx " count " count[idx]
26529                                 }
26530                         }
26531                 }')
26532
26533         if [[ -n "$dupe_stripes" ]] ; then
26534                 lfs getdirstripe $stripe_dir
26535                 error_noexit "Dupe MDT above: $dupe_stripes "
26536         fi
26537
26538         rm -rf $stripe_dir ||
26539                 error_noexit "unlink $stripe_dir fails"
26540 }
26541
26542 test_300s() {
26543         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26544                 skip "Need MDS version at least 2.7.55" && return
26545         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
26546
26547         mkdir $DIR/$tdir
26548         for count in $(seq 2 $MDSCOUNT); do
26549                 test_300s_helper $count
26550         done
26551 }
26552 run_test 300s "test lfs mkdir -c without -i"
26553
26554 test_300t() {
26555         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
26556                 skip "need MDS 2.14.55 or later"
26557         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
26558
26559         local testdir="$DIR/$tdir/striped_dir"
26560         local dir1=$testdir/dir1
26561         local dir2=$testdir/dir2
26562
26563         mkdir -p $testdir
26564
26565         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
26566                 error "failed to set default stripe count for $testdir"
26567
26568         mkdir $dir1
26569         local stripe_count=$($LFS getdirstripe -c $dir1)
26570
26571         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
26572
26573         local max_count=$((MDSCOUNT - 1))
26574         local mdts=$(comma_list $(mdts_nodes))
26575
26576         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
26577         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
26578
26579         mkdir $dir2
26580         stripe_count=$($LFS getdirstripe -c $dir2)
26581
26582         (( $stripe_count == $max_count )) || error "wrong stripe count"
26583 }
26584 run_test 300t "test max_mdt_stripecount"
26585
26586 MDT_OVSTRP_VER="2.15.60"
26587 # 300u family tests MDT overstriping
26588 test_300ua() {
26589         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26590
26591         local setcount=$((MDSCOUNT * 2))
26592
26593         local expected_count
26594
26595         mkdir $DIR/$tdir
26596         $LFS setdirstripe -C $setcount $DIR/$tdir/${tdir}.0 ||
26597                 error "(0) failed basic overstriped dir creation test"
26598         local getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.0)
26599
26600         # This does a basic interop test - if the MDS does not support mdt
26601         # overstriping, we should get stripes == number of MDTs
26602         if (( $MDS1_VERSION < $(version_code $MDT_OVSTRP_VER) )); then
26603                 expected_count=$MDSCOUNT
26604         else
26605                 expected_count=$setcount
26606         fi
26607         (( getstripe_count == expected_count )) ||
26608                 error "(1) incorrect stripe count for simple overstriped dir"
26609
26610         rm -rf $DIR/$tdir/${tdir}.0 ||
26611                 error "(2) unable to rm overstriped dir"
26612
26613         # Tests after this require overstriping support
26614         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26615                 { echo "skipped for MDS < $MDT_OVSTRP_VER"; return 0; }
26616
26617         test_striped_dir 0 $setcount true ||
26618                 error "(3)failed on overstriped dir"
26619         test_striped_dir 1 $setcount true ||
26620                 error "(4)failed on overstriped dir"
26621
26622         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26623
26624         test_striped_dir 0 $setcount true ||
26625                 error "(5)failed on overstriped dir"
26626 }
26627 run_test 300ua "basic overstriped dir sanity test"
26628
26629 test_300ub() {
26630         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26631                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26632         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26633
26634         mkdir $DIR/$tdir
26635
26636         echo "Testing invalid stripe count, failure expected"
26637         local setcount=$((MDSCOUNT * 2))
26638
26639         $LFS setdirstripe -c $setcount $DIR/$tdir/${tdir}.0
26640         local getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.0)
26641
26642         (( getstripe_count <= MDSCOUNT )) ||
26643                 error "(0)stripe count ($setcount) > MDT count ($MDSCOUNT) succeeded with -c"
26644
26645         # When a user requests > LMV_MAX_STRIPES_PER_MDT, we reduce to that
26646         setcount=$((MDSCOUNT * 2 * LMV_MAX_STRIPES_PER_MDT))
26647         $LFS setdirstripe -C $setcount $DIR/$tdir/${tdir}.1
26648
26649         local maxcount=$((MDSCOUNT * LMV_MAX_STRIPES_PER_MDT))
26650
26651         getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.1)
26652         (( getstripe_count == maxcount )) ||
26653                 error "(1)stripe_count is $getstripe_count, expect $maxcount"
26654
26655         # Test specific striping with -i
26656         $LFS setdirstripe -i 0,0,0,0 $DIR/$tdir/${tdir}.2
26657
26658         getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.2)
26659         (( getstripe_count == 4 )) ||
26660                 error "(2)stripe_count is $getstripe_count, expect 4"
26661
26662         local nonzeroindices=$($LFS getdirstripe $DIR/$tdir/${tdir}.2 | grep "\[" | \
26663                                grep -v mdtidx | awk '{print $1}' | grep -c -v 0)
26664
26665         [[ -n "$nonzeroindices" ]] ||
26666                 error "(3) stripes indices not all 0: $nonzeroindices"
26667
26668         # Test specific striping with too many stripes on one MDT
26669         echo "Testing invalid striping, failure expected"
26670         $LFS setdirstripe -i 0,1,0,1,0,1,0,1,0,1,0 $DIR/$tdir/${tdir}.3
26671         $LFS getdirstripe $DIR/$tdir/${tdir}.3
26672         getstripe_count=$($LFS getdirstripe $DIR/$tdir/${tdir}.3 | grep "\[" | \
26673                           grep -v mdtidx | awk '{print $1}' | grep -c '0')
26674         echo "stripes on MDT0: $getstripe_count"
26675         (( getstripe_count <= LMV_MAX_STRIPES_PER_MDT )) ||
26676                 error "(4) setstripe with too many stripes on MDT0 succeeded"
26677
26678         setcount=$((MDSCOUNT * 2))
26679         $LFS setdirstripe -C $setcount -H all_char $DIR/${tdir}.4 ||
26680                 error "(5) can't setdirstripe with manually set hash function"
26681
26682         getstripe_count=$($LFS getdirstripe -c $DIR/${tdir}.4)
26683         (( getstripe_count == setcount )) ||
26684                 error "(6)stripe_count is $getstripe_count, expect $setcount"
26685
26686         setcount=$((MDSCOUNT * 2))
26687         mkdir $DIR/${tdir}.5
26688         $LFS setdirstripe -C $setcount -D -H crush $DIR/${tdir}.5 ||
26689                 error "(7) can't setdirstripe with manually set hash function"
26690         mkdir $DIR/${tdir}.5/${tdir}.6
26691
26692         getstripe_count=$($LFS getdirstripe -c $DIR/${tdir}.5/${tdir}.6)
26693         (( getstripe_count == setcount )) ||
26694                 error "(8)stripe_count is $getstripe_count, expect $setcount"
26695 }
26696 run_test 300ub "test MDT overstriping interface & limits"
26697
26698 test_300uc() {
26699         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26700                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26701         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26702
26703         mkdir $DIR/$tdir
26704
26705         local setcount=$((MDSCOUNT * 2))
26706
26707         $LFS setdirstripe -D -C $setcount $DIR/$tdir
26708
26709         mkdir $DIR/$tdir/${tdir}.1
26710
26711         local getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.1)
26712
26713         (( getstripe_count == setcount )) ||
26714                 error "(0)stripe_count is $getstripe_count, expect $setcount"
26715
26716         mkdir $DIR/$tdir/${tdir}.1/${tdir}.2
26717
26718         local getstripe_count=$($LFS getdirstripe -c \
26719                                 $DIR/$tdir/${tdir}.1/${tdir}.2)
26720
26721         (( getstripe_count == setcount )) ||
26722                 error "(1)stripe_count is $getstripe_count, expect $setcount"
26723 }
26724 run_test 300uc "test MDT overstriping as default & inheritance"
26725
26726 test_300ud() {
26727         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26728                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26729         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26730
26731         local mdts=$(comma_list $(mdts_nodes))
26732         local timeout=100
26733
26734         local restripe_status
26735         local delta
26736         local i
26737
26738         [[ $mds1_FSTYPE == zfs ]] && timeout=300
26739
26740         # in case "crush" hash type is not set
26741         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
26742
26743         restripe_status=$(do_facet mds1 $LCTL get_param -n \
26744                            mdt.*MDT0000.enable_dir_restripe)
26745         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
26746         stack_trap "do_nodes $mdts $LCTL set_param \
26747                     mdt.*.enable_dir_restripe=$restripe_status"
26748
26749         mkdir $DIR/$tdir
26750         createmany -m $DIR/$tdir/f $((50 * MDSCOUNT)) ||
26751                 error "create files under remote dir failed $i"
26752         createmany -d $DIR/$tdir/d $((50 * MDSCOUNT)) ||
26753                 error "create dirs under remote dir failed $i"
26754
26755         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26756
26757         (( setcount < 13 )) || setcount=12
26758         for i in $(seq 2 $setcount); do
26759                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
26760                 $LFS setdirstripe -C $i $DIR/$tdir ||
26761                         error "split -C $i $tdir failed"
26762                 wait_update $HOSTNAME \
26763                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
26764                         error "dir split not finished"
26765                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
26766                         awk '/migrate/ {sum += $2} END { print sum }')
26767                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
26768                 # delta is around total_files/stripe_count, deviation 3%
26769                 (( delta < 100 * MDSCOUNT / i + 3 * MDSCOUNT )) ||
26770                         error "$delta files migrated >= $((100 * MDSCOUNT / i + 3 * MDSCOUNT))"
26771         done
26772 }
26773 run_test 300ud "dir split"
26774
26775 test_300ue() {
26776         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26777                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26778         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26779
26780         local mdts=$(comma_list $(mdts_nodes))
26781         local timeout=100
26782
26783         local restripe_status
26784         local delta
26785         local c
26786
26787         [[ $mds1_FSTYPE == zfs ]] && timeout=300
26788
26789         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
26790
26791         restripe_status=$(do_facet mds1 $LCTL get_param -n \
26792                            mdt.*MDT0000.enable_dir_restripe)
26793         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
26794         stack_trap "do_nodes $mdts $LCTL set_param \
26795                     mdt.*.enable_dir_restripe=$restripe_status"
26796
26797         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26798
26799         (( setcount < 13 )) || setcount=12
26800         test_mkdir -C $setcount -H crush $DIR/$tdir
26801         createmany -m $DIR/$tdir/f $((50 * MDSCOUNT)) ||
26802                 error "create files under remote dir failed"
26803         createmany -d $DIR/$tdir/d $((50 * MDSCOUNT)) ||
26804                 error "create dirs under remote dir failed"
26805
26806         for c in $(seq $((setcount - 1)) -1 1); do
26807                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
26808                 $LFS setdirstripe -C $c $DIR/$tdir ||
26809                         error "split -C $c $tdir failed"
26810                 wait_update $HOSTNAME \
26811                         "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" $timeout ||
26812                         error "dir merge not finished"
26813                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
26814                         awk '/migrate/ {sum += $2} END { print sum }')
26815                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
26816                 # delta is around total_files/stripe_count, deviation 3%
26817                 (( delta < 100 * MDSCOUNT / c + 3 * MDSCOUNT )) ||
26818                         error "$delta files migrated >= $((100 * MDSCOUNT / c + 3 * MDSCOUNT))"
26819         done
26820 }
26821 run_test 300ue "dir merge"
26822
26823 test_300uf() {
26824         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26825                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26826         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26827
26828         # maximum amount of local locks:
26829         # parent striped dir - 2 locks
26830         # new stripe in parent to migrate to - 1 lock
26831         # source and target - 2 locks
26832         # Total 5 locks for regular file
26833         #
26834         # NB: Overstriping should add several extra local locks
26835         # FIXME: Remove this once understood
26836         #lctl set_param *debug=-1 debug_mb=10000
26837         lctl clear
26838         lctl mark "touch/create"
26839         mkdir -p $DIR/$tdir
26840         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26841         local setcount=$((MDSCOUNT * 5))
26842
26843         $LFS mkdir -i1 -C $setcount $DIR/$tdir/dir1
26844         touch $DIR/$tdir/dir1/eee
26845
26846         lctl mark "hardlinks"
26847         # create 4 hardlink for 4 more locks
26848         # Total: 9 locks > RS_MAX_LOCKS (8)
26849         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
26850         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
26851         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
26852         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
26853         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
26854         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
26855         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
26856         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
26857
26858         lctl mark "cancel lru"
26859         cancel_lru_locks mdc
26860
26861         lctl mark "migrate"
26862         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
26863                 error "migrate dir fails"
26864
26865         rm -rf $DIR/$tdir || error "rm dir failed after migration"
26866 }
26867 run_test 300uf "migrate with too many local locks"
26868
26869 test_300ug() {
26870         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26871                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26872         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26873
26874         mkdir -p $DIR/$tdir
26875         local migrate_dir=$DIR/$tdir/migrate_dir
26876         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26877         local setcount2=$((setcount - 2))
26878
26879         $LFS setdirstripe -c 2 $migrate_dir ||
26880                 error "(0) failed to create striped directory"
26881
26882         $LFS migrate -m 0 -C $setcount $migrate_dir ||
26883                 error "(1)failed to migrate to overstriped directory"
26884         local getstripe_count=$($LFS getdirstripe -c $migrate_dir)
26885
26886         (( getstripe_count == setcount )) ||
26887                 error "(2)stripe_count is $getstripe_count, expect $setcount"
26888         touch $DIR/$tdir/migrate_dir/$tfile ||
26889                 error "(3)failed to create file in overstriped directory"
26890         $LFS migrate -m 0 -C $setcount2 $migrate_dir ||
26891                 error "(4)failed to migrate overstriped directory"
26892         # Check stripe count after migration
26893         $LFS getdirstripe $migrate_dir
26894         getstripe_count=$($LFS getdirstripe -c $migrate_dir)
26895         (( getstripe_count == setcount2 )) ||
26896                 error "(5)stripe_count is $getstripe_count, expect $setcount2"
26897
26898         rm -rf $migrate_dir || error "(6) unable to rm overstriped dir"
26899 }
26900 run_test 300ug "migrate overstriped dirs"
26901
26902 prepare_remote_file() {
26903         mkdir $DIR/$tdir/src_dir ||
26904                 error "create remote source failed"
26905
26906         cp /etc/hosts $DIR/$tdir/src_dir/a ||
26907                  error "cp to remote source failed"
26908         touch $DIR/$tdir/src_dir/a
26909
26910         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
26911                 error "create remote target dir failed"
26912
26913         touch $DIR/$tdir/tgt_dir/b
26914
26915         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
26916                 error "rename dir cross MDT failed!"
26917
26918         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
26919                 error "src_child still exists after rename"
26920
26921         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
26922                 error "missing file(a) after rename"
26923
26924         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
26925                 error "diff after rename"
26926 }
26927
26928 test_310a() {
26929         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
26930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26931
26932         local remote_file=$DIR/$tdir/tgt_dir/b
26933
26934         mkdir -p $DIR/$tdir
26935
26936         prepare_remote_file || error "prepare remote file failed"
26937
26938         #open-unlink file
26939         $OPENUNLINK $remote_file $remote_file ||
26940                 error "openunlink $remote_file failed"
26941         $CHECKSTAT -a $remote_file || error "$remote_file exists"
26942 }
26943 run_test 310a "open unlink remote file"
26944
26945 test_310b() {
26946         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
26947         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26948
26949         local remote_file=$DIR/$tdir/tgt_dir/b
26950
26951         mkdir -p $DIR/$tdir
26952
26953         prepare_remote_file || error "prepare remote file failed"
26954
26955         ln $remote_file $DIR/$tfile || error "link failed for remote file"
26956         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
26957         $CHECKSTAT -t file $remote_file || error "check file failed"
26958 }
26959 run_test 310b "unlink remote file with multiple links while open"
26960
26961 test_310c() {
26962         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26963         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
26964
26965         local remote_file=$DIR/$tdir/tgt_dir/b
26966
26967         mkdir -p $DIR/$tdir
26968
26969         prepare_remote_file || error "prepare remote file failed"
26970
26971         ln $remote_file $DIR/$tfile || error "link failed for remote file"
26972         multiop_bg_pause $remote_file O_uc ||
26973                         error "mulitop failed for remote file"
26974         MULTIPID=$!
26975         $MULTIOP $DIR/$tfile Ouc
26976         kill -USR1 $MULTIPID
26977         wait $MULTIPID
26978 }
26979 run_test 310c "open-unlink remote file with multiple links"
26980
26981 #LU-4825
26982 test_311() {
26983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26984         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
26985         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
26986                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
26987         remote_mds_nodsh && skip "remote MDS with nodsh"
26988
26989         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
26990         local mdts=$(comma_list $(mdts_nodes))
26991
26992         mkdir -p $DIR/$tdir
26993         $LFS setstripe -i 0 -c 1 $DIR/$tdir
26994         createmany -o $DIR/$tdir/$tfile. 1000
26995
26996         # statfs data is not real time, let's just calculate it
26997         old_iused=$((old_iused + 1000))
26998
26999         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27000                         osp.*OST0000*MDT0000.create_count")
27001         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27002                                 osp.*OST0000*MDT0000.max_create_count")
27003         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
27004
27005         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
27006         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
27007         [ $index -ne 0 ] || error "$tfile stripe index is 0"
27008
27009         unlinkmany $DIR/$tdir/$tfile. 1000
27010
27011         do_nodes $mdts "$LCTL set_param -n \
27012                         osp.*OST0000*.max_create_count=$max_count"
27013         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
27014                 do_nodes $mdts "$LCTL set_param -n \
27015                                 osp.*OST0000*.create_count=$count"
27016         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
27017                         grep "=0" && error "create_count is zero"
27018
27019         local new_iused
27020         for i in $(seq 120); do
27021                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
27022                 # system may be too busy to destroy all objs in time, use
27023                 # a somewhat small value to not fail autotest
27024                 [ $((old_iused - new_iused)) -gt 400 ] && break
27025                 sleep 1
27026         done
27027
27028         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
27029         [ $((old_iused - new_iused)) -gt 400 ] ||
27030                 error "objs not destroyed after unlink"
27031 }
27032 run_test 311 "disable OSP precreate, and unlink should destroy objs"
27033
27034 zfs_get_objid()
27035 {
27036         local ost=$1
27037         local tf=$2
27038         local fid=($($LFS getstripe $tf | grep 0x))
27039         local seq=${fid[3]#0x}
27040         local objid=${fid[1]}
27041
27042         local vdevdir=$(dirname $(facet_vdevice $ost))
27043         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
27044         local zfs_zapid=$(do_facet $ost $cmd |
27045                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
27046                           awk '/Object/{getline; print $1}')
27047         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
27048                           awk "/$objid = /"'{printf $3}')
27049
27050         echo $zfs_objid
27051 }
27052
27053 zfs_object_blksz() {
27054         local ost=$1
27055         local objid=$2
27056
27057         local vdevdir=$(dirname $(facet_vdevice $ost))
27058         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
27059         local blksz=$(do_facet $ost $cmd $objid |
27060                       awk '/dblk/{getline; printf $4}')
27061
27062         case "${blksz: -1}" in
27063                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
27064                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
27065                 *) ;;
27066         esac
27067
27068         echo $blksz
27069 }
27070
27071 test_312() { # LU-4856
27072         remote_ost_nodsh && skip "remote OST with nodsh"
27073         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
27074
27075         local max_blksz=$(do_facet ost1 \
27076                           $ZFS get -p recordsize $(facet_device ost1) |
27077                           awk '!/VALUE/{print $3}')
27078         local tf=$DIR/$tfile
27079
27080         $LFS setstripe -c1 $tf
27081         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
27082
27083         # Get ZFS object id
27084         local zfs_objid=$(zfs_get_objid $facet $tf)
27085         # block size change by sequential overwrite
27086         local bs
27087
27088         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
27089                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
27090
27091                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
27092                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
27093         done
27094         rm -f $tf
27095
27096         $LFS setstripe -c1 $tf
27097         facet="ost$(($($LFS getstripe -i $tf) + 1))"
27098
27099         # block size change by sequential append write
27100         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
27101         zfs_objid=$(zfs_get_objid $facet $tf)
27102         local count
27103
27104         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
27105                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
27106                         oflag=sync conv=notrunc
27107
27108                 blksz=$(zfs_object_blksz $facet $zfs_objid)
27109                 (( $blksz == 2 * count * PAGE_SIZE )) ||
27110                         error "blksz error, actual $blksz, " \
27111                                 "expected: 2 * $count * $PAGE_SIZE"
27112         done
27113         rm -f $tf
27114
27115         # random write
27116         $LFS setstripe -c1 $tf
27117         facet="ost$(($($LFS getstripe -i $tf) + 1))"
27118         zfs_objid=$(zfs_get_objid $facet $tf)
27119
27120         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
27121         blksz=$(zfs_object_blksz $facet $zfs_objid)
27122         (( blksz == PAGE_SIZE )) ||
27123                 error "blksz error: $blksz, expected: $PAGE_SIZE"
27124
27125         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
27126         blksz=$(zfs_object_blksz $facet $zfs_objid)
27127         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
27128
27129         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
27130         blksz=$(zfs_object_blksz $facet $zfs_objid)
27131         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
27132 }
27133 run_test 312 "make sure ZFS adjusts its block size by write pattern"
27134
27135 test_313() {
27136         remote_ost_nodsh && skip "remote OST with nodsh"
27137
27138         local file=$DIR/$tfile
27139
27140         rm -f $file
27141         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
27142
27143         # define OBD_FAIL_TGT_RCVD_EIO           0x720
27144         do_facet ost1 "$LCTL set_param fail_loc=0x720"
27145         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
27146                 error "write should failed"
27147         do_facet ost1 "$LCTL set_param fail_loc=0"
27148         rm -f $file
27149 }
27150 run_test 313 "io should fail after last_rcvd update fail"
27151
27152 test_314() {
27153         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
27154
27155         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
27156         do_facet ost1 "$LCTL set_param fail_loc=0x720"
27157         rm -f $DIR/$tfile
27158         wait_delete_completed
27159         do_facet ost1 "$LCTL set_param fail_loc=0"
27160 }
27161 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
27162
27163 test_315() { # LU-618
27164         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
27165
27166         local file=$DIR/$tfile
27167         rm -f $file
27168
27169         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
27170                 error "multiop file write failed"
27171         $MULTIOP $file oO_RDONLY:r4063232_c &
27172         PID=$!
27173
27174         sleep 2
27175
27176         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
27177         kill -USR1 $PID
27178
27179         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
27180         rm -f $file
27181 }
27182 run_test 315 "read should be accounted"
27183
27184 test_316() {
27185         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
27186         large_xattr_enabled || skip "ea_inode feature disabled"
27187
27188         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27189         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
27190         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
27191         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
27192
27193         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
27194 }
27195 run_test 316 "lfs migrate of file with large_xattr enabled"
27196
27197 test_317() {
27198         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
27199                 skip "Need MDS version at least 2.11.53"
27200         if [ "$ost1_FSTYPE" == "zfs" ]; then
27201                 skip "LU-10370: no implementation for ZFS"
27202         fi
27203
27204         local trunc_sz
27205         local grant_blk_size
27206
27207         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
27208                         awk '/grant_block_size:/ { print $2; exit; }')
27209         #
27210         # Create File of size 5M. Truncate it to below size's and verify
27211         # blocks count.
27212         #
27213         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
27214                 error "Create file $DIR/$tfile failed"
27215         stack_trap "rm -f $DIR/$tfile" EXIT
27216
27217         for trunc_sz in 2097152 4097 4000 509 0; do
27218                 $TRUNCATE $DIR/$tfile $trunc_sz ||
27219                         error "truncate $tfile to $trunc_sz failed"
27220                 local sz=$(stat --format=%s $DIR/$tfile)
27221                 local blk=$(stat --format=%b $DIR/$tfile)
27222                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
27223                                      grant_blk_size) * 8))
27224
27225                 if [[ $blk -ne $trunc_blk ]]; then
27226                         $(which stat) $DIR/$tfile
27227                         error "Expected Block $trunc_blk got $blk for $tfile"
27228                 fi
27229
27230                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
27231                         error "Expected Size $trunc_sz got $sz for $tfile"
27232         done
27233
27234         #
27235         # sparse file test
27236         # Create file with a hole and write actual 65536 bytes which aligned
27237         # with 4K and 64K PAGE_SIZE. Block count must be 128.
27238         #
27239         local bs=65536
27240         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
27241                 error "Create file : $DIR/$tfile"
27242
27243         #
27244         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
27245         # blocks. The block count must drop to 8.
27246         #
27247         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
27248                 ((bs - grant_blk_size) + 1)))
27249         $TRUNCATE $DIR/$tfile $trunc_sz ||
27250                 error "truncate $tfile to $trunc_sz failed"
27251
27252         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
27253         sz=$(stat --format=%s $DIR/$tfile)
27254         blk=$(stat --format=%b $DIR/$tfile)
27255
27256         if [[ $blk -ne $trunc_bsz ]]; then
27257                 $(which stat) $DIR/$tfile
27258                 error "Expected Block $trunc_bsz got $blk for $tfile"
27259         fi
27260
27261         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
27262                 error "Expected Size $trunc_sz got $sz for $tfile"
27263 }
27264 run_test 317 "Verify blocks get correctly update after truncate"
27265
27266 test_318() {
27267         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
27268         local old_max_active=$($LCTL get_param -n \
27269                             ${llite_name}.max_read_ahead_async_active \
27270                             2>/dev/null)
27271
27272         $LCTL set_param llite.*.max_read_ahead_async_active=256
27273         local max_active=$($LCTL get_param -n \
27274                            ${llite_name}.max_read_ahead_async_active \
27275                            2>/dev/null)
27276         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
27277
27278         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
27279                 error "set max_read_ahead_async_active should succeed"
27280
27281         $LCTL set_param llite.*.max_read_ahead_async_active=512
27282         max_active=$($LCTL get_param -n \
27283                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
27284         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
27285
27286         # restore @max_active
27287         [ $old_max_active -ne 0 ] && $LCTL set_param \
27288                 llite.*.max_read_ahead_async_active=$old_max_active
27289
27290         local old_threshold=$($LCTL get_param -n \
27291                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
27292         local max_per_file_mb=$($LCTL get_param -n \
27293                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
27294
27295         local invalid=$(($max_per_file_mb + 1))
27296         $LCTL set_param \
27297                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
27298                         && error "set $invalid should fail"
27299
27300         local valid=$(($invalid - 1))
27301         $LCTL set_param \
27302                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
27303                         error "set $valid should succeed"
27304         local threshold=$($LCTL get_param -n \
27305                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
27306         [ $threshold -eq $valid ] || error \
27307                 "expect threshold $valid got $threshold"
27308         $LCTL set_param \
27309                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
27310 }
27311 run_test 318 "Verify async readahead tunables"
27312
27313 test_319() {
27314         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
27315
27316         local before=$(date +%s)
27317         local evict
27318         local mdir=$DIR/$tdir
27319         local file=$mdir/xxx
27320
27321         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
27322         touch $file
27323
27324 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
27325         $LCTL set_param fail_val=5 fail_loc=0x8000032c
27326         $LFS migrate -m1 $mdir &
27327
27328         sleep 1
27329         dd if=$file of=/dev/null
27330         wait
27331         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
27332           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
27333
27334         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
27335 }
27336 run_test 319 "lost lease lock on migrate error"
27337
27338 test_360() {
27339         (( $OST1_VERSION >= $(version_code 2.15.58.96) )) ||
27340                 skip "Need OST version at least 2.15.58.96"
27341         [[ "$ost1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
27342
27343         check_set_fallocate_or_skip
27344         local param="osd-ldiskfs.delayed_unlink_mb"
27345         local old=($(do_facet ost1 "$LCTL get_param -n $param"))
27346
27347         do_facet ost1 "$LCTL set_param $param=1MiB"
27348         stack_trap "do_facet ost1 $LCTL set_param $param=${old[0]}"
27349
27350         mkdir $DIR/$tdir/
27351         do_facet ost1 $LCTL set_param debug=+inode
27352         do_facet ost1 $LCTL clear
27353         local files=100
27354
27355         for ((i = 0; i < $files; i++)); do
27356                 fallocate -l 1280k $DIR/$tdir/$tfile.$i ||
27357                         error "fallocate 1280k $DIR/$tdir/$tfile.$i failed"
27358         done
27359         local min=$(($($LFS find $DIR/$tdir --ost 0 | wc -l) / 2))
27360
27361         for ((i = 0; i < $files; i++)); do
27362                 unlink $DIR/$tdir/$tfile.$i ||
27363                         error "unlink $DIR/$tdir/$tfile.$i failed"
27364         done
27365
27366         local count=0
27367         local loop
27368
27369         for (( loop = 0; loop < 30 && count < min; loop++)); do
27370                 sleep 1
27371                 (( count += $(do_facet ost1 $LCTL dk | grep -c "delayed iput")))
27372                 echo "Count[$loop]: $count"
27373         done
27374         (( count >= min )) || error "$count < $min delayed iput after $loop s"
27375 }
27376 run_test 360 "ldiskfs unlink in a separate thread"
27377
27378 test_398a() { # LU-4198
27379         local ost1_imp=$(get_osc_import_name client ost1)
27380         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27381                          cut -d'.' -f2)
27382
27383         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27384         stack_trap "rm -f $DIR/$tfile"
27385         $LCTL set_param ldlm.namespaces.*.lru_size=clear
27386
27387         # request a new lock on client
27388         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27389
27390         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
27391         local lock_count=$($LCTL get_param -n \
27392                            ldlm.namespaces.$imp_name.lru_size)
27393         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
27394
27395         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
27396
27397         # no lock cached, should use lockless DIO and not enqueue new lock
27398         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
27399         lock_count=$($LCTL get_param -n \
27400                      ldlm.namespaces.$imp_name.lru_size)
27401         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
27402
27403         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
27404
27405         # no lock cached, should use locked DIO append
27406         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
27407                 conv=notrunc || error "DIO append failed"
27408         lock_count=$($LCTL get_param -n \
27409                      ldlm.namespaces.$imp_name.lru_size)
27410         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
27411 }
27412 run_test 398a "direct IO should cancel lock otherwise lockless"
27413
27414 test_398b() { # LU-4198
27415         local before=$(date +%s)
27416         local njobs=4
27417         local size=48
27418
27419         which fio || skip_env "no fio installed"
27420         $LFS setstripe -c -1 -S 1M $DIR/$tfile
27421         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
27422
27423         # Single page, multiple pages, stripe size, 4*stripe size
27424         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
27425                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
27426                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
27427                         --numjobs=$njobs --fallocate=none \
27428                         --iodepth=16 --allow_file_create=0 \
27429                         --size=$((size/njobs))M \
27430                         --filename=$DIR/$tfile &
27431                 bg_pid=$!
27432
27433                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
27434                 fio --name=rand-rw --rw=randrw --bs=$bsize \
27435                         --numjobs=$njobs --fallocate=none \
27436                         --iodepth=16 --allow_file_create=0 \
27437                         --size=$((size/njobs))M \
27438                         --filename=$DIR/$tfile || true
27439                 wait $bg_pid
27440         done
27441
27442         evict=$(do_facet client $LCTL get_param \
27443                 osc.$FSNAME-OST*-osc-*/state |
27444             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
27445
27446         [ -z "$evict" ] || [[ $evict -le $before ]] ||
27447                 (do_facet client $LCTL get_param \
27448                         osc.$FSNAME-OST*-osc-*/state;
27449                     error "eviction happened: $evict before:$before")
27450
27451         rm -f $DIR/$tfile
27452 }
27453 run_test 398b "DIO and buffer IO race"
27454
27455 test_398c() { # LU-4198
27456         local ost1_imp=$(get_osc_import_name client ost1)
27457         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27458                          cut -d'.' -f2)
27459
27460         which fio || skip_env "no fio installed"
27461
27462         saved_debug=$($LCTL get_param -n debug)
27463         $LCTL set_param debug=0
27464
27465         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
27466         ((size /= 1024)) # by megabytes
27467         ((size /= 2)) # write half of the OST at most
27468         [ $size -gt 40 ] && size=40 #reduce test time anyway
27469
27470         $LFS setstripe -c 1 $DIR/$tfile
27471
27472         # it seems like ldiskfs reserves more space than necessary if the
27473         # writing blocks are not mapped, so it extends the file firstly
27474         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
27475         cancel_lru_locks osc
27476
27477         # clear and verify rpc_stats later
27478         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
27479
27480         local njobs=4
27481         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
27482         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
27483                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
27484                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
27485                 --filename=$DIR/$tfile
27486         [ $? -eq 0 ] || error "fio write error"
27487
27488         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
27489                 error "Locks were requested while doing AIO"
27490
27491         # get the percentage of 1-page I/O
27492         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
27493                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
27494                 awk '{print $7}')
27495         (( $pct <= 50 )) || {
27496                 $LCTL get_param osc.${imp_name}.rpc_stats
27497                 error "$pct% of I/O are 1-page"
27498         }
27499
27500         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
27501         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
27502                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
27503                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
27504                 --filename=$DIR/$tfile
27505         [ $? -eq 0 ] || error "fio mixed read write error"
27506
27507         echo "AIO with large block size ${size}M"
27508         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
27509                 --numjobs=1 --fallocate=none --ioengine=libaio \
27510                 --iodepth=16 --allow_file_create=0 --size=${size}M \
27511                 --filename=$DIR/$tfile
27512         [ $? -eq 0 ] || error "fio large block size failed"
27513
27514         rm -f $DIR/$tfile
27515         $LCTL set_param debug="$saved_debug"
27516 }
27517 run_test 398c "run fio to test AIO"
27518
27519 test_398d() { #  LU-13846
27520         which aiocp || skip_env "no aiocp installed"
27521         local aio_file=$DIR/$tfile.aio
27522
27523         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
27524
27525         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
27526         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
27527         stack_trap "rm -f $DIR/$tfile $aio_file"
27528
27529         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
27530
27531         # test memory unaligned aio
27532         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file ||
27533                 error "unaligned aio failed"
27534         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
27535
27536         rm -f $DIR/$tfile $aio_file
27537 }
27538 run_test 398d "run aiocp to verify block size > stripe size"
27539
27540 test_398e() {
27541         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
27542         touch $DIR/$tfile.new
27543         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
27544 }
27545 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
27546
27547 test_398f() { #  LU-14687
27548         which aiocp || skip_env "no aiocp installed"
27549         local aio_file=$DIR/$tfile.aio
27550
27551         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
27552
27553         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
27554         stack_trap "rm -f $DIR/$tfile $aio_file"
27555
27556         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
27557         $LCTL set_param fail_loc=0x1418
27558         # make sure we don't crash and fail properly
27559         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
27560                 error "aio with page allocation failure succeeded"
27561         $LCTL set_param fail_loc=0
27562         diff $DIR/$tfile $aio_file
27563         [[ $? != 0 ]] || error "no diff after failed aiocp"
27564 }
27565 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
27566
27567 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
27568 # stripe and i/o size must be > stripe size
27569 # Old style synchronous DIO waits after submitting each chunk, resulting in a
27570 # single RPC in flight.  This test shows async DIO submission is working by
27571 # showing multiple RPCs in flight.
27572 test_398g() { #  LU-13798
27573         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
27574
27575         # We need to do some i/o first to acquire enough grant to put our RPCs
27576         # in flight; otherwise a new connection may not have enough grant
27577         # available
27578         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27579                 error "parallel dio failed"
27580         stack_trap "rm -f $DIR/$tfile"
27581
27582         # Reduce RPC size to 1M to avoid combination in to larger RPCs
27583         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
27584         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
27585         stack_trap "$LCTL set_param -n $pages_per_rpc"
27586
27587         # Recreate file so it's empty
27588         rm -f $DIR/$tfile
27589         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
27590         #Pause rpc completion to guarantee we see multiple rpcs in flight
27591         #define OBD_FAIL_OST_BRW_PAUSE_BULK
27592         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
27593         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
27594
27595         # Clear rpc stats
27596         $LCTL set_param osc.*.rpc_stats=c
27597
27598         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27599                 error "parallel dio failed"
27600         stack_trap "rm -f $DIR/$tfile"
27601
27602         $LCTL get_param osc.*-OST0000-*.rpc_stats
27603         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
27604                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
27605                 grep "8:" | awk '{print $8}')
27606         # We look at the "8 rpcs in flight" field, and verify A) it is present
27607         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
27608         # as expected for an 8M DIO to a file with 1M stripes.
27609         # NB: There is occasionally a mystery extra write RPC to a different
27610         # file.  I can't identify why that's happening, so we set up a margin
27611         # of 1 RPC here, ie, 8/9 RPCs at this size, or ~88%
27612         [ $pct -gt 87 ] || error "we should see 8 RPCs in flight"
27613
27614         # Verify turning off parallel dio works as expected
27615         # Clear rpc stats
27616         $LCTL set_param osc.*.rpc_stats=c
27617         $LCTL set_param llite.*.parallel_dio=0
27618         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
27619
27620         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27621                 error "dio with parallel dio disabled failed"
27622
27623         # Ideally, we would see only one RPC in flight here, but there is an
27624         # unavoidable race between i/o completion and RPC in flight counting,
27625         # so while only 1 i/o is in flight at a time, the RPC in flight counter
27626         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
27627         # So instead we just verify it's always < 8.
27628         $LCTL get_param osc.*-OST0000-*.rpc_stats
27629         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
27630                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
27631                 grep '^$' -B1 | grep . | awk '{print $1}')
27632         [ $ret != "8:" ] ||
27633                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
27634 }
27635 run_test 398g "verify parallel dio async RPC submission"
27636
27637 test_398h() { #  LU-13798
27638         local dio_file=$DIR/$tfile.dio
27639
27640         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
27641
27642         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27643         stack_trap "rm -f $DIR/$tfile $dio_file"
27644
27645         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
27646                 error "parallel dio failed"
27647         diff $DIR/$tfile $dio_file
27648         [[ $? == 0 ]] || error "file diff after aiocp"
27649 }
27650 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
27651
27652 test_398i() { #  LU-13798
27653         local dio_file=$DIR/$tfile.dio
27654
27655         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
27656
27657         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27658         stack_trap "rm -f $DIR/$tfile $dio_file"
27659
27660         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
27661         $LCTL set_param fail_loc=0x1418
27662         # make sure we don't crash and fail properly
27663         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
27664                 error "parallel dio page allocation failure succeeded"
27665         diff $DIR/$tfile $dio_file
27666         [[ $? != 0 ]] || error "no diff after failed aiocp"
27667 }
27668 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
27669
27670 test_398j() { #  LU-13798
27671         # Stripe size > RPC size but less than i/o size tests split across
27672         # stripes and RPCs for individual i/o op
27673         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
27674
27675         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
27676         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
27677         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
27678         stack_trap "$LCTL set_param -n $pages_per_rpc"
27679
27680         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27681                 error "parallel dio write failed"
27682         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
27683
27684         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
27685                 error "parallel dio read failed"
27686         diff $DIR/$tfile $DIR/$tfile.2
27687         [[ $? == 0 ]] || error "file diff after parallel dio read"
27688 }
27689 run_test 398j "test parallel dio where stripe size > rpc_size"
27690
27691 test_398k() { #  LU-13798
27692         wait_delete_completed
27693         wait_mds_ost_sync
27694
27695         # 4 stripe file; we will cause out of space on OST0
27696         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
27697
27698         # Fill OST0 (if it's not too large)
27699         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
27700                    head -n1)
27701         if [[ $ORIGFREE -gt $MAXFREE ]]; then
27702                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
27703         fi
27704         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
27705         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
27706                 error "dd should fill OST0"
27707         stack_trap "rm -f $DIR/$tfile.1"
27708
27709         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27710         err=$?
27711
27712         ls -la $DIR/$tfile
27713         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
27714                 error "file is not 0 bytes in size"
27715
27716         # dd above should not succeed, but don't error until here so we can
27717         # get debug info above
27718         [[ $err != 0 ]] ||
27719                 error "parallel dio write with enospc succeeded"
27720         stack_trap "rm -f $DIR/$tfile"
27721 }
27722 run_test 398k "test enospc on first stripe"
27723
27724 test_398l() { #  LU-13798
27725         wait_delete_completed
27726         wait_mds_ost_sync
27727
27728         # 4 stripe file; we will cause out of space on OST0
27729         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
27730         # happens on the second i/o chunk we issue
27731         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
27732
27733         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
27734         stack_trap "rm -f $DIR/$tfile"
27735
27736         # Fill OST0 (if it's not too large)
27737         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
27738                    head -n1)
27739         if [[ $ORIGFREE -gt $MAXFREE ]]; then
27740                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
27741         fi
27742         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
27743         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
27744                 error "dd should fill OST0"
27745         stack_trap "rm -f $DIR/$tfile.1"
27746
27747         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
27748         err=$?
27749         stack_trap "rm -f $DIR/$tfile.2"
27750
27751         # Check that short write completed as expected
27752         ls -la $DIR/$tfile.2
27753         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
27754                 error "file is not 1M in size"
27755
27756         # dd above should not succeed, but don't error until here so we can
27757         # get debug info above
27758         [[ $err != 0 ]] ||
27759                 error "parallel dio write with enospc succeeded"
27760
27761         # Truncate source file to same length as output file and diff them
27762         $TRUNCATE $DIR/$tfile 1048576
27763         diff $DIR/$tfile $DIR/$tfile.2
27764         [[ $? == 0 ]] || error "data incorrect after short write"
27765 }
27766 run_test 398l "test enospc on intermediate stripe/RPC"
27767
27768 test_398m() { #  LU-13798
27769         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
27770
27771         # Set up failure on OST0, the first stripe:
27772         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
27773         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
27774         # OST0 is on ost1, OST1 is on ost2.
27775         # So this fail_val specifies OST0
27776         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
27777         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
27778
27779         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
27780                 error "parallel dio write with failure on first stripe succeeded"
27781         stack_trap "rm -f $DIR/$tfile"
27782         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
27783
27784         # Place data in file for read
27785         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27786                 error "parallel dio write failed"
27787
27788         # Fail read on OST0, first stripe
27789         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
27790         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
27791         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
27792                 error "parallel dio read with error on first stripe succeeded"
27793         rm -f $DIR/$tfile.2
27794         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
27795
27796         # Switch to testing on OST1, second stripe
27797         # Clear file contents, maintain striping
27798         echo > $DIR/$tfile
27799         # Set up failure on OST1, second stripe:
27800         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
27801         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
27802
27803         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
27804                 error "parallel dio write with failure on second stripe succeeded"
27805         stack_trap "rm -f $DIR/$tfile"
27806         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
27807
27808         # Place data in file for read
27809         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27810                 error "parallel dio write failed"
27811
27812         # Fail read on OST1, second stripe
27813         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
27814         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
27815         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
27816                 error "parallel dio read with error on second stripe succeeded"
27817         rm -f $DIR/$tfile.2
27818         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
27819 }
27820 run_test 398m "test RPC failures with parallel dio"
27821
27822 # Parallel submission of DIO should not cause problems for append, but it's
27823 # important to verify.
27824 test_398n() { #  LU-13798
27825         $LFS setstripe -C 2 -S 1M $DIR/$tfile
27826
27827         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
27828                 error "dd to create source file failed"
27829         stack_trap "rm -f $DIR/$tfile"
27830
27831         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
27832                 error "parallel dio write with failure on second stripe succeeded"
27833         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
27834         diff $DIR/$tfile $DIR/$tfile.1
27835         [[ $? == 0 ]] || error "data incorrect after append"
27836
27837 }
27838 run_test 398n "test append with parallel DIO"
27839
27840 test_398o() {
27841         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
27842 }
27843 run_test 398o "right kms with DIO"
27844
27845 test_398p()
27846 {
27847         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
27848         which aiocp || skip_env "no aiocp installed"
27849
27850         local stripe_size=$((1024 * 1024)) #1 MiB
27851         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
27852         local file_size=$((25 * stripe_size))
27853
27854         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
27855         stack_trap "rm -f $DIR/$tfile*"
27856         # Just a bit bigger than the largest size in the test set below
27857         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
27858                 error "buffered i/o to create file failed"
27859
27860         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
27861                 $((stripe_size * 4)); do
27862
27863                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
27864
27865                 echo "bs: $bs, file_size $file_size"
27866                 aiocp -a $PAGE_SIZE -b $bs -s $file_size -f O_DIRECT \
27867                         $DIR/$tfile.1 $DIR/$tfile.2 &
27868                 pid_dio1=$!
27869                 # Buffered I/O with similar but not the same block size
27870                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
27871                         conv=notrunc &
27872                 pid_bio2=$!
27873                 wait $pid_dio1
27874                 rc1=$?
27875                 wait $pid_bio2
27876                 rc2=$?
27877                 if (( rc1 != 0 )); then
27878                         error "aio copy 1 w/bsize $bs failed: $rc1"
27879                 fi
27880                 if (( rc2 != 0 )); then
27881                         error "buffered copy 2 w/bsize $bs failed: $rc2"
27882                 fi
27883
27884                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
27885                         error "size incorrect"
27886                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
27887                         error "files differ, bsize $bs"
27888                 rm -f $DIR/$tfile.2
27889         done
27890 }
27891 run_test 398p "race aio with buffered i/o"
27892
27893 test_398q()
27894 {
27895         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
27896
27897         local stripe_size=$((1024 * 1024)) #1 MiB
27898         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
27899         local file_size=$((25 * stripe_size))
27900
27901         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
27902         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
27903
27904         # Just a bit bigger than the largest size in the test set below
27905         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
27906                 error "buffered i/o to create file failed"
27907
27908         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
27909                 $((stripe_size * 4)); do
27910
27911                 echo "bs: $bs, file_size $file_size"
27912                 dd if=$DIR/$tfile.1 bs=$((bs *2 )) of=$DIR/$tfile.2 \
27913                         conv=notrunc oflag=direct iflag=direct &
27914                 pid_dio1=$!
27915                 # Buffered I/O with similar but not the same block size
27916                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
27917                         conv=notrunc &
27918                 pid_bio2=$!
27919                 wait $pid_dio1
27920                 rc1=$?
27921                 wait $pid_bio2
27922                 rc2=$?
27923                 if (( rc1 != 0 )); then
27924                         error "dio copy 1 w/bsize $bs failed: $rc1"
27925                 fi
27926                 if (( rc2 != 0 )); then
27927                         error "buffered copy 2 w/bsize $bs failed: $rc2"
27928                 fi
27929
27930                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
27931                         error "size incorrect"
27932                 diff $DIR/$tfile.1 $DIR/$tfile.2 ||
27933                         error "files differ, bsize $bs"
27934         done
27935
27936         rm -f $DIR/$tfile*
27937 }
27938 run_test 398q "race dio with buffered i/o"
27939
27940 test_fake_rw() {
27941         local read_write=$1
27942         if [ "$read_write" = "write" ]; then
27943                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
27944         elif [ "$read_write" = "read" ]; then
27945                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
27946         else
27947                 error "argument error"
27948         fi
27949
27950         # turn off debug for performance testing
27951         local saved_debug=$($LCTL get_param -n debug)
27952         $LCTL set_param debug=0
27953
27954         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27955
27956         # get ost1 size - $FSNAME-OST0000
27957         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
27958         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
27959         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
27960
27961         if [ "$read_write" = "read" ]; then
27962                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
27963         fi
27964
27965         local start_time=$(date +%s.%N)
27966         $dd_cmd bs=1M count=$blocks oflag=sync ||
27967                 error "real dd $read_write error"
27968         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
27969
27970         if [ "$read_write" = "write" ]; then
27971                 rm -f $DIR/$tfile
27972         fi
27973
27974         # define OBD_FAIL_OST_FAKE_RW           0x238
27975         do_facet ost1 $LCTL set_param fail_loc=0x238
27976
27977         local start_time=$(date +%s.%N)
27978         $dd_cmd bs=1M count=$blocks oflag=sync ||
27979                 error "fake dd $read_write error"
27980         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
27981
27982         if [ "$read_write" = "write" ]; then
27983                 # verify file size
27984                 cancel_lru_locks osc
27985                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
27986                         error "$tfile size not $blocks MB"
27987         fi
27988         do_facet ost1 $LCTL set_param fail_loc=0
27989
27990         echo "fake $read_write $duration_fake vs. normal $read_write" \
27991                 "$duration in seconds"
27992         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
27993                 error_not_in_vm "fake write is slower"
27994
27995         $LCTL set_param -n debug="$saved_debug"
27996         rm -f $DIR/$tfile
27997 }
27998 test_399a() { # LU-7655 for OST fake write
27999         remote_ost_nodsh && skip "remote OST with nodsh"
28000
28001         test_fake_rw write
28002 }
28003 run_test 399a "fake write should not be slower than normal write"
28004
28005 test_399b() { # LU-8726 for OST fake read
28006         remote_ost_nodsh && skip "remote OST with nodsh"
28007         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
28008                 skip_env "ldiskfs only test"
28009         fi
28010
28011         test_fake_rw read
28012 }
28013 run_test 399b "fake read should not be slower than normal read"
28014
28015 test_400a() { # LU-1606, was conf-sanity test_74
28016         if ! which $CC > /dev/null 2>&1; then
28017                 skip_env "$CC is not installed"
28018         fi
28019
28020         local extra_flags=''
28021         local out=$TMP/$tfile
28022         local prefix=/usr/include/lustre
28023         local prog
28024
28025         # Oleg removes .c files in his test rig so test if any c files exist
28026         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
28027                 skip_env "Needed .c test files are missing"
28028
28029         if ! [[ -d $prefix ]]; then
28030                 # Assume we're running in tree and fixup the include path.
28031                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
28032                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
28033                 extra_flags+=" -L$LUSTRE/utils/.libs"
28034         fi
28035
28036         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
28037                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
28038                         error "client api broken"
28039         done
28040         rm -f $out
28041 }
28042 run_test 400a "Lustre client api program can compile and link"
28043
28044 test_400b() { # LU-1606, LU-5011
28045         local header
28046         local out=$TMP/$tfile
28047         local prefix=/usr/include/linux/lustre
28048
28049         # We use a hard coded prefix so that this test will not fail
28050         # when run in tree. There are headers in lustre/include/lustre/
28051         # that are not packaged (like lustre_idl.h) and have more
28052         # complicated include dependencies (like config.h and lnet/types.h).
28053         # Since this test about correct packaging we just skip them when
28054         # they don't exist (see below) rather than try to fixup cppflags.
28055
28056         if ! which $CC > /dev/null 2>&1; then
28057                 skip_env "$CC is not installed"
28058         fi
28059
28060         for header in $prefix/*.h; do
28061                 if ! [[ -f "$header" ]]; then
28062                         continue
28063                 fi
28064
28065                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
28066                         continue # lustre_ioctl.h is internal header
28067                 fi
28068
28069                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
28070                         error "cannot compile '$header'"
28071         done
28072         rm -f $out
28073 }
28074 run_test 400b "packaged headers can be compiled"
28075
28076 test_401a() { #LU-7437
28077         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
28078         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
28079
28080         #count the number of parameters by "list_param -R"
28081         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
28082         #count the number of parameters by listing proc files
28083         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
28084         echo "proc_dirs='$proc_dirs'"
28085         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
28086         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
28087                       sort -u | wc -l)
28088
28089         [ $params -eq $procs ] ||
28090                 error "found $params parameters vs. $procs proc files"
28091
28092         # test the list_param -D option only returns directories
28093         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
28094         #count the number of parameters by listing proc directories
28095         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
28096                 sort -u | wc -l)
28097
28098         [ $params -eq $procs ] ||
28099                 error "found $params parameters vs. $procs proc files"
28100 }
28101 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
28102
28103 test_401b() {
28104         # jobid_var may not allow arbitrary values, so use jobid_name
28105         # if available
28106         if $LCTL list_param jobid_name > /dev/null 2>&1; then
28107                 local testname=jobid_name tmp='testing%p'
28108         else
28109                 local testname=jobid_var tmp=testing
28110         fi
28111
28112         local save=$($LCTL get_param -n $testname)
28113
28114         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
28115                 error "no error returned when setting bad parameters"
28116
28117         local jobid_new=$($LCTL get_param -n foe $testname baz)
28118         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
28119
28120         $LCTL set_param -n fog=bam $testname=$save bat=fog
28121         local jobid_old=$($LCTL get_param -n foe $testname bag)
28122         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
28123 }
28124 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
28125
28126 test_401c() {
28127         # jobid_var may not allow arbitrary values, so use jobid_name
28128         # if available
28129         if $LCTL list_param jobid_name > /dev/null 2>&1; then
28130                 local testname=jobid_name
28131         else
28132                 local testname=jobid_var
28133         fi
28134
28135         local jobid_var_old=$($LCTL get_param -n $testname)
28136         local jobid_var_new
28137
28138         $LCTL set_param $testname= &&
28139                 error "no error returned for 'set_param a='"
28140
28141         jobid_var_new=$($LCTL get_param -n $testname)
28142         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
28143                 error "$testname was changed by setting without value"
28144
28145         $LCTL set_param $testname &&
28146                 error "no error returned for 'set_param a'"
28147
28148         jobid_var_new=$($LCTL get_param -n $testname)
28149         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
28150                 error "$testname was changed by setting without value"
28151 }
28152 run_test 401c "Verify 'lctl set_param' without value fails in either format."
28153
28154 test_401d() {
28155         # jobid_var may not allow arbitrary values, so use jobid_name
28156         # if available
28157         if $LCTL list_param jobid_name > /dev/null 2>&1; then
28158                 local testname=jobid_name new_value='foo=bar%p'
28159         else
28160                 local testname=jobid_var new_valuie=foo=bar
28161         fi
28162
28163         local jobid_var_old=$($LCTL get_param -n $testname)
28164         local jobid_var_new
28165
28166         $LCTL set_param $testname=$new_value ||
28167                 error "'set_param a=b' did not accept a value containing '='"
28168
28169         jobid_var_new=$($LCTL get_param -n $testname)
28170         [[ "$jobid_var_new" == "$new_value" ]] ||
28171                 error "'set_param a=b' failed on a value containing '='"
28172
28173         # Reset the $testname to test the other format
28174         $LCTL set_param $testname=$jobid_var_old
28175         jobid_var_new=$($LCTL get_param -n $testname)
28176         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
28177                 error "failed to reset $testname"
28178
28179         $LCTL set_param $testname $new_value ||
28180                 error "'set_param a b' did not accept a value containing '='"
28181
28182         jobid_var_new=$($LCTL get_param -n $testname)
28183         [[ "$jobid_var_new" == "$new_value" ]] ||
28184                 error "'set_param a b' failed on a value containing '='"
28185
28186         $LCTL set_param $testname $jobid_var_old
28187         jobid_var_new=$($LCTL get_param -n $testname)
28188         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
28189                 error "failed to reset $testname"
28190 }
28191 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
28192
28193 test_401e() { # LU-14779
28194         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
28195                 error "lctl list_param MGC* failed"
28196         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
28197         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
28198                 error "lctl get_param lru_size failed"
28199 }
28200 run_test 401e "verify 'lctl get_param' works with NID in parameter"
28201
28202 test_402() {
28203         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
28204         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
28205                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
28206         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
28207                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
28208                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
28209         remote_mds_nodsh && skip "remote MDS with nodsh"
28210
28211         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
28212 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
28213         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
28214         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
28215                 echo "Touch failed - OK"
28216 }
28217 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
28218
28219 test_403() {
28220         local file1=$DIR/$tfile.1
28221         local file2=$DIR/$tfile.2
28222         local tfile=$TMP/$tfile
28223
28224         rm -f $file1 $file2 $tfile
28225
28226         touch $file1
28227         ln $file1 $file2
28228
28229         # 30 sec OBD_TIMEOUT in ll_getattr()
28230         # right before populating st_nlink
28231         $LCTL set_param fail_loc=0x80001409
28232         stat -c %h $file1 > $tfile &
28233
28234         # create an alias, drop all locks and reclaim the dentry
28235         < $file2
28236         cancel_lru_locks mdc
28237         cancel_lru_locks osc
28238         sysctl -w vm.drop_caches=2
28239
28240         wait
28241
28242         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
28243
28244         rm -f $tfile $file1 $file2
28245 }
28246 run_test 403 "i_nlink should not drop to zero due to aliasing"
28247
28248 test_404() { # LU-6601
28249         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
28250                 skip "Need server version newer than 2.8.52"
28251         remote_mds_nodsh && skip "remote MDS with nodsh"
28252
28253         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
28254                 awk '/osp .*-osc-MDT/ { print $4}')
28255
28256         local osp
28257         for osp in $mosps; do
28258                 echo "Deactivate: " $osp
28259                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
28260                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
28261                         awk -vp=$osp '$4 == p { print $2 }')
28262                 [ $stat = IN ] || {
28263                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
28264                         error "deactivate error"
28265                 }
28266                 echo "Activate: " $osp
28267                 do_facet $SINGLEMDS $LCTL --device %$osp activate
28268                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
28269                         awk -vp=$osp '$4 == p { print $2 }')
28270                 [ $stat = UP ] || {
28271                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
28272                         error "activate error"
28273                 }
28274         done
28275 }
28276 run_test 404 "validate manual {de}activated works properly for OSPs"
28277
28278 test_405() {
28279         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
28280         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
28281                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
28282                         skip "Layout swap lock is not supported"
28283
28284         check_swap_layouts_support
28285         check_swap_layout_no_dom $DIR
28286
28287         test_mkdir $DIR/$tdir
28288         swap_lock_test -d $DIR/$tdir ||
28289                 error "One layout swap locked test failed"
28290 }
28291 run_test 405 "Various layout swap lock tests"
28292
28293 test_406() {
28294         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
28295         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
28296         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
28297         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28298         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
28299                 skip "Need MDS version at least 2.8.50"
28300
28301         local def_stripe_size=$($LFS getstripe -S $MOUNT)
28302         local test_pool=$TESTNAME
28303
28304         pool_add $test_pool || error "pool_add failed"
28305         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
28306                 error "pool_add_targets failed"
28307
28308         save_layout_restore_at_exit $MOUNT
28309
28310         # parent set default stripe count only, child will stripe from both
28311         # parent and fs default
28312         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
28313                 error "setstripe $MOUNT failed"
28314         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
28315         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
28316         for i in $(seq 10); do
28317                 local f=$DIR/$tdir/$tfile.$i
28318                 touch $f || error "touch failed"
28319                 local count=$($LFS getstripe -c $f)
28320                 [ $count -eq $OSTCOUNT ] ||
28321                         error "$f stripe count $count != $OSTCOUNT"
28322                 local offset=$($LFS getstripe -i $f)
28323                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
28324                 local size=$($LFS getstripe -S $f)
28325                 [ $size -eq $((def_stripe_size * 2)) ] ||
28326                         error "$f stripe size $size != $((def_stripe_size * 2))"
28327                 local pool=$($LFS getstripe -p $f)
28328                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
28329         done
28330
28331         # change fs default striping, delete parent default striping, now child
28332         # will stripe from new fs default striping only
28333         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
28334                 error "change $MOUNT default stripe failed"
28335         $LFS setstripe -c 0 $DIR/$tdir ||
28336                 error "delete $tdir default stripe failed"
28337         for i in $(seq 11 20); do
28338                 local f=$DIR/$tdir/$tfile.$i
28339                 touch $f || error "touch $f failed"
28340                 local count=$($LFS getstripe -c $f)
28341                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
28342                 local offset=$($LFS getstripe -i $f)
28343                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
28344                 local size=$($LFS getstripe -S $f)
28345                 [ $size -eq $def_stripe_size ] ||
28346                         error "$f stripe size $size != $def_stripe_size"
28347                 local pool=$($LFS getstripe -p $f)
28348                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
28349         done
28350
28351         unlinkmany $DIR/$tdir/$tfile. 1 20
28352
28353         local f=$DIR/$tdir/$tfile
28354         pool_remove_all_targets $test_pool $f
28355         pool_remove $test_pool $f
28356 }
28357 run_test 406 "DNE support fs default striping"
28358
28359 test_407() {
28360         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
28361         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
28362                 skip "Need MDS version at least 2.8.55"
28363         remote_mds_nodsh && skip "remote MDS with nodsh"
28364
28365         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
28366                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
28367         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
28368                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
28369         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
28370
28371         #define OBD_FAIL_DT_TXN_STOP    0x2019
28372         for idx in $(seq $MDSCOUNT); do
28373                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
28374         done
28375         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
28376         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
28377                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
28378         true
28379 }
28380 run_test 407 "transaction fail should cause operation fail"
28381
28382 test_408() {
28383         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
28384
28385         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
28386         lctl set_param fail_loc=0x8000040a
28387         # let ll_prepare_partial_page() fail
28388         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
28389
28390         rm -f $DIR/$tfile
28391
28392         # create at least 100 unused inodes so that
28393         # shrink_icache_memory(0) should not return 0
28394         touch $DIR/$tfile-{0..100}
28395         rm -f $DIR/$tfile-{0..100}
28396         sync
28397
28398         echo 2 > /proc/sys/vm/drop_caches
28399 }
28400 run_test 408 "drop_caches should not hang due to page leaks"
28401
28402 test_409()
28403 {
28404         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28405
28406         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
28407         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
28408         touch $DIR/$tdir/guard || error "(2) Fail to create"
28409
28410         local PREFIX=$(str_repeat 'A' 128)
28411         echo "Create 1K hard links start at $(date)"
28412         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
28413                 error "(3) Fail to hard link"
28414
28415         echo "Links count should be right although linkEA overflow"
28416         stat $DIR/$tdir/guard || error "(4) Fail to stat"
28417         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
28418         [ $linkcount -eq 1001 ] ||
28419                 error "(5) Unexpected hard links count: $linkcount"
28420
28421         echo "List all links start at $(date)"
28422         ls -l $DIR/$tdir/foo > /dev/null ||
28423                 error "(6) Fail to list $DIR/$tdir/foo"
28424
28425         echo "Unlink hard links start at $(date)"
28426         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
28427                 error "(7) Fail to unlink"
28428         echo "Unlink hard links finished at $(date)"
28429 }
28430 run_test 409 "Large amount of cross-MDTs hard links on the same file"
28431
28432 test_410()
28433 {
28434         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
28435                 skip "Need client version at least 2.9.59"
28436
28437         # Create a file, and stat it from the kernel
28438         local testfile=$DIR/$tfile
28439         touch $testfile
28440
28441         local run_id=$RANDOM
28442         local my_ino=$(stat --format "%i" $testfile)
28443
28444         # Try to insert the module.
28445         load_module kunit/kinode run_id=$run_id fname=$testfile ||
28446                 error "load_module failed"
28447
28448         # Anything but success is a test failure
28449         dmesg | grep -q \
28450             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
28451             error "no inode match"
28452
28453         # Remove the test module
28454         rmmod -v kinode ||
28455                 error "rmmod failed (may trigger a failure in a later test)"
28456 }
28457 run_test 410 "Test inode number returned from kernel thread"
28458
28459 cleanup_test411_cgroup() {
28460         trap 0
28461         cat $1/memory.stat
28462         rmdir "$1"
28463 }
28464
28465 test_411a() {
28466         local cg_basedir=/sys/fs/cgroup/memory
28467         # LU-9966
28468         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
28469                 skip "no setup for cgroup"
28470
28471         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
28472                 error "test file creation failed"
28473         cancel_lru_locks osc
28474
28475         # Create a very small memory cgroup to force a slab allocation error
28476         local cgdir=$cg_basedir/osc_slab_alloc
28477         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
28478         trap "cleanup_test411_cgroup $cgdir" EXIT
28479         echo 2M > $cgdir/memory.kmem.limit_in_bytes
28480         echo 1M > $cgdir/memory.limit_in_bytes
28481
28482         # Should not LBUG, just be killed by oom-killer
28483         # dd will return 0 even allocation failure in some environment.
28484         # So don't check return value
28485         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
28486         cleanup_test411_cgroup $cgdir
28487
28488         return 0
28489 }
28490 run_test 411a "Slab allocation error with cgroup does not LBUG"
28491
28492 test_411b() {
28493         local cg_basedir=/sys/fs/cgroup/memory
28494         # LU-9966
28495         [ -e "$cg_basedir/memory.kmem.limit_in_bytes" ] ||
28496                 skip "no setup for cgroup"
28497         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
28498         # (x86) testing suggests we can't reliably avoid OOM with a 64M-256M
28499         # limit, so we have 384M in cgroup
28500         # (arm) this seems to hit OOM more often than x86, so 1024M
28501         if [[ $(uname -m) = aarch64 ]]; then
28502                 local memlimit_mb=1024
28503         else
28504                 local memlimit_mb=384
28505         fi
28506
28507         # Create a cgroup and set memory limit
28508         # (tfile is used as an easy way to get a recognizable cgroup name)
28509         local cgdir=$cg_basedir/$tfile
28510         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
28511         stack_trap "cleanup_test411_cgroup $cgdir" EXIT
28512         echo $((memlimit_mb * 1024 * 1024)) > $cgdir/memory.limit_in_bytes
28513
28514         echo "writing first file"
28515         # Write a file 4x the memory limit in size
28516         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=1M count=$((memlimit_mb * 4))" ||
28517                 error "(1) failed to write successfully"
28518
28519         sync
28520         cancel_lru_locks osc
28521
28522         rm -f $DIR/$tfile
28523         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
28524
28525         # Try writing at a larger block size
28526         # NB: if block size is >= 1/2 cgroup size, we sometimes get OOM killed
28527         # so test with 1/4 cgroup size (this seems reasonable to me - we do
28528         # need *some* memory to do IO in)
28529         echo "writing at larger block size"
28530         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=64M count=$((memlimit_mb * 4 / 128))" ||
28531                 error "(3) failed to write successfully"
28532
28533         sync
28534         cancel_lru_locks osc
28535         rm -f $DIR/$tfile
28536         $LFS setstripe -c 2 $DIR/$tfile.{1..4} || error "unable to setstripe"
28537
28538         # Try writing multiple files at once
28539         echo "writing multiple files"
28540         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.1 bs=32M count=$((memlimit_mb * 4 / 64))" &
28541         local pid1=$!
28542         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.2 bs=32M count=$((memlimit_mb * 4 / 64))" &
28543         local pid2=$!
28544         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.3 bs=32M count=$((memlimit_mb * 4 / 64))" &
28545         local pid3=$!
28546         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.4 bs=32M count=$((memlimit_mb * 4 / 64))" &
28547         local pid4=$!
28548
28549         wait $pid1
28550         local rc1=$?
28551         wait $pid2
28552         local rc2=$?
28553         wait $pid3
28554         local rc3=$?
28555         wait $pid4
28556         local rc4=$?
28557         if (( rc1 != 0)); then
28558                 error "error $rc1 writing to file from $pid1"
28559         fi
28560         if (( rc2 != 0)); then
28561                 error "error $rc2 writing to file from $pid2"
28562         fi
28563         if (( rc3 != 0)); then
28564                 error "error $rc3 writing to file from $pid3"
28565         fi
28566         if (( rc4 != 0)); then
28567                 error "error $rc4 writing to file from $pid4"
28568         fi
28569
28570         sync
28571         cancel_lru_locks osc
28572
28573         # These files can be large-ish (~1 GiB total), so delete them rather
28574         # than leave for later cleanup
28575         rm -f $DIR/$tfile.*
28576         return 0
28577 }
28578 run_test 411b "confirm Lustre can avoid OOM with reasonable cgroups limits"
28579
28580 test_412() {
28581         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
28582         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
28583                 skip "Need server version at least 2.10.55"
28584
28585         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
28586                 error "mkdir failed"
28587         $LFS getdirstripe $DIR/$tdir
28588         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
28589         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
28590                 error "expect $((MDSCOUT - 1)) get $stripe_index"
28591         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
28592         [ $stripe_count -eq 2 ] ||
28593                 error "expect 2 get $stripe_count"
28594
28595         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
28596
28597         local index
28598         local index2
28599
28600         # subdirs should be on the same MDT as parent
28601         for i in $(seq 0 $((MDSCOUNT - 1))); do
28602                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
28603                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
28604                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
28605                 (( index == i )) || error "mdt$i/sub on MDT$index"
28606         done
28607
28608         # stripe offset -1, ditto
28609         for i in {1..10}; do
28610                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
28611                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
28612                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
28613                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
28614                 (( index == index2 )) ||
28615                         error "qos$i on MDT$index, sub on MDT$index2"
28616         done
28617
28618         local testdir=$DIR/$tdir/inherit
28619
28620         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
28621         # inherit 2 levels
28622         for i in 1 2; do
28623                 testdir=$testdir/s$i
28624                 mkdir $testdir || error "mkdir $testdir failed"
28625                 index=$($LFS getstripe -m $testdir)
28626                 (( index == 1 )) ||
28627                         error "$testdir on MDT$index"
28628         done
28629
28630         # not inherit any more
28631         testdir=$testdir/s3
28632         mkdir $testdir || error "mkdir $testdir failed"
28633         getfattr -d -m dmv $testdir | grep dmv &&
28634                 error "default LMV set on $testdir" || true
28635 }
28636 run_test 412 "mkdir on specific MDTs"
28637
28638 TEST413_COUNT=${TEST413_COUNT:-200}
28639
28640 #
28641 # set_maxage() is used by test_413 only.
28642 # This is a helper function to set maxage. Does not return any value.
28643 # Input: maxage to set
28644 #
28645 set_maxage() {
28646         local lmv_qos_maxage
28647         local lod_qos_maxage
28648         local new_maxage=$1
28649
28650         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
28651         $LCTL set_param lmv.*.qos_maxage=$new_maxage
28652         stack_trap "$LCTL set_param \
28653                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
28654         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
28655                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
28656         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28657                 lod.*.mdt_qos_maxage=$new_maxage
28658         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28659                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
28660 }
28661
28662 generate_uneven_mdts() {
28663         local threshold=$1
28664         local ffree
28665         local bavail
28666         local max
28667         local min
28668         local max_index
28669         local min_index
28670         local tmp
28671         local i
28672
28673         echo
28674         echo "Check for uneven MDTs: "
28675
28676         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28677         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28678         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28679
28680         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28681         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28682         max_index=0
28683         min_index=0
28684         for ((i = 1; i < ${#ffree[@]}; i++)); do
28685                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28686                 if [ $tmp -gt $max ]; then
28687                         max=$tmp
28688                         max_index=$i
28689                 fi
28690                 if [ $tmp -lt $min ]; then
28691                         min=$tmp
28692                         min_index=$i
28693                 fi
28694         done
28695
28696         (( min > 0 )) || skip "low space on MDT$min_index"
28697         (( ${ffree[min_index]} > 0 )) ||
28698                 skip "no free files on MDT$min_index"
28699         (( ${ffree[min_index]} < 10000000 )) ||
28700                 skip "too many free files on MDT$min_index"
28701
28702         # Check if we need to generate uneven MDTs
28703         local diff=$(((max - min) * 100 / min))
28704         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
28705         local testdir # individual folder within $testdirp
28706         local start
28707         local cmd
28708
28709         # fallocate is faster to consume space on MDT, if available
28710         if check_fallocate_supported mds$((min_index + 1)); then
28711                 cmd="fallocate -l 128K "
28712         else
28713                 cmd="dd if=/dev/zero bs=128K count=1 of="
28714         fi
28715
28716         echo "using cmd $cmd"
28717         for (( i = 0; diff < threshold; i++ )); do
28718                 testdir=${testdirp}/$i
28719                 [ -d $testdir ] && continue
28720
28721                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
28722
28723                 mkdir -p $testdirp
28724                 # generate uneven MDTs, create till $threshold% diff
28725                 echo -n "weight diff=$diff% must be > $threshold% ..."
28726                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
28727                 $LFS mkdir -i $min_index $testdir ||
28728                         error "mkdir $testdir failed"
28729                 $LFS setstripe -E 1M -L mdt $testdir ||
28730                         error "setstripe $testdir failed"
28731                 start=$SECONDS
28732                 for (( f = 0; f < TEST413_COUNT; f++ )); do
28733                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
28734                 done
28735                 sync; sleep 1; sync
28736
28737                 # wait for QOS to update
28738                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
28739
28740                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
28741                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
28742                 max=$(((${ffree[max_index]} >> 8) *
28743                         (${bavail[max_index]} * bsize >> 16)))
28744                 min=$(((${ffree[min_index]} >> 8) *
28745                         (${bavail[min_index]} * bsize >> 16)))
28746                 (( min > 0 )) || skip "low space on MDT$min_index"
28747                 diff=$(((max - min) * 100 / min))
28748         done
28749
28750         echo "MDT filesfree available: ${ffree[*]}"
28751         echo "MDT blocks available: ${bavail[*]}"
28752         echo "weight diff=$diff%"
28753 }
28754
28755 test_qos_mkdir() {
28756         local mkdir_cmd=$1
28757         local stripe_count=$2
28758         local mdts=$(comma_list $(mdts_nodes))
28759
28760         local testdir
28761         local lmv_qos_prio_free
28762         local lmv_qos_threshold_rr
28763         local lod_qos_prio_free
28764         local lod_qos_threshold_rr
28765         local total
28766         local count
28767         local i
28768
28769         # @total is total directories created if it's testing plain
28770         # directories, otherwise it's total stripe object count for
28771         # striped directories test.
28772         # remote/striped directory unlinking is slow on zfs and may
28773         # timeout, test with fewer directories
28774         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
28775
28776         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
28777         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
28778         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
28779                 head -n1)
28780         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
28781         stack_trap "$LCTL set_param \
28782                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
28783         stack_trap "$LCTL set_param \
28784                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
28785
28786         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
28787                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
28788         lod_qos_prio_free=${lod_qos_prio_free%%%}
28789         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
28790                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
28791         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
28792         stack_trap "do_nodes $mdts $LCTL set_param \
28793                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
28794         stack_trap "do_nodes $mdts $LCTL set_param \
28795                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
28796
28797         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
28798         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
28799
28800         testdir=$DIR/$tdir-s$stripe_count/rr
28801
28802         local stripe_index=$($LFS getstripe -m $testdir)
28803         local test_mkdir_rr=true
28804
28805         getfattr -d -m dmv -e hex $testdir | grep dmv
28806         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
28807                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
28808                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
28809                         test_mkdir_rr=false
28810         fi
28811
28812         echo
28813         $test_mkdir_rr &&
28814                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
28815                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
28816
28817         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
28818         for (( i = 0; i < total / stripe_count; i++ )); do
28819                 eval $mkdir_cmd $testdir/subdir$i ||
28820                         error "$mkdir_cmd subdir$i failed"
28821         done
28822
28823         for (( i = 0; i < $MDSCOUNT; i++ )); do
28824                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
28825                 echo "$count directories created on MDT$i"
28826                 if $test_mkdir_rr; then
28827                         (( count == total / stripe_count / MDSCOUNT )) ||
28828                                 error "subdirs are not evenly distributed"
28829                 elif (( i == stripe_index )); then
28830                         (( count == total / stripe_count )) ||
28831                                 error "$count subdirs created on MDT$i"
28832                 else
28833                         (( count == 0 )) ||
28834                                 error "$count subdirs created on MDT$i"
28835                 fi
28836
28837                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
28838                         count=$($LFS getdirstripe $testdir/* |
28839                                 grep -c -P "^\s+$i\t")
28840                         echo "$count stripes created on MDT$i"
28841                         # deviation should < 5% of average
28842                         delta=$((count - total / MDSCOUNT))
28843                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
28844                                 error "stripes are not evenly distributed"
28845                 fi
28846         done
28847
28848         echo
28849         echo "Check for uneven MDTs: "
28850
28851         local ffree
28852         local bavail
28853         local max
28854         local min
28855         local max_index
28856         local min_index
28857         local tmp
28858
28859         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28860         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28861         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28862
28863         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28864         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28865         max_index=0
28866         min_index=0
28867         for ((i = 1; i < ${#ffree[@]}; i++)); do
28868                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28869                 if [ $tmp -gt $max ]; then
28870                         max=$tmp
28871                         max_index=$i
28872                 fi
28873                 if [ $tmp -lt $min ]; then
28874                         min=$tmp
28875                         min_index=$i
28876                 fi
28877         done
28878         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
28879
28880         (( min > 0 )) || skip "low space on MDT$min_index"
28881         (( ${ffree[min_index]} < 10000000 )) ||
28882                 skip "too many free files on MDT$min_index"
28883
28884         generate_uneven_mdts 120
28885
28886         echo "MDT filesfree available: ${ffree[*]}"
28887         echo "MDT blocks available: ${bavail[*]}"
28888         echo "weight diff=$(((max - min) * 100 / min))%"
28889         echo
28890         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
28891
28892         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
28893         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
28894         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
28895         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
28896         # decrease statfs age, so that it can be updated in time
28897         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
28898         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
28899
28900         sleep 1
28901
28902         testdir=$DIR/$tdir-s$stripe_count/qos
28903
28904         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
28905         for (( i = 0; i < total / stripe_count; i++ )); do
28906                 eval $mkdir_cmd $testdir/subdir$i ||
28907                         error "$mkdir_cmd subdir$i failed"
28908         done
28909
28910         max=0
28911         for (( i = 0; i < $MDSCOUNT; i++ )); do
28912                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
28913                 (( count > max )) && max=$count
28914                 echo "$count directories created on MDT$i : curmax=$max"
28915         done
28916
28917         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
28918
28919         # D-value should > 10% of average
28920         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
28921                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
28922
28923         # ditto for stripes
28924         if (( stripe_count > 1 )); then
28925                 max=0
28926                 for (( i = 0; i < $MDSCOUNT; i++ )); do
28927                         count=$($LFS getdirstripe $testdir/* |
28928                                 grep -c -P "^\s+$i\t")
28929                         (( count > max )) && max=$count
28930                         echo "$count stripes created on MDT$i"
28931                 done
28932
28933                 min=$($LFS getdirstripe $testdir/* |
28934                         grep -c -P "^\s+$min_index\t")
28935                 (( max - min > total / MDSCOUNT / 10 )) ||
28936                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
28937         fi
28938 }
28939
28940 most_full_mdt() {
28941         local ffree
28942         local bavail
28943         local bsize
28944         local min
28945         local min_index
28946         local tmp
28947
28948         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28949         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28950         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28951
28952         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28953         min_index=0
28954         for ((i = 1; i < ${#ffree[@]}; i++)); do
28955                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28956                 (( tmp < min )) && min=$tmp && min_index=$i
28957         done
28958
28959         echo -n $min_index
28960 }
28961
28962 test_413a() {
28963         [ $MDSCOUNT -lt 2 ] &&
28964                 skip "We need at least 2 MDTs for this test"
28965
28966         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
28967                 skip "Need server version at least 2.12.52"
28968
28969         local stripe_max=$((MDSCOUNT - 1))
28970         local stripe_count
28971
28972         # let caller set maxage for latest result
28973         set_maxage 1
28974
28975         # fill MDT unevenly
28976         generate_uneven_mdts 120
28977
28978         # test 4-stripe directory at most, otherwise it's too slow
28979         # We are being very defensive. Although Autotest uses 4 MDTs.
28980         # We make sure stripe_max does not go over 4.
28981         (( stripe_max > 4 )) && stripe_max=4
28982         # unlinking striped directory is slow on zfs, and may timeout, only test
28983         # plain directory
28984         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
28985         for stripe_count in $(seq 1 $stripe_max); do
28986                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
28987                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
28988                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
28989                         error "mkdir failed"
28990                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
28991         done
28992 }
28993 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
28994
28995 test_413b() {
28996         [ $MDSCOUNT -lt 2 ] &&
28997                 skip "We need at least 2 MDTs for this test"
28998
28999         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
29000                 skip "Need server version at least 2.12.52"
29001
29002         local stripe_max=$((MDSCOUNT - 1))
29003         local testdir
29004         local stripe_count
29005
29006         # let caller set maxage for latest result
29007         set_maxage 1
29008
29009         # fill MDT unevenly
29010         generate_uneven_mdts 120
29011
29012         # test 4-stripe directory at most, otherwise it's too slow
29013         # We are being very defensive. Although Autotest uses 4 MDTs.
29014         # We make sure stripe_max does not go over 4.
29015         (( stripe_max > 4 )) && stripe_max=4
29016         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
29017         for stripe_count in $(seq 1 $stripe_max); do
29018                 testdir=$DIR/$tdir-s$stripe_count
29019                 mkdir $testdir || error "mkdir $testdir failed"
29020                 mkdir $testdir/rr || error "mkdir rr failed"
29021                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
29022                         error "mkdir qos failed"
29023                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
29024                         $testdir/rr || error "setdirstripe rr failed"
29025                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
29026                         error "setdirstripe failed"
29027                 test_qos_mkdir "mkdir" $stripe_count
29028         done
29029 }
29030 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
29031
29032 test_413c() {
29033         (( $MDSCOUNT >= 2 )) ||
29034                 skip "We need at least 2 MDTs for this test"
29035
29036         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
29037                 skip "Need server version at least 2.14.51"
29038
29039         local testdir
29040         local inherit
29041         local inherit_rr
29042         local lmv_qos_maxage
29043         local lod_qos_maxage
29044
29045         # let caller set maxage for latest result
29046         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
29047         $LCTL set_param lmv.*.qos_maxage=1
29048         stack_trap "$LCTL set_param \
29049                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
29050         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
29051                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
29052         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
29053                 lod.*.mdt_qos_maxage=1
29054         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
29055                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
29056
29057         # fill MDT unevenly
29058         generate_uneven_mdts 120
29059
29060         testdir=$DIR/${tdir}-s1
29061         mkdir $testdir || error "mkdir $testdir failed"
29062         mkdir $testdir/rr || error "mkdir rr failed"
29063         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
29064         # default max_inherit is -1, default max_inherit_rr is 0
29065         $LFS setdirstripe -D -c 1 $testdir/rr ||
29066                 error "setdirstripe rr failed"
29067         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
29068                 error "setdirstripe qos failed"
29069         test_qos_mkdir "mkdir" 1
29070
29071         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
29072         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
29073         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
29074         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
29075         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
29076
29077         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
29078         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
29079         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
29080         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
29081         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
29082         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
29083         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
29084                 error "level2 shouldn't have default LMV" || true
29085 }
29086 run_test 413c "mkdir with default LMV max inherit rr"
29087
29088 test_413d() {
29089         (( MDSCOUNT >= 2 )) ||
29090                 skip "We need at least 2 MDTs for this test"
29091
29092         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
29093                 skip "Need server version at least 2.14.51"
29094
29095         local lmv_qos_threshold_rr
29096
29097         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
29098                 head -n1)
29099         stack_trap "$LCTL set_param \
29100                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
29101
29102         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
29103         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
29104         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
29105                 error "$tdir shouldn't have default LMV"
29106         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
29107                 error "mkdir sub failed"
29108
29109         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
29110
29111         (( count == 100 )) || error "$count subdirs on MDT0"
29112 }
29113 run_test 413d "inherit ROOT default LMV"
29114
29115 test_413e() {
29116         (( MDSCOUNT >= 2 )) ||
29117                 skip "We need at least 2 MDTs for this test"
29118         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
29119                 skip "Need server version at least 2.14.55"
29120
29121         local testdir=$DIR/$tdir
29122         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
29123         local max_inherit
29124         local sub_max_inherit
29125
29126         mkdir -p $testdir || error "failed to create $testdir"
29127
29128         # set default max-inherit to -1 if stripe count is 0 or 1
29129         $LFS setdirstripe -D -c 1 $testdir ||
29130                 error "failed to set default LMV"
29131         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
29132         (( max_inherit == -1 )) ||
29133                 error "wrong max_inherit value $max_inherit"
29134
29135         # set default max_inherit to a fixed value if stripe count is not 0 or 1
29136         $LFS setdirstripe -D -c -1 $testdir ||
29137                 error "failed to set default LMV"
29138         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
29139         (( max_inherit > 0 )) ||
29140                 error "wrong max_inherit value $max_inherit"
29141
29142         # and the subdir will decrease the max_inherit by 1
29143         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
29144         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
29145         (( sub_max_inherit == max_inherit - 1)) ||
29146                 error "wrong max-inherit of subdir $sub_max_inherit"
29147
29148         # check specified --max-inherit and warning message
29149         stack_trap "rm -f $tmpfile"
29150         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
29151                 error "failed to set default LMV"
29152         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
29153         (( max_inherit == -1 )) ||
29154                 error "wrong max_inherit value $max_inherit"
29155
29156         # check the warning messages
29157         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
29158                 error "failed to detect warning string"
29159         fi
29160 }
29161 run_test 413e "check default max-inherit value"
29162
29163 test_fs_dmv_inherit()
29164 {
29165         local testdir=$DIR/$tdir
29166
29167         local count
29168         local inherit
29169         local inherit_rr
29170
29171         for i in 1 2; do
29172                 mkdir $testdir || error "mkdir $testdir failed"
29173                 count=$($LFS getdirstripe -D -c $testdir)
29174                 (( count == 1 )) ||
29175                         error "$testdir default LMV count mismatch $count != 1"
29176                 inherit=$($LFS getdirstripe -D -X $testdir)
29177                 (( inherit == 3 - i )) ||
29178                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
29179                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
29180                 (( inherit_rr == 3 - i )) ||
29181                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
29182                 testdir=$testdir/sub
29183         done
29184
29185         mkdir $testdir || error "mkdir $testdir failed"
29186         count=$($LFS getdirstripe -D -c $testdir)
29187         (( count == 0 )) ||
29188                 error "$testdir default LMV count not zero: $count"
29189 }
29190
29191 test_413f() {
29192         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
29193
29194         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
29195                 skip "Need server version at least 2.14.55"
29196
29197         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
29198                 error "dump $DIR default LMV failed"
29199         stack_trap "setfattr --restore=$TMP/dmv.ea"
29200
29201         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
29202                 error "set $DIR default LMV failed"
29203
29204         test_fs_dmv_inherit
29205 }
29206 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
29207
29208 test_413g() {
29209         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
29210
29211         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
29212         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
29213                 error "dump $DIR default LMV failed"
29214         stack_trap "setfattr --restore=$TMP/dmv.ea"
29215
29216         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
29217                 error "set $DIR default LMV failed"
29218
29219         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
29220                 error "mount $MOUNT2 failed"
29221         stack_trap "umount_client $MOUNT2"
29222
29223         local saved_DIR=$DIR
29224
29225         export DIR=$MOUNT2
29226
29227         stack_trap "export DIR=$saved_DIR"
29228
29229         # first check filesystem-wide default LMV inheritance
29230         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
29231
29232         # then check subdirs are spread to all MDTs
29233         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
29234
29235         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
29236
29237         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
29238 }
29239 run_test 413g "enforce ROOT default LMV on subdir mount"
29240
29241 test_413h() {
29242         (( MDSCOUNT >= 2 )) ||
29243                 skip "We need at least 2 MDTs for this test"
29244
29245         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
29246                 skip "Need server version at least 2.15.50.6"
29247
29248         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
29249
29250         stack_trap "$LCTL set_param \
29251                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
29252         $LCTL set_param lmv.*.qos_maxage=1
29253
29254         local depth=5
29255         local rr_depth=4
29256         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
29257         local count=$((MDSCOUNT * 20))
29258
29259         generate_uneven_mdts 50
29260
29261         mkdir -p $dir || error "mkdir $dir failed"
29262         stack_trap "rm -rf $dir"
29263         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
29264                 --max-inherit-rr=$rr_depth $dir
29265
29266         for ((d=0; d < depth + 2; d++)); do
29267                 log "dir=$dir:"
29268                 for ((sub=0; sub < count; sub++)); do
29269                         mkdir $dir/d$sub
29270                 done
29271                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
29272                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
29273                 # subdirs within $rr_depth should be created round-robin
29274                 if (( d < rr_depth )); then
29275                         (( ${num[0]} != count )) ||
29276                                 error "all objects created on MDT ${num[1]}"
29277                 fi
29278
29279                 dir=$dir/d0
29280         done
29281 }
29282 run_test 413h "don't stick to parent for round-robin dirs"
29283
29284 test_413i() {
29285         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
29286
29287         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
29288                 skip "Need server version at least 2.14.55"
29289
29290         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
29291                 error "dump $DIR default LMV failed"
29292         stack_trap "setfattr --restore=$TMP/dmv.ea"
29293
29294         local testdir=$DIR/$tdir
29295         local def_max_rr=1
29296         local def_max=3
29297         local count
29298
29299         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
29300                 --max-inherit-rr=$def_max_rr $DIR ||
29301                 error "set $DIR default LMV failed"
29302
29303         for i in $(seq 2 3); do
29304                 def_max=$((def_max - 1))
29305                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
29306
29307                 mkdir $testdir
29308                 # RR is decremented and keeps zeroed once exhausted
29309                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
29310                 (( count == def_max_rr )) ||
29311                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
29312
29313                 # max-inherit is decremented
29314                 count=$($LFS getdirstripe -D --max-inherit $testdir)
29315                 (( count == def_max )) ||
29316                         error_noexit "$testdir: max-inherit $count != $def_max"
29317
29318                 testdir=$testdir/d$i
29319         done
29320
29321         # d3 is the last inherited from ROOT, no inheritance anymore
29322         # i.e. no the default layout anymore
29323         mkdir -p $testdir/d4/d5
29324         count=$($LFS getdirstripe -D --max-inherit $testdir)
29325         (( count == -1 )) ||
29326                 error_noexit "$testdir: max-inherit $count != -1"
29327
29328         local p_count=$($LFS getdirstripe -i $testdir)
29329
29330         for i in $(seq 4 5); do
29331                 testdir=$testdir/d$i
29332
29333                 # the root default layout is not applied once exhausted
29334                 count=$($LFS getdirstripe -i $testdir)
29335                 (( count == p_count )) ||
29336                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
29337         done
29338
29339         $LFS setdirstripe -i 0 $DIR/d2
29340         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
29341         (( count == -1 )) ||
29342                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
29343 }
29344 run_test 413i "check default layout inheritance"
29345
29346 test_413j()
29347 {
29348         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
29349
29350         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
29351         $LFS setdirstripe -D -c2 --max-inherit=2 $DIR/$tdir ||
29352                 error "setdirstripe $tdir failed"
29353
29354         local value=$(getfattr -n trusted.dmv $DIR/$tdir | \
29355                       grep "trusted.dmv" |sed -e 's/[^=]\+=//')
29356
29357         mkdir -p $DIR/$tdir/sub || error "mkdir sub failed"
29358         # setfattr dmv calls setdirstripe -D
29359         setfattr -n trusted.dmv -v $value $DIR/$tdir/sub ||
29360                 error "setfattr sub failed"
29361         local value2=$(getfattr -n trusted.dmv $DIR/$tdir/sub | \
29362                        grep "trusted.dmv" |sed -e 's/[^=]\+=//')
29363
29364         [ $value == $value2 ] || error "dmv mismatch"
29365
29366         (( MDS1_VERSION >= $(version_code 2.15.58) )) || return 0
29367
29368         # do not allow remove dmv by setfattr -x
29369         do_nodes $(comma_list $(mdts_nodes)) \
29370                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=0"
29371         setfattr -x trusted.dmv $DIR/$tdir/sub || error "setfattr sub failed"
29372         getfattr -n trusted.dmv $DIR/$tdir/sub || error "default LMV deleted"
29373
29374         # allow remove dmv by setfattr -x
29375         do_nodes $(comma_list $(mdts_nodes)) \
29376                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=1"
29377         setfattr -x trusted.dmv $DIR/$tdir/sub || error "setfattr sub failed"
29378         getfattr -n trusted.dmv $DIR/$tdir/sub && error "default LMV exists"
29379         do_nodes $(comma_list $(mdts_nodes)) \
29380                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=0"
29381 }
29382 run_test 413j "set default LMV by setxattr"
29383
29384 test_413z() {
29385         local pids=""
29386         local subdir
29387         local pid
29388
29389         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
29390                 unlinkmany $subdir/f. $TEST413_COUNT &
29391                 pids="$pids $!"
29392         done
29393
29394         for pid in $pids; do
29395                 wait $pid
29396         done
29397
29398         true
29399 }
29400 run_test 413z "413 test cleanup"
29401
29402 test_414() {
29403 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
29404         $LCTL set_param fail_loc=0x80000521
29405         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
29406         rm -f $DIR/$tfile
29407 }
29408 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
29409
29410 test_415() {
29411         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
29412         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
29413                 skip "Need server version at least 2.11.52"
29414
29415         # LU-11102
29416         local total=500
29417         local max=120
29418
29419         # this test may be slow on ZFS
29420         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
29421
29422         # though this test is designed for striped directory, let's test normal
29423         # directory too since lock is always saved as CoS lock.
29424         test_mkdir $DIR/$tdir || error "mkdir $tdir"
29425         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
29426         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
29427         # if looping with ONLY_REPEAT, wait for previous deletions to finish
29428         wait_delete_completed_mds
29429
29430         # run a loop without concurrent touch to measure rename duration.
29431         # only for test debug/robustness, NOT part of COS functional test.
29432         local start_time=$SECONDS
29433         for ((i = 0; i < total; i++)); do
29434                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
29435                         > /dev/null
29436         done
29437         local baseline=$((SECONDS - start_time))
29438         echo "rename $total files without 'touch' took $baseline sec"
29439
29440         (
29441                 while true; do
29442                         touch $DIR/$tdir
29443                 done
29444         ) &
29445         local setattr_pid=$!
29446
29447         # rename files back to original name so unlinkmany works
29448         start_time=$SECONDS
29449         for ((i = 0; i < total; i++)); do
29450                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
29451                         > /dev/null
29452         done
29453         local duration=$((SECONDS - start_time))
29454
29455         kill -9 $setattr_pid
29456
29457         echo "rename $total files with 'touch' took $duration sec"
29458         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
29459         (( duration <= max )) ||
29460                 error_not_in_vm "rename took $duration > $max sec"
29461 }
29462 run_test 415 "lock revoke is not missing"
29463
29464 test_416() {
29465         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
29466                 skip "Need server version at least 2.11.55"
29467
29468         # define OBD_FAIL_OSD_TXN_START    0x19a
29469         do_facet mds1 lctl set_param fail_loc=0x19a
29470
29471         lfs mkdir -c $MDSCOUNT $DIR/$tdir
29472
29473         true
29474 }
29475 run_test 416 "transaction start failure won't cause system hung"
29476
29477 cleanup_417() {
29478         trap 0
29479         do_nodes $(comma_list $(mdts_nodes)) \
29480                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
29481         do_nodes $(comma_list $(mdts_nodes)) \
29482                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
29483         do_nodes $(comma_list $(mdts_nodes)) \
29484                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
29485 }
29486
29487 test_417() {
29488         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
29489         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
29490                 skip "Need MDS version at least 2.11.56"
29491
29492         trap cleanup_417 RETURN EXIT
29493
29494         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
29495         do_nodes $(comma_list $(mdts_nodes)) \
29496                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
29497         $LFS migrate -m 0 $DIR/$tdir.1 &&
29498                 error "migrate dir $tdir.1 should fail"
29499
29500         do_nodes $(comma_list $(mdts_nodes)) \
29501                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
29502         $LFS mkdir -i 1 $DIR/$tdir.2 &&
29503                 error "create remote dir $tdir.2 should fail"
29504
29505         do_nodes $(comma_list $(mdts_nodes)) \
29506                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
29507         $LFS mkdir -c 2 $DIR/$tdir.3 &&
29508                 error "create striped dir $tdir.3 should fail"
29509         true
29510 }
29511 run_test 417 "disable remote dir, striped dir and dir migration"
29512
29513 # Checks that the outputs of df [-i] and lfs df [-i] match
29514 #
29515 # usage: check_lfs_df <blocks | inodes> <mountpoint>
29516 check_lfs_df() {
29517         local dir=$2
29518         local inodes
29519         local df_out
29520         local lfs_df_out
29521         local count
29522         local passed=false
29523
29524         # blocks or inodes
29525         [ "$1" == "blocks" ] && inodes= || inodes="-i"
29526
29527         for count in {1..100}; do
29528                 do_nodes "$CLIENTS" \
29529                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
29530                 sync; sleep 0.2
29531
29532                 # read the lines of interest
29533                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
29534                         error "df $inodes $dir | tail -n +2 failed"
29535                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
29536                         error "lfs df $inodes $dir | grep summary: failed"
29537
29538                 # skip first substrings of each output as they are different
29539                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
29540                 # compare the two outputs
29541                 passed=true
29542                 #  skip "available" on MDT until LU-13997 is fixed.
29543                 #for i in {1..5}; do
29544                 for i in 1 2 4 5; do
29545                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
29546                 done
29547                 $passed && break
29548         done
29549
29550         if ! $passed; then
29551                 df -P $inodes $dir
29552                 echo
29553                 lfs df $inodes $dir
29554                 error "df and lfs df $1 output mismatch: "      \
29555                       "df ${inodes}: ${df_out[*]}, "            \
29556                       "lfs df ${inodes}: ${lfs_df_out[*]}"
29557         fi
29558 }
29559
29560 test_418() {
29561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29562
29563         local dir=$DIR/$tdir
29564         local numfiles=$((RANDOM % 4096 + 2))
29565         local numblocks=$((RANDOM % 256 + 1))
29566
29567         wait_delete_completed
29568         test_mkdir $dir
29569
29570         # check block output
29571         check_lfs_df blocks $dir
29572         # check inode output
29573         check_lfs_df inodes $dir
29574
29575         # create a single file and retest
29576         echo "Creating a single file and testing"
29577         createmany -o $dir/$tfile- 1 &>/dev/null ||
29578                 error "creating 1 file in $dir failed"
29579         check_lfs_df blocks $dir
29580         check_lfs_df inodes $dir
29581
29582         # create a random number of files
29583         echo "Creating $((numfiles - 1)) files and testing"
29584         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
29585                 error "creating $((numfiles - 1)) files in $dir failed"
29586
29587         # write a random number of blocks to the first test file
29588         echo "Writing $numblocks 4K blocks and testing"
29589         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
29590                 count=$numblocks &>/dev/null ||
29591                 error "dd to $dir/${tfile}-0 failed"
29592
29593         # retest
29594         check_lfs_df blocks $dir
29595         check_lfs_df inodes $dir
29596
29597         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
29598                 error "unlinking $numfiles files in $dir failed"
29599 }
29600 run_test 418 "df and lfs df outputs match"
29601
29602 test_419()
29603 {
29604         local dir=$DIR/$tdir
29605
29606         mkdir -p $dir
29607         touch $dir/file
29608
29609         cancel_lru_locks mdc
29610
29611         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
29612         $LCTL set_param fail_loc=0x1410
29613         cat $dir/file
29614         $LCTL set_param fail_loc=0
29615         rm -rf $dir
29616 }
29617 run_test 419 "Verify open file by name doesn't crash kernel"
29618
29619 test_420()
29620 {
29621         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
29622                 skip "Need MDS version at least 2.12.53"
29623
29624         local SAVE_UMASK=$(umask)
29625         local dir=$DIR/$tdir
29626         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
29627
29628         mkdir -p $dir
29629         umask 0000
29630         mkdir -m03777 $dir/testdir
29631         ls -dn $dir/testdir
29632         # Need to remove trailing '.' when SELinux is enabled
29633         local dirperms=$(ls -dn $dir/testdir |
29634                          awk '{ sub(/\.$/, "", $1); print $1}')
29635         [ $dirperms == "drwxrwsrwt" ] ||
29636                 error "incorrect perms on $dir/testdir"
29637
29638         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
29639                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
29640         ls -n $dir/testdir/testfile
29641         local fileperms=$(ls -n $dir/testdir/testfile |
29642                           awk '{ sub(/\.$/, "", $1); print $1}')
29643         [ $fileperms == "-rwxr-xr-x" ] ||
29644                 error "incorrect perms on $dir/testdir/testfile"
29645
29646         umask $SAVE_UMASK
29647 }
29648 run_test 420 "clear SGID bit on non-directories for non-members"
29649
29650 test_421a() {
29651         local cnt
29652         local fid1
29653         local fid2
29654
29655         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29656                 skip "Need MDS version at least 2.12.54"
29657
29658         test_mkdir $DIR/$tdir
29659         createmany -o $DIR/$tdir/f 3
29660         cnt=$(ls -1 $DIR/$tdir | wc -l)
29661         [ $cnt != 3 ] && error "unexpected #files: $cnt"
29662
29663         fid1=$(lfs path2fid $DIR/$tdir/f1)
29664         fid2=$(lfs path2fid $DIR/$tdir/f2)
29665         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
29666
29667         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
29668         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
29669
29670         cnt=$(ls -1 $DIR/$tdir | wc -l)
29671         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
29672
29673         rm -f $DIR/$tdir/f3 || error "can't remove f3"
29674         createmany -o $DIR/$tdir/f 3
29675         cnt=$(ls -1 $DIR/$tdir | wc -l)
29676         [ $cnt != 3 ] && error "unexpected #files: $cnt"
29677
29678         fid1=$(lfs path2fid $DIR/$tdir/f1)
29679         fid2=$(lfs path2fid $DIR/$tdir/f2)
29680         echo "remove using fsname $FSNAME"
29681         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
29682
29683         cnt=$(ls -1 $DIR/$tdir | wc -l)
29684         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
29685 }
29686 run_test 421a "simple rm by fid"
29687
29688 test_421b() {
29689         local cnt
29690         local FID1
29691         local FID2
29692
29693         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29694                 skip "Need MDS version at least 2.12.54"
29695
29696         test_mkdir $DIR/$tdir
29697         createmany -o $DIR/$tdir/f 3
29698         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
29699         MULTIPID=$!
29700
29701         FID1=$(lfs path2fid $DIR/$tdir/f1)
29702         FID2=$(lfs path2fid $DIR/$tdir/f2)
29703         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
29704
29705         kill -USR1 $MULTIPID
29706         wait
29707
29708         cnt=$(ls $DIR/$tdir | wc -l)
29709         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
29710 }
29711 run_test 421b "rm by fid on open file"
29712
29713 test_421c() {
29714         local cnt
29715         local FIDS
29716
29717         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29718                 skip "Need MDS version at least 2.12.54"
29719
29720         test_mkdir $DIR/$tdir
29721         createmany -o $DIR/$tdir/f 3
29722         touch $DIR/$tdir/$tfile
29723         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
29724         cnt=$(ls -1 $DIR/$tdir | wc -l)
29725         [ $cnt != 184 ] && error "unexpected #files: $cnt"
29726
29727         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
29728         $LFS rmfid $DIR $FID1 || error "rmfid failed"
29729
29730         cnt=$(ls $DIR/$tdir | wc -l)
29731         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
29732 }
29733 run_test 421c "rm by fid against hardlinked files"
29734
29735 test_421d() {
29736         local cnt
29737         local FIDS
29738
29739         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29740                 skip "Need MDS version at least 2.12.54"
29741
29742         test_mkdir $DIR/$tdir
29743         createmany -o $DIR/$tdir/f 4097
29744         cnt=$(ls -1 $DIR/$tdir | wc -l)
29745         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
29746
29747         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
29748         $LFS rmfid $DIR $FIDS || error "rmfid failed"
29749
29750         cnt=$(ls $DIR/$tdir | wc -l)
29751         rm -rf $DIR/$tdir
29752         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
29753 }
29754 run_test 421d "rmfid en masse"
29755
29756 test_421e() {
29757         local cnt
29758         local FID
29759
29760         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
29761         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29762                 skip "Need MDS version at least 2.12.54"
29763
29764         mkdir -p $DIR/$tdir
29765         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
29766         createmany -o $DIR/$tdir/striped_dir/f 512
29767         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
29768         [ $cnt != 512 ] && error "unexpected #files: $cnt"
29769
29770         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
29771                 sed "s/[/][^:]*://g")
29772         $LFS rmfid $DIR $FIDS || error "rmfid failed"
29773
29774         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
29775         rm -rf $DIR/$tdir
29776         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
29777 }
29778 run_test 421e "rmfid in DNE"
29779
29780 test_421f() {
29781         local cnt
29782         local FID
29783
29784         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29785                 skip "Need MDS version at least 2.12.54"
29786
29787         test_mkdir $DIR/$tdir
29788         touch $DIR/$tdir/f
29789         cnt=$(ls -1 $DIR/$tdir | wc -l)
29790         [ $cnt != 1 ] && error "unexpected #files: $cnt"
29791
29792         FID=$(lfs path2fid $DIR/$tdir/f)
29793         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
29794         # rmfid should fail
29795         cnt=$(ls -1 $DIR/$tdir | wc -l)
29796         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
29797
29798         chmod a+rw $DIR/$tdir
29799         ls -la $DIR/$tdir
29800         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
29801         # rmfid should fail
29802         cnt=$(ls -1 $DIR/$tdir | wc -l)
29803         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
29804
29805         rm -f $DIR/$tdir/f
29806         $RUNAS touch $DIR/$tdir/f
29807         FID=$(lfs path2fid $DIR/$tdir/f)
29808         echo "rmfid as root"
29809         $LFS rmfid $DIR $FID || error "rmfid as root failed"
29810         cnt=$(ls -1 $DIR/$tdir | wc -l)
29811         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
29812
29813         rm -f $DIR/$tdir/f
29814         $RUNAS touch $DIR/$tdir/f
29815         cnt=$(ls -1 $DIR/$tdir | wc -l)
29816         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
29817         FID=$(lfs path2fid $DIR/$tdir/f)
29818         # rmfid w/o user_fid2path mount option should fail
29819         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
29820         cnt=$(ls -1 $DIR/$tdir | wc -l)
29821         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
29822
29823         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
29824         stack_trap "rmdir $tmpdir"
29825         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
29826                 error "failed to mount client'"
29827         stack_trap "umount_client $tmpdir"
29828
29829         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
29830         # rmfid should succeed
29831         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
29832         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
29833
29834         # rmfid shouldn't allow to remove files due to dir's permission
29835         chmod a+rwx $tmpdir/$tdir
29836         touch $tmpdir/$tdir/f
29837         ls -la $tmpdir/$tdir
29838         FID=$(lfs path2fid $tmpdir/$tdir/f)
29839         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
29840         return 0
29841 }
29842 run_test 421f "rmfid checks permissions"
29843
29844 test_421g() {
29845         local cnt
29846         local FIDS
29847
29848         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
29849         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29850                 skip "Need MDS version at least 2.12.54"
29851
29852         mkdir -p $DIR/$tdir
29853         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
29854         createmany -o $DIR/$tdir/striped_dir/f 512
29855         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
29856         [ $cnt != 512 ] && error "unexpected #files: $cnt"
29857
29858         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
29859                 sed "s/[/][^:]*://g")
29860
29861         rm -f $DIR/$tdir/striped_dir/f1*
29862         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
29863         removed=$((512 - cnt))
29864
29865         # few files have been just removed, so we expect
29866         # rmfid to fail on their fids
29867         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
29868         [ $removed != $errors ] && error "$errors != $removed"
29869
29870         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
29871         rm -rf $DIR/$tdir
29872         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
29873 }
29874 run_test 421g "rmfid to return errors properly"
29875
29876 test_421h() {
29877         local mount_other
29878         local mount_ret
29879         local rmfid_ret
29880         local old_fid
29881         local fidA
29882         local fidB
29883         local fidC
29884         local fidD
29885
29886         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
29887                 skip "Need MDS version at least 2.15.53"
29888
29889         test_mkdir $DIR/$tdir
29890         test_mkdir $DIR/$tdir/subdir
29891         touch $DIR/$tdir/subdir/file0
29892         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
29893         echo File $DIR/$tdir/subdir/file0 FID $old_fid
29894         rm -f $DIR/$tdir/subdir/file0
29895         touch $DIR/$tdir/subdir/fileA
29896         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
29897         echo File $DIR/$tdir/subdir/fileA FID $fidA
29898         touch $DIR/$tdir/subdir/fileB
29899         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
29900         echo File $DIR/$tdir/subdir/fileB FID $fidB
29901         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
29902         touch $DIR/$tdir/subdir/fileC
29903         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
29904         echo File $DIR/$tdir/subdir/fileC FID $fidC
29905         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
29906         touch $DIR/$tdir/fileD
29907         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
29908         echo File $DIR/$tdir/fileD FID $fidD
29909
29910         # mount another client mount point with subdirectory mount
29911         export FILESET=/$tdir/subdir
29912         mount_other=${MOUNT}_other
29913         mount_client $mount_other ${MOUNT_OPTS}
29914         mount_ret=$?
29915         export FILESET=""
29916         (( mount_ret == 0 )) || error "mount $mount_other failed"
29917
29918         echo Removing FIDs:
29919         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
29920         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
29921         rmfid_ret=$?
29922
29923         umount_client $mount_other || error "umount $mount_other failed"
29924
29925         (( rmfid_ret != 0 )) || error "rmfid should have failed"
29926
29927         # fileA should have been deleted
29928         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
29929
29930         # fileB should have been deleted
29931         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
29932
29933         # fileC should not have been deleted, fid also exists outside of fileset
29934         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
29935
29936         # fileD should not have been deleted, it exists outside of fileset
29937         stat $DIR/$tdir/fileD || error "fileD deleted"
29938 }
29939 run_test 421h "rmfid with fileset mount"
29940
29941 test_422() {
29942         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
29943         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
29944         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
29945         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
29946         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
29947
29948         local amc=$(at_max_get client)
29949         local amo=$(at_max_get mds1)
29950         local timeout=`lctl get_param -n timeout`
29951
29952         at_max_set 0 client
29953         at_max_set 0 mds1
29954
29955 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
29956         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
29957                         fail_val=$(((2*timeout + 10)*1000))
29958         touch $DIR/$tdir/d3/file &
29959         sleep 2
29960 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
29961         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
29962                         fail_val=$((2*timeout + 5))
29963         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
29964         local pid=$!
29965         sleep 1
29966         kill -9 $pid
29967         sleep $((2 * timeout))
29968         echo kill $pid
29969         kill -9 $pid
29970         lctl mark touch
29971         touch $DIR/$tdir/d2/file3
29972         touch $DIR/$tdir/d2/file4
29973         touch $DIR/$tdir/d2/file5
29974
29975         wait
29976         at_max_set $amc client
29977         at_max_set $amo mds1
29978
29979         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
29980         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
29981                 error "Watchdog is always throttled"
29982 }
29983 run_test 422 "kill a process with RPC in progress"
29984
29985 stat_test() {
29986     df -h $MOUNT &
29987     df -h $MOUNT &
29988     df -h $MOUNT &
29989     df -h $MOUNT &
29990     df -h $MOUNT &
29991     df -h $MOUNT &
29992 }
29993
29994 test_423() {
29995     local _stats
29996     # ensure statfs cache is expired
29997     sleep 2;
29998
29999     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
30000     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
30001
30002     return 0
30003 }
30004 run_test 423 "statfs should return a right data"
30005
30006 test_424() {
30007 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | CFS_FAIL_ONCE
30008         $LCTL set_param fail_loc=0x80000522
30009         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
30010         rm -f $DIR/$tfile
30011 }
30012 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
30013
30014 test_425() {
30015         test_mkdir -c -1 $DIR/$tdir
30016         $LFS setstripe -c -1 $DIR/$tdir
30017
30018         lru_resize_disable "" 100
30019         stack_trap "lru_resize_enable" EXIT
30020
30021         sleep 5
30022
30023         for i in $(seq $((MDSCOUNT * 125))); do
30024                 local t=$DIR/$tdir/$tfile_$i
30025
30026                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
30027                         error_noexit "Create file $t"
30028         done
30029         stack_trap "rm -rf $DIR/$tdir" EXIT
30030
30031         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
30032                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
30033                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
30034
30035                 [ $lock_count -le $lru_size ] ||
30036                         error "osc lock count $lock_count > lru size $lru_size"
30037         done
30038
30039         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
30040                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
30041                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
30042
30043                 [ $lock_count -le $lru_size ] ||
30044                         error "mdc lock count $lock_count > lru size $lru_size"
30045         done
30046 }
30047 run_test 425 "lock count should not exceed lru size"
30048
30049 test_426() {
30050         splice-test -r $DIR/$tfile
30051         splice-test -rd $DIR/$tfile
30052         splice-test $DIR/$tfile
30053         splice-test -d $DIR/$tfile
30054 }
30055 run_test 426 "splice test on Lustre"
30056
30057 test_427() {
30058         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
30059         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
30060                 skip "Need MDS version at least 2.12.4"
30061         local log
30062
30063         mkdir $DIR/$tdir
30064         mkdir $DIR/$tdir/1
30065         mkdir $DIR/$tdir/2
30066         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
30067         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
30068
30069         $LFS getdirstripe $DIR/$tdir/1/dir
30070
30071         #first setfattr for creating updatelog
30072         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
30073
30074 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
30075         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
30076         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
30077         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
30078
30079         sleep 2
30080         fail mds2
30081         wait_recovery_complete mds2 $((2*TIMEOUT))
30082
30083         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
30084         echo $log | grep "get update log failed" &&
30085                 error "update log corruption is detected" || true
30086 }
30087 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
30088
30089 test_428() {
30090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30091         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
30092                               awk '/^max_cached_mb/ { print $2 }')
30093         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
30094
30095         $LCTL set_param -n llite.*.max_cached_mb=64
30096
30097         mkdir $DIR/$tdir
30098         $LFS setstripe -c 1 $DIR/$tdir
30099         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
30100         stack_trap "rm -f $DIR/$tdir/$tfile.*"
30101         #test write
30102         for f in $(seq 4); do
30103                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
30104         done
30105         wait
30106
30107         cancel_lru_locks osc
30108         # Test read
30109         for f in $(seq 4); do
30110                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
30111         done
30112         wait
30113 }
30114 run_test 428 "large block size IO should not hang"
30115
30116 test_429() { # LU-7915 / LU-10948
30117         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
30118         local testfile=$DIR/$tfile
30119         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
30120         local new_flag=1
30121         local first_rpc
30122         local second_rpc
30123         local third_rpc
30124
30125         $LCTL get_param $ll_opencache_threshold_count ||
30126                 skip "client does not have opencache parameter"
30127
30128         set_opencache $new_flag
30129         stack_trap "restore_opencache"
30130         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
30131                 error "enable opencache failed"
30132         touch $testfile
30133         # drop MDC DLM locks
30134         cancel_lru_locks mdc
30135         # clear MDC RPC stats counters
30136         $LCTL set_param $mdc_rpcstats=clear
30137
30138         # According to the current implementation, we need to run 3 times
30139         # open & close file to verify if opencache is enabled correctly.
30140         # 1st, RPCs are sent for lookup/open and open handle is released on
30141         #      close finally.
30142         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
30143         #      so open handle won't be released thereafter.
30144         # 3rd, No RPC is sent out.
30145         $MULTIOP $testfile oc || error "multiop failed"
30146         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
30147         echo "1st: $first_rpc RPCs in flight"
30148
30149         $MULTIOP $testfile oc || error "multiop failed"
30150         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
30151         echo "2nd: $second_rpc RPCs in flight"
30152
30153         $MULTIOP $testfile oc || error "multiop failed"
30154         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
30155         echo "3rd: $third_rpc RPCs in flight"
30156
30157         #verify no MDC RPC is sent
30158         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
30159 }
30160 run_test 429 "verify if opencache flag on client side does work"
30161
30162 lseek_test_430() {
30163         local offset
30164         local file=$1
30165
30166         # data at [200K, 400K)
30167         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
30168                 error "256K->512K dd fails"
30169         # data at [2M, 3M)
30170         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
30171                 error "2M->3M dd fails"
30172         # data at [4M, 5M)
30173         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
30174                 error "4M->5M dd fails"
30175         echo "Data at 256K...512K, 2M...3M and 4M...5M"
30176         # start at first component hole #1
30177         printf "Seeking hole from 1000 ... "
30178         offset=$(lseek_test -l 1000 $file)
30179         echo $offset
30180         [[ $offset == 1000 ]] || error "offset $offset != 1000"
30181         printf "Seeking data from 1000 ... "
30182         offset=$(lseek_test -d 1000 $file)
30183         echo $offset
30184         [[ $offset == 262144 ]] || error "offset $offset != 262144"
30185
30186         # start at first component data block
30187         printf "Seeking hole from 300000 ... "
30188         offset=$(lseek_test -l 300000 $file)
30189         echo $offset
30190         [[ $offset == 524288 ]] || error "offset $offset != 524288"
30191         printf "Seeking data from 300000 ... "
30192         offset=$(lseek_test -d 300000 $file)
30193         echo $offset
30194         [[ $offset == 300000 ]] || error "offset $offset != 300000"
30195
30196         # start at the first component but beyond end of object size
30197         printf "Seeking hole from 1000000 ... "
30198         offset=$(lseek_test -l 1000000 $file)
30199         echo $offset
30200         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
30201         printf "Seeking data from 1000000 ... "
30202         offset=$(lseek_test -d 1000000 $file)
30203         echo $offset
30204         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
30205
30206         # start at second component stripe 2 (empty file)
30207         printf "Seeking hole from 1500000 ... "
30208         offset=$(lseek_test -l 1500000 $file)
30209         echo $offset
30210         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
30211         printf "Seeking data from 1500000 ... "
30212         offset=$(lseek_test -d 1500000 $file)
30213         echo $offset
30214         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
30215
30216         # start at second component stripe 1 (all data)
30217         printf "Seeking hole from 3000000 ... "
30218         offset=$(lseek_test -l 3000000 $file)
30219         echo $offset
30220         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
30221         printf "Seeking data from 3000000 ... "
30222         offset=$(lseek_test -d 3000000 $file)
30223         echo $offset
30224         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
30225
30226         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
30227                 error "2nd dd fails"
30228         echo "Add data block at 640K...1280K"
30229
30230         # start at before new data block, in hole
30231         printf "Seeking hole from 600000 ... "
30232         offset=$(lseek_test -l 600000 $file)
30233         echo $offset
30234         [[ $offset == 600000 ]] || error "offset $offset != 600000"
30235         printf "Seeking data from 600000 ... "
30236         offset=$(lseek_test -d 600000 $file)
30237         echo $offset
30238         [[ $offset == 655360 ]] || error "offset $offset != 655360"
30239
30240         # start at the first component new data block
30241         printf "Seeking hole from 1000000 ... "
30242         offset=$(lseek_test -l 1000000 $file)
30243         echo $offset
30244         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
30245         printf "Seeking data from 1000000 ... "
30246         offset=$(lseek_test -d 1000000 $file)
30247         echo $offset
30248         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
30249
30250         # start at second component stripe 2, new data
30251         printf "Seeking hole from 1200000 ... "
30252         offset=$(lseek_test -l 1200000 $file)
30253         echo $offset
30254         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
30255         printf "Seeking data from 1200000 ... "
30256         offset=$(lseek_test -d 1200000 $file)
30257         echo $offset
30258         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
30259
30260         # start beyond file end
30261         printf "Using offset > filesize ... "
30262         lseek_test -l 4000000 $file && error "lseek should fail"
30263         printf "Using offset > filesize ... "
30264         lseek_test -d 4000000 $file && error "lseek should fail"
30265
30266         printf "Done\n\n"
30267 }
30268
30269 test_430a() {
30270         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
30271                 skip "MDT does not support SEEK_HOLE"
30272
30273         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
30274                 skip "OST does not support SEEK_HOLE"
30275
30276         local file=$DIR/$tdir/$tfile
30277
30278         mkdir -p $DIR/$tdir
30279
30280         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
30281         # OST stripe #1 will have continuous data at [1M, 3M)
30282         # OST stripe #2 is empty
30283         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
30284         lseek_test_430 $file
30285         rm $file
30286         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
30287         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
30288         lseek_test_430 $file
30289         rm $file
30290         $LFS setstripe -c2 -S 512K $file
30291         echo "Two stripes, stripe size 512K"
30292         lseek_test_430 $file
30293         rm $file
30294         # FLR with stale mirror
30295         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
30296                        -N -c2 -S 1M $file
30297         echo "Mirrored file:"
30298         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
30299         echo "Plain 2 stripes 1M"
30300         lseek_test_430 $file
30301         rm $file
30302 }
30303 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
30304
30305 test_430b() {
30306         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
30307                 skip "OST does not support SEEK_HOLE"
30308
30309         local offset
30310         local file=$DIR/$tdir/$tfile
30311
30312         mkdir -p $DIR/$tdir
30313         # Empty layout lseek should fail
30314         $MCREATE $file
30315         # seek from 0
30316         printf "Seeking hole from 0 ... "
30317         lseek_test -l 0 $file && error "lseek should fail"
30318         printf "Seeking data from 0 ... "
30319         lseek_test -d 0 $file && error "lseek should fail"
30320         rm $file
30321
30322         # 1M-hole file
30323         $LFS setstripe -E 1M -c2 -E eof $file
30324         $TRUNCATE $file 1048576
30325         printf "Seeking hole from 1000000 ... "
30326         offset=$(lseek_test -l 1000000 $file)
30327         echo $offset
30328         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
30329         printf "Seeking data from 1000000 ... "
30330         lseek_test -d 1000000 $file && error "lseek should fail"
30331         rm $file
30332
30333         # full component followed by non-inited one
30334         $LFS setstripe -E 1M -c2 -E eof $file
30335         dd if=/dev/urandom of=$file bs=1M count=1
30336         printf "Seeking hole from 1000000 ... "
30337         offset=$(lseek_test -l 1000000 $file)
30338         echo $offset
30339         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
30340         printf "Seeking hole from 1048576 ... "
30341         lseek_test -l 1048576 $file && error "lseek should fail"
30342         # init second component and truncate back
30343         echo "123" >> $file
30344         $TRUNCATE $file 1048576
30345         printf "Seeking hole from 1000000 ... "
30346         offset=$(lseek_test -l 1000000 $file)
30347         echo $offset
30348         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
30349         printf "Seeking hole from 1048576 ... "
30350         lseek_test -l 1048576 $file && error "lseek should fail"
30351         # boundary checks for big values
30352         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
30353         offset=$(lseek_test -d 0 $file.10g)
30354         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
30355         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
30356         offset=$(lseek_test -d 0 $file.100g)
30357         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
30358         return 0
30359 }
30360 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
30361
30362 test_430c() {
30363         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
30364                 skip "OST does not support SEEK_HOLE"
30365
30366         local file=$DIR/$tdir/$tfile
30367         local start
30368
30369         mkdir -p $DIR/$tdir
30370         stack_trap "rm -f $file $file.tmp"
30371         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M || error "dd failed"
30372
30373         # cp version 8.33+ prefers lseek over fiemap
30374         local ver=$(cp --version | awk '{ print $4; exit; }')
30375
30376         echo "cp $ver installed"
30377         if (( $(version_code $ver) >= $(version_code 8.33) )); then
30378                 start=$SECONDS
30379                 time cp -v $file $file.tmp || error "cp $file failed"
30380                 (( SECONDS - start < 5 )) || {
30381                         strace cp $file $file.tmp |&
30382                                 grep -E "open|read|seek|FIEMAP" |
30383                                 grep -A 100 $file
30384                         error "cp: too long runtime $((SECONDS - start))"
30385                 }
30386         else
30387                 echo "cp test skipped due to $ver < 8.33"
30388         fi
30389
30390         # tar version 1.29+ supports SEEK_HOLE/DATA
30391         ver=$(tar --version | awk '{ print $4; exit; }')
30392         echo "tar $ver installed"
30393         if (( $(version_code $ver) >= $(version_code 1.29) )); then
30394                 start=$SECONDS
30395                 time tar cvf $file.tmp --sparse $file || error "tar $file error"
30396                 (( SECONDS - start < 5 )) || {
30397                         strace tar cf $file.tmp --sparse $file |&
30398                                 grep -E "open|read|seek|FIEMAP" |
30399                                 grep -A 100 $file
30400                         error "tar: too long runtime $((SECONDS - start))"
30401                 }
30402         else
30403                 echo "tar test skipped due to $ver < 1.29"
30404         fi
30405 }
30406 run_test 430c "lseek: external tools check"
30407
30408 test_431() { # LU-14187
30409         local file=$DIR/$tdir/$tfile
30410
30411         mkdir -p $DIR/$tdir
30412         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
30413         dd if=/dev/urandom of=$file bs=4k count=1
30414         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
30415         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
30416         #define OBD_FAIL_OST_RESTART_IO 0x251
30417         do_facet ost1 "$LCTL set_param fail_loc=0x251"
30418         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
30419         cp $file $file.0
30420         cancel_lru_locks
30421         sync_all_data
30422         echo 3 > /proc/sys/vm/drop_caches
30423         diff  $file $file.0 || error "data diff"
30424 }
30425 run_test 431 "Restart transaction for IO"
30426
30427 cleanup_test_432() {
30428         do_facet mgs $LCTL nodemap_activate 0
30429         wait_nm_sync active
30430 }
30431
30432 test_432() {
30433         local tmpdir=$TMP/dir432
30434
30435         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
30436                 skip "Need MDS version at least 2.14.52"
30437
30438         stack_trap cleanup_test_432 EXIT
30439         mkdir $DIR/$tdir
30440         mkdir $tmpdir
30441
30442         do_facet mgs $LCTL nodemap_activate 1
30443         wait_nm_sync active
30444         do_facet mgs $LCTL nodemap_modify --name default \
30445                 --property admin --value 1
30446         do_facet mgs $LCTL nodemap_modify --name default \
30447                 --property trusted --value 1
30448         cancel_lru_locks mdc
30449         wait_nm_sync default admin_nodemap
30450         wait_nm_sync default trusted_nodemap
30451
30452         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
30453                grep -ci "Operation not permitted") -ne 0 ]; then
30454                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
30455         fi
30456 }
30457 run_test 432 "mv dir from outside Lustre"
30458
30459 test_433() {
30460         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30461
30462         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
30463                 skip "inode cache not supported"
30464
30465         $LCTL set_param llite.*.inode_cache=0
30466         stack_trap "$LCTL set_param llite.*.inode_cache=1"
30467
30468         local count=256
30469         local before
30470         local after
30471
30472         cancel_lru_locks mdc
30473         test_mkdir $DIR/$tdir || error "mkdir $tdir"
30474         createmany -m $DIR/$tdir/f $count
30475         createmany -d $DIR/$tdir/d $count
30476         ls -l $DIR/$tdir > /dev/null
30477         stack_trap "rm -rf $DIR/$tdir"
30478
30479         before=$(num_objects)
30480         cancel_lru_locks mdc
30481         after=$(num_objects)
30482
30483         # sometimes even @before is less than 2 * count
30484         while (( before - after < count )); do
30485                 sleep 1
30486                 after=$(num_objects)
30487                 wait=$((wait + 1))
30488                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
30489                 if (( wait > 60 )); then
30490                         error "inode slab grew from $before to $after"
30491                 fi
30492         done
30493
30494         echo "lustre_inode_cache $before objs before lock cancel, $after after"
30495 }
30496 run_test 433 "ldlm lock cancel releases dentries and inodes"
30497
30498 test_434() {
30499         local file
30500         local getxattr_count
30501         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
30502         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30503
30504         [[ $(getenforce) == "Disabled" ]] ||
30505                 skip "lsm selinux module have to be disabled for this test"
30506
30507         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
30508                 error "fail to create $DIR/$tdir/ on MDT0000"
30509
30510         touch $DIR/$tdir/$tfile-{001..100}
30511
30512         # disable the xattr cache
30513         save_lustre_params client "llite.*.xattr_cache" > $p
30514         lctl set_param llite.*.xattr_cache=0
30515         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
30516
30517         # clear clients mdc stats
30518         clear_stats $mdc_stat_param ||
30519                 error "fail to clear stats on mdc MDT0000"
30520
30521         for file in $DIR/$tdir/$tfile-{001..100}; do
30522                 getfattr -n security.selinux $file |&
30523                         grep -q "Operation not supported" ||
30524                         error "getxattr on security.selinux should return EOPNOTSUPP"
30525         done
30526
30527         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
30528         (( getxattr_count < 100 )) ||
30529                 error "client sent $getxattr_count getxattr RPCs to the MDS"
30530 }
30531 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
30532
30533 test_440() {
30534         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
30535                 source $LUSTRE/scripts/bash-completion/lustre
30536         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
30537                 source /usr/share/bash-completion/completions/lustre
30538         else
30539                 skip "bash completion scripts not found"
30540         fi
30541
30542         local lctl_completions
30543         local lfs_completions
30544
30545         lctl_completions=$(_lustre_cmds lctl)
30546         if [[ ! $lctl_completions =~ "get_param" ]]; then
30547                 error "lctl bash completion failed"
30548         fi
30549
30550         lfs_completions=$(_lustre_cmds lfs)
30551         if [[ ! $lfs_completions =~ "setstripe" ]]; then
30552                 error "lfs bash completion failed"
30553         fi
30554 }
30555 run_test 440 "bash completion for lfs, lctl"
30556
30557 test_442() {
30558         local pid1
30559         local pid2
30560         mkdir -p $DIR/$tdir
30561         multiop $DIR/$tdir/$tfile.1 O_w1 & pid1=$!
30562         multiop $DIR/$tdir/$tfile.1 O_w1 & pid2=$!
30563         sleep 1
30564         touch $DIR/$tdir/$tfile.2
30565         $LFS swap_layouts -n $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
30566         $LCTL set_param fail_loc=0x1430
30567         kill -USR1 $pid1
30568         sleep 1
30569         kill -USR1 $pid2
30570         wait
30571 }
30572 run_test 442 "truncate vs read/write should not panic"
30573
30574 test_460d() {
30575         verify_yaml_available || skip_env "YAML verification not installed"
30576         $LCTL get_param -n sptlrpc.page_pools
30577         $LCTL get_param -n sptlrpc.page_pools | verify_yaml ||
30578                 error "The output of encrypt_page_pools is not an valid YAML"
30579 }
30580 run_test 460d "Check encrypt pools output"
30581
30582 prep_801() {
30583         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
30584         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
30585                 skip "Need server version at least 2.9.55"
30586
30587         start_full_debug_logging
30588 }
30589
30590 post_801() {
30591         stop_full_debug_logging
30592 }
30593
30594 barrier_stat() {
30595         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
30596                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
30597                            awk '/The barrier for/ { print $7 }')
30598                 echo $st
30599         else
30600                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
30601                 echo \'$st\'
30602         fi
30603 }
30604
30605 barrier_expired() {
30606         local expired
30607
30608         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
30609                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
30610                           awk '/will be expired/ { print $7 }')
30611         else
30612                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
30613         fi
30614
30615         echo $expired
30616 }
30617
30618 test_801a() {
30619         prep_801
30620
30621         echo "Start barrier_freeze at: $(date)"
30622         #define OBD_FAIL_BARRIER_DELAY          0x2202
30623         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
30624         # Do not reduce barrier time - See LU-11873
30625         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
30626
30627         sleep 2
30628         local b_status=$(barrier_stat)
30629         echo "Got barrier status at: $(date)"
30630         [ "$b_status" = "'freezing_p1'" ] ||
30631                 error "(1) unexpected barrier status $b_status"
30632
30633         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
30634         wait
30635         b_status=$(barrier_stat)
30636         [ "$b_status" = "'frozen'" ] ||
30637                 error "(2) unexpected barrier status $b_status"
30638
30639         local expired=$(barrier_expired)
30640         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
30641         sleep $((expired + 3))
30642
30643         b_status=$(barrier_stat)
30644         [ "$b_status" = "'expired'" ] ||
30645                 error "(3) unexpected barrier status $b_status"
30646
30647         # Do not reduce barrier time - See LU-11873
30648         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
30649                 error "(4) fail to freeze barrier"
30650
30651         b_status=$(barrier_stat)
30652         [ "$b_status" = "'frozen'" ] ||
30653                 error "(5) unexpected barrier status $b_status"
30654
30655         echo "Start barrier_thaw at: $(date)"
30656         #define OBD_FAIL_BARRIER_DELAY          0x2202
30657         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
30658         do_facet mgs $LCTL barrier_thaw $FSNAME &
30659
30660         sleep 2
30661         b_status=$(barrier_stat)
30662         echo "Got barrier status at: $(date)"
30663         [ "$b_status" = "'thawing'" ] ||
30664                 error "(6) unexpected barrier status $b_status"
30665
30666         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
30667         wait
30668         b_status=$(barrier_stat)
30669         [ "$b_status" = "'thawed'" ] ||
30670                 error "(7) unexpected barrier status $b_status"
30671
30672         #define OBD_FAIL_BARRIER_FAILURE        0x2203
30673         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
30674         do_facet mgs $LCTL barrier_freeze $FSNAME
30675
30676         b_status=$(barrier_stat)
30677         [ "$b_status" = "'failed'" ] ||
30678                 error "(8) unexpected barrier status $b_status"
30679
30680         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
30681         do_facet mgs $LCTL barrier_thaw $FSNAME
30682
30683         post_801
30684 }
30685 run_test 801a "write barrier user interfaces and stat machine"
30686
30687 test_801b() {
30688         prep_801
30689
30690         mkdir $DIR/$tdir || error "(1) fail to mkdir"
30691         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
30692         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
30693         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
30694         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
30695
30696         cancel_lru_locks mdc
30697
30698         # 180 seconds should be long enough
30699         do_facet mgs $LCTL barrier_freeze $FSNAME 180
30700
30701         local b_status=$(barrier_stat)
30702         [ "$b_status" = "'frozen'" ] ||
30703                 error "(6) unexpected barrier status $b_status"
30704
30705         mkdir $DIR/$tdir/d0/d10 &
30706         mkdir_pid=$!
30707
30708         touch $DIR/$tdir/d1/f13 &
30709         touch_pid=$!
30710
30711         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
30712         ln_pid=$!
30713
30714         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
30715         mv_pid=$!
30716
30717         rm -f $DIR/$tdir/d4/f12 &
30718         rm_pid=$!
30719
30720         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
30721
30722         # To guarantee taht the 'stat' is not blocked
30723         b_status=$(barrier_stat)
30724         [ "$b_status" = "'frozen'" ] ||
30725                 error "(8) unexpected barrier status $b_status"
30726
30727         # let above commands to run at background
30728         sleep 5
30729
30730         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
30731         ps -p $touch_pid || error "(10) touch should be blocked"
30732         ps -p $ln_pid || error "(11) link should be blocked"
30733         ps -p $mv_pid || error "(12) rename should be blocked"
30734         ps -p $rm_pid || error "(13) unlink should be blocked"
30735
30736         b_status=$(barrier_stat)
30737         [ "$b_status" = "'frozen'" ] ||
30738                 error "(14) unexpected barrier status $b_status"
30739
30740         do_facet mgs $LCTL barrier_thaw $FSNAME
30741         b_status=$(barrier_stat)
30742         [ "$b_status" = "'thawed'" ] ||
30743                 error "(15) unexpected barrier status $b_status"
30744
30745         wait $mkdir_pid || error "(16) mkdir should succeed"
30746         wait $touch_pid || error "(17) touch should succeed"
30747         wait $ln_pid || error "(18) link should succeed"
30748         wait $mv_pid || error "(19) rename should succeed"
30749         wait $rm_pid || error "(20) unlink should succeed"
30750
30751         post_801
30752 }
30753 run_test 801b "modification will be blocked by write barrier"
30754
30755 test_801c() {
30756         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30757
30758         prep_801
30759
30760         stop mds2 || error "(1) Fail to stop mds2"
30761
30762         do_facet mgs $LCTL barrier_freeze $FSNAME 30
30763
30764         local b_status=$(barrier_stat)
30765         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
30766                 do_facet mgs $LCTL barrier_thaw $FSNAME
30767                 error "(2) unexpected barrier status $b_status"
30768         }
30769
30770         do_facet mgs $LCTL barrier_rescan $FSNAME ||
30771                 error "(3) Fail to rescan barrier bitmap"
30772
30773         # Do not reduce barrier time - See LU-11873
30774         do_facet mgs $LCTL barrier_freeze $FSNAME 20
30775
30776         b_status=$(barrier_stat)
30777         [ "$b_status" = "'frozen'" ] ||
30778                 error "(4) unexpected barrier status $b_status"
30779
30780         do_facet mgs $LCTL barrier_thaw $FSNAME
30781         b_status=$(barrier_stat)
30782         [ "$b_status" = "'thawed'" ] ||
30783                 error "(5) unexpected barrier status $b_status"
30784
30785         local devname=$(mdsdevname 2)
30786
30787         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
30788
30789         do_facet mgs $LCTL barrier_rescan $FSNAME ||
30790                 error "(7) Fail to rescan barrier bitmap"
30791
30792         post_801
30793 }
30794 run_test 801c "rescan barrier bitmap"
30795
30796 test_802b() {
30797         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30798         remote_mds_nodsh && skip "remote MDS with nodsh"
30799
30800         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
30801                 skip "readonly option not available"
30802
30803         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
30804
30805         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
30806                 error "(2) Fail to copy"
30807
30808         # write back all cached data before setting MDT to readonly
30809         cancel_lru_locks
30810         sync_all_data
30811
30812         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
30813         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
30814
30815         echo "Modify should be refused"
30816         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
30817
30818         echo "Read should be allowed"
30819         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
30820                 error "(7) Read should succeed under ro mode"
30821
30822         # disable readonly
30823         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
30824 }
30825 run_test 802b "be able to set MDTs to readonly"
30826
30827 test_803a() {
30828         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30829         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
30830                 skip "MDS needs to be newer than 2.10.54"
30831
30832         mkdir_on_mdt0 $DIR/$tdir
30833         # Create some objects on all MDTs to trigger related logs objects
30834         for idx in $(seq $MDSCOUNT); do
30835                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
30836                         $DIR/$tdir/dir${idx} ||
30837                         error "Fail to create $DIR/$tdir/dir${idx}"
30838         done
30839
30840         wait_delete_completed # ensure old test cleanups are finished
30841         sleep 3
30842         echo "before create:"
30843         $LFS df -i $MOUNT
30844         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
30845
30846         for i in {1..10}; do
30847                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
30848                         error "Fail to create $DIR/$tdir/foo$i"
30849         done
30850
30851         # sync ZFS-on-MDS to refresh statfs data
30852         wait_zfs_commit mds1
30853         sleep 3
30854         echo "after create:"
30855         $LFS df -i $MOUNT
30856         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
30857
30858         # allow for an llog to be cleaned up during the test
30859         [ $after_used -ge $((before_used + 10 - 1)) ] ||
30860                 error "before ($before_used) + 10 > after ($after_used)"
30861
30862         for i in {1..10}; do
30863                 rm -rf $DIR/$tdir/foo$i ||
30864                         error "Fail to remove $DIR/$tdir/foo$i"
30865         done
30866
30867         # sync ZFS-on-MDS to refresh statfs data
30868         wait_zfs_commit mds1
30869         wait_delete_completed
30870         sleep 3 # avoid MDT return cached statfs
30871         echo "after unlink:"
30872         $LFS df -i $MOUNT
30873         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
30874
30875         # allow for an llog to be created during the test
30876         [ $after_used -le $((before_used + 1)) ] ||
30877                 error "after ($after_used) > before ($before_used) + 1"
30878 }
30879 run_test 803a "verify agent object for remote object"
30880
30881 test_803b() {
30882         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30883         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
30884                 skip "MDS needs to be newer than 2.13.56"
30885         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30886
30887         for i in $(seq 0 $((MDSCOUNT - 1))); do
30888                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
30889         done
30890
30891         local before=0
30892         local after=0
30893
30894         local tmp
30895
30896         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
30897         for i in $(seq 0 $((MDSCOUNT - 1))); do
30898                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
30899                         awk '/getattr/ { print $2 }')
30900                 before=$((before + tmp))
30901         done
30902         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
30903         for i in $(seq 0 $((MDSCOUNT - 1))); do
30904                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
30905                         awk '/getattr/ { print $2 }')
30906                 after=$((after + tmp))
30907         done
30908
30909         [ $before -eq $after ] || error "getattr count $before != $after"
30910 }
30911 run_test 803b "remote object can getattr from cache"
30912
30913 test_804() {
30914         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30915         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
30916                 skip "MDS needs to be newer than 2.10.54"
30917         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
30918
30919         mkdir -p $DIR/$tdir
30920         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
30921                 error "Fail to create $DIR/$tdir/dir0"
30922
30923         local fid=$($LFS path2fid $DIR/$tdir/dir0)
30924         local dev=$(mdsdevname 2)
30925
30926         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30927                 grep ${fid} || error "NOT found agent entry for dir0"
30928
30929         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
30930                 error "Fail to create $DIR/$tdir/dir1"
30931
30932         touch $DIR/$tdir/dir1/foo0 ||
30933                 error "Fail to create $DIR/$tdir/dir1/foo0"
30934         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
30935         local rc=0
30936
30937         for idx in $(seq $MDSCOUNT); do
30938                 dev=$(mdsdevname $idx)
30939                 do_facet mds${idx} \
30940                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30941                         grep ${fid} && rc=$idx
30942         done
30943
30944         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
30945                 error "Fail to rename foo0 to foo1"
30946         if [ $rc -eq 0 ]; then
30947                 for idx in $(seq $MDSCOUNT); do
30948                         dev=$(mdsdevname $idx)
30949                         do_facet mds${idx} \
30950                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30951                         grep ${fid} && rc=$idx
30952                 done
30953         fi
30954
30955         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
30956                 error "Fail to rename foo1 to foo2"
30957         if [ $rc -eq 0 ]; then
30958                 for idx in $(seq $MDSCOUNT); do
30959                         dev=$(mdsdevname $idx)
30960                         do_facet mds${idx} \
30961                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30962                         grep ${fid} && rc=$idx
30963                 done
30964         fi
30965
30966         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
30967
30968         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
30969                 error "Fail to link to $DIR/$tdir/dir1/foo2"
30970         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
30971                 error "Fail to rename foo2 to foo0"
30972         unlink $DIR/$tdir/dir1/foo0 ||
30973                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
30974         rm -rf $DIR/$tdir/dir0 ||
30975                 error "Fail to rm $DIR/$tdir/dir0"
30976
30977         for idx in $(seq $MDSCOUNT); do
30978                 rc=0
30979
30980                 stop mds${idx}
30981                 dev=$(mdsdevname $idx)
30982                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
30983                         rc=$?
30984                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
30985                         error "mount mds$idx failed"
30986                 df $MOUNT > /dev/null 2>&1
30987
30988                 # e2fsck should not return error
30989                 [ $rc -eq 0 ] ||
30990                         error "e2fsck detected error on MDT${idx}: rc=$rc"
30991         done
30992 }
30993 run_test 804 "verify agent entry for remote entry"
30994
30995 cleanup_805() {
30996         do_facet $SINGLEMDS zfs set quota=$old $fsset
30997         unlinkmany $DIR/$tdir/f- 1000000
30998         trap 0
30999 }
31000
31001 test_805() {
31002         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
31003         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
31004         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
31005                 skip "netfree not implemented before 0.7"
31006         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
31007                 skip "Need MDS version at least 2.10.57"
31008
31009         local fsset
31010         local freekb
31011         local usedkb
31012         local old
31013         local quota
31014         local pref="osd-zfs.$FSNAME-MDT0000."
31015
31016         # limit available space on MDS dataset to meet nospace issue
31017         # quickly. then ZFS 0.7.2 can use reserved space if asked
31018         # properly (using netfree flag in osd_declare_destroy()
31019         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
31020         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
31021                 gawk '{print $3}')
31022         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
31023         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
31024         let "usedkb=usedkb-freekb"
31025         let "freekb=freekb/2"
31026         if let "freekb > 5000"; then
31027                 let "freekb=5000"
31028         fi
31029         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
31030         trap cleanup_805 EXIT
31031         mkdir_on_mdt0 $DIR/$tdir
31032         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
31033                 error "Can't set PFL layout"
31034         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
31035         rm -rf $DIR/$tdir || error "not able to remove"
31036         do_facet $SINGLEMDS zfs set quota=$old $fsset
31037         trap 0
31038 }
31039 run_test 805 "ZFS can remove from full fs"
31040
31041 # Size-on-MDS test
31042 check_lsom_data()
31043 {
31044         local file=$1
31045         local expect=$(stat -c %s $file)
31046
31047         check_lsom_size $1 $expect
31048
31049         local blocks=$($LFS getsom -b $file)
31050         expect=$(stat -c %b $file)
31051         [[ $blocks == $expect ]] ||
31052                 error "$file expected blocks: $expect, got: $blocks"
31053 }
31054
31055 check_lsom_size()
31056 {
31057         local size
31058         local expect=$2
31059
31060         cancel_lru_locks mdc
31061
31062         size=$($LFS getsom -s $1)
31063         [[ $size == $expect ]] ||
31064                 error "$file expected size: $expect, got: $size"
31065 }
31066
31067 test_806() {
31068         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
31069                 skip "Need MDS version at least 2.11.52"
31070
31071         local bs=1048576
31072
31073         $LFS setstripe -c-1 $DIR/$tfile || error "setstripe $tfile failed"
31074
31075         disable_opencache
31076         stack_trap "restore_opencache"
31077
31078         # single-threaded write
31079         echo "Test SOM for single-threaded write"
31080         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
31081                 error "write $tfile failed"
31082         check_lsom_size $DIR/$tfile $bs
31083
31084         local num=32
31085         local size=$(($num * $bs))
31086         local offset=0
31087         local i
31088
31089         echo "Test SOM for single client multi-threaded($num) write"
31090         $TRUNCATE $DIR/$tfile 0
31091         for ((i = 0; i < $num; i++)); do
31092                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31093                 local pids[$i]=$!
31094                 offset=$((offset + $bs))
31095         done
31096         for (( i=0; i < $num; i++ )); do
31097                 wait ${pids[$i]}
31098         done
31099         check_lsom_size $DIR/$tfile $size
31100
31101         $TRUNCATE $DIR/$tfile 0
31102         for ((i = 0; i < $num; i++)); do
31103                 offset=$((offset - $bs))
31104                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31105                 local pids[$i]=$!
31106         done
31107         for (( i=0; i < $num; i++ )); do
31108                 wait ${pids[$i]}
31109         done
31110         check_lsom_size $DIR/$tfile $size
31111
31112         # multi-client writes
31113         num=$(get_node_count ${CLIENTS//,/ })
31114         size=$(($num * $bs))
31115         offset=0
31116         i=0
31117
31118         echo "Test SOM for multi-client ($num) writes"
31119         $TRUNCATE $DIR/$tfile 0
31120         for client in ${CLIENTS//,/ }; do
31121                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31122                 local pids[$i]=$!
31123                 i=$((i + 1))
31124                 offset=$((offset + $bs))
31125         done
31126         for (( i=0; i < $num; i++ )); do
31127                 wait ${pids[$i]}
31128         done
31129         check_lsom_size $DIR/$tfile $offset
31130
31131         i=0
31132         $TRUNCATE $DIR/$tfile 0
31133         for client in ${CLIENTS//,/ }; do
31134                 offset=$((offset - $bs))
31135                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31136                 local pids[$i]=$!
31137                 i=$((i + 1))
31138         done
31139         for (( i=0; i < $num; i++ )); do
31140                 wait ${pids[$i]}
31141         done
31142         check_lsom_size $DIR/$tfile $size
31143
31144         # verify SOM blocks count
31145         echo "Verify SOM block count"
31146         $TRUNCATE $DIR/$tfile 0
31147         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs))YSc ||
31148                 error "failed to write file $tfile with fdatasync and fstat"
31149         check_lsom_data $DIR/$tfile
31150
31151         $TRUNCATE $DIR/$tfile 0
31152         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs * 2))Yc ||
31153                 error "failed to write file $tfile with fdatasync"
31154         check_lsom_data $DIR/$tfile
31155
31156         $TRUNCATE $DIR/$tfile 0
31157         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:O_SYNC:w$((bs * 3))c ||
31158                 error "failed to write file $tfile with sync IO"
31159         check_lsom_data $DIR/$tfile
31160
31161         # verify truncate
31162         echo "Test SOM for truncate"
31163         # use ftruncate to sync blocks on close request
31164         $MULTIOP $DIR/$tfile oO_WRONLY:T16384c
31165         check_lsom_size $DIR/$tfile 16384
31166         check_lsom_data $DIR/$tfile
31167
31168         $TRUNCATE $DIR/$tfile 1234
31169         check_lsom_size $DIR/$tfile 1234
31170         # sync blocks on the MDT
31171         $MULTIOP $DIR/$tfile oc
31172         check_lsom_data $DIR/$tfile
31173 }
31174 run_test 806 "Verify Lazy Size on MDS"
31175
31176 test_807() {
31177         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
31178         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
31179                 skip "Need MDS version at least 2.11.52"
31180
31181         # Registration step
31182         changelog_register || error "changelog_register failed"
31183         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
31184         changelog_users $SINGLEMDS | grep -q $cl_user ||
31185                 error "User $cl_user not found in changelog_users"
31186
31187         rm -rf $DIR/$tdir || error "rm $tdir failed"
31188         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
31189         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
31190         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
31191         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
31192                 error "truncate $tdir/trunc failed"
31193
31194         local bs=1048576
31195         echo "Test SOM for single-threaded write with fsync"
31196         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
31197                 error "write $tfile failed"
31198         sync;sync;sync
31199
31200         # multi-client wirtes
31201         local num=$(get_node_count ${CLIENTS//,/ })
31202         local offset=0
31203         local i=0
31204
31205         echo "Test SOM for multi-client ($num) writes"
31206         touch $DIR/$tfile || error "touch $tfile failed"
31207         $TRUNCATE $DIR/$tfile 0
31208         for client in ${CLIENTS//,/ }; do
31209                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31210                 local pids[$i]=$!
31211                 i=$((i + 1))
31212                 offset=$((offset + $bs))
31213         done
31214         for (( i=0; i < $num; i++ )); do
31215                 wait ${pids[$i]}
31216         done
31217
31218         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
31219         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
31220         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
31221         check_lsom_data $DIR/$tdir/trunc
31222         check_lsom_data $DIR/$tdir/single_dd
31223         check_lsom_data $DIR/$tfile
31224
31225         rm -rf $DIR/$tdir
31226         # Deregistration step
31227         changelog_deregister || error "changelog_deregister failed"
31228 }
31229 run_test 807 "verify LSOM syncing tool"
31230
31231 check_som_nologged()
31232 {
31233         local lines=$($LFS changelog $FSNAME-MDT0000 |
31234                 grep 'x=trusted.som' | wc -l)
31235         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
31236 }
31237
31238 test_808() {
31239         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
31240                 skip "Need MDS version at least 2.11.55"
31241
31242         # Registration step
31243         changelog_register || error "changelog_register failed"
31244
31245         touch $DIR/$tfile || error "touch $tfile failed"
31246         check_som_nologged
31247
31248         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
31249                 error "write $tfile failed"
31250         check_som_nologged
31251
31252         $TRUNCATE $DIR/$tfile 1234
31253         check_som_nologged
31254
31255         $TRUNCATE $DIR/$tfile 1048576
31256         check_som_nologged
31257
31258         # Deregistration step
31259         changelog_deregister || error "changelog_deregister failed"
31260 }
31261 run_test 808 "Check trusted.som xattr not logged in Changelogs"
31262
31263 check_som_nodata()
31264 {
31265         $LFS getsom $1
31266         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
31267 }
31268
31269 test_809() {
31270         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
31271                 skip "Need MDS version at least 2.11.56"
31272
31273         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
31274                 error "failed to create DoM-only file $DIR/$tfile"
31275         touch $DIR/$tfile || error "touch $tfile failed"
31276         check_som_nodata $DIR/$tfile
31277
31278         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
31279                 error "write $tfile failed"
31280         check_som_nodata $DIR/$tfile
31281
31282         $TRUNCATE $DIR/$tfile 1234
31283         check_som_nodata $DIR/$tfile
31284
31285         $TRUNCATE $DIR/$tfile 4097
31286         check_som_nodata $DIR/$file
31287 }
31288 run_test 809 "Verify no SOM xattr store for DoM-only files"
31289
31290 test_810() {
31291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31292         $GSS && skip_env "could not run with gss"
31293         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
31294                 skip "OST < 2.12.58 doesn't align checksum"
31295
31296         set_checksums 1
31297         stack_trap "set_checksums $ORIG_CSUM" EXIT
31298         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
31299
31300         local csum
31301         local before
31302         local after
31303         for csum in $CKSUM_TYPES; do
31304                 #define OBD_FAIL_OSC_NO_GRANT   0x411
31305                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
31306                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
31307                         eval set -- $i
31308                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
31309                         before=$(md5sum $DIR/$tfile)
31310                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
31311                         after=$(md5sum $DIR/$tfile)
31312                         [ "$before" == "$after" ] ||
31313                                 error "$csum: $before != $after bs=$1 seek=$2"
31314                 done
31315         done
31316 }
31317 run_test 810 "partial page writes on ZFS (LU-11663)"
31318
31319 test_812a() {
31320         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
31321                 skip "OST < 2.12.51 doesn't support this fail_loc"
31322
31323         $LFS setstripe -c 1 -i 0 $DIR/$tfile
31324         # ensure ost1 is connected
31325         stat $DIR/$tfile >/dev/null || error "can't stat"
31326         wait_osc_import_state client ost1 FULL
31327         # no locks, no reqs to let the connection idle
31328         cancel_lru_locks osc
31329
31330         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
31331 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
31332         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
31333         wait_osc_import_state client ost1 CONNECTING
31334         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
31335
31336         stat $DIR/$tfile >/dev/null || error "can't stat file"
31337 }
31338 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
31339
31340 test_812b() { # LU-12378
31341         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
31342                 skip "OST < 2.12.51 doesn't support this fail_loc"
31343
31344         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
31345         # ensure ost1 is connected
31346         stat $DIR/$tfile >/dev/null || error "can't stat"
31347         wait_osc_import_state client ost1 FULL
31348         # no locks, no reqs to let the connection idle
31349         cancel_lru_locks osc
31350
31351         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
31352 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
31353         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
31354         wait_osc_import_state client ost1 CONNECTING
31355         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
31356
31357         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
31358         wait_osc_import_state client ost1 IDLE
31359 }
31360 run_test 812b "do not drop no resend request for idle connect"
31361
31362 test_812c() {
31363         local old
31364
31365         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
31366
31367         $LFS setstripe -c 1 -o 0 $DIR/$tfile
31368         $LFS getstripe $DIR/$tfile
31369         $LCTL set_param osc.*.idle_timeout=10
31370         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
31371         # ensure ost1 is connected
31372         stat $DIR/$tfile >/dev/null || error "can't stat"
31373         wait_osc_import_state client ost1 FULL
31374         # no locks, no reqs to let the connection idle
31375         cancel_lru_locks osc
31376
31377 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
31378         $LCTL set_param fail_loc=0x80000533
31379         sleep 15
31380         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
31381 }
31382 run_test 812c "idle import vs lock enqueue race"
31383
31384 test_813() {
31385         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
31386         [ -z "$file_heat_sav" ] && skip "no file heat support"
31387
31388         local readsample
31389         local writesample
31390         local readbyte
31391         local writebyte
31392         local readsample1
31393         local writesample1
31394         local readbyte1
31395         local writebyte1
31396
31397         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
31398         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
31399
31400         $LCTL set_param -n llite.*.file_heat=1
31401         echo "Turn on file heat"
31402         echo "Period second: $period_second, Decay percentage: $decay_pct"
31403
31404         echo "QQQQ" > $DIR/$tfile
31405         echo "QQQQ" > $DIR/$tfile
31406         echo "QQQQ" > $DIR/$tfile
31407         cat $DIR/$tfile > /dev/null
31408         cat $DIR/$tfile > /dev/null
31409         cat $DIR/$tfile > /dev/null
31410         cat $DIR/$tfile > /dev/null
31411
31412         local out=$($LFS heat_get $DIR/$tfile)
31413
31414         $LFS heat_get $DIR/$tfile
31415         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31416         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31417         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31418         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31419
31420         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
31421         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
31422         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
31423         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
31424
31425         sleep $((period_second + 3))
31426         echo "Sleep $((period_second + 3)) seconds..."
31427         # The recursion formula to calculate the heat of the file f is as
31428         # follow:
31429         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
31430         # Where Hi is the heat value in the period between time points i*I and
31431         # (i+1)*I; Ci is the access count in the period; the symbol P refers
31432         # to the weight of Ci.
31433         out=$($LFS heat_get $DIR/$tfile)
31434         $LFS heat_get $DIR/$tfile
31435         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31436         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31437         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31438         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31439
31440         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
31441                 error "read sample ($readsample) is wrong"
31442         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
31443                 error "write sample ($writesample) is wrong"
31444         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
31445                 error "read bytes ($readbyte) is wrong"
31446         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
31447                 error "write bytes ($writebyte) is wrong"
31448
31449         echo "QQQQ" > $DIR/$tfile
31450         echo "QQQQ" > $DIR/$tfile
31451         echo "QQQQ" > $DIR/$tfile
31452         cat $DIR/$tfile > /dev/null
31453         cat $DIR/$tfile > /dev/null
31454         cat $DIR/$tfile > /dev/null
31455         cat $DIR/$tfile > /dev/null
31456
31457         sleep $((period_second + 3))
31458         echo "Sleep $((period_second + 3)) seconds..."
31459
31460         out=$($LFS heat_get $DIR/$tfile)
31461         $LFS heat_get $DIR/$tfile
31462         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31463         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31464         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31465         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31466
31467         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
31468                 4 * $decay_pct) / 100") -eq 1 ] ||
31469                 error "read sample ($readsample1) is wrong"
31470         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
31471                 3 * $decay_pct) / 100") -eq 1 ] ||
31472                 error "write sample ($writesample1) is wrong"
31473         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
31474                 20 * $decay_pct) / 100") -eq 1 ] ||
31475                 error "read bytes ($readbyte1) is wrong"
31476         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
31477                 15 * $decay_pct) / 100") -eq 1 ] ||
31478                 error "write bytes ($writebyte1) is wrong"
31479
31480         echo "Turn off file heat for the file $DIR/$tfile"
31481         $LFS heat_set -o $DIR/$tfile
31482
31483         echo "QQQQ" > $DIR/$tfile
31484         echo "QQQQ" > $DIR/$tfile
31485         echo "QQQQ" > $DIR/$tfile
31486         cat $DIR/$tfile > /dev/null
31487         cat $DIR/$tfile > /dev/null
31488         cat $DIR/$tfile > /dev/null
31489         cat $DIR/$tfile > /dev/null
31490
31491         out=$($LFS heat_get $DIR/$tfile)
31492         $LFS heat_get $DIR/$tfile
31493         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31494         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31495         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31496         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31497
31498         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
31499         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
31500         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
31501         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
31502
31503         echo "Trun on file heat for the file $DIR/$tfile"
31504         $LFS heat_set -O $DIR/$tfile
31505
31506         echo "QQQQ" > $DIR/$tfile
31507         echo "QQQQ" > $DIR/$tfile
31508         echo "QQQQ" > $DIR/$tfile
31509         cat $DIR/$tfile > /dev/null
31510         cat $DIR/$tfile > /dev/null
31511         cat $DIR/$tfile > /dev/null
31512         cat $DIR/$tfile > /dev/null
31513
31514         out=$($LFS heat_get $DIR/$tfile)
31515         $LFS heat_get $DIR/$tfile
31516         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31517         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31518         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31519         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31520
31521         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
31522         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
31523         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
31524         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
31525
31526         $LFS heat_set -c $DIR/$tfile
31527         $LCTL set_param -n llite.*.file_heat=0
31528         echo "Turn off file heat support for the Lustre filesystem"
31529
31530         echo "QQQQ" > $DIR/$tfile
31531         echo "QQQQ" > $DIR/$tfile
31532         echo "QQQQ" > $DIR/$tfile
31533         cat $DIR/$tfile > /dev/null
31534         cat $DIR/$tfile > /dev/null
31535         cat $DIR/$tfile > /dev/null
31536         cat $DIR/$tfile > /dev/null
31537
31538         out=$($LFS heat_get $DIR/$tfile)
31539         $LFS heat_get $DIR/$tfile
31540         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31541         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31542         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31543         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31544
31545         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
31546         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
31547         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
31548         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
31549
31550         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
31551         rm -f $DIR/$tfile
31552 }
31553 run_test 813 "File heat verfication"
31554
31555 test_814()
31556 {
31557         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
31558         echo -n y >> $DIR/$tfile
31559         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
31560         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
31561 }
31562 run_test 814 "sparse cp works as expected (LU-12361)"
31563
31564 test_815()
31565 {
31566         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
31567         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
31568 }
31569 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
31570
31571 test_816() {
31572         local ost1_imp=$(get_osc_import_name client ost1)
31573         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
31574                          cut -d'.' -f2)
31575
31576         $LFS setstripe -c 1 -i 0 $DIR/$tfile
31577         # ensure ost1 is connected
31578
31579         stat $DIR/$tfile >/dev/null || error "can't stat"
31580         wait_osc_import_state client ost1 FULL
31581         # no locks, no reqs to let the connection idle
31582         cancel_lru_locks osc
31583         lru_resize_disable osc
31584         local before
31585         local now
31586         before=$($LCTL get_param -n \
31587                  ldlm.namespaces.$imp_name.lru_size)
31588
31589         wait_osc_import_state client ost1 IDLE
31590         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
31591         now=$($LCTL get_param -n \
31592               ldlm.namespaces.$imp_name.lru_size)
31593         [ $before == $now ] || error "lru_size changed $before != $now"
31594 }
31595 run_test 816 "do not reset lru_resize on idle reconnect"
31596
31597 cleanup_817() {
31598         umount $tmpdir
31599         exportfs -u localhost:$DIR/nfsexp
31600         rm -rf $DIR/nfsexp
31601 }
31602
31603 test_817() {
31604         systemctl restart nfs-server.service || skip "failed to restart nfsd"
31605
31606         mkdir -p $DIR/nfsexp
31607         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
31608                 error "failed to export nfs"
31609
31610         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
31611         stack_trap cleanup_817 EXIT
31612
31613         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
31614                 error "failed to mount nfs to $tmpdir"
31615
31616         cp /bin/true $tmpdir
31617         $DIR/nfsexp/true || error "failed to execute 'true' command"
31618 }
31619 run_test 817 "nfsd won't cache write lock for exec file"
31620
31621 test_818() {
31622         test_mkdir -i0 -c1 $DIR/$tdir
31623         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
31624         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
31625         stop $SINGLEMDS
31626
31627         # restore osp-syn threads
31628         stack_trap "fail $SINGLEMDS"
31629
31630         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
31631         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
31632         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
31633                 error "start $SINGLEMDS failed"
31634         rm -rf $DIR/$tdir
31635
31636         local testid=$(echo $TESTNAME | tr '_' ' ')
31637
31638         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
31639                 grep "run LFSCK" || error "run LFSCK is not suggested"
31640 }
31641 run_test 818 "unlink with failed llog"
31642
31643 test_819a() {
31644         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
31645         cancel_lru_locks osc
31646         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
31647         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
31648         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
31649         rm -f $TDIR/$tfile
31650 }
31651 run_test 819a "too big niobuf in read"
31652
31653 test_819b() {
31654         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
31655         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
31656         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
31657         cancel_lru_locks osc
31658         sleep 1
31659         rm -f $TDIR/$tfile
31660 }
31661 run_test 819b "too big niobuf in write"
31662
31663
31664 function test_820_start_ost() {
31665         sleep 5
31666
31667         for num in $(seq $OSTCOUNT); do
31668                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
31669         done
31670 }
31671
31672 test_820() {
31673         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
31674
31675         mkdir $DIR/$tdir
31676         umount_client $MOUNT || error "umount failed"
31677         for num in $(seq $OSTCOUNT); do
31678                 stop ost$num
31679         done
31680
31681         # mount client with no active OSTs
31682         # so that the client can't initialize max LOV EA size
31683         # from OSC notifications
31684         mount_client $MOUNT || error "mount failed"
31685         # delay OST starting to keep this 0 max EA size for a while
31686         test_820_start_ost &
31687
31688         # create a directory on MDS2
31689         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
31690                 error "Failed to create directory"
31691         # open intent should update default EA size
31692         # see mdc_update_max_ea_from_body()
31693         # notice this is the very first RPC to MDS2
31694         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
31695         ret=$?
31696         echo $out
31697         # With SSK, this situation can lead to -EPERM being returned.
31698         # In that case, simply retry.
31699         if [ $ret -ne 0 ] && $SHARED_KEY; then
31700                 if echo "$out" | grep -q "not permitted"; then
31701                         cp /etc/services $DIR/$tdir/mds2
31702                         ret=$?
31703                 fi
31704         fi
31705         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
31706 }
31707 run_test 820 "update max EA from open intent"
31708
31709 test_823() {
31710         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
31711         local OST_MAX_PRECREATE=20000
31712
31713         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
31714                 skip "Need MDS version at least 2.14.56"
31715
31716         save_lustre_params mds1 \
31717                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
31718         do_facet $SINGLEMDS "$LCTL set_param -n \
31719                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
31720         do_facet $SINGLEMDS "$LCTL set_param -n \
31721                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
31722
31723         stack_trap "restore_lustre_params < $p; rm $p"
31724
31725         do_facet $SINGLEMDS "$LCTL set_param -n \
31726                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
31727
31728         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
31729                       osp.$FSNAME-OST0000*MDT0000.create_count")
31730         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
31731                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
31732         local expect_count=$(((($max/2)/256) * 256))
31733
31734         log "setting create_count to 100200:"
31735         log " -result- count: $count with max: $max, expecting: $expect_count"
31736
31737         [[ $count -eq expect_count ]] ||
31738                 error "Create count not set to max precreate."
31739 }
31740 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
31741
31742 test_831() {
31743         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
31744                 skip "Need MDS version 2.14.56"
31745
31746         local sync_changes=$(do_facet $SINGLEMDS \
31747                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
31748
31749         [ "$sync_changes" -gt 100 ] &&
31750                 skip "Sync changes $sync_changes > 100 already"
31751
31752         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
31753
31754         $LFS mkdir -i 0 $DIR/$tdir
31755         $LFS setstripe -c 1 -i 0 $DIR/$tdir
31756
31757         save_lustre_params mds1 \
31758                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
31759         save_lustre_params mds1 \
31760                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
31761
31762         do_facet mds1 "$LCTL set_param -n \
31763                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
31764                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
31765         stack_trap "restore_lustre_params < $p" EXIT
31766
31767         createmany -o $DIR/$tdir/f- 1000
31768         unlinkmany $DIR/$tdir/f- 1000 &
31769         local UNLINK_PID=$!
31770
31771         while sleep 1; do
31772                 sync_changes=$(do_facet mds1 \
31773                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
31774                 # the check in the code is racy, fail the test
31775                 # if the value above the limit by 10.
31776                 [ $sync_changes -gt 110 ] && {
31777                         kill -2 $UNLINK_PID
31778                         wait
31779                         error "osp changes throttling failed, $sync_changes>110"
31780                 }
31781                 kill -0 $UNLINK_PID 2> /dev/null || break
31782         done
31783         wait
31784 }
31785 run_test 831 "throttling unlink/setattr queuing on OSP"
31786
31787 test_832() {
31788         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
31789         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
31790                 skip "Need MDS version 2.15.52+"
31791         is_rmentry_supported || skip "rm_entry not supported"
31792
31793         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
31794         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
31795         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
31796                 error "mkdir remote_dir failed"
31797         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
31798                 error "mkdir striped_dir failed"
31799         touch $DIR/$tdir/file || error "touch file failed"
31800         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
31801         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
31802 }
31803 run_test 832 "lfs rm_entry"
31804
31805 test_833() {
31806         local file=$DIR/$tfile
31807
31808         stack_trap "rm -f $file" EXIT
31809         dd if=/dev/zero of=$file bs=1M count=50 || error "Write $file failed"
31810
31811         local wpid
31812         local rpid
31813         local rpid2
31814
31815         # Buffered I/O write
31816         (
31817                 while [ ! -e $DIR/sanity.833.lck ]; do
31818                         dd if=/dev/zero of=$file bs=1M count=50 conv=notrunc ||
31819                                 error "failed to write $file"
31820                         sleep 0.$((RANDOM % 4 + 1))
31821                 done
31822         )&
31823         wpid=$!
31824
31825         # Buffered I/O read
31826         (
31827                 while [ ! -e $DIR/sanity.833.lck ]; do
31828                         dd if=$file of=/dev/null bs=1M count=50 ||
31829                                 error "failed to read $file"
31830                         sleep 0.$((RANDOM % 4 + 1))
31831                 done
31832         )&
31833         rpid=$!
31834
31835         # Direct I/O read
31836         (
31837                 while [ ! -e $DIR/sanity.833.lck ]; do
31838                         dd if=$file of=/dev/null bs=1M count=50 iflag=direct ||
31839                                 error "failed to read $file in direct I/O mode"
31840                         sleep 0.$((RANDOM % 4 + 1))
31841                 done
31842         )&
31843         rpid2=$!
31844
31845         sleep 30
31846         touch $DIR/sanity.833.lck
31847         wait $wpid || error "$?: buffered write failed"
31848         wait $rpid || error "$?: buffered read failed"
31849         wait $rpid2 || error "$?: direct read failed"
31850 }
31851 run_test 833 "Mixed buffered/direct read and write should not return -EIO"
31852
31853 test_850() {
31854         local dir=$DIR/$tdir
31855         local file=$dir/$tfile
31856         local statsfile=$dir/all_job_stats.txt
31857
31858         test_mkdir -p $dir || error "failed to create dir $dir"
31859         echo "abcdefg" > $file || error "failed to create file $file"
31860
31861         # read job_stats in the living system
31862         lljobstat -n 1 ||
31863                 error "failed to run lljobstat on living system"
31864
31865         $LCTL get_param *.*.job_stats > $statsfile
31866         lljobstat --statsfile=$statsfile ||
31867                 error "failed to run lljobstat on file $statsfile"
31868 }
31869 run_test 850 "lljobstat can parse living and aggregated job_stats"
31870
31871 #
31872 # tests that do cleanup/setup should be run at the end
31873 #
31874
31875 test_900() {
31876         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31877         local ls
31878
31879         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
31880         $LCTL set_param fail_loc=0x903
31881
31882         cancel_lru_locks MGC
31883
31884         FAIL_ON_ERROR=true cleanup
31885         FAIL_ON_ERROR=true setup
31886 }
31887 run_test 900 "umount should not race with any mgc requeue thread"
31888
31889 # LUS-6253/LU-11185
31890 test_901() {
31891         local old
31892         local count
31893         local oldc
31894         local newc
31895         local olds
31896         local news
31897         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31898
31899         # some get_param have a bug to handle dot in param name
31900         cancel_lru_locks MGC
31901         old=$(mount -t lustre | wc -l)
31902         # 1 config+sptlrpc
31903         # 2 params
31904         # 3 nodemap
31905         # 4 IR
31906         old=$((old * 4))
31907         oldc=0
31908         count=0
31909         while [ $old -ne $oldc ]; do
31910                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
31911                 sleep 1
31912                 ((count++))
31913                 if [ $count -ge $TIMEOUT ]; then
31914                         error "too large timeout"
31915                 fi
31916         done
31917         umount_client $MOUNT || error "umount failed"
31918         mount_client $MOUNT || error "mount failed"
31919         cancel_lru_locks MGC
31920         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
31921
31922         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
31923
31924         return 0
31925 }
31926 run_test 901 "don't leak a mgc lock on client umount"
31927
31928 # LU-13377
31929 test_902() {
31930         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
31931                 skip "client does not have LU-13377 fix"
31932         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
31933         $LCTL set_param fail_loc=0x1415
31934         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
31935         cancel_lru_locks osc
31936         rm -f $DIR/$tfile
31937 }
31938 run_test 902 "test short write doesn't hang lustre"
31939
31940 # LU-14711
31941 test_903() {
31942         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
31943         echo "blah" > $DIR/${tfile}-2
31944         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
31945         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
31946         $LCTL set_param fail_loc=0x417 fail_val=20
31947
31948         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
31949         sleep 1 # To start the destroy
31950         wait_destroy_complete 150 || error "Destroy taking too long"
31951         cat $DIR/$tfile > /dev/null || error "Evicted"
31952 }
31953 run_test 903 "Test long page discard does not cause evictions"
31954
31955 test_904() {
31956         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
31957         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
31958                 grep -q project || skip "skip project quota not supported"
31959
31960         local testfile="$DIR/$tdir/$tfile"
31961         local xattr="trusted.projid"
31962         local projid
31963         local mdts=$(comma_list $(mdts_nodes))
31964         local saved=$(do_facet mds1 $LCTL get_param -n \
31965                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
31966
31967         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
31968         stack_trap "do_nodes $mdts $LCTL set_param \
31969                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
31970
31971         mkdir -p $DIR/$tdir
31972         touch $testfile
31973         #hide projid xattr on server
31974         $LFS project -p 1 $testfile ||
31975                 error "set $testfile project id failed"
31976         getfattr -m - $testfile | grep $xattr &&
31977                 error "do not show trusted.projid when disabled on server"
31978         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
31979         #should be hidden when projid is 0
31980         $LFS project -p 0 $testfile ||
31981                 error "set $testfile project id failed"
31982         getfattr -m - $testfile | grep $xattr &&
31983                 error "do not show trusted.projid with project ID 0"
31984
31985         #still can getxattr explicitly
31986         projid=$(getfattr -n $xattr $testfile |
31987                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
31988         [ $projid == "0" ] ||
31989                 error "projid expected 0 not $projid"
31990
31991         #set the projid via setxattr
31992         setfattr -n $xattr -v "1000" $testfile ||
31993                 error "setattr failed with $?"
31994         projid=($($LFS project $testfile))
31995         [ ${projid[0]} == "1000" ] ||
31996                 error "projid expected 1000 not $projid"
31997
31998         #check the new projid via getxattr
31999         $LFS project -p 1001 $testfile ||
32000                 error "set $testfile project id failed"
32001         getfattr -m - $testfile | grep $xattr ||
32002                 error "should show trusted.projid when project ID != 0"
32003         projid=$(getfattr -n $xattr $testfile |
32004                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
32005         [ $projid == "1001" ] ||
32006                 error "projid expected 1001 not $projid"
32007
32008         #try to set invalid projid
32009         setfattr -n $xattr -v "4294967295" $testfile &&
32010                 error "set invalid projid should fail"
32011
32012         #remove the xattr means setting projid to 0
32013         setfattr -x $xattr $testfile ||
32014                 error "setfattr failed with $?"
32015         projid=($($LFS project $testfile))
32016         [ ${projid[0]} == "0" ] ||
32017                 error "projid expected 0 not $projid"
32018
32019         #should be hidden when parent has inherit flag and same projid
32020         $LFS project -srp 1002 $DIR/$tdir ||
32021                 error "set $tdir project id failed"
32022         getfattr -m - $testfile | grep $xattr &&
32023                 error "do not show trusted.projid with inherit flag"
32024
32025         #still can getxattr explicitly
32026         projid=$(getfattr -n $xattr $testfile |
32027                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
32028         [ $projid == "1002" ] ||
32029                 error "projid expected 1002 not $projid"
32030 }
32031 run_test 904 "virtual project ID xattr"
32032
32033 # LU-8582
32034 test_905() {
32035         (( $OST1_VERSION >= $(version_code 2.15.50.220) )) ||
32036                 skip "need OST version >= 2.15.50.220 for fail_loc"
32037
32038         remote_ost_nodsh && skip "remote OST with nodsh"
32039         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
32040
32041         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
32042
32043         #define OBD_FAIL_OST_OPCODE 0x253
32044         # OST_LADVISE = 21
32045         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
32046         $LFS ladvise -a willread $DIR/$tfile &&
32047                 error "unexpected success of ladvise with fault injection"
32048         $LFS ladvise -a willread $DIR/$tfile |&
32049                 grep -q "Operation not supported"
32050         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
32051 }
32052 run_test 905 "bad or new opcode should not stuck client"
32053
32054 test_906() {
32055         grep -q io_uring_setup /proc/kallsyms ||
32056                 skip "Client OS does not support io_uring I/O engine"
32057         io_uring_probe || skip "kernel does not support io_uring fully"
32058         which fio || skip_env "no fio installed"
32059         fio --enghelp | grep -q io_uring ||
32060                 skip_env "fio does not support io_uring I/O engine"
32061
32062         local file=$DIR/$tfile
32063         local ioengine="io_uring"
32064         local numjobs=2
32065         local size=50M
32066
32067         fio --name=seqwrite --ioengine=$ioengine        \
32068                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
32069                 --iodepth=64 --size=$size --filename=$file --rw=write ||
32070                 error "fio seqwrite $file failed"
32071
32072         fio --name=seqread --ioengine=$ioengine \
32073                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
32074                 --iodepth=64 --size=$size --filename=$file --rw=read ||
32075                 error "fio seqread $file failed"
32076
32077         rm -f $file || error "rm -f $file failed"
32078 }
32079 run_test 906 "Simple test for io_uring I/O engine via fio"
32080
32081 test_907() {
32082         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
32083
32084         # set stripe size to max rpc size
32085         $LFS setstripe -i 0 -c 2 -S $((max_pages * PAGE_SIZE)) $DIR/$tfile
32086         $LFS getstripe $DIR/$tfile
32087 #define OBD_FAIL_OST_EROFS               0x216
32088         do_facet ost1 "$LCTL set_param fail_val=3 fail_loc=0x80000216"
32089
32090         local bs=$((max_pages * PAGE_SIZE / 16))
32091
32092         # write full one stripe and one block
32093         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=17 || error "dd failed"
32094
32095         rm $DIR/$tfile || error "rm failed"
32096 }
32097 run_test 907 "write rpc error during unlink"
32098
32099
32100 complete_test $SECONDS
32101 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
32102 check_and_cleanup_lustre
32103 if [ "$I_MOUNTED" != "yes" ]; then
32104         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
32105 fi
32106 exit_status