Whamcloud - gitweb
LU-16752 test: improve sanity 413a/b reliability
[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 wait_end() {
13035         echo $*
13036         while :; do
13037                 [ -f $TMP/${tfile}_sTOP ] && return
13038                 sleep 1
13039         done
13040 }
13041
13042 test_105f() {
13043         flock_is_enabled || skip_env "mount w/o flock enabled"
13044
13045         local pmax=$(ulimit -u)
13046         local i=0
13047         touch $DIR/$tfile
13048         [ $pmax -gt 20 ] && pmax=20
13049         for((i=0; i <= $pmax; i++)) {
13050                 wait_end "R4000, 5000" | flocks_test 6 $DIR/$tfile &
13051         }
13052         for((i=0; i <= 10; i++)) {
13053                 local locks=$(do_facet $SINGLEMDS $LCTL get_param -n \
13054                         ldlm.namespaces.mdt-${FSNAME}-MDT0000*.lock_count)
13055                 [ $locks -ge $pmax ] && break
13056                 [ $i -eq 10 ] && error "The locks cannot be added after 10 secs"
13057                 sleep 1
13058         }
13059         touch $TMP/${tfile}_sTOP
13060         wait
13061         rm -r $DIR/$tfile $TMP/${tfile}_sTOP
13062 }
13063 run_test 105f "Enqueue same range flocks"
13064
13065 test_106() { #bug 10921
13066         test_mkdir $DIR/$tdir
13067         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
13068         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
13069 }
13070 run_test 106 "attempt exec of dir followed by chown of that dir"
13071
13072 test_107() {
13073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13074
13075         CDIR=`pwd`
13076         local file=core
13077
13078         cd $DIR
13079         rm -f $file
13080
13081         local save_pattern=$(sysctl -n kernel.core_pattern)
13082         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
13083         sysctl -w kernel.core_pattern=$file
13084         sysctl -w kernel.core_uses_pid=0
13085
13086         ulimit -c unlimited
13087         sleep 60 &
13088         SLEEPPID=$!
13089
13090         sleep 1
13091
13092         kill -s 11 $SLEEPPID
13093         wait $SLEEPPID
13094         if [ -e $file ]; then
13095                 size=`stat -c%s $file`
13096                 [ $size -eq 0 ] && error "Fail to create core file $file"
13097         else
13098                 error "Fail to create core file $file"
13099         fi
13100         rm -f $file
13101         sysctl -w kernel.core_pattern=$save_pattern
13102         sysctl -w kernel.core_uses_pid=$save_uses_pid
13103         cd $CDIR
13104 }
13105 run_test 107 "Coredump on SIG"
13106
13107 test_110() {
13108         test_mkdir $DIR/$tdir
13109         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
13110         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
13111                 error "mkdir with 256 char should fail, but did not"
13112         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
13113                 error "create with 255 char failed"
13114         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
13115                 error "create with 256 char should fail, but did not"
13116
13117         ls -l $DIR/$tdir
13118         rm -rf $DIR/$tdir
13119 }
13120 run_test 110 "filename length checking"
13121
13122 test_116a() { # was previously test_116()
13123         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13124         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13125         remote_mds_nodsh && skip "remote MDS with nodsh"
13126
13127         echo -n "Free space priority "
13128         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
13129                 head -n1
13130         declare -a AVAIL
13131         free_min_max
13132
13133         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
13134         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
13135         stack_trap simple_cleanup_common
13136
13137         # Check if we need to generate uneven OSTs
13138         test_mkdir -p $DIR/$tdir/OST${MINI}
13139         local FILL=$((MINV / 4))
13140         local DIFF=$((MAXV - MINV))
13141         local DIFF2=$((DIFF * 100 / MINV))
13142
13143         local threshold=$(do_facet $SINGLEMDS \
13144                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
13145         threshold=${threshold%%%}
13146         echo -n "Check for uneven OSTs: "
13147         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
13148
13149         if [[ $DIFF2 -gt $threshold ]]; then
13150                 echo "ok"
13151                 echo "Don't need to fill OST$MINI"
13152         else
13153                 # generate uneven OSTs. Write 2% over the QOS threshold value
13154                 echo "no"
13155                 DIFF=$((threshold - DIFF2 + 2))
13156                 DIFF2=$((MINV * DIFF / 100))
13157                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
13158                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
13159                         error "setstripe failed"
13160                 DIFF=$((DIFF2 / 2048))
13161                 i=0
13162                 while [ $i -lt $DIFF ]; do
13163                         i=$((i + 1))
13164                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
13165                                 bs=2M count=1 2>/dev/null
13166                         echo -n .
13167                 done
13168                 echo .
13169                 sync
13170                 sleep_maxage
13171                 free_min_max
13172         fi
13173
13174         DIFF=$((MAXV - MINV))
13175         DIFF2=$((DIFF * 100 / MINV))
13176         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
13177         if [ $DIFF2 -gt $threshold ]; then
13178                 echo "ok"
13179         else
13180                 skip "QOS imbalance criteria not met"
13181         fi
13182
13183         MINI1=$MINI
13184         MINV1=$MINV
13185         MAXI1=$MAXI
13186         MAXV1=$MAXV
13187
13188         # now fill using QOS
13189         $LFS setstripe -c 1 $DIR/$tdir
13190         FILL=$((FILL / 200))
13191         if [ $FILL -gt 600 ]; then
13192                 FILL=600
13193         fi
13194         echo "writing $FILL files to QOS-assigned OSTs"
13195         i=0
13196         while [ $i -lt $FILL ]; do
13197                 i=$((i + 1))
13198                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
13199                         count=1 2>/dev/null
13200                 echo -n .
13201         done
13202         echo "wrote $i 200k files"
13203         sync
13204         sleep_maxage
13205
13206         echo "Note: free space may not be updated, so measurements might be off"
13207         free_min_max
13208         DIFF2=$((MAXV - MINV))
13209         echo "free space delta: orig $DIFF final $DIFF2"
13210         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
13211         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
13212         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
13213         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
13214         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
13215         if [[ $DIFF -gt 0 ]]; then
13216                 FILL=$((DIFF2 * 100 / DIFF - 100))
13217                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
13218         fi
13219
13220         # Figure out which files were written where
13221         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
13222                awk '/'$MINI1': / {print $2; exit}')
13223         echo $UUID
13224         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
13225         echo "$MINC files created on smaller OST $MINI1"
13226         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
13227                awk '/'$MAXI1': / {print $2; exit}')
13228         echo $UUID
13229         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
13230         echo "$MAXC files created on larger OST $MAXI1"
13231         if [[ $MINC -gt 0 ]]; then
13232                 FILL=$((MAXC * 100 / MINC - 100))
13233                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
13234         fi
13235         [[ $MAXC -gt $MINC ]] ||
13236                 error_ignore LU-9 "stripe QOS didn't balance free space"
13237 }
13238 run_test 116a "stripe QOS: free space balance ==================="
13239
13240 test_116b() { # LU-2093
13241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13242         remote_mds_nodsh && skip "remote MDS with nodsh"
13243
13244 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
13245         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
13246                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
13247         [ -z "$old_rr" ] && skip "no QOS"
13248         do_facet $SINGLEMDS lctl set_param \
13249                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
13250         mkdir -p $DIR/$tdir
13251         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
13252         createmany -o $DIR/$tdir/f- 20 || error "can't create"
13253         do_facet $SINGLEMDS lctl set_param fail_loc=0
13254         rm -rf $DIR/$tdir
13255         do_facet $SINGLEMDS lctl set_param \
13256                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
13257 }
13258 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
13259
13260 test_117() # bug 10891
13261 {
13262         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13263
13264         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
13265         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
13266         lctl set_param fail_loc=0x21e
13267         > $DIR/$tfile || error "truncate failed"
13268         lctl set_param fail_loc=0
13269         echo "Truncate succeeded."
13270         rm -f $DIR/$tfile
13271 }
13272 run_test 117 "verify osd extend =========="
13273
13274 NO_SLOW_RESENDCOUNT=4
13275 export OLD_RESENDCOUNT=""
13276 set_resend_count () {
13277         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
13278         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
13279         lctl set_param -n $PROC_RESENDCOUNT $1
13280         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
13281 }
13282
13283 # for reduce test_118* time (b=14842)
13284 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13285
13286 # Reset async IO behavior after error case
13287 reset_async() {
13288         FILE=$DIR/reset_async
13289
13290         # Ensure all OSCs are cleared
13291         $LFS setstripe -c -1 $FILE
13292         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
13293         sync
13294         rm $FILE
13295 }
13296
13297 test_118a() #bug 11710
13298 {
13299         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13300
13301         reset_async
13302
13303         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13304         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13305         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13306
13307         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13308                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13309                 return 1;
13310         fi
13311         rm -f $DIR/$tfile
13312 }
13313 run_test 118a "verify O_SYNC works =========="
13314
13315 test_118b()
13316 {
13317         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13318         remote_ost_nodsh && skip "remote OST with nodsh"
13319
13320         reset_async
13321
13322         #define OBD_FAIL_SRV_ENOENT 0x217
13323         set_nodes_failloc "$(osts_nodes)" 0x217
13324         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13325         RC=$?
13326         set_nodes_failloc "$(osts_nodes)" 0
13327         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13328         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13329                     grep -c writeback)
13330
13331         if [[ $RC -eq 0 ]]; then
13332                 error "Must return error due to dropped pages, rc=$RC"
13333                 return 1;
13334         fi
13335
13336         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13337                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13338                 return 1;
13339         fi
13340
13341         echo "Dirty pages not leaked on ENOENT"
13342
13343         # Due to the above error the OSC will issue all RPCs syncronously
13344         # until a subsequent RPC completes successfully without error.
13345         $MULTIOP $DIR/$tfile Ow4096yc
13346         rm -f $DIR/$tfile
13347
13348         return 0
13349 }
13350 run_test 118b "Reclaim dirty pages on fatal error =========="
13351
13352 test_118c()
13353 {
13354         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13355
13356         # for 118c, restore the original resend count, LU-1940
13357         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
13358                                 set_resend_count $OLD_RESENDCOUNT
13359         remote_ost_nodsh && skip "remote OST with nodsh"
13360
13361         reset_async
13362
13363         #define OBD_FAIL_OST_EROFS               0x216
13364         set_nodes_failloc "$(osts_nodes)" 0x216
13365
13366         # multiop should block due to fsync until pages are written
13367         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13368         MULTIPID=$!
13369         sleep 1
13370
13371         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13372                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13373         fi
13374
13375         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13376                     grep -c writeback)
13377         if [[ $WRITEBACK -eq 0 ]]; then
13378                 error "No page in writeback, writeback=$WRITEBACK"
13379         fi
13380
13381         set_nodes_failloc "$(osts_nodes)" 0
13382         wait $MULTIPID
13383         RC=$?
13384         if [[ $RC -ne 0 ]]; then
13385                 error "Multiop fsync failed, rc=$RC"
13386         fi
13387
13388         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13389         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13390                     grep -c writeback)
13391         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13392                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13393         fi
13394
13395         rm -f $DIR/$tfile
13396         echo "Dirty pages flushed via fsync on EROFS"
13397         return 0
13398 }
13399 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
13400
13401 # continue to use small resend count to reduce test_118* time (b=14842)
13402 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13403
13404 test_118d()
13405 {
13406         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13407         remote_ost_nodsh && skip "remote OST with nodsh"
13408
13409         reset_async
13410
13411         #define OBD_FAIL_OST_BRW_PAUSE_BULK
13412         set_nodes_failloc "$(osts_nodes)" 0x214
13413         # multiop should block due to fsync until pages are written
13414         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13415         MULTIPID=$!
13416         sleep 1
13417
13418         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13419                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13420         fi
13421
13422         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13423                     grep -c writeback)
13424         if [[ $WRITEBACK -eq 0 ]]; then
13425                 error "No page in writeback, writeback=$WRITEBACK"
13426         fi
13427
13428         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
13429         set_nodes_failloc "$(osts_nodes)" 0
13430
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 [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13435                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13436         fi
13437
13438         rm -f $DIR/$tfile
13439         echo "Dirty pages gaurenteed flushed via fsync"
13440         return 0
13441 }
13442 run_test 118d "Fsync validation inject a delay of the bulk =========="
13443
13444 test_118f() {
13445         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13446
13447         reset_async
13448
13449         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
13450         lctl set_param fail_loc=0x8000040a
13451
13452         # Should simulate EINVAL error which is fatal
13453         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13454         RC=$?
13455         if [[ $RC -eq 0 ]]; then
13456                 error "Must return error due to dropped pages, rc=$RC"
13457         fi
13458
13459         lctl set_param fail_loc=0x0
13460
13461         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13462         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13463         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13464                     grep -c writeback)
13465         if [[ $LOCKED -ne 0 ]]; then
13466                 error "Locked pages remain in cache, locked=$LOCKED"
13467         fi
13468
13469         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13470                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13471         fi
13472
13473         rm -f $DIR/$tfile
13474         echo "No pages locked after fsync"
13475
13476         reset_async
13477         return 0
13478 }
13479 run_test 118f "Simulate unrecoverable OSC side error =========="
13480
13481 test_118g() {
13482         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13483
13484         reset_async
13485
13486         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
13487         lctl set_param fail_loc=0x406
13488
13489         # simulate local -ENOMEM
13490         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13491         RC=$?
13492
13493         lctl set_param fail_loc=0
13494         if [[ $RC -eq 0 ]]; then
13495                 error "Must return error due to dropped pages, rc=$RC"
13496         fi
13497
13498         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13499         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13500         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13501                         grep -c writeback)
13502         if [[ $LOCKED -ne 0 ]]; then
13503                 error "Locked pages remain in cache, locked=$LOCKED"
13504         fi
13505
13506         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13507                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13508         fi
13509
13510         rm -f $DIR/$tfile
13511         echo "No pages locked after fsync"
13512
13513         reset_async
13514         return 0
13515 }
13516 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
13517
13518 test_118h() {
13519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13520         remote_ost_nodsh && skip "remote OST with nodsh"
13521
13522         reset_async
13523
13524         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13525         set_nodes_failloc "$(osts_nodes)" 0x20e
13526         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13527         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13528         RC=$?
13529
13530         set_nodes_failloc "$(osts_nodes)" 0
13531         if [[ $RC -eq 0 ]]; then
13532                 error "Must return error due to dropped pages, rc=$RC"
13533         fi
13534
13535         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13536         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13537         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13538                     grep -c writeback)
13539         if [[ $LOCKED -ne 0 ]]; then
13540                 error "Locked pages remain in cache, locked=$LOCKED"
13541         fi
13542
13543         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13544                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13545         fi
13546
13547         rm -f $DIR/$tfile
13548         echo "No pages locked after fsync"
13549
13550         return 0
13551 }
13552 run_test 118h "Verify timeout in handling recoverables errors  =========="
13553
13554 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13555
13556 test_118i() {
13557         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13558         remote_ost_nodsh && skip "remote OST with nodsh"
13559
13560         reset_async
13561
13562         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13563         set_nodes_failloc "$(osts_nodes)" 0x20e
13564
13565         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13566         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13567         PID=$!
13568         sleep 5
13569         set_nodes_failloc "$(osts_nodes)" 0
13570
13571         wait $PID
13572         RC=$?
13573         if [[ $RC -ne 0 ]]; then
13574                 error "got error, but should be not, rc=$RC"
13575         fi
13576
13577         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13578         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13579         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13580         if [[ $LOCKED -ne 0 ]]; then
13581                 error "Locked pages remain in cache, locked=$LOCKED"
13582         fi
13583
13584         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13585                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13586         fi
13587
13588         rm -f $DIR/$tfile
13589         echo "No pages locked after fsync"
13590
13591         return 0
13592 }
13593 run_test 118i "Fix error before timeout in recoverable error  =========="
13594
13595 [ "$SLOW" = "no" ] && set_resend_count 4
13596
13597 test_118j() {
13598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13599         remote_ost_nodsh && skip "remote OST with nodsh"
13600
13601         reset_async
13602
13603         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
13604         set_nodes_failloc "$(osts_nodes)" 0x220
13605
13606         # return -EIO from OST
13607         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13608         RC=$?
13609         set_nodes_failloc "$(osts_nodes)" 0x0
13610         if [[ $RC -eq 0 ]]; then
13611                 error "Must return error due to dropped pages, rc=$RC"
13612         fi
13613
13614         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13615         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13616         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13617         if [[ $LOCKED -ne 0 ]]; then
13618                 error "Locked pages remain in cache, locked=$LOCKED"
13619         fi
13620
13621         # in recoverable error on OST we want resend and stay until it finished
13622         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13623                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13624         fi
13625
13626         rm -f $DIR/$tfile
13627         echo "No pages locked after fsync"
13628
13629         return 0
13630 }
13631 run_test 118j "Simulate unrecoverable OST side error =========="
13632
13633 test_118k()
13634 {
13635         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13636         remote_ost_nodsh && skip "remote OSTs with nodsh"
13637
13638         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13639         set_nodes_failloc "$(osts_nodes)" 0x20e
13640         test_mkdir $DIR/$tdir
13641
13642         for ((i=0;i<10;i++)); do
13643                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
13644                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
13645                 SLEEPPID=$!
13646                 sleep 0.500s
13647                 kill $SLEEPPID
13648                 wait $SLEEPPID
13649         done
13650
13651         set_nodes_failloc "$(osts_nodes)" 0
13652         rm -rf $DIR/$tdir
13653 }
13654 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
13655
13656 test_118l() # LU-646
13657 {
13658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13659
13660         test_mkdir $DIR/$tdir
13661         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
13662         rm -rf $DIR/$tdir
13663 }
13664 run_test 118l "fsync dir"
13665
13666 test_118m() # LU-3066
13667 {
13668         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13669
13670         test_mkdir $DIR/$tdir
13671         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
13672         rm -rf $DIR/$tdir
13673 }
13674 run_test 118m "fdatasync dir ========="
13675
13676 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13677
13678 test_118n()
13679 {
13680         local begin
13681         local end
13682
13683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13684         remote_ost_nodsh && skip "remote OSTs with nodsh"
13685
13686         # Sleep to avoid a cached response.
13687         #define OBD_STATFS_CACHE_SECONDS 1
13688         sleep 2
13689
13690         # Inject a 10 second delay in the OST_STATFS handler.
13691         #define OBD_FAIL_OST_STATFS_DELAY 0x242
13692         set_nodes_failloc "$(osts_nodes)" 0x242
13693
13694         begin=$SECONDS
13695         stat --file-system $MOUNT > /dev/null
13696         end=$SECONDS
13697
13698         set_nodes_failloc "$(osts_nodes)" 0
13699
13700         if ((end - begin > 20)); then
13701             error "statfs took $((end - begin)) seconds, expected 10"
13702         fi
13703 }
13704 run_test 118n "statfs() sends OST_STATFS requests in parallel"
13705
13706 test_119a() # bug 11737
13707 {
13708         BSIZE=$((512 * 1024))
13709         directio write $DIR/$tfile 0 1 $BSIZE
13710         # We ask to read two blocks, which is more than a file size.
13711         # directio will indicate an error when requested and actual
13712         # sizes aren't equeal (a normal situation in this case) and
13713         # print actual read amount.
13714         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
13715         if [ "$NOB" != "$BSIZE" ]; then
13716                 error "read $NOB bytes instead of $BSIZE"
13717         fi
13718         rm -f $DIR/$tfile
13719 }
13720 run_test 119a "Short directIO read must return actual read amount"
13721
13722 test_119b() # bug 11737
13723 {
13724         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13725
13726         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
13727         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
13728         sync
13729         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
13730                 error "direct read failed"
13731         rm -f $DIR/$tfile
13732 }
13733 run_test 119b "Sparse directIO read must return actual read amount"
13734
13735 test_119c() # bug 13099
13736 {
13737         BSIZE=1048576
13738         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
13739         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
13740         rm -f $DIR/$tfile
13741 }
13742 run_test 119c "Testing for direct read hitting hole"
13743
13744 # Note: test 119d was removed, skipping 119d for new tests to avoid polluting
13745 # Maloo test history
13746
13747 test_119e()
13748 {
13749         (( $MDS1_VERSION >= $(version_code 2.15.58) )) ||
13750                 skip "Need server version at least 2.15.58"
13751         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13752
13753         local stripe_size=$((1024 * 1024)) #1 MiB
13754         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13755         local file_size=$((25 * stripe_size))
13756         local bsizes
13757
13758         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13759         stack_trap "rm -f $DIR/$tfile*"
13760
13761         # Just a bit bigger than the largest size in the test set below
13762         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13763                 error "buffered i/o to create file failed"
13764
13765         # trivial test of unaligned DIO
13766         dd if=$DIR/$tfile.1 bs=4095 of=$DIR/$tfile.2 count=4 \
13767                 iflag=direct oflag=direct ||
13768                 error "trivial unaligned dio failed"
13769
13770         # Test of disabling unaligned DIO support
13771         $LCTL set_param llite.*.unaligned_dio=0
13772         stack_trap "$LCTL set_param llite.*.unaligned_dio=1"
13773         echo "testing disabling unaligned DIO - 'invalid argument' expected:"
13774         dd if=$DIR/$tfile.1 bs=1024 of=$DIR/$tfile.2 count=4 \
13775                 iflag=direct oflag=direct &&
13776                 error "unaligned dio succeeded when disabled"
13777         $LCTL set_param llite.*.unaligned_dio=1
13778
13779         # Clean up before next part of test
13780         rm -f $DIR/$tfile.2
13781
13782         if zfs_or_rotational; then
13783                 # DIO on ZFS can take up to 2 seconds per IO
13784                 # rotational is better, but still slow.
13785                 # Limit testing on those media to larger sizes
13786                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13787                         $((stripe_size + 1024))"
13788         else
13789                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13790                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13791                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13792                         $((stripe_size - 1)) $stripe_size \
13793                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13794                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13795         fi
13796
13797         for bs in $bsizes; do
13798                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13799                 echo "Read/write with DIO at size $bs"
13800                 # Read and write with DIO from source to dest
13801                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 \
13802                         iflag=direct oflag=direct ||
13803                         error "dio failed"
13804
13805                 ls -la $DIR/$tfile.1 $DIR/$tfile.2
13806                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13807                         error "size incorrect, file copy read/write bsize: $bs"
13808                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13809                         error "files differ, bsize $bs"
13810                 rm -f $DIR/$tfile.2
13811         done
13812 }
13813 run_test 119e "Basic tests of dio read and write at various sizes"
13814
13815 test_119f()
13816 {
13817         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13818
13819         local stripe_size=$((1024 * 1024)) #1 MiB
13820         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13821         local file_size=$((25 * stripe_size))
13822         local bsizes
13823
13824         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13825         stack_trap "rm -f $DIR/$tfile*"
13826
13827         # Just a bit bigger than the largest size in the test set below
13828         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13829                 error "buffered i/o to create file failed"
13830
13831         if zfs_or_rotational; then
13832                 # DIO on ZFS can take up to 2 seconds per IO
13833                 # rotational is better, but still slow.
13834                 # Limit testing on those media to larger sizes
13835                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13836                         $((stripe_size + 1024))"
13837         else
13838                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13839                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13840                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13841                         $((stripe_size - 1)) $stripe_size \
13842                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13843                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13844         fi
13845
13846         for bs in $bsizes; do
13847                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13848                 # Read and write with DIO from source to dest in two
13849                 # threads - should give correct copy of file
13850
13851                 echo "bs: $bs"
13852                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13853                         oflag=direct conv=notrunc &
13854                 pid_dio1=$!
13855                 # Note block size is different here for a more interesting race
13856                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
13857                         iflag=direct oflag=direct conv=notrunc &
13858                 pid_dio2=$!
13859                 wait $pid_dio1
13860                 rc1=$?
13861                 wait $pid_dio2
13862                 rc2=$?
13863                 if (( rc1 != 0 )); then
13864                         error "dio copy 1 w/bsize $bs failed: $rc1"
13865                 fi
13866                 if (( rc2 != 0 )); then
13867                         error "dio copy 2 w/bsize $bs failed: $rc2"
13868                 fi
13869
13870
13871                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13872                         error "size incorrect, file copy read/write bsize: $bs"
13873                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13874                         error "files differ, bsize $bs"
13875                 rm -f $DIR/$tfile.2
13876         done
13877 }
13878 run_test 119f "dio vs dio race"
13879
13880 test_119g()
13881 {
13882         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13883
13884         local stripe_size=$((1024 * 1024)) #1 MiB
13885         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13886         local file_size=$((25 * stripe_size))
13887         local bsizes
13888
13889         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13890         stack_trap "rm -f $DIR/$tfile*"
13891
13892         # Just a bit bigger than the largest size in the test set below
13893         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13894                 error "buffered i/o to create file failed"
13895
13896         if zfs_or_rotational; then
13897                 # DIO on ZFS can take up to 2 seconds per IO
13898                 # rotational is better, but still slow.
13899                 # Limit testing on those media to larger sizes
13900                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13901                         $((stripe_size + 1024))"
13902         else
13903                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13904                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13905                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13906                         $((stripe_size - 1)) $stripe_size \
13907                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13908                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13909         fi
13910
13911         for bs in $bsizes; do
13912                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13913                 echo "bs: $bs"
13914                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13915                         oflag=direct conv=notrunc &
13916                 pid_dio1=$!
13917                 # Buffered I/O with similar but not the same block size
13918                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 &
13919                 pid_bio2=$!
13920                 wait $pid_dio1
13921                 rc1=$?
13922                 wait $pid_bio2
13923                 rc2=$?
13924                 if (( rc1 != 0 )); then
13925                         error "dio copy 1 w/bsize $bs failed: $rc1"
13926                 fi
13927                 if (( rc2 != 0 )); then
13928                         error "buffered copy 2 w/bsize $bs failed: $rc2"
13929                 fi
13930
13931                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13932                         error "size incorrect"
13933                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13934                         error "files differ, bsize $bs"
13935                 rm -f $DIR/$tfile.2
13936         done
13937 }
13938 run_test 119g "dio vs buffered I/O race"
13939
13940 test_119h()
13941 {
13942         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13943
13944         local stripe_size=$((1024 * 1024)) #1 MiB
13945         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13946         local file_size=$((25 * stripe_size))
13947         local bsizes
13948
13949         stack_trap "rm -f $DIR/$tfile.*"
13950
13951         if zfs_or_rotational; then
13952                 # DIO on ZFS can take up to 2 seconds per IO
13953                 # rotational is better, but still slow.
13954                 # Limit testing on those media to larger sizes
13955                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13956                         $((stripe_size + 1024))"
13957         else
13958                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13959                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13960                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13961                         $((stripe_size - 1)) $stripe_size \
13962                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13963                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13964         fi
13965
13966         for bs in $bsizes; do
13967                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13968                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13969                 echo "unaligned writes of blocksize: $bs"
13970                 # Write a file with unaligned DIO and regular DIO, and compare
13971                 # them
13972                 # with 'u', multiop randomly unaligns the io from the buffer
13973                 $MULTIOP $DIR/$tfile.1 \
13974                 oO_CREAT:O_RDWR:O_DIRECT:wu${bs}wu${bs}wu${bs}wu${bs}wu${bs} ||
13975                         error "multiop memory unaligned write failed, $bs"
13976                 $MULTIOP $DIR/$tfile.2 \
13977                 oO_CREAT:O_RDWR:O_DIRECT:w${bs}w${bs}w${bs}w${bs}w${bs} ||
13978                         error "multiop memory aligned write failed, $bs"
13979
13980                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13981                         error "files differ, bsize $bs"
13982                 rm -f $DIR/$tfile.*
13983         done
13984
13985         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13986         dd if=/dev/zero bs=$((stripe_size * 5)) of=$DIR/$tfile.1 count=5 ||
13987                 error "dd to create source file for read failed"
13988
13989         # Just a few quick tests to make sure unaligned DIO reads don't crash
13990         for bs in $bsizes; do
13991
13992                 echo "unaligned reads of blocksize: $bs"
13993                 # with 'u', multiop randomly unaligns the io from the buffer
13994                 $MULTIOP $DIR/$tfile.1 \
13995                 oO_CREAT:O_RDWR:O_DIRECT:ru${bs}ru${bs}ru${bs}ru${bs}ru${bs} ||
13996                         error "multiop memory unaligned read failed, $bs"
13997
13998         done
13999         rm -f $DIR/$tfile*
14000 }
14001 run_test 119h "basic tests of memory unaligned dio"
14002
14003 # aiocp with the '-a' option makes testing memory unaligned aio trivial
14004 test_119i()
14005 {
14006         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14007         which aiocp || skip_env "no aiocp installed"
14008
14009         local stripe_size=$((1024 * 1024)) #1 MiB
14010         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
14011         local file_size=$((25 * stripe_size))
14012         local bsizes
14013
14014         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
14015         stack_trap "rm -f $DIR/$tfile.*"
14016
14017         # Just a bit bigger than the largest size in the test set below
14018         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
14019                 error "buffered i/o to create file failed"
14020
14021         if zfs_or_rotational; then
14022                 # DIO on ZFS can take up to 2 seconds per IO
14023                 # rotational is better, but still slow.
14024                 # Limit testing on those media to larger sizes
14025                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
14026                         $((stripe_size + 1024))"
14027         else
14028                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
14029                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
14030                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
14031                         $((stripe_size - 1)) $stripe_size \
14032                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
14033                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
14034         fi
14035
14036         # Do page aligned and NOT page aligned AIO
14037         for align in 8 512 $((PAGE_SIZE)); do
14038         # Deliberately includes a few aligned sizes
14039         for bs in $bsizes; do
14040                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
14041
14042                 echo "bs: $bs, align: $align, file_size $file_size"
14043                 aiocp -a $align -b $bs -s $file_size -f O_DIRECT \
14044                         $DIR/$tfile.1 $DIR/$tfile.2 ||
14045                         error "unaligned aio failed, bs: $bs, align: $align"
14046
14047                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
14048                         error "size incorrect"
14049                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
14050                         error "files differ"
14051                 rm -f $DIR/$tfile.2
14052         done
14053         done
14054 }
14055 run_test 119i "test unaligned aio at varying sizes"
14056
14057 test_120a() {
14058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14059         remote_mds_nodsh && skip "remote MDS with nodsh"
14060         test_mkdir -i0 -c1 $DIR/$tdir
14061         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14062                 skip_env "no early lock cancel on server"
14063
14064         lru_resize_disable mdc
14065         lru_resize_disable osc
14066         cancel_lru_locks mdc
14067         # asynchronous object destroy at MDT could cause bl ast to client
14068         cancel_lru_locks osc
14069
14070         stat $DIR/$tdir > /dev/null
14071         can1=$(do_facet mds1 \
14072                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14073                awk '/ldlm_cancel/ {print $2}')
14074         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14075                awk '/ldlm_bl_callback/ {print $2}')
14076         test_mkdir -i0 -c1 $DIR/$tdir/d1
14077         can2=$(do_facet mds1 \
14078                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14079                awk '/ldlm_cancel/ {print $2}')
14080         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14081                awk '/ldlm_bl_callback/ {print $2}')
14082         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14083         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14084         lru_resize_enable mdc
14085         lru_resize_enable osc
14086 }
14087 run_test 120a "Early Lock Cancel: mkdir test"
14088
14089 test_120b() {
14090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14091         remote_mds_nodsh && skip "remote MDS with nodsh"
14092         test_mkdir $DIR/$tdir
14093         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14094                 skip_env "no early lock cancel on server"
14095
14096         lru_resize_disable mdc
14097         lru_resize_disable osc
14098         cancel_lru_locks mdc
14099         stat $DIR/$tdir > /dev/null
14100         can1=$(do_facet $SINGLEMDS \
14101                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14102                awk '/ldlm_cancel/ {print $2}')
14103         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14104                awk '/ldlm_bl_callback/ {print $2}')
14105         touch $DIR/$tdir/f1
14106         can2=$(do_facet $SINGLEMDS \
14107                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14108                awk '/ldlm_cancel/ {print $2}')
14109         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14110                awk '/ldlm_bl_callback/ {print $2}')
14111         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14112         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14113         lru_resize_enable mdc
14114         lru_resize_enable osc
14115 }
14116 run_test 120b "Early Lock Cancel: create test"
14117
14118 test_120c() {
14119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14120         remote_mds_nodsh && skip "remote MDS with nodsh"
14121         test_mkdir -i0 -c1 $DIR/$tdir
14122         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14123                 skip "no early lock cancel on server"
14124
14125         lru_resize_disable mdc
14126         lru_resize_disable osc
14127         test_mkdir -i0 -c1 $DIR/$tdir/d1
14128         test_mkdir -i0 -c1 $DIR/$tdir/d2
14129         touch $DIR/$tdir/d1/f1
14130         cancel_lru_locks mdc
14131         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
14132         can1=$(do_facet mds1 \
14133                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14134                awk '/ldlm_cancel/ {print $2}')
14135         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14136                awk '/ldlm_bl_callback/ {print $2}')
14137         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
14138         can2=$(do_facet mds1 \
14139                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14140                awk '/ldlm_cancel/ {print $2}')
14141         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14142                awk '/ldlm_bl_callback/ {print $2}')
14143         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14144         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14145         lru_resize_enable mdc
14146         lru_resize_enable osc
14147 }
14148 run_test 120c "Early Lock Cancel: link test"
14149
14150 test_120d() {
14151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14152         remote_mds_nodsh && skip "remote MDS with nodsh"
14153         test_mkdir -i0 -c1 $DIR/$tdir
14154         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14155                 skip_env "no early lock cancel on server"
14156
14157         lru_resize_disable mdc
14158         lru_resize_disable osc
14159         touch $DIR/$tdir
14160         cancel_lru_locks mdc
14161         stat $DIR/$tdir > /dev/null
14162         can1=$(do_facet mds1 \
14163                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14164                awk '/ldlm_cancel/ {print $2}')
14165         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14166                awk '/ldlm_bl_callback/ {print $2}')
14167         chmod a+x $DIR/$tdir
14168         can2=$(do_facet mds1 \
14169                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14170                awk '/ldlm_cancel/ {print $2}')
14171         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14172                awk '/ldlm_bl_callback/ {print $2}')
14173         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14174         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14175         lru_resize_enable mdc
14176         lru_resize_enable osc
14177 }
14178 run_test 120d "Early Lock Cancel: setattr test"
14179
14180 test_120e() {
14181         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14182         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14183                 skip_env "no early lock cancel on server"
14184         remote_mds_nodsh && skip "remote MDS with nodsh"
14185
14186         local dlmtrace_set=false
14187
14188         test_mkdir -i0 -c1 $DIR/$tdir
14189         lru_resize_disable mdc
14190         lru_resize_disable osc
14191         ! $LCTL get_param debug | grep -q dlmtrace &&
14192                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
14193         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
14194         cancel_lru_locks mdc
14195         cancel_lru_locks osc
14196         dd if=$DIR/$tdir/f1 of=/dev/null
14197         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
14198         # XXX client can not do early lock cancel of OST lock
14199         # during unlink (LU-4206), so cancel osc lock now.
14200         sleep 2
14201         cancel_lru_locks osc
14202         can1=$(do_facet mds1 \
14203                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14204                awk '/ldlm_cancel/ {print $2}')
14205         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14206                awk '/ldlm_bl_callback/ {print $2}')
14207         unlink $DIR/$tdir/f1
14208         sleep 5
14209         can2=$(do_facet mds1 \
14210                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14211                awk '/ldlm_cancel/ {print $2}')
14212         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14213                awk '/ldlm_bl_callback/ {print $2}')
14214         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
14215                 $LCTL dk $TMP/cancel.debug.txt
14216         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
14217                 $LCTL dk $TMP/blocking.debug.txt
14218         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
14219         lru_resize_enable mdc
14220         lru_resize_enable osc
14221 }
14222 run_test 120e "Early Lock Cancel: unlink test"
14223
14224 test_120f() {
14225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14226         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14227                 skip_env "no early lock cancel on server"
14228         remote_mds_nodsh && skip "remote MDS with nodsh"
14229
14230         test_mkdir -i0 -c1 $DIR/$tdir
14231         lru_resize_disable mdc
14232         lru_resize_disable osc
14233         test_mkdir -i0 -c1 $DIR/$tdir/d1
14234         test_mkdir -i0 -c1 $DIR/$tdir/d2
14235         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
14236         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
14237         cancel_lru_locks mdc
14238         cancel_lru_locks osc
14239         dd if=$DIR/$tdir/d1/f1 of=/dev/null
14240         dd if=$DIR/$tdir/d2/f2 of=/dev/null
14241         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
14242         # XXX client can not do early lock cancel of OST lock
14243         # during rename (LU-4206), so cancel osc lock now.
14244         sleep 2
14245         cancel_lru_locks osc
14246         can1=$(do_facet mds1 \
14247                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14248                awk '/ldlm_cancel/ {print $2}')
14249         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14250                awk '/ldlm_bl_callback/ {print $2}')
14251         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
14252         sleep 5
14253         can2=$(do_facet mds1 \
14254                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14255                awk '/ldlm_cancel/ {print $2}')
14256         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14257                awk '/ldlm_bl_callback/ {print $2}')
14258         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14259         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14260         lru_resize_enable mdc
14261         lru_resize_enable osc
14262 }
14263 run_test 120f "Early Lock Cancel: rename test"
14264
14265 test_120g() {
14266         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14267         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14268                 skip_env "no early lock cancel on server"
14269         remote_mds_nodsh && skip "remote MDS with nodsh"
14270
14271         lru_resize_disable mdc
14272         lru_resize_disable osc
14273         count=10000
14274         echo create $count files
14275         test_mkdir $DIR/$tdir
14276         cancel_lru_locks mdc
14277         cancel_lru_locks osc
14278         t0=$(date +%s)
14279
14280         can0=$(do_facet $SINGLEMDS \
14281                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14282                awk '/ldlm_cancel/ {print $2}')
14283         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14284                awk '/ldlm_bl_callback/ {print $2}')
14285         createmany -o $DIR/$tdir/f $count
14286         sync
14287         can1=$(do_facet $SINGLEMDS \
14288                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14289                awk '/ldlm_cancel/ {print $2}')
14290         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14291                awk '/ldlm_bl_callback/ {print $2}')
14292         t1=$(date +%s)
14293         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
14294         echo rm $count files
14295         rm -r $DIR/$tdir
14296         sync
14297         can2=$(do_facet $SINGLEMDS \
14298                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14299                awk '/ldlm_cancel/ {print $2}')
14300         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14301                awk '/ldlm_bl_callback/ {print $2}')
14302         t2=$(date +%s)
14303         echo total: $count removes in $((t2-t1))
14304         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
14305         sleep 2
14306         # wait for commitment of removal
14307         lru_resize_enable mdc
14308         lru_resize_enable osc
14309 }
14310 run_test 120g "Early Lock Cancel: performance test"
14311
14312 test_121() { #bug #10589
14313         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14314
14315         rm -rf $DIR/$tfile
14316         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
14317 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
14318         lctl set_param fail_loc=0x310
14319         cancel_lru_locks osc > /dev/null
14320         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
14321         lctl set_param fail_loc=0
14322         [[ $reads -eq $writes ]] ||
14323                 error "read $reads blocks, must be $writes blocks"
14324 }
14325 run_test 121 "read cancel race ========="
14326
14327 test_123a_base() { # was test 123, statahead(bug 11401)
14328         local lsx="$1"
14329
14330         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
14331
14332         SLOWOK=0
14333         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
14334                 log "testing UP system. Performance may be lower than expected."
14335                 SLOWOK=1
14336         fi
14337         running_in_vm && SLOWOK=1
14338
14339         $LCTL set_param mdc.*.batch_stats=0
14340
14341         rm -rf $DIR/$tdir
14342         test_mkdir $DIR/$tdir
14343         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
14344         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
14345         MULT=10
14346         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
14347                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
14348
14349                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
14350                 lctl set_param -n llite.*.statahead_max 0
14351                 lctl get_param llite.*.statahead_max
14352                 cancel_lru_locks mdc
14353                 cancel_lru_locks osc
14354                 stime=$(date +%s)
14355                 time $lsx $DIR/$tdir | wc -l
14356                 etime=$(date +%s)
14357                 delta=$((etime - stime))
14358                 log "$lsx $i files without statahead: $delta sec"
14359                 lctl set_param llite.*.statahead_max=$max
14360
14361                 swrong=$(lctl get_param -n llite.*.statahead_stats |
14362                          awk '/statahead.wrong:/ { print $NF }')
14363                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
14364                 cancel_lru_locks mdc
14365                 cancel_lru_locks osc
14366                 stime=$(date +%s)
14367                 time $lsx $DIR/$tdir | wc -l
14368                 etime=$(date +%s)
14369                 delta_sa=$((etime - stime))
14370                 log "$lsx $i files with statahead: $delta_sa sec"
14371                 lctl get_param -n llite.*.statahead_stats
14372                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
14373                          awk '/statahead.wrong:/ { print $NF }')
14374
14375                 [[ $swrong -lt $ewrong ]] &&
14376                         log "statahead was stopped, maybe too many locks held!"
14377                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
14378
14379                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
14380                         max=$(lctl get_param -n llite.*.statahead_max |
14381                                 head -n 1)
14382                         lctl set_param -n llite.*.statahead_max 0
14383                         lctl get_param llite.*.statahead_max
14384                         cancel_lru_locks mdc
14385                         cancel_lru_locks osc
14386                         stime=$(date +%s)
14387                         time $lsx $DIR/$tdir | wc -l
14388                         etime=$(date +%s)
14389                         delta=$((etime - stime))
14390                         log "$lsx $i files again without statahead: $delta sec"
14391                         lctl set_param llite.*.statahead_max=$max
14392                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
14393                                 if [ $SLOWOK -eq 0 ]; then
14394                                         error "$lsx $i files is slower with statahead!"
14395                                 else
14396                                         log "$lsx $i files is slower with statahead!"
14397                                 fi
14398                                 break
14399                         fi
14400                 fi
14401
14402                 [ $delta -gt 20 ] && break
14403                 [ $delta -gt 8 ] && MULT=$((50 / delta))
14404                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
14405         done
14406         log "$lsx done"
14407
14408         stime=$(date +%s)
14409         rm -r $DIR/$tdir
14410         sync
14411         etime=$(date +%s)
14412         delta=$((etime - stime))
14413         log "rm -r $DIR/$tdir/: $delta seconds"
14414         log "rm done"
14415         lctl get_param -n llite.*.statahead_stats
14416         $LCTL get_param mdc.*.batch_stats
14417 }
14418
14419 test_123aa() {
14420         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14421
14422         test_123a_base "ls -l"
14423 }
14424 run_test 123aa "verify statahead work"
14425
14426 test_123ab() {
14427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14428
14429         statx_supported || skip_env "Test must be statx() syscall supported"
14430
14431         test_123a_base "$STATX -l"
14432 }
14433 run_test 123ab "verify statahead work by using statx"
14434
14435 test_123ac() {
14436         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14437
14438         statx_supported || skip_env "Test must be statx() syscall supported"
14439
14440         local rpcs_before
14441         local rpcs_after
14442         local agl_before
14443         local agl_after
14444
14445         cancel_lru_locks $OSC
14446         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14447         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
14448                      awk '/agl.total:/ { print $NF }')
14449         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
14450         test_123a_base "$STATX --cached=always -D"
14451         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
14452                     awk '/agl.total:/ { print $NF }')
14453         [ $agl_before -eq $agl_after ] ||
14454                 error "Should not trigger AGL thread - $agl_before:$agl_after"
14455         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14456         [ $rpcs_after -eq $rpcs_before ] ||
14457                 error "$STATX should not send glimpse RPCs to $OSC"
14458 }
14459 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
14460
14461 test_batch_statahead() {
14462         local max=$1
14463         local batch_max=$2
14464         local num=10000
14465         local batch_rpcs
14466         local unbatch_rpcs
14467         local hit_total
14468
14469         echo -e "\nbatching: statahead_max=$max statahead_batch_max=$batch_max"
14470         $LCTL set_param mdc.*.batch_stats=0
14471         $LCTL set_param llite.*.statahead_max=$max
14472         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14473         # Verify that batched statahead is faster than one without statahead
14474         test_123a_base "ls -l"
14475
14476         stack_trap "rm -rf $DIR/$tdir" EXIT
14477         mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
14478         createmany -o $DIR/$tdir/$tfile $num || error "failed to create files"
14479
14480         # unbatched statahead
14481         $LCTL set_param llite.*.statahead_batch_max=0
14482         $LCTL set_param llite.*.statahead_stats=clear
14483         $LCTL set_param mdc.*.stats=clear
14484         cancel_lru_locks mdc
14485         cancel_lru_locks osc
14486         time ls -l $DIR/$tdir | wc -l
14487         unbatch_rpcs=$(calc_stats mdc.*.stats ldlm_ibits_enqueue)
14488         wait_update_facet client "pgrep ll_sa" "" 35 ||
14489                 error "ll_sa thread is still running"
14490         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14491                     awk '/hit.total:/ { print $NF }')
14492         # hit ratio should be larger than 75% (7500).
14493         (( $hit_total > 7500 )) ||
14494                 error "unbatched statahead hit count ($hit_total) is too low"
14495
14496         # batched statahead
14497         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14498         $LCTL set_param llite.*.statahead_stats=clear
14499         $LCTL set_param mdc.*.batch_stats=clear
14500         $LCTL set_param mdc.*.stats=clear
14501         cancel_lru_locks mdc
14502         cancel_lru_locks osc
14503         time ls -l $DIR/$tdir | wc -l
14504         batch_rpcs=$(calc_stats mdc.*.stats mds_batch)
14505         # wait for statahead thread to quit and update statahead stats
14506         wait_update_facet client "pgrep ll_sa" "" 35 ||
14507                 error "ll_sa thread is still running"
14508         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14509                     awk '/hit.total:/ { print $NF }')
14510         # hit ratio should be larger than 75% (7500).
14511         (( $hit_total > 7500 )) ||
14512                 error "batched statahead hit count ($hit_total) is too low"
14513
14514         echo "unbatched RPCs: $unbatch_rpcs, batched RPCs: $batch_rpcs"
14515         (( $unbatch_rpcs > $batch_rpcs )) ||
14516                 error "batched statahead does not reduce RPC count"
14517         $LCTL get_param mdc.*.batch_stats
14518 }
14519
14520 test_123ad() {
14521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14522
14523         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
14524                 skip "Need server version at least 2.15.53"
14525
14526         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14527                 skip "Server does not support batch RPC"
14528
14529         local max
14530         local batch_max
14531
14532         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14533         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14534
14535         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14536         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14537
14538         test_batch_statahead 32 32
14539         test_batch_statahead 2048 256
14540 }
14541 run_test 123ad "Verify batching statahead works correctly"
14542
14543 test_123b () { # statahead(bug 15027)
14544         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14545
14546         test_mkdir $DIR/$tdir
14547         createmany -o $DIR/$tdir/$tfile-%d 1000
14548
14549         cancel_lru_locks mdc
14550         cancel_lru_locks osc
14551
14552 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
14553         lctl set_param fail_loc=0x80000803
14554         ls -lR $DIR/$tdir > /dev/null
14555         log "ls done"
14556         lctl set_param fail_loc=0x0
14557         lctl get_param -n llite.*.statahead_stats
14558         rm -r $DIR/$tdir
14559         sync
14560
14561 }
14562 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
14563
14564 test_123c() {
14565         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
14566
14567         test_mkdir -i 0 -c 1 $DIR/$tdir.0
14568         test_mkdir -i 1 -c 1 $DIR/$tdir.1
14569         touch $DIR/$tdir.1/{1..3}
14570         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
14571
14572         remount_client $MOUNT
14573
14574         $MULTIOP $DIR/$tdir.0 Q
14575
14576         # let statahead to complete
14577         ls -l $DIR/$tdir.0 > /dev/null
14578
14579         testid=$(echo $TESTNAME | tr '_' ' ')
14580         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
14581                 error "statahead warning" || true
14582 }
14583 run_test 123c "Can not initialize inode warning on DNE statahead"
14584
14585 test_123d() {
14586         local num=100
14587         local swrong
14588         local ewrong
14589
14590         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
14591         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
14592                 error "setdirstripe $DIR/$tdir failed"
14593         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
14594         remount_client $MOUNT
14595         $LCTL get_param llite.*.statahead_max
14596         $LCTL set_param llite.*.statahead_stats=0 ||
14597                 error "clear statahead_stats failed"
14598         swrong=$(lctl get_param -n llite.*.statahead_stats |
14599                  awk '/statahead.wrong:/ { print $NF }')
14600         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
14601         # wait for statahead thread finished to update hit/miss stats.
14602         sleep 1
14603         $LCTL get_param -n llite.*.statahead_stats
14604         ewrong=$(lctl get_param -n llite.*.statahead_stats |
14605                  awk '/statahead.wrong:/ { print $NF }')
14606         (( $swrong == $ewrong )) ||
14607                 log "statahead was stopped, maybe too many locks held!"
14608 }
14609 run_test 123d "Statahead on striped directories works correctly"
14610
14611 test_123e() {
14612         local max
14613         local batch_max
14614         local dir=$DIR/$tdir
14615
14616         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14617                 skip "Server does not support batch RPC"
14618
14619         mkdir $dir || error "mkdir $dir failed"
14620         $LFS setstripe -C 32 $dir || error "setstripe $dir failed"
14621         stack_trap "rm -rf $dir"
14622
14623         touch $dir/$tfile.{0..1000} || error "touch 1000 files failed"
14624
14625         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14626         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14627         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14628         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14629
14630         $LCTL set_param llite.*.statahead_max=2048
14631         $LCTL set_param llite.*.statahead_batch_max=1024
14632
14633         ls -l $dir
14634         $LCTL get_param mdc.*.batch_stats
14635         $LCTL get_param llite.*.statahead_*
14636 }
14637 run_test 123e "statahead with large wide striping"
14638
14639 test_123f() {
14640         local max
14641         local batch_max
14642         local dir=$DIR/$tdir
14643
14644         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14645                 skip "Server does not support batch RPC"
14646
14647         mkdir $dir || error "mkdir $dir failed"
14648         $LFS setstripe -C 1000 $dir || error "setstripe $dir failed"
14649         stack_trap "rm -rf $dir"
14650
14651         touch $dir/$tfile.{0..200} || error "touch 200 files failed"
14652
14653         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14654         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14655
14656         $LCTL set_param llite.*.statahead_max=64
14657         $LCTL set_param llite.*.statahead_batch_max=64
14658
14659         ls -l $dir
14660         lctl get_param mdc.*.batch_stats
14661         lctl get_param llite.*.statahead_*
14662
14663         $LCTL set_param llite.*.statahead_max=$max
14664         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14665 }
14666 run_test 123f "Retry mechanism with large wide striping files"
14667
14668 test_123g() {
14669         local dir=$DIR/$tdir
14670         local num=1000
14671
14672         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14673                 skip "Server does not support batch RPC"
14674
14675         mkdir $dir || error "failed to mkdir $dir"
14676         createmany -o $dir/$tfile $num || error "failed creatmany files"
14677         cancel_lru_locks mdc
14678         cancel_lru_locks osc
14679
14680         $LCTL set_param llite.*.statahead_stats=clear
14681         $LCTL set_param mdc.*.batch_stats=clear
14682         aheadmany -c stat -s 0 -e $num -b $tfile -d $dir ||
14683                 error "aheadmany $dir with $tfile failed"
14684         wait_update_facet client "pgrep ll_sa" "" 35 ||
14685                 error "ll_sa thread is still running"
14686         $LCTL get_param -n llite.*.statahead_stats
14687         $LCTL get_param -n mdc.*.batch_stats
14688
14689         local count
14690
14691         count=$($LCTL get_param -n llite.*.statahead_stats |
14692                 awk '/hit.total:/ {print $2}')
14693         echo "Hit total: $count"
14694         # Hit ratio should be >= 75%
14695         (( $count > num * 75 / 100 )) ||
14696                 error "hit total $count is be > 75% of $num"
14697 }
14698 run_test 123g "Test for stat-ahead advise"
14699
14700 test_123h_base() {
14701         local dir=$DIR/$tdir
14702         local cmd="touch $dir/$tfile.{$1}"
14703         local fcnt=$2
14704
14705         stack_trap "rm -rf $dir"
14706         mkdir -p $dir || error "failed to mkdir $dir"
14707         eval $cmd
14708
14709         cancel_lru_locks mdc
14710         $LCTL set_param llite.*.statahead_stats=clear
14711         $LCTL set_param mdc.*.batch_stats=0
14712         $LCTL set_param llite.*.statahead_max=1024
14713         $LCTL set_param llite.*.statahead_batch_max=1024
14714         lctl get_param -n llite.*.statahead_stats
14715         du -a $dir > /dev/null
14716         echo "Wait statahead thread (ll_sa_xxx) to exit..."
14717         wait_update_facet client "pgrep ll_sa" "" 35 ||
14718                 error "ll_sa statahead thread does not quit in 35s"
14719         $LCTL get_param -n llite.*.statahead_stats
14720         $LCTL get_param -n mdc.*.batch_stats
14721
14722         local count=$($LCTL get_param -n llite.*.statahead_stats |
14723                         awk '/fname.total:/ {print $2}')
14724
14725         [ $count == 1 ] || error "File name pattern statahead not trigger"
14726         count=$($LCTL get_param -n llite.*.statahead_stats |
14727                 awk '/hit.total:/ {print $2}')
14728         # Hit ratio should be >= 75%
14729         (( $count > fcnt * 75 / 100 )) ||
14730                 error "hit total is too low: $count"
14731         rm -rf $dir || error "rm -rf $dir failed"
14732 }
14733
14734 test_123h() {
14735         local max
14736         local batch_max
14737         local enabled
14738
14739         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14740                 skip "Server does not support batch RPC"
14741
14742         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14743         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14744         enabled=$($LCTL get_param -n llite.*.enable_statahead_fname | head -n 1)
14745         stack_trap "$LCTL set_param llite.*.statahead_max=$max"
14746         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max"
14747         stack_trap "$LCTL set_param llite.*.enable_statahead_fname=$enabled"
14748
14749         $LCTL set_param llite.*.enable_statahead_fname=1
14750
14751         echo "Scan a directory with number regularized fname"
14752         test_123h_base "0..10000" 10000
14753
14754         echo "Scan a directory with zeroed padding number regularized fname"
14755         test_123h_base "000000..010000" 10000
14756 }
14757 run_test 123h "Verify statahead work with the fname pattern via du"
14758
14759 test_123i_base() {
14760         local fmt=$1
14761         local iocmd=$2
14762         local dir=$DIR/$tdir
14763         local cmd="createmany -m $fmt"
14764
14765         echo "Command:"
14766         echo "- $cmd"
14767         echo "- $iocmd"
14768         stack_trap "unlinkmany $fmt"
14769         mkdir -p $dir || error "failed to mkdir $dir"
14770         eval $cmd
14771
14772         cancel_lru_locks mdc
14773         $LCTL set_param llite.*.statahead_stats=clear
14774         $LCTL set_param mdc.*.batch_stats=0
14775
14776         echo "statahead_stats (Pre):"
14777         lctl get_param -n llite.*.statahead_stats
14778         eval $iocmd || error "$iocmd failed"
14779         echo "statahead_stats (Post):"
14780         $LCTL get_param -n llite.*.statahead_stats
14781         $LCTL get_param -n mdc.*.batch_stats
14782
14783         echo "Wait the statahead thread (ll_sa_xxx) to exit ..."
14784         wait_update_facet client "pgrep ll_sa" "" 35 ||
14785                 error "ll_sa statahead thread does not quit in 35s"
14786         $LCTL get_param -n llite.*.statahead_stats
14787         $LCTL get_param -n mdc.*.batch_stats
14788
14789         local count=$($LCTL get_param -n llite.*.statahead_stats |
14790                         awk '/fname.total:/ {print $2}')
14791
14792         [ $count == 1 ] || error "File name pattern statahead not trigger"
14793         count=$($LCTL get_param -n llite.*.statahead_stats |
14794                 awk '/hit.total:/ {print $2}')
14795         # Hit ratio should be >= 75%
14796         (( $count > 750 )) || error "hit total is too low: $count"
14797 }
14798
14799 test_123i() {
14800         local dir=$DIR/$tdir
14801         local cnt=1000
14802         local max
14803         local batch_max
14804         local enabled
14805         local min
14806
14807         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14808                 skip "Server does not support batch RPC"
14809
14810         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14811         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14812         min=$($LCTL get_param -n llite.*.statahead_min | head -n 1)
14813         enabled=$($LCTL get_param -n llite.*.enable_statahead_fname | head -n 1)
14814         stack_trap "$LCTL set_param llite.*.statahead_max=$max"
14815         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max"
14816         stack_trap "$LCTL set_param llite.*.statahead_min=$min"
14817         stack_trap "$LCTL set_param llite.*.enable_statahead_fname=$enabled"
14818         $LCTL set_param llite.*.statahead_max=1024
14819         $LCTL set_param llite.*.statahead_batch_max=32
14820         $LCTL set_param llite.*.statahead_min=64
14821         $LCTL set_param llite.*.enable_statahead_fname=1
14822
14823         test_123i_base "$dir/$tfile.%06d $cnt" "ls $dir/* > /dev/null"
14824         test_123i_base "$dir/$tfile $cnt" \
14825                 "aheadmany -c stat -N -s 0 -e $cnt -b $tfile -d $dir"
14826 }
14827 run_test 123i "Verify statahead work with the fname indexing pattern"
14828
14829 test_124a() {
14830         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14831         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14832                 skip_env "no lru resize on server"
14833
14834         local NR=2000
14835
14836         test_mkdir $DIR/$tdir
14837
14838         log "create $NR files at $DIR/$tdir"
14839         createmany -o $DIR/$tdir/f $NR ||
14840                 error "failed to create $NR files in $DIR/$tdir"
14841
14842         cancel_lru_locks mdc
14843         ls -l $DIR/$tdir > /dev/null
14844
14845         local NSDIR=""
14846         local LRU_SIZE=0
14847         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
14848                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
14849                 LRU_SIZE=$($LCTL get_param -n $PARAM)
14850                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
14851                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
14852                         log "NSDIR=$NSDIR"
14853                         log "NS=$(basename $NSDIR)"
14854                         break
14855                 fi
14856         done
14857
14858         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
14859                 skip "Not enough cached locks created!"
14860         fi
14861         log "LRU=$LRU_SIZE"
14862
14863         local SLEEP=30
14864
14865         # We know that lru resize allows one client to hold $LIMIT locks
14866         # for 10h. After that locks begin to be killed by client.
14867         local MAX_HRS=10
14868         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
14869         log "LIMIT=$LIMIT"
14870         if [ $LIMIT -lt $LRU_SIZE ]; then
14871                 skip "Limit is too small $LIMIT"
14872         fi
14873
14874         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
14875         # killing locks. Some time was spent for creating locks. This means
14876         # that up to the moment of sleep finish we must have killed some of
14877         # them (10-100 locks). This depends on how fast ther were created.
14878         # Many of them were touched in almost the same moment and thus will
14879         # be killed in groups.
14880         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
14881
14882         # Use $LRU_SIZE_B here to take into account real number of locks
14883         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
14884         local LRU_SIZE_B=$LRU_SIZE
14885         log "LVF=$LVF"
14886         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
14887         log "OLD_LVF=$OLD_LVF"
14888         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
14889
14890         # Let's make sure that we really have some margin. Client checks
14891         # cached locks every 10 sec.
14892         SLEEP=$((SLEEP+20))
14893         log "Sleep ${SLEEP} sec"
14894         local SEC=0
14895         while ((SEC<$SLEEP)); do
14896                 echo -n "..."
14897                 sleep 5
14898                 SEC=$((SEC+5))
14899                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
14900                 echo -n "$LRU_SIZE"
14901         done
14902         echo ""
14903         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
14904         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
14905
14906         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
14907                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
14908                 unlinkmany $DIR/$tdir/f $NR
14909                 return
14910         }
14911
14912         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
14913         log "unlink $NR files at $DIR/$tdir"
14914         unlinkmany $DIR/$tdir/f $NR
14915 }
14916 run_test 124a "lru resize ======================================="
14917
14918 get_max_pool_limit()
14919 {
14920         local limit=$($LCTL get_param \
14921                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
14922         local max=0
14923         for l in $limit; do
14924                 if [[ $l -gt $max ]]; then
14925                         max=$l
14926                 fi
14927         done
14928         echo $max
14929 }
14930
14931 test_124b() {
14932         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14933         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14934                 skip_env "no lru resize on server"
14935
14936         LIMIT=$(get_max_pool_limit)
14937
14938         NR=$(($(default_lru_size)*20))
14939         if [[ $NR -gt $LIMIT ]]; then
14940                 log "Limit lock number by $LIMIT locks"
14941                 NR=$LIMIT
14942         fi
14943
14944         IFree=$(mdsrate_inodes_available)
14945         if [ $IFree -lt $NR ]; then
14946                 log "Limit lock number by $IFree inodes"
14947                 NR=$IFree
14948         fi
14949
14950         lru_resize_disable mdc
14951         test_mkdir -p $DIR/$tdir/disable_lru_resize
14952
14953         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
14954         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
14955         cancel_lru_locks mdc
14956         stime=`date +%s`
14957         PID=""
14958         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14959         PID="$PID $!"
14960         sleep 2
14961         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14962         PID="$PID $!"
14963         sleep 2
14964         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14965         PID="$PID $!"
14966         wait $PID
14967         etime=`date +%s`
14968         nolruresize_delta=$((etime-stime))
14969         log "ls -la time: $nolruresize_delta seconds"
14970         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14971         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
14972
14973         lru_resize_enable mdc
14974         test_mkdir -p $DIR/$tdir/enable_lru_resize
14975
14976         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
14977         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
14978         cancel_lru_locks mdc
14979         stime=`date +%s`
14980         PID=""
14981         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14982         PID="$PID $!"
14983         sleep 2
14984         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14985         PID="$PID $!"
14986         sleep 2
14987         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14988         PID="$PID $!"
14989         wait $PID
14990         etime=`date +%s`
14991         lruresize_delta=$((etime-stime))
14992         log "ls -la time: $lruresize_delta seconds"
14993         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14994
14995         if [ $lruresize_delta -gt $nolruresize_delta ]; then
14996                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
14997         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
14998                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
14999         else
15000                 log "lru resize performs the same with no lru resize"
15001         fi
15002         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
15003 }
15004 run_test 124b "lru resize (performance test) ======================="
15005
15006 test_124c() {
15007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15008         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
15009                 skip_env "no lru resize on server"
15010
15011         # cache ununsed locks on client
15012         local nr=100
15013         cancel_lru_locks mdc
15014         test_mkdir $DIR/$tdir
15015         createmany -o $DIR/$tdir/f $nr ||
15016                 error "failed to create $nr files in $DIR/$tdir"
15017         ls -l $DIR/$tdir > /dev/null
15018
15019         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15020         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15021         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
15022         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
15023         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
15024
15025         # set lru_max_age to 1 sec
15026         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
15027         echo "sleep $((recalc_p * 2)) seconds..."
15028         sleep $((recalc_p * 2))
15029
15030         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
15031         # restore lru_max_age
15032         $LCTL set_param -n $nsdir.lru_max_age $max_age
15033         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
15034         unlinkmany $DIR/$tdir/f $nr
15035 }
15036 run_test 124c "LRUR cancel very aged locks"
15037
15038 test_124d() {
15039         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15040         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
15041                 skip_env "no lru resize on server"
15042
15043         # cache ununsed locks on client
15044         local nr=100
15045
15046         lru_resize_disable mdc
15047         stack_trap "lru_resize_enable mdc" EXIT
15048
15049         cancel_lru_locks mdc
15050
15051         # asynchronous object destroy at MDT could cause bl ast to client
15052         test_mkdir $DIR/$tdir
15053         createmany -o $DIR/$tdir/f $nr ||
15054                 error "failed to create $nr files in $DIR/$tdir"
15055         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
15056
15057         ls -l $DIR/$tdir > /dev/null
15058
15059         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15060         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15061         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
15062         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
15063
15064         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
15065
15066         # set lru_max_age to 1 sec
15067         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
15068         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
15069
15070         echo "sleep $((recalc_p * 2)) seconds..."
15071         sleep $((recalc_p * 2))
15072
15073         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
15074
15075         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
15076 }
15077 run_test 124d "cancel very aged locks if lru-resize disabled"
15078
15079 test_125() { # 13358
15080         $LCTL get_param -n llite.*.client_type | grep -q local ||
15081                 skip "must run as local client"
15082         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
15083                 skip_env "must have acl enabled"
15084         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15085         id $USER0 || skip_env "missing user $USER0"
15086
15087         test_mkdir $DIR/$tdir
15088         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
15089         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
15090                 error "setfacl $DIR/$tdir failed"
15091         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
15092 }
15093 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
15094
15095 test_126() { # bug 12829/13455
15096         $GSS && skip_env "must run as gss disabled"
15097         $LCTL get_param -n llite.*.client_type | grep -q local ||
15098                 skip "must run as local client"
15099         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
15100
15101         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
15102         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
15103         rm -f $DIR/$tfile
15104         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
15105 }
15106 run_test 126 "check that the fsgid provided by the client is taken into account"
15107
15108 test_127a() { # bug 15521
15109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15110         local name count samp unit min max sum sumsq
15111         local tmpfile=$TMP/$tfile.tmp
15112
15113         # enable stats header if it is disabled
15114         $LCTL set_param enable_stats_header=1
15115
15116         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
15117         echo "stats before reset"
15118         stack_trap "rm -f $tmpfile"
15119         local now=$(date +%s)
15120
15121         $LCTL get_param osc.*.stats | tee $tmpfile
15122
15123         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
15124         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
15125         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
15126         local uptime=$(awk '{ print $1 }' /proc/uptime)
15127
15128         # snapshot_time should match POSIX epoch time, allow some delta for VMs
15129         (( ${snapshot_time%\.*} >= $now - 5 &&
15130            ${snapshot_time%\.*} <= $now + 5 )) ||
15131                 error "snapshot_time=$snapshot_time != now=$now"
15132         # elapsed _should_ be from mount, but at least less than uptime
15133         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
15134                 error "elapsed=$elapsed > uptime=$uptime"
15135         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
15136            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
15137                 error "elapsed=$elapsed != $snapshot_time - $start_time"
15138
15139         $LCTL set_param osc.*.stats=0
15140         local reset=$(date +%s)
15141         local fsize=$((2048 * 1024))
15142
15143         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
15144         cancel_lru_locks osc
15145         dd if=$DIR/$tfile of=/dev/null bs=$fsize
15146
15147         now=$(date +%s)
15148         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
15149         while read name count samp unit min max sum sumsq; do
15150                 [[ "$samp" == "samples" ]] || continue
15151
15152                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
15153                 [ ! $min ] && error "Missing min value for $name proc entry"
15154                 eval $name=$count || error "Wrong proc format"
15155
15156                 case $name in
15157                 read_bytes|write_bytes)
15158                         [[ "$unit" =~ "bytes" ]] ||
15159                                 error "unit is not 'bytes': $unit"
15160                         (( $min >= 4096 )) || error "min is too small: $min"
15161                         (( $min <= $fsize )) || error "min is too big: $min"
15162                         (( $max >= 4096 )) || error "max is too small: $max"
15163                         (( $max <= $fsize )) || error "max is too big: $max"
15164                         (( $sum == $fsize )) || error "sum is wrong: $sum"
15165                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
15166                                 error "sumsquare is too small: $sumsq"
15167                         (( $sumsq <= $fsize * $fsize )) ||
15168                                 error "sumsquare is too big: $sumsq"
15169                         ;;
15170                 ost_read|ost_write)
15171                         [[ "$unit" =~ "usec" ]] ||
15172                                 error "unit is not 'usec': $unit"
15173                         ;;
15174                 *)      ;;
15175                 esac
15176         done < $tmpfile
15177
15178         #check that we actually got some stats
15179         [ "$read_bytes" ] || error "Missing read_bytes stats"
15180         [ "$write_bytes" ] || error "Missing write_bytes stats"
15181         [ "$read_bytes" != 0 ] || error "no read done"
15182         [ "$write_bytes" != 0 ] || error "no write done"
15183
15184         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
15185         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
15186         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
15187
15188         # snapshot_time should match POSIX epoch time, allow some delta for VMs
15189         (( ${snapshot_time%\.*} >= $now - 5 &&
15190            ${snapshot_time%\.*} <= $now + 5 )) ||
15191                 error "reset snapshot_time=$snapshot_time != now=$now"
15192         # elapsed should be from time of stats reset
15193         (( ${elapsed%\.*} >= $now - $reset - 2 &&
15194            ${elapsed%\.*} <= $now - $reset + 2 )) ||
15195                 error "reset elapsed=$elapsed > $now - $reset"
15196         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
15197            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
15198                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
15199 }
15200 run_test 127a "verify the client stats are sane"
15201
15202 test_127b() { # bug LU-333
15203         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15204         local name count samp unit min max sum sumsq
15205
15206         echo "stats before reset"
15207         $LCTL get_param llite.*.stats
15208         $LCTL set_param llite.*.stats=0
15209
15210         # perform 2 reads and writes so MAX is different from SUM.
15211         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
15212         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
15213         cancel_lru_locks osc
15214         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
15215         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
15216
15217         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
15218         stack_trap "rm -f $TMP/$tfile.tmp"
15219         while read name count samp unit min max sum sumsq; do
15220                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
15221                 eval $name=$count || error "Wrong proc format"
15222
15223                 case $name in
15224                 read_bytes|write_bytes)
15225                         [[ "$unit" =~ "bytes" ]] ||
15226                                 error "unit is not 'bytes': $unit"
15227                         (( $count == 2 )) || error "count is not 2: $count"
15228                         (( $min == $PAGE_SIZE )) ||
15229                                 error "min is not $PAGE_SIZE: $min"
15230                         (( $max == $PAGE_SIZE )) ||
15231                                 error "max is not $PAGE_SIZE: $max"
15232                         (( $sum == $PAGE_SIZE * 2 )) ||
15233                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
15234                         ;;
15235                 read|write)
15236                         [[ "$unit" =~ "usec" ]] ||
15237                                 error "unit is not 'usec': $unit"
15238                         ;;
15239                 *)      ;;
15240                 esac
15241         done < $TMP/$tfile.tmp
15242
15243         #check that we actually got some stats
15244         [ "$read_bytes" ] || error "Missing read_bytes stats"
15245         [ "$write_bytes" ] || error "Missing write_bytes stats"
15246         [ "$read_bytes" != 0 ] || error "no read done"
15247         [ "$write_bytes" != 0 ] || error "no write done"
15248 }
15249 run_test 127b "verify the llite client stats are sane"
15250
15251 test_127c() { # LU-12394
15252         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
15253         local size
15254         local bsize
15255         local reads
15256         local writes
15257         local count
15258
15259         $LCTL set_param llite.*.extents_stats=1
15260         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
15261
15262         # Use two stripes so there is enough space in default config
15263         $LFS setstripe -c 2 $DIR/$tfile
15264
15265         # Extent stats start at 0-4K and go in power of two buckets
15266         # LL_HIST_START = 12 --> 2^12 = 4K
15267         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
15268         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
15269         # small configs
15270         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
15271                 do
15272                 # Write and read, 2x each, second time at a non-zero offset
15273                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
15274                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
15275                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
15276                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
15277                 rm -f $DIR/$tfile
15278         done
15279
15280         $LCTL get_param llite.*.extents_stats
15281
15282         count=2
15283         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
15284                 do
15285                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
15286                                 grep -m 1 $bsize)
15287                 reads=$(echo $bucket | awk '{print $5}')
15288                 writes=$(echo $bucket | awk '{print $9}')
15289                 [ "$reads" -eq $count ] ||
15290                         error "$reads reads in < $bsize bucket, expect $count"
15291                 [ "$writes" -eq $count ] ||
15292                         error "$writes writes in < $bsize bucket, expect $count"
15293         done
15294
15295         # Test mmap write and read
15296         $LCTL set_param llite.*.extents_stats=c
15297         size=512
15298         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
15299         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
15300         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
15301
15302         $LCTL get_param llite.*.extents_stats
15303
15304         count=$(((size*1024) / PAGE_SIZE))
15305
15306         bsize=$((2 * PAGE_SIZE / 1024))K
15307
15308         bucket=$($LCTL get_param -n llite.*.extents_stats |
15309                         grep -m 1 $bsize)
15310         reads=$(echo $bucket | awk '{print $5}')
15311         writes=$(echo $bucket | awk '{print $9}')
15312         # mmap writes fault in the page first, creating an additonal read
15313         [ "$reads" -eq $((2 * count)) ] ||
15314                 error "$reads reads in < $bsize bucket, expect $count"
15315         [ "$writes" -eq $count ] ||
15316                 error "$writes writes in < $bsize bucket, expect $count"
15317 }
15318 run_test 127c "test llite extent stats with regular & mmap i/o"
15319
15320 test_128() { # bug 15212
15321         touch $DIR/$tfile
15322         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
15323                 find $DIR/$tfile
15324                 find $DIR/$tfile
15325         EOF
15326
15327         result=$(grep error $TMP/$tfile.log)
15328         rm -f $DIR/$tfile $TMP/$tfile.log
15329         [ -z "$result" ] ||
15330                 error "consecutive find's under interactive lfs failed"
15331 }
15332 run_test 128 "interactive lfs for 2 consecutive find's"
15333
15334 set_dir_limits () {
15335         local mntdev
15336         local canondev
15337         local node
15338
15339         local ldproc=/proc/fs/ldiskfs
15340         local facets=$(get_facets MDS)
15341
15342         for facet in ${facets//,/ }; do
15343                 canondev=$(ldiskfs_canon \
15344                            *.$(convert_facet2label $facet).mntdev $facet)
15345                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
15346                         ldproc=/sys/fs/ldiskfs
15347                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
15348                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
15349         done
15350 }
15351
15352 check_mds_dmesg() {
15353         local facets=$(get_facets MDS)
15354         for facet in ${facets//,/ }; do
15355                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
15356         done
15357         return 1
15358 }
15359
15360 test_129() {
15361         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15362         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
15363                 skip "Need MDS version with at least 2.5.56"
15364         if [ "$mds1_FSTYPE" != ldiskfs ]; then
15365                 skip_env "ldiskfs only test"
15366         fi
15367         remote_mds_nodsh && skip "remote MDS with nodsh"
15368
15369         local ENOSPC=28
15370         local has_warning=false
15371
15372         rm -rf $DIR/$tdir
15373         mkdir -p $DIR/$tdir
15374
15375         # block size of mds1
15376         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
15377         set_dir_limits $maxsize $((maxsize * 6 / 8))
15378         stack_trap "set_dir_limits 0 0"
15379         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
15380         local dirsize=$(stat -c%s "$DIR/$tdir")
15381         local nfiles=0
15382         while (( $dirsize <= $maxsize )); do
15383                 $MCREATE $DIR/$tdir/file_base_$nfiles
15384                 rc=$?
15385                 # check two errors:
15386                 # ENOSPC for ext4 max_dir_size, which has been used since
15387                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
15388                 if (( rc == ENOSPC )); then
15389                         set_dir_limits 0 0
15390                         echo "rc=$rc returned as expected after $nfiles files"
15391
15392                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
15393                                 error "create failed w/o dir size limit"
15394
15395                         # messages may be rate limited if test is run repeatedly
15396                         check_mds_dmesg '"is approaching max"' ||
15397                                 echo "warning message should be output"
15398                         check_mds_dmesg '"has reached max"' ||
15399                                 echo "reached message should be output"
15400
15401                         dirsize=$(stat -c%s "$DIR/$tdir")
15402
15403                         [[ $dirsize -ge $maxsize ]] && return 0
15404                         error "dirsize $dirsize < $maxsize after $nfiles files"
15405                 elif (( rc != 0 )); then
15406                         break
15407                 fi
15408                 nfiles=$((nfiles + 1))
15409                 dirsize=$(stat -c%s "$DIR/$tdir")
15410         done
15411
15412         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
15413 }
15414 run_test 129 "test directory size limit ========================"
15415
15416 OLDIFS="$IFS"
15417 cleanup_130() {
15418         trap 0
15419         IFS="$OLDIFS"
15420         rm -f $DIR/$tfile
15421 }
15422
15423 test_130a() {
15424         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
15425         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
15426
15427         trap cleanup_130 EXIT RETURN
15428
15429         local fm_file=$DIR/$tfile
15430         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
15431         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
15432                 error "dd failed for $fm_file"
15433
15434         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
15435         filefrag -ves $fm_file
15436         local rc=$?
15437         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15438                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15439         (( $rc == 0 )) || error "filefrag $fm_file failed"
15440
15441         filefrag_op=$(filefrag -ve -k $fm_file |
15442                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15443         local lun=$($LFS getstripe -i $fm_file)
15444
15445         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
15446         IFS=$'\n'
15447         local tot_len=0
15448         for line in $filefrag_op; do
15449                 local frag_lun=$(echo $line | cut -d: -f5)
15450                 local ext_len=$(echo $line | cut -d: -f4)
15451
15452                 if (( $frag_lun != $lun )); then
15453                         error "FIEMAP on 1-stripe file($fm_file) failed"
15454                         return
15455                 fi
15456                 (( tot_len += ext_len ))
15457         done
15458
15459         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
15460                 error "FIEMAP on 1-stripe file($fm_file) failed"
15461                 return
15462         fi
15463
15464         echo "FIEMAP on single striped file succeeded"
15465 }
15466 run_test 130a "FIEMAP (1-stripe file)"
15467
15468 test_130b() {
15469         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15470
15471         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15472         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15473         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15474                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15475
15476         trap cleanup_130 EXIT RETURN
15477
15478         local fm_file=$DIR/$tfile
15479         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15480                 error "setstripe on $fm_file"
15481
15482         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
15483                 error "dd failed on $fm_file"
15484
15485         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15486         filefrag_op=$(filefrag -ve -k $fm_file |
15487                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15488
15489         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15490                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15491
15492         IFS=$'\n'
15493         local tot_len=0
15494         local num_luns=1
15495
15496         for line in $filefrag_op; do
15497                 local frag_lun=$(echo $line | cut -d: -f5 |
15498                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15499                 local ext_len=$(echo $line | cut -d: -f4)
15500                 if (( $frag_lun != $last_lun )); then
15501                         if (( tot_len != 1024 )); then
15502                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15503                                 return
15504                         else
15505                                 (( num_luns += 1 ))
15506                                 tot_len=0
15507                         fi
15508                 fi
15509                 (( tot_len += ext_len ))
15510                 last_lun=$frag_lun
15511         done
15512         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
15513                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15514                 return
15515         fi
15516
15517         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
15518 }
15519 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
15520
15521 test_130c() {
15522         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15523
15524         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15525         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15526         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15527                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15528
15529         trap cleanup_130 EXIT RETURN
15530
15531         local fm_file=$DIR/$tfile
15532         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
15533
15534         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
15535                 error "dd failed on $fm_file"
15536
15537         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15538         filefrag_op=$(filefrag -ve -k $fm_file |
15539                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15540
15541         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15542                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15543
15544         IFS=$'\n'
15545         local tot_len=0
15546         local num_luns=1
15547         for line in $filefrag_op; do
15548                 local frag_lun=$(echo $line | cut -d: -f5 |
15549                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15550                 local ext_len=$(echo $line | cut -d: -f4)
15551                 if (( $frag_lun != $last_lun )); then
15552                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
15553                         if (( logical != 512 )); then
15554                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
15555                                 return
15556                         fi
15557                         if (( tot_len != 512 )); then
15558                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15559                                 return
15560                         else
15561                                 (( num_luns += 1 ))
15562                                 tot_len=0
15563                         fi
15564                 fi
15565                 (( tot_len += ext_len ))
15566                 last_lun=$frag_lun
15567         done
15568         if (( num_luns != 2 || tot_len != 512 )); then
15569                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15570                 return
15571         fi
15572
15573         echo "FIEMAP on 2-stripe file with hole succeeded"
15574 }
15575 run_test 130c "FIEMAP (2-stripe file with hole)"
15576
15577 test_130d() {
15578         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
15579
15580         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15581         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15582         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15583                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15584
15585         trap cleanup_130 EXIT RETURN
15586
15587         local fm_file=$DIR/$tfile
15588         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15589                         error "setstripe on $fm_file"
15590
15591         local actual_stripe_count=$($LFS getstripe -c $fm_file)
15592         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
15593                 error "dd failed on $fm_file"
15594
15595         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15596         filefrag_op=$(filefrag -ve -k $fm_file |
15597                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15598
15599         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15600                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15601
15602         IFS=$'\n'
15603         local tot_len=0
15604         local num_luns=1
15605         for line in $filefrag_op; do
15606                 local frag_lun=$(echo $line | cut -d: -f5 |
15607                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15608                 local ext_len=$(echo $line | cut -d: -f4)
15609                 if (( $frag_lun != $last_lun )); then
15610                         if (( tot_len != 1024 )); then
15611                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15612                                 return
15613                         else
15614                                 (( num_luns += 1 ))
15615                                 local tot_len=0
15616                         fi
15617                 fi
15618                 (( tot_len += ext_len ))
15619                 last_lun=$frag_lun
15620         done
15621         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
15622                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15623                 return
15624         fi
15625
15626         echo "FIEMAP on N-stripe file succeeded"
15627 }
15628 run_test 130d "FIEMAP (N-stripe file)"
15629
15630 test_130e() {
15631         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15632
15633         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15634         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15635         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15636                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15637
15638         trap cleanup_130 EXIT RETURN
15639
15640         local fm_file=$DIR/$tfile
15641         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
15642         stack_trap "rm -f $fm_file"
15643
15644         local num_blks=512
15645         local expected_len=$(( (num_blks / 2) * 64 ))
15646         for ((i = 0; i < $num_blks; i++)); do
15647                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
15648                         conv=notrunc > /dev/null 2>&1
15649         done
15650
15651         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15652         filefrag_op=$(filefrag -ve -k $fm_file |
15653                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15654
15655         local last_lun=$(echo $filefrag_op | cut -d: -f5)
15656
15657         IFS=$'\n'
15658         local tot_len=0
15659         local num_luns=1
15660         for line in $filefrag_op; do
15661                 local frag_lun=$(echo $line | cut -d: -f5)
15662                 local ext_len=$(echo $line | cut -d: -f4)
15663                 if (( $frag_lun != $last_lun )); then
15664                         if (( tot_len != $expected_len )); then
15665                                 error "OST$last_lun $tot_len != $expected_len"
15666                         else
15667                                 (( num_luns += 1 ))
15668                                 tot_len=0
15669                         fi
15670                 fi
15671                 (( tot_len += ext_len ))
15672                 last_lun=$frag_lun
15673         done
15674         if (( num_luns != 2 || tot_len != $expected_len )); then
15675                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
15676         fi
15677
15678         echo "FIEMAP with continuation calls succeeded"
15679 }
15680 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
15681
15682 test_130f() {
15683         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15684         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15685         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15686                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15687
15688         local fm_file=$DIR/$tfile
15689         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
15690                 error "multiop create with lov_delay_create on $fm_file"
15691
15692         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15693         filefrag_extents=$(filefrag -vek $fm_file |
15694                            awk '/extents? found/ { print $2 }')
15695         if (( $filefrag_extents != 0 )); then
15696                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
15697         fi
15698
15699         rm -f $fm_file
15700 }
15701 run_test 130f "FIEMAP (unstriped file)"
15702
15703 test_130g() {
15704         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
15705                 skip "Need MDS version with at least 2.12.53 for overstriping"
15706         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15707         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15708         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15709                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15710
15711         local file=$DIR/$tfile
15712         local nr=$((OSTCOUNT * 100))
15713
15714         $LFS setstripe -C $nr -S1M $file ||
15715                 error "failed to setstripe -C $nr $file"
15716
15717         stack_trap "rm -f $file"
15718         dd if=/dev/zero of=$file count=$nr bs=1M
15719         sync
15720         nr=$($LFS getstripe -c $file)
15721
15722         local extents=$(filefrag -v $file |
15723                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
15724
15725         echo "filefrag list $extents extents in file with stripecount $nr"
15726         if (( extents < nr )); then
15727                 $LFS getstripe $file
15728                 filefrag -v $file
15729                 error "filefrag printed $extents < $nr extents"
15730         fi
15731 }
15732 run_test 130g "FIEMAP (overstripe file)"
15733
15734 # Test for writev/readv
15735 test_131a() {
15736         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
15737                 error "writev test failed"
15738         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
15739                 error "readv failed"
15740         rm -f $DIR/$tfile
15741 }
15742 run_test 131a "test iov's crossing stripe boundary for writev/readv"
15743
15744 test_131b() {
15745         local fsize=$((524288 + 1048576 + 1572864))
15746         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
15747                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15748                         error "append writev test failed"
15749
15750         ((fsize += 1572864 + 1048576))
15751         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
15752                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15753                         error "append writev test failed"
15754         rm -f $DIR/$tfile
15755 }
15756 run_test 131b "test append writev"
15757
15758 test_131c() {
15759         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
15760         error "NOT PASS"
15761 }
15762 run_test 131c "test read/write on file w/o objects"
15763
15764 test_131d() {
15765         rwv -f $DIR/$tfile -w -n 1 1572864
15766         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
15767         if [ "$NOB" != 1572864 ]; then
15768                 error "Short read filed: read $NOB bytes instead of 1572864"
15769         fi
15770         rm -f $DIR/$tfile
15771 }
15772 run_test 131d "test short read"
15773
15774 test_131e() {
15775         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
15776         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
15777         error "read hitting hole failed"
15778         rm -f $DIR/$tfile
15779 }
15780 run_test 131e "test read hitting hole"
15781
15782 check_stats() {
15783         local facet=$1
15784         local op=$2
15785         local want=${3:-0}
15786         local res
15787
15788         # open             11 samples [usecs] 468 4793 13658 35791898
15789         case $facet in
15790         mds*) res=($(do_facet $facet \
15791                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
15792                  ;;
15793         ost*) res=($(do_facet $facet \
15794                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
15795                  ;;
15796         *) error "Wrong facet '$facet'" ;;
15797         esac
15798         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
15799         # if $want is zero, it means any stat increment is ok.
15800         if (( $want > 0 )); then
15801                 local count=${res[1]}
15802
15803                 if (( $count != $want )); then
15804                         if [[ $facet =~ "mds" ]]; then
15805                                 do_nodes $(comma_list $(mdts_nodes)) \
15806                                         $LCTL get_param mdt.*.md_stats
15807                         else
15808                                 do_nodes $(comma_list $(osts-nodes)) \
15809                                         $LCTL get_param obdfilter.*.stats
15810                         fi
15811                         error "The $op counter on $facet is $count, not $want"
15812                 fi
15813         fi
15814 }
15815
15816 test_133a() {
15817         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15818         remote_ost_nodsh && skip "remote OST with nodsh"
15819         remote_mds_nodsh && skip "remote MDS with nodsh"
15820         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15821                 skip_env "MDS doesn't support rename stats"
15822
15823         local testdir=$DIR/${tdir}/stats_testdir
15824
15825         mkdir_on_mdt0 $DIR/${tdir}
15826
15827         # clear stats.
15828         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15829         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15830
15831         # verify mdt stats first.
15832         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15833         check_stats $SINGLEMDS "mkdir" 1
15834
15835         # clear "open" from "lfs mkdir" above
15836         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15837         touch ${testdir}/${tfile} || error "touch failed"
15838         check_stats $SINGLEMDS "open" 1
15839         check_stats $SINGLEMDS "close" 1
15840         # open should match close
15841         ls -lR ${testdir}
15842         check_stats $SINGLEMDS "open" 2
15843         check_stats $SINGLEMDS "close" 2
15844         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
15845                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
15846                 check_stats $SINGLEMDS "mknod" 2
15847         }
15848         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
15849         check_stats $SINGLEMDS "unlink" 1
15850         rm -f ${testdir}/${tfile} || error "file remove failed"
15851         check_stats $SINGLEMDS "unlink" 2
15852
15853         # remove working dir and check mdt stats again.
15854         rmdir ${testdir} || error "rmdir failed"
15855         check_stats $SINGLEMDS "rmdir" 1
15856
15857         local testdir1=$DIR/${tdir}/stats_testdir1
15858         mkdir_on_mdt0 ${testdir}
15859         mkdir_on_mdt0 ${testdir1}
15860         touch ${testdir1}/test1
15861         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
15862         check_stats $SINGLEMDS "crossdir_rename" 1
15863
15864         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
15865         check_stats $SINGLEMDS "samedir_rename" 1
15866
15867         rm -rf $DIR/${tdir}
15868 }
15869 run_test 133a "Verifying MDT stats ========================================"
15870
15871 test_133b() {
15872         local res
15873
15874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15875         remote_ost_nodsh && skip "remote OST with nodsh"
15876         remote_mds_nodsh && skip "remote MDS with nodsh"
15877
15878         local testdir=$DIR/${tdir}/stats_testdir
15879
15880         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15881         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15882         touch ${testdir}/${tfile} || error "touch failed"
15883         cancel_lru_locks mdc
15884
15885         # clear stats.
15886         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15887         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15888
15889         # extra mdt stats verification.
15890         chmod 444 ${testdir}/${tfile} || error "chmod failed"
15891         check_stats $SINGLEMDS "setattr" 1
15892         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15893         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
15894         then            # LU-1740
15895                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
15896                 check_stats $SINGLEMDS "getattr" 1
15897         fi
15898         rm -rf $DIR/${tdir}
15899
15900         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
15901         # so the check below is not reliable
15902         [ $MDSCOUNT -eq 1 ] || return 0
15903
15904         # Sleep to avoid a cached response.
15905         #define OBD_STATFS_CACHE_SECONDS 1
15906         sleep 2
15907         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15908         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15909         $LFS df || error "lfs failed"
15910         check_stats $SINGLEMDS "statfs" 1
15911
15912         # check aggregated statfs (LU-10018)
15913         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
15914                 return 0
15915         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
15916                 return 0
15917         sleep 2
15918         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15919         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15920         df $DIR
15921         check_stats $SINGLEMDS "statfs" 1
15922
15923         # We want to check that the client didn't send OST_STATFS to
15924         # ost1 but the MDT also uses OST_STATFS for precreate. So some
15925         # extra care is needed here.
15926         if remote_mds; then
15927                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
15928                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
15929
15930                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
15931                 [ "$res" ] && error "OST got STATFS"
15932         fi
15933
15934         return 0
15935 }
15936 run_test 133b "Verifying extra MDT stats =================================="
15937
15938 test_133c() {
15939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15940         remote_ost_nodsh && skip "remote OST with nodsh"
15941         remote_mds_nodsh && skip "remote MDS with nodsh"
15942
15943         local testdir=$DIR/$tdir/stats_testdir
15944
15945         test_mkdir -p $testdir
15946
15947         # verify obdfilter stats.
15948         $LFS setstripe -c 1 -i 0 $testdir/$tfile
15949         sync
15950         cancel_lru_locks osc
15951         wait_delete_completed
15952
15953         # clear stats.
15954         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15955         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15956
15957         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
15958                 error "dd failed"
15959         sync
15960         cancel_lru_locks osc
15961         check_stats ost1 "write" 1
15962
15963         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
15964         check_stats ost1 "read" 1
15965
15966         > $testdir/$tfile || error "truncate failed"
15967         check_stats ost1 "punch" 1
15968
15969         rm -f $testdir/$tfile || error "file remove failed"
15970         wait_delete_completed
15971         check_stats ost1 "destroy" 1
15972
15973         rm -rf $DIR/$tdir
15974 }
15975 run_test 133c "Verifying OST stats ========================================"
15976
15977 order_2() {
15978         local value=$1
15979         local orig=$value
15980         local order=1
15981
15982         while [ $value -ge 2 ]; do
15983                 order=$((order*2))
15984                 value=$((value/2))
15985         done
15986
15987         if [ $orig -gt $order ]; then
15988                 order=$((order*2))
15989         fi
15990         echo $order
15991 }
15992
15993 size_in_KMGT() {
15994     local value=$1
15995     local size=('K' 'M' 'G' 'T');
15996     local i=0
15997     local size_string=$value
15998
15999     while [ $value -ge 1024 ]; do
16000         if [ $i -gt 3 ]; then
16001             #T is the biggest unit we get here, if that is bigger,
16002             #just return XXXT
16003             size_string=${value}T
16004             break
16005         fi
16006         value=$((value >> 10))
16007         if [ $value -lt 1024 ]; then
16008             size_string=${value}${size[$i]}
16009             break
16010         fi
16011         i=$((i + 1))
16012     done
16013
16014     echo $size_string
16015 }
16016
16017 get_rename_size() {
16018         local size=$1
16019         local context=${2:-.}
16020         local sample=$(do_facet $SINGLEMDS $LCTL \
16021                 get_param mdt.$FSNAME-MDT0000.rename_stats |
16022                 grep -A1 $context |
16023                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
16024         echo $sample
16025 }
16026
16027 test_133d() {
16028         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16029         remote_ost_nodsh && skip "remote OST with nodsh"
16030         remote_mds_nodsh && skip "remote MDS with nodsh"
16031         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
16032                 skip_env "MDS doesn't support rename stats"
16033
16034         local testdir1=$DIR/${tdir}/stats_testdir1
16035         local testdir2=$DIR/${tdir}/stats_testdir2
16036         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
16037
16038         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
16039
16040         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
16041         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
16042
16043         createmany -o $testdir1/test 512 || error "createmany failed"
16044
16045         # check samedir rename size
16046         mv ${testdir1}/test0 ${testdir1}/test_0
16047
16048         local testdir1_size=$(ls -l $DIR/${tdir} |
16049                 awk '/stats_testdir1/ {print $5}')
16050         local testdir2_size=$(ls -l $DIR/${tdir} |
16051                 awk '/stats_testdir2/ {print $5}')
16052
16053         testdir1_size=$(order_2 $testdir1_size)
16054         testdir2_size=$(order_2 $testdir2_size)
16055
16056         testdir1_size=$(size_in_KMGT $testdir1_size)
16057         testdir2_size=$(size_in_KMGT $testdir2_size)
16058
16059         echo "source rename dir size: ${testdir1_size}"
16060         echo "target rename dir size: ${testdir2_size}"
16061
16062         local cmd="do_facet $SINGLEMDS $LCTL "
16063         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
16064
16065         eval $cmd || error "$cmd failed"
16066         local samedir=$($cmd | grep 'same_dir')
16067         local same_sample=$(get_rename_size $testdir1_size)
16068         [ -z "$samedir" ] && error "samedir_rename_size count error"
16069         [[ $same_sample -eq 1 ]] ||
16070                 error "samedir_rename_size error $same_sample"
16071         echo "Check same dir rename stats success"
16072
16073         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
16074
16075         # check crossdir rename size
16076         mv ${testdir1}/test_0 ${testdir2}/test_0
16077
16078         testdir1_size=$(ls -l $DIR/${tdir} |
16079                 awk '/stats_testdir1/ {print $5}')
16080         testdir2_size=$(ls -l $DIR/${tdir} |
16081                 awk '/stats_testdir2/ {print $5}')
16082
16083         testdir1_size=$(order_2 $testdir1_size)
16084         testdir2_size=$(order_2 $testdir2_size)
16085
16086         testdir1_size=$(size_in_KMGT $testdir1_size)
16087         testdir2_size=$(size_in_KMGT $testdir2_size)
16088
16089         echo "source rename dir size: ${testdir1_size}"
16090         echo "target rename dir size: ${testdir2_size}"
16091
16092         eval $cmd || error "$cmd failed"
16093         local crossdir=$($cmd | grep 'crossdir')
16094         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
16095         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
16096         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
16097         [[ $src_sample -eq 1 ]] ||
16098                 error "crossdir_rename_size error $src_sample"
16099         [[ $tgt_sample -eq 1 ]] ||
16100                 error "crossdir_rename_size error $tgt_sample"
16101         echo "Check cross dir rename stats success"
16102         rm -rf $DIR/${tdir}
16103 }
16104 run_test 133d "Verifying rename_stats ========================================"
16105
16106 test_133e() {
16107         remote_mds_nodsh && skip "remote MDS with nodsh"
16108         remote_ost_nodsh && skip "remote OST with nodsh"
16109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16110
16111         local testdir=$DIR/${tdir}/stats_testdir
16112         local ctr f0 f1 bs=32768 count=42 sum
16113
16114         mkdir -p ${testdir} || error "mkdir failed"
16115
16116         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
16117
16118         for ctr in {write,read}_bytes; do
16119                 sync
16120                 cancel_lru_locks osc
16121
16122                 do_facet ost1 $LCTL set_param -n \
16123                         "obdfilter.*.exports.clear=clear"
16124
16125                 if [ $ctr = write_bytes ]; then
16126                         f0=/dev/zero
16127                         f1=${testdir}/${tfile}
16128                 else
16129                         f0=${testdir}/${tfile}
16130                         f1=/dev/null
16131                 fi
16132
16133                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
16134                         error "dd failed"
16135                 sync
16136                 cancel_lru_locks osc
16137
16138                 sum=$(do_facet ost1 $LCTL get_param \
16139                         "obdfilter.*.exports.*.stats" |
16140                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
16141                                 $1 == ctr { sum += $7 }
16142                                 END { printf("%0.0f", sum) }')
16143
16144                 if ((sum != bs * count)); then
16145                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
16146                 fi
16147         done
16148
16149         rm -rf $DIR/${tdir}
16150 }
16151 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
16152
16153 test_133f() {
16154         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
16155                 skip "too old lustre for get_param -R ($facet_ver)"
16156
16157         # verifying readability.
16158         $LCTL get_param -R '*' &> /dev/null
16159
16160         # Verifing writability with badarea_io.
16161         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
16162         local skipped_params='force_lbug|changelog_mask|daemon_file'
16163         $LCTL list_param -FR '*' | grep '=' | tr -d = |
16164                 egrep -v "$skipped_params" |
16165                 xargs -n 1 find $proc_dirs -name |
16166                 xargs -n 1 badarea_io ||
16167                 error "client badarea_io failed"
16168
16169         # remount the FS in case writes/reads /proc break the FS
16170         cleanup || error "failed to unmount"
16171         setup || error "failed to setup"
16172 }
16173 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
16174
16175 test_133g() {
16176         remote_mds_nodsh && skip "remote MDS with nodsh"
16177         remote_ost_nodsh && skip "remote OST with nodsh"
16178
16179         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
16180         local proc_dirs_str=$(eval echo $proc_dirs)
16181         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
16182         local facet
16183         for facet in mds1 ost1; do
16184                 local facet_ver=$(lustre_version_code $facet)
16185                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
16186                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
16187                 else
16188                         log "$facet: too old lustre for get_param -R"
16189                 fi
16190                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
16191                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
16192                                 tr -d = | egrep -v $skipped_params |
16193                                 xargs -n 1 find $proc_dirs_str -name |
16194                                 xargs -n 1 badarea_io" ||
16195                                         error "$facet badarea_io failed"
16196                 else
16197                         skip_noexit "$facet: too old lustre for get_param -R"
16198                 fi
16199         done
16200
16201         # remount the FS in case writes/reads /proc break the FS
16202         cleanup || error "failed to unmount"
16203         setup || error "failed to setup"
16204 }
16205 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
16206
16207 test_133h() {
16208         remote_mds_nodsh && skip "remote MDS with nodsh"
16209         remote_ost_nodsh && skip "remote OST with nodsh"
16210         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
16211                 skip "Need MDS version at least 2.9.54"
16212
16213         local facet
16214         for facet in client mds1 ost1; do
16215                 # Get the list of files that are missing the terminating newline
16216                 local plist=$(do_facet $facet
16217                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
16218                 local ent
16219                 for ent in $plist; do
16220                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
16221                                 awk -v FS='\v' -v RS='\v\v' \
16222                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
16223                                         print FILENAME}'" 2>/dev/null)
16224                         [ -z $missing ] || {
16225                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
16226                                 error "file does not end with newline: $facet-$ent"
16227                         }
16228                 done
16229         done
16230 }
16231 run_test 133h "Proc files should end with newlines"
16232
16233 test_134a() {
16234         remote_mds_nodsh && skip "remote MDS with nodsh"
16235         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
16236                 skip "Need MDS version at least 2.7.54"
16237
16238         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
16239         cancel_lru_locks mdc
16240
16241         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
16242         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
16243         [ $unused -eq 0 ] || error "$unused locks are not cleared"
16244
16245         local nr=1000
16246         createmany -o $DIR/$tdir/f $nr ||
16247                 error "failed to create $nr files in $DIR/$tdir"
16248         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
16249
16250         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
16251         do_facet mds1 $LCTL set_param fail_loc=0x327
16252         do_facet mds1 $LCTL set_param fail_val=500
16253         touch $DIR/$tdir/m
16254
16255         echo "sleep 10 seconds ..."
16256         sleep 10
16257         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
16258
16259         do_facet mds1 $LCTL set_param fail_loc=0
16260         do_facet mds1 $LCTL set_param fail_val=0
16261         [ $lck_cnt -lt $unused ] ||
16262                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
16263
16264         rm $DIR/$tdir/m
16265         unlinkmany $DIR/$tdir/f $nr
16266 }
16267 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
16268
16269 test_134b() {
16270         remote_mds_nodsh && skip "remote MDS with nodsh"
16271         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
16272                 skip "Need MDS version at least 2.7.54"
16273
16274         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
16275         cancel_lru_locks mdc
16276
16277         local low_wm=$(do_facet mds1 $LCTL get_param -n \
16278                         ldlm.lock_reclaim_threshold_mb)
16279         # disable reclaim temporarily
16280         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
16281
16282         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
16283         do_facet mds1 $LCTL set_param fail_loc=0x328
16284         do_facet mds1 $LCTL set_param fail_val=500
16285
16286         $LCTL set_param debug=+trace
16287
16288         local nr=600
16289         createmany -o $DIR/$tdir/f $nr &
16290         local create_pid=$!
16291
16292         echo "Sleep $TIMEOUT seconds ..."
16293         sleep $TIMEOUT
16294         if ! ps -p $create_pid  > /dev/null 2>&1; then
16295                 do_facet mds1 $LCTL set_param fail_loc=0
16296                 do_facet mds1 $LCTL set_param fail_val=0
16297                 do_facet mds1 $LCTL set_param \
16298                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
16299                 error "createmany finished incorrectly!"
16300         fi
16301         do_facet mds1 $LCTL set_param fail_loc=0
16302         do_facet mds1 $LCTL set_param fail_val=0
16303         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
16304         wait $create_pid || return 1
16305
16306         unlinkmany $DIR/$tdir/f $nr
16307 }
16308 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
16309
16310 test_135() {
16311         remote_mds_nodsh && skip "remote MDS with nodsh"
16312         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
16313                 skip "Need MDS version at least 2.13.50"
16314         local fname
16315
16316         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
16317
16318 #define OBD_FAIL_PLAIN_RECORDS 0x1319
16319         #set only one record at plain llog
16320         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
16321
16322         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
16323
16324         #fill already existed plain llog each 64767
16325         #wrapping whole catalog
16326         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
16327
16328         createmany -o $DIR/$tdir/$tfile_ 64700
16329         for (( i = 0; i < 64700; i = i + 2 ))
16330         do
16331                 rm $DIR/$tdir/$tfile_$i &
16332                 rm $DIR/$tdir/$tfile_$((i + 1)) &
16333                 local pid=$!
16334                 wait $pid
16335         done
16336
16337         #waiting osp synchronization
16338         wait_delete_completed
16339 }
16340 run_test 135 "Race catalog processing"
16341
16342 test_136() {
16343         remote_mds_nodsh && skip "remote MDS with nodsh"
16344         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
16345                 skip "Need MDS version at least 2.13.50"
16346         local fname
16347
16348         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
16349         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
16350         #set only one record at plain llog
16351 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
16352         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
16353
16354         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
16355
16356         #fill already existed 2 plain llogs each 64767
16357         #wrapping whole catalog
16358         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
16359         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
16360         wait_delete_completed
16361
16362         createmany -o $DIR/$tdir/$tfile_ 10
16363         sleep 25
16364
16365         do_facet $SINGLEMDS $LCTL set_param fail_val=3
16366         for (( i = 0; i < 10; i = i + 3 ))
16367         do
16368                 rm $DIR/$tdir/$tfile_$i &
16369                 rm $DIR/$tdir/$tfile_$((i + 1)) &
16370                 local pid=$!
16371                 wait $pid
16372                 sleep 7
16373                 rm $DIR/$tdir/$tfile_$((i + 2)) &
16374         done
16375
16376         #waiting osp synchronization
16377         wait_delete_completed
16378 }
16379 run_test 136 "Race catalog processing 2"
16380
16381 test_140() { #bug-17379
16382         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16383
16384         test_mkdir $DIR/$tdir
16385         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
16386         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
16387
16388         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
16389         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
16390         local i=0
16391         while i=$((i + 1)); do
16392                 test_mkdir $i
16393                 cd $i || error "Changing to $i"
16394                 ln -s ../stat stat || error "Creating stat symlink"
16395                 # Read the symlink until ELOOP present,
16396                 # not LBUGing the system is considered success,
16397                 # we didn't overrun the stack.
16398                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
16399                 if [ $ret -ne 0 ]; then
16400                         if [ $ret -eq 40 ]; then
16401                                 break  # -ELOOP
16402                         else
16403                                 error "Open stat symlink"
16404                                         return
16405                         fi
16406                 fi
16407         done
16408         i=$((i - 1))
16409         echo "The symlink depth = $i"
16410         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
16411                 error "Invalid symlink depth"
16412
16413         # Test recursive symlink
16414         ln -s symlink_self symlink_self
16415         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
16416         echo "open symlink_self returns $ret"
16417         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
16418 }
16419 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
16420
16421 test_150a() {
16422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16423
16424         local TF="$TMP/$tfile"
16425
16426         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16427         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16428         cp $TF $DIR/$tfile
16429         cancel_lru_locks $OSC
16430         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
16431         remount_client $MOUNT
16432         df -P $MOUNT
16433         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
16434
16435         $TRUNCATE $TF 6000
16436         $TRUNCATE $DIR/$tfile 6000
16437         cancel_lru_locks $OSC
16438         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
16439
16440         echo "12345" >>$TF
16441         echo "12345" >>$DIR/$tfile
16442         cancel_lru_locks $OSC
16443         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
16444
16445         echo "12345" >>$TF
16446         echo "12345" >>$DIR/$tfile
16447         cancel_lru_locks $OSC
16448         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
16449 }
16450 run_test 150a "truncate/append tests"
16451
16452 test_150b() {
16453         check_set_fallocate_or_skip
16454         local out
16455
16456         touch $DIR/$tfile
16457         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16458         out=$(check_fallocate $DIR/$tfile 2>&1) ||
16459                 skip_eopnotsupp "$out|check_fallocate failed"
16460 }
16461 run_test 150b "Verify fallocate (prealloc) functionality"
16462
16463 test_150bb() {
16464         check_set_fallocate_or_skip
16465
16466         touch $DIR/$tfile
16467         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16468         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
16469         > $DIR/$tfile
16470         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
16471         # precomputed md5sum for 20MB of zeroes
16472         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
16473         local sum=($(md5sum $DIR/$tfile))
16474
16475         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
16476
16477         check_set_fallocate 1
16478
16479         > $DIR/$tfile
16480         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
16481         sum=($(md5sum $DIR/$tfile))
16482
16483         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
16484 }
16485 run_test 150bb "Verify fallocate modes both zero space"
16486
16487 test_150c() {
16488         check_set_fallocate_or_skip
16489         local striping="-c2"
16490
16491         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16492         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
16493         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
16494         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
16495         local want=$((OSTCOUNT * 1048576))
16496
16497         # Must allocate all requested space, not more than 5% extra
16498         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16499                 error "bytes $bytes is not $want"
16500
16501         rm -f $DIR/$tfile
16502
16503         echo "verify fallocate on PFL file"
16504
16505         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
16506
16507         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
16508                 error "Create $DIR/$tfile failed"
16509         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
16510         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
16511         want=$((512 * 1048576))
16512
16513         # Must allocate all requested space, not more than 5% extra
16514         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16515                 error "bytes $bytes is not $want"
16516 }
16517 run_test 150c "Verify fallocate Size and Blocks"
16518
16519 test_150d() {
16520         check_set_fallocate_or_skip
16521         local striping="-c2"
16522
16523         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
16524
16525         stack_trap "rm -f $DIR/$tdir; wait_delete_completed"
16526         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
16527                 error "setstripe failed"
16528         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
16529         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
16530         local want=$((OSTCOUNT * 1048576))
16531
16532         # Must allocate all requested space, not more than 5% extra
16533         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16534                 error "bytes $bytes is not $want"
16535 }
16536 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
16537
16538 test_150e() {
16539         check_set_fallocate_or_skip
16540
16541         echo "df before:"
16542         $LFS df
16543         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16544         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16545                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16546
16547         # Find OST with Minimum Size
16548         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16549                        sort -un | head -1)
16550
16551         # Get 100MB per OST of the available space to reduce run time
16552         # else 60% of the available space if we are running SLOW tests
16553         if [ $SLOW == "no" ]; then
16554                 local space=$((1024 * 100 * OSTCOUNT))
16555         else
16556                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
16557         fi
16558
16559         fallocate -l${space}k $DIR/$tfile ||
16560                 error "fallocate ${space}k $DIR/$tfile failed"
16561         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
16562
16563         # get size immediately after fallocate. This should be correctly
16564         # updated
16565         local size=$(stat -c '%s' $DIR/$tfile)
16566         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
16567
16568         # Sleep for a while for statfs to get updated. And not pull from cache.
16569         sleep 2
16570
16571         echo "df after fallocate:"
16572         $LFS df
16573
16574         (( size / 1024 == space )) || error "size $size != requested $space"
16575         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
16576                 error "used $used < space $space"
16577
16578         rm $DIR/$tfile || error "rm failed"
16579         sync
16580         wait_delete_completed
16581
16582         echo "df after unlink:"
16583         $LFS df
16584 }
16585 run_test 150e "Verify 60% of available OST space consumed by fallocate"
16586
16587 test_150f() {
16588         local size
16589         local blocks
16590         local want_size_before=20480 # in bytes
16591         local want_blocks_before=40 # 512 sized blocks
16592         local want_blocks_after=24  # 512 sized blocks
16593         local length=$(((want_blocks_before - want_blocks_after) * 512))
16594
16595         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16596                 skip "need at least 2.14.0 for fallocate punch"
16597
16598         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16599                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16600         fi
16601
16602         check_set_fallocate_or_skip
16603         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16604
16605         [[ "x$DOM" == "xyes" ]] &&
16606                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
16607
16608         echo "Verify fallocate punch: Range within the file range"
16609         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16610                 error "dd failed for bs 4096 and count 5"
16611
16612         # Call fallocate with punch range which is within the file range
16613         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
16614                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
16615         # client must see changes immediately after fallocate
16616         size=$(stat -c '%s' $DIR/$tfile)
16617         blocks=$(stat -c '%b' $DIR/$tfile)
16618
16619         # Verify punch worked.
16620         (( blocks == want_blocks_after )) ||
16621                 error "punch failed: blocks $blocks != $want_blocks_after"
16622
16623         (( size == want_size_before )) ||
16624                 error "punch failed: size $size != $want_size_before"
16625
16626         # Verify there is hole in file
16627         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
16628         # precomputed md5sum
16629         local expect="4a9a834a2db02452929c0a348273b4aa"
16630
16631         cksum=($(md5sum $DIR/$tfile))
16632         [[ "${cksum[0]}" == "$expect" ]] ||
16633                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16634
16635         # Start second sub-case for fallocate punch.
16636         echo "Verify fallocate punch: Range overlapping and less than blocksize"
16637         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16638                 error "dd failed for bs 4096 and count 5"
16639
16640         # Punch range less than block size will have no change in block count
16641         want_blocks_after=40  # 512 sized blocks
16642
16643         # Punch overlaps two blocks and less than blocksize
16644         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
16645                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
16646         size=$(stat -c '%s' $DIR/$tfile)
16647         blocks=$(stat -c '%b' $DIR/$tfile)
16648
16649         # Verify punch worked.
16650         (( blocks == want_blocks_after )) ||
16651                 error "punch failed: blocks $blocks != $want_blocks_after"
16652
16653         (( size == want_size_before )) ||
16654                 error "punch failed: size $size != $want_size_before"
16655
16656         # Verify if range is really zero'ed out. We expect Zeros.
16657         # precomputed md5sum
16658         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
16659         cksum=($(md5sum $DIR/$tfile))
16660         [[ "${cksum[0]}" == "$expect" ]] ||
16661                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16662 }
16663 run_test 150f "Verify fallocate punch functionality"
16664
16665 test_150g() {
16666         local space
16667         local size
16668         local blocks
16669         local blocks_after
16670         local size_after
16671         local BS=4096 # Block size in bytes
16672
16673         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16674                 skip "need at least 2.14.0 for fallocate punch"
16675
16676         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16677                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16678         fi
16679
16680         check_set_fallocate_or_skip
16681         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16682
16683         if [[ "x$DOM" == "xyes" ]]; then
16684                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
16685                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
16686         else
16687                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16688                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16689         fi
16690
16691         # Get 100MB per OST of the available space to reduce run time
16692         # else 60% of the available space if we are running SLOW tests
16693         if [ $SLOW == "no" ]; then
16694                 space=$((1024 * 100 * OSTCOUNT))
16695         else
16696                 # Find OST with Minimum Size
16697                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16698                         sort -un | head -1)
16699                 echo "min size OST: $space"
16700                 space=$(((space * 60)/100 * OSTCOUNT))
16701         fi
16702         # space in 1k units, round to 4k blocks
16703         local blkcount=$((space * 1024 / $BS))
16704
16705         echo "Verify fallocate punch: Very large Range"
16706         fallocate -l${space}k $DIR/$tfile ||
16707                 error "fallocate ${space}k $DIR/$tfile failed"
16708         # write 1M at the end, start and in the middle
16709         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
16710                 error "dd failed: bs $BS count 256"
16711         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
16712                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
16713         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
16714                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
16715
16716         # Gather stats.
16717         size=$(stat -c '%s' $DIR/$tfile)
16718
16719         # gather punch length.
16720         local punch_size=$((size - (BS * 2)))
16721
16722         echo "punch_size = $punch_size"
16723         echo "size - punch_size: $((size - punch_size))"
16724         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
16725
16726         # Call fallocate to punch all except 2 blocks. We leave the
16727         # first and the last block
16728         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
16729         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
16730                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
16731
16732         size_after=$(stat -c '%s' $DIR/$tfile)
16733         blocks_after=$(stat -c '%b' $DIR/$tfile)
16734
16735         # Verify punch worked.
16736         # Size should be kept
16737         (( size == size_after )) ||
16738                 error "punch failed: size $size != $size_after"
16739
16740         # two 4k data blocks to remain plus possible 1 extra extent block
16741         (( blocks_after <= ((BS / 512) * 3) )) ||
16742                 error "too many blocks remains: $blocks_after"
16743
16744         # Verify that file has hole between the first and the last blocks
16745         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
16746         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
16747
16748         echo "Hole at [$hole_start, $hole_end)"
16749         (( hole_start == BS )) ||
16750                 error "no hole at offset $BS after punch"
16751
16752         (( hole_end == BS + punch_size )) ||
16753                 error "data at offset $hole_end < $((BS + punch_size))"
16754 }
16755 run_test 150g "Verify fallocate punch on large range"
16756
16757 test_150h() {
16758         local file=$DIR/$tfile
16759         local size
16760
16761         check_set_fallocate_or_skip
16762         statx_supported || skip_env "Test must be statx() syscall supported"
16763
16764         # fallocate() does not update the size information on the MDT
16765         fallocate -l 16K $file || error "failed to fallocate $file"
16766         cancel_lru_locks $OSC
16767         # STATX with cached-always mode will not send glimpse RPCs to OST,
16768         # it uses the caching attrs on the client side as much as possible.
16769         size=$($STATX --cached=always -c %s $file)
16770         [ $size == 16384 ] ||
16771                 error "size after fallocate() is $size, expected 16384"
16772 }
16773 run_test 150h "Verify extend fallocate updates the file size"
16774
16775 #LU-2902 roc_hit was not able to read all values from lproc
16776 function roc_hit_init() {
16777         local list=$(comma_list $(osts_nodes))
16778         local dir=$DIR/$tdir-check
16779         local file=$dir/$tfile
16780         local BEFORE
16781         local AFTER
16782         local idx
16783
16784         test_mkdir $dir
16785         #use setstripe to do a write to every ost
16786         for i in $(seq 0 $((OSTCOUNT-1))); do
16787                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
16788                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
16789                 idx=$(printf %04x $i)
16790                 BEFORE=$(get_osd_param $list *OST*$idx stats |
16791                         awk '$1 == "cache_access" {sum += $7}
16792                                 END { printf("%0.0f", sum) }')
16793
16794                 cancel_lru_locks osc
16795                 cat $file >/dev/null
16796
16797                 AFTER=$(get_osd_param $list *OST*$idx stats |
16798                         awk '$1 == "cache_access" {sum += $7}
16799                                 END { printf("%0.0f", sum) }')
16800
16801                 echo BEFORE:$BEFORE AFTER:$AFTER
16802                 if ! let "AFTER - BEFORE == 4"; then
16803                         rm -rf $dir
16804                         error "roc_hit is not safe to use"
16805                 fi
16806                 rm $file
16807         done
16808
16809         rm -rf $dir
16810 }
16811
16812 function roc_hit() {
16813         local list=$(comma_list $(osts_nodes))
16814         echo $(get_osd_param $list '' stats |
16815                 awk '$1 == "cache_hit" {sum += $7}
16816                         END { printf("%0.0f", sum) }')
16817 }
16818
16819 function set_cache() {
16820         local on=1
16821
16822         if [ "$2" == "off" ]; then
16823                 on=0;
16824         fi
16825         local list=$(comma_list $(osts_nodes))
16826         set_osd_param $list '' $1_cache_enable $on
16827
16828         cancel_lru_locks osc
16829 }
16830
16831 test_151() {
16832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16833         remote_ost_nodsh && skip "remote OST with nodsh"
16834         (( CLIENT_VERSION == OST1_VERSION )) ||
16835                 skip "LU-13081: no interop testing for OSS cache"
16836
16837         local CPAGES=3
16838         local list=$(comma_list $(osts_nodes))
16839
16840         # check whether obdfilter is cache capable at all
16841         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
16842                 skip "not cache-capable obdfilter"
16843         fi
16844
16845         # check cache is enabled on all obdfilters
16846         if get_osd_param $list '' read_cache_enable | grep 0; then
16847                 skip "oss cache is disabled"
16848         fi
16849
16850         set_osd_param $list '' writethrough_cache_enable 1
16851
16852         # check write cache is enabled on all obdfilters
16853         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
16854                 skip "oss write cache is NOT enabled"
16855         fi
16856
16857         roc_hit_init
16858
16859         #define OBD_FAIL_OBD_NO_LRU  0x609
16860         do_nodes $list $LCTL set_param fail_loc=0x609
16861
16862         # pages should be in the case right after write
16863         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
16864                 error "dd failed"
16865
16866         local BEFORE=$(roc_hit)
16867         cancel_lru_locks osc
16868         cat $DIR/$tfile >/dev/null
16869         local AFTER=$(roc_hit)
16870
16871         do_nodes $list $LCTL set_param fail_loc=0
16872
16873         if ! let "AFTER - BEFORE == CPAGES"; then
16874                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
16875         fi
16876
16877         cancel_lru_locks osc
16878         # invalidates OST cache
16879         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
16880         set_osd_param $list '' read_cache_enable 0
16881         cat $DIR/$tfile >/dev/null
16882
16883         # now data shouldn't be found in the cache
16884         BEFORE=$(roc_hit)
16885         cancel_lru_locks osc
16886         cat $DIR/$tfile >/dev/null
16887         AFTER=$(roc_hit)
16888         if let "AFTER - BEFORE != 0"; then
16889                 error "IN CACHE: before: $BEFORE, after: $AFTER"
16890         fi
16891
16892         set_osd_param $list '' read_cache_enable 1
16893         rm -f $DIR/$tfile
16894 }
16895 run_test 151 "test cache on oss and controls ==============================="
16896
16897 test_152() {
16898         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16899
16900         local TF="$TMP/$tfile"
16901
16902         # simulate ENOMEM during write
16903 #define OBD_FAIL_OST_NOMEM      0x226
16904         lctl set_param fail_loc=0x80000226
16905         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16906         cp $TF $DIR/$tfile
16907         sync || error "sync failed"
16908         lctl set_param fail_loc=0
16909
16910         # discard client's cache
16911         cancel_lru_locks osc
16912
16913         # simulate ENOMEM during read
16914         lctl set_param fail_loc=0x80000226
16915         cmp $TF $DIR/$tfile || error "cmp failed"
16916         lctl set_param fail_loc=0
16917
16918         rm -f $TF
16919 }
16920 run_test 152 "test read/write with enomem ============================"
16921
16922 test_153() {
16923         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
16924 }
16925 run_test 153 "test if fdatasync does not crash ======================="
16926
16927 dot_lustre_fid_permission_check() {
16928         local fid=$1
16929         local ffid=$MOUNT/.lustre/fid/$fid
16930         local test_dir=$2
16931
16932         echo "stat fid $fid"
16933         stat $ffid || error "stat $ffid failed."
16934         echo "touch fid $fid"
16935         touch $ffid || error "touch $ffid failed."
16936         echo "write to fid $fid"
16937         cat /etc/hosts > $ffid || error "write $ffid failed."
16938         echo "read fid $fid"
16939         diff /etc/hosts $ffid || error "read $ffid failed."
16940         echo "append write to fid $fid"
16941         cat /etc/hosts >> $ffid || error "append write $ffid failed."
16942         echo "rename fid $fid"
16943         mv $ffid $test_dir/$tfile.1 &&
16944                 error "rename $ffid to $tfile.1 should fail."
16945         touch $test_dir/$tfile.1
16946         mv $test_dir/$tfile.1 $ffid &&
16947                 error "rename $tfile.1 to $ffid should fail."
16948         rm -f $test_dir/$tfile.1
16949         echo "truncate fid $fid"
16950         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
16951         echo "link fid $fid"
16952         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
16953         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
16954                 id $USER0 || skip_env "missing user $USER0"
16955                 echo "setfacl fid $fid"
16956                 setfacl -R -m u:$USER0:rwx $ffid ||
16957                         error "setfacl $ffid failed"
16958                 echo "getfacl fid $fid"
16959                 getfacl $ffid || error "getfacl $ffid failed."
16960         fi
16961         echo "unlink fid $fid"
16962         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
16963         echo "mknod fid $fid"
16964         mknod $ffid c 1 3 && error "mknod $ffid should fail."
16965
16966         fid=[0xf00000400:0x1:0x0]
16967         ffid=$MOUNT/.lustre/fid/$fid
16968
16969         echo "stat non-exist fid $fid"
16970         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
16971         echo "write to non-exist fid $fid"
16972         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
16973         echo "link new fid $fid"
16974         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
16975
16976         mkdir -p $test_dir/$tdir
16977         touch $test_dir/$tdir/$tfile
16978         fid=$($LFS path2fid $test_dir/$tdir)
16979         rc=$?
16980         [ $rc -ne 0 ] &&
16981                 error "error: could not get fid for $test_dir/$dir/$tfile."
16982
16983         ffid=$MOUNT/.lustre/fid/$fid
16984
16985         echo "ls $fid"
16986         ls $ffid || error "ls $ffid failed."
16987         echo "touch $fid/$tfile.1"
16988         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
16989
16990         echo "touch $MOUNT/.lustre/fid/$tfile"
16991         touch $MOUNT/.lustre/fid/$tfile && \
16992                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
16993
16994         echo "setxattr to $MOUNT/.lustre/fid"
16995         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
16996
16997         echo "listxattr for $MOUNT/.lustre/fid"
16998         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
16999
17000         echo "delxattr from $MOUNT/.lustre/fid"
17001         setfattr -x trusted.name1 $MOUNT/.lustre/fid
17002
17003         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
17004         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
17005                 error "touch invalid fid should fail."
17006
17007         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
17008         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
17009                 error "touch non-normal fid should fail."
17010
17011         echo "rename $tdir to $MOUNT/.lustre/fid"
17012         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
17013                 error "rename to $MOUNT/.lustre/fid should fail."
17014
17015         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
17016         then            # LU-3547
17017                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
17018                 local new_obf_mode=777
17019
17020                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
17021                 chmod $new_obf_mode $DIR/.lustre/fid ||
17022                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
17023
17024                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
17025                 [ $obf_mode -eq $new_obf_mode ] ||
17026                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
17027
17028                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
17029                 chmod $old_obf_mode $DIR/.lustre/fid ||
17030                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
17031         fi
17032
17033         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
17034         fid=$($LFS path2fid $test_dir/$tfile-2)
17035
17036         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
17037         then # LU-5424
17038                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
17039                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
17040                         error "create lov data thru .lustre failed"
17041         fi
17042         echo "cp /etc/passwd $test_dir/$tfile-2"
17043         cp /etc/passwd $test_dir/$tfile-2 ||
17044                 error "copy to $test_dir/$tfile-2 failed."
17045         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
17046         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
17047                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
17048
17049         rm -rf $test_dir/tfile.lnk
17050         rm -rf $test_dir/$tfile-2
17051 }
17052
17053 test_154A() {
17054         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
17055                 skip "Need MDS version at least 2.4.1"
17056
17057         local tf=$DIR/$tfile
17058         touch $tf
17059
17060         local fid=$($LFS path2fid $tf)
17061         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
17062
17063         # check that we get the same pathname back
17064         local rootpath
17065         local found
17066         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
17067                 echo "$rootpath $fid"
17068                 found=$($LFS fid2path $rootpath "$fid")
17069                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
17070                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
17071         done
17072
17073         # check wrong root path format
17074         rootpath=$MOUNT"_wrong"
17075         found=$($LFS fid2path $rootpath "$fid")
17076         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
17077 }
17078 run_test 154A "lfs path2fid and fid2path basic checks"
17079
17080 test_154B() {
17081         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
17082                 skip "Need MDS version at least 2.4.1"
17083
17084         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
17085         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
17086         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
17087         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
17088
17089         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
17090         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
17091
17092         # check that we get the same pathname
17093         echo "PFID: $PFID, name: $name"
17094         local FOUND=$($LFS fid2path $MOUNT "$PFID")
17095         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
17096         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
17097                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
17098
17099         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
17100 }
17101 run_test 154B "verify the ll_decode_linkea tool"
17102
17103 test_154a() {
17104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17105         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17106         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
17107                 skip "Need MDS version at least 2.2.51"
17108         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
17109
17110         cp /etc/hosts $DIR/$tfile
17111
17112         fid=$($LFS path2fid $DIR/$tfile)
17113         rc=$?
17114         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
17115
17116         dot_lustre_fid_permission_check "$fid" $DIR ||
17117                 error "dot lustre permission check $fid failed"
17118
17119         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
17120
17121         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
17122
17123         touch $MOUNT/.lustre/file &&
17124                 error "creation is not allowed under .lustre"
17125
17126         mkdir $MOUNT/.lustre/dir &&
17127                 error "mkdir is not allowed under .lustre"
17128
17129         rm -rf $DIR/$tfile
17130 }
17131 run_test 154a "Open-by-FID"
17132
17133 test_154b() {
17134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17135         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17136         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17137         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
17138                 skip "Need MDS version at least 2.2.51"
17139
17140         local remote_dir=$DIR/$tdir/remote_dir
17141         local MDTIDX=1
17142         local rc=0
17143
17144         mkdir -p $DIR/$tdir
17145         $LFS mkdir -i $MDTIDX $remote_dir ||
17146                 error "create remote directory failed"
17147
17148         cp /etc/hosts $remote_dir/$tfile
17149
17150         fid=$($LFS path2fid $remote_dir/$tfile)
17151         rc=$?
17152         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
17153
17154         dot_lustre_fid_permission_check "$fid" $remote_dir ||
17155                 error "dot lustre permission check $fid failed"
17156         rm -rf $DIR/$tdir
17157 }
17158 run_test 154b "Open-by-FID for remote directory"
17159
17160 test_154c() {
17161         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
17162                 skip "Need MDS version at least 2.4.1"
17163
17164         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
17165         local FID1=$($LFS path2fid $DIR/$tfile.1)
17166         local FID2=$($LFS path2fid $DIR/$tfile.2)
17167         local FID3=$($LFS path2fid $DIR/$tfile.3)
17168
17169         local N=1
17170         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
17171                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
17172                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
17173                 local want=FID$N
17174                 [ "$FID" = "${!want}" ] ||
17175                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
17176                 N=$((N + 1))
17177         done
17178
17179         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
17180         do
17181                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
17182                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
17183                 N=$((N + 1))
17184         done
17185 }
17186 run_test 154c "lfs path2fid and fid2path multiple arguments"
17187
17188 test_154d() {
17189         remote_mds_nodsh && skip "remote MDS with nodsh"
17190         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
17191                 skip "Need MDS version at least 2.5.53"
17192
17193         if remote_mds; then
17194                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
17195         else
17196                 nid="0@lo"
17197         fi
17198         local proc_ofile="mdt.*.exports.'$nid'.open_files"
17199         local fd
17200         local cmd
17201
17202         rm -f $DIR/$tfile
17203         touch $DIR/$tfile
17204
17205         local fid=$($LFS path2fid $DIR/$tfile)
17206         # Open the file
17207         fd=$(free_fd)
17208         cmd="exec $fd<$DIR/$tfile"
17209         eval $cmd
17210         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
17211         echo "$fid_list" | grep "$fid"
17212         rc=$?
17213
17214         cmd="exec $fd>/dev/null"
17215         eval $cmd
17216         if [ $rc -ne 0 ]; then
17217                 error "FID $fid not found in open files list $fid_list"
17218         fi
17219 }
17220 run_test 154d "Verify open file fid"
17221
17222 test_154e()
17223 {
17224         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
17225                 skip "Need MDS version at least 2.6.50"
17226
17227         if ls -a $MOUNT | grep -q '^\.lustre$'; then
17228                 error ".lustre returned by readdir"
17229         fi
17230 }
17231 run_test 154e ".lustre is not returned by readdir"
17232
17233 test_154f() {
17234         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17235
17236         # create parent directory on a single MDT to avoid cross-MDT hardlinks
17237         mkdir_on_mdt0 $DIR/$tdir
17238         # test dirs inherit from its stripe
17239         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
17240         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
17241         cp /etc/hosts $DIR/$tdir/foo1/$tfile
17242         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
17243         touch $DIR/f
17244
17245         # get fid of parents
17246         local FID0=$($LFS path2fid $DIR/$tdir)
17247         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
17248         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
17249         local FID3=$($LFS path2fid $DIR)
17250
17251         # check that path2fid --parents returns expected <parent_fid>/name
17252         # 1) test for a directory (single parent)
17253         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
17254         [ "$parent" == "$FID0/foo1" ] ||
17255                 error "expected parent: $FID0/foo1, got: $parent"
17256
17257         # 2) test for a file with nlink > 1 (multiple parents)
17258         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
17259         echo "$parent" | grep -F "$FID1/$tfile" ||
17260                 error "$FID1/$tfile not returned in parent list"
17261         echo "$parent" | grep -F "$FID2/link" ||
17262                 error "$FID2/link not returned in parent list"
17263
17264         # 3) get parent by fid
17265         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
17266         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17267         echo "$parent" | grep -F "$FID1/$tfile" ||
17268                 error "$FID1/$tfile not returned in parent list (by fid)"
17269         echo "$parent" | grep -F "$FID2/link" ||
17270                 error "$FID2/link not returned in parent list (by fid)"
17271
17272         # 4) test for entry in root directory
17273         parent=$($LFS path2fid --parents $DIR/f)
17274         echo "$parent" | grep -F "$FID3/f" ||
17275                 error "$FID3/f not returned in parent list"
17276
17277         # 5) test it on root directory
17278         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
17279                 error "$MOUNT should not have parents"
17280
17281         # enable xattr caching and check that linkea is correctly updated
17282         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
17283         save_lustre_params client "llite.*.xattr_cache" > $save
17284         lctl set_param llite.*.xattr_cache 1
17285
17286         # 6.1) linkea update on rename
17287         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
17288
17289         # get parents by fid
17290         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17291         # foo1 should no longer be returned in parent list
17292         echo "$parent" | grep -F "$FID1" &&
17293                 error "$FID1 should no longer be in parent list"
17294         # the new path should appear
17295         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
17296                 error "$FID2/$tfile.moved is not in parent list"
17297
17298         # 6.2) linkea update on unlink
17299         rm -f $DIR/$tdir/foo2/link
17300         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17301         # foo2/link should no longer be returned in parent list
17302         echo "$parent" | grep -F "$FID2/link" &&
17303                 error "$FID2/link should no longer be in parent list"
17304         true
17305
17306         rm -f $DIR/f
17307         restore_lustre_params < $save
17308         rm -f $save
17309 }
17310 run_test 154f "get parent fids by reading link ea"
17311
17312 test_154g()
17313 {
17314         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
17315            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
17316                 skip "Need MDS version at least 2.6.92"
17317
17318         mkdir_on_mdt0 $DIR/$tdir
17319         llapi_fid_test -d $DIR/$tdir
17320 }
17321 run_test 154g "various llapi FID tests"
17322
17323 test_154h()
17324 {
17325         (( $CLIENT_VERSION >= $(version_code 2.15.55.1) )) ||
17326                 skip "Need client at least version 2.15.55.1"
17327
17328         # Create an empty file
17329         touch $DIR/$tfile
17330
17331         # Get FID (interactive mode) and save under $TMP/$tfile.log
17332         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
17333                 path2fid $DIR/$tfile
17334         EOF
17335
17336         fid=$(cat $TMP/$tfile.log)
17337         # $fid should not be empty
17338         [[ ! -z $fid ]] || error "FID is empty"
17339         $LFS rmfid $DIR "$fid" || error "rmfid failed for $fid"
17340 }
17341 run_test 154h "Verify interactive path2fid"
17342
17343 test_155_small_load() {
17344     local temp=$TMP/$tfile
17345     local file=$DIR/$tfile
17346
17347     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
17348         error "dd of=$temp bs=6096 count=1 failed"
17349     cp $temp $file
17350     cancel_lru_locks $OSC
17351     cmp $temp $file || error "$temp $file differ"
17352
17353     $TRUNCATE $temp 6000
17354     $TRUNCATE $file 6000
17355     cmp $temp $file || error "$temp $file differ (truncate1)"
17356
17357     echo "12345" >>$temp
17358     echo "12345" >>$file
17359     cmp $temp $file || error "$temp $file differ (append1)"
17360
17361     echo "12345" >>$temp
17362     echo "12345" >>$file
17363     cmp $temp $file || error "$temp $file differ (append2)"
17364
17365     rm -f $temp $file
17366     true
17367 }
17368
17369 test_155_big_load() {
17370         remote_ost_nodsh && skip "remote OST with nodsh"
17371
17372         local temp=$TMP/$tfile
17373         local file=$DIR/$tfile
17374
17375         free_min_max
17376         local cache_size=$(do_facet ost$((MAXI+1)) \
17377                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
17378
17379         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
17380         # pre-set value
17381         if [ -z "$cache_size" ]; then
17382                 cache_size=256
17383         fi
17384         local large_file_size=$((cache_size * 2))
17385
17386         echo "OSS cache size: $cache_size KB"
17387         echo "Large file size: $large_file_size KB"
17388
17389         [ $MAXV -le $large_file_size ] &&
17390                 skip_env "max available OST size needs > $large_file_size KB"
17391
17392         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
17393
17394         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
17395                 error "dd of=$temp bs=$large_file_size count=1k failed"
17396         cp $temp $file
17397         ls -lh $temp $file
17398         cancel_lru_locks osc
17399         cmp $temp $file || error "$temp $file differ"
17400
17401         rm -f $temp $file
17402         true
17403 }
17404
17405 save_writethrough() {
17406         local facets=$(get_facets OST)
17407
17408         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
17409 }
17410
17411 test_155a() {
17412         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17413
17414         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17415
17416         save_writethrough $p
17417
17418         set_cache read on
17419         set_cache writethrough on
17420         test_155_small_load
17421         restore_lustre_params < $p
17422         rm -f $p
17423 }
17424 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
17425
17426 test_155b() {
17427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17428
17429         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17430
17431         save_writethrough $p
17432
17433         set_cache read on
17434         set_cache writethrough off
17435         test_155_small_load
17436         restore_lustre_params < $p
17437         rm -f $p
17438 }
17439 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
17440
17441 test_155c() {
17442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17443
17444         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17445
17446         save_writethrough $p
17447
17448         set_cache read off
17449         set_cache writethrough on
17450         test_155_small_load
17451         restore_lustre_params < $p
17452         rm -f $p
17453 }
17454 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
17455
17456 test_155d() {
17457         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17458
17459         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17460
17461         save_writethrough $p
17462
17463         set_cache read off
17464         set_cache writethrough off
17465         test_155_small_load
17466         restore_lustre_params < $p
17467         rm -f $p
17468 }
17469 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
17470
17471 test_155e() {
17472         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17473
17474         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17475
17476         save_writethrough $p
17477
17478         set_cache read on
17479         set_cache writethrough on
17480         test_155_big_load
17481         restore_lustre_params < $p
17482         rm -f $p
17483 }
17484 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
17485
17486 test_155f() {
17487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17488
17489         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17490
17491         save_writethrough $p
17492
17493         set_cache read on
17494         set_cache writethrough off
17495         test_155_big_load
17496         restore_lustre_params < $p
17497         rm -f $p
17498 }
17499 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
17500
17501 test_155g() {
17502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17503
17504         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17505
17506         save_writethrough $p
17507
17508         set_cache read off
17509         set_cache writethrough on
17510         test_155_big_load
17511         restore_lustre_params < $p
17512         rm -f $p
17513 }
17514 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
17515
17516 test_155h() {
17517         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17518
17519         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17520
17521         save_writethrough $p
17522
17523         set_cache read off
17524         set_cache writethrough off
17525         test_155_big_load
17526         restore_lustre_params < $p
17527         rm -f $p
17528 }
17529 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
17530
17531 test_156() {
17532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17533         remote_ost_nodsh && skip "remote OST with nodsh"
17534         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
17535                 skip "stats not implemented on old servers"
17536         [ "$ost1_FSTYPE" = "zfs" ] &&
17537                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
17538         (( CLIENT_VERSION == OST1_VERSION )) ||
17539                 skip "LU-13081: no interop testing for OSS cache"
17540
17541         local CPAGES=3
17542         local BEFORE
17543         local AFTER
17544         local file="$DIR/$tfile"
17545         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17546
17547         save_writethrough $p
17548         roc_hit_init
17549
17550         log "Turn on read and write cache"
17551         set_cache read on
17552         set_cache writethrough on
17553
17554         log "Write data and read it back."
17555         log "Read should be satisfied from the cache."
17556         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17557         BEFORE=$(roc_hit)
17558         cancel_lru_locks osc
17559         cat $file >/dev/null
17560         AFTER=$(roc_hit)
17561         if ! let "AFTER - BEFORE == CPAGES"; then
17562                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
17563         else
17564                 log "cache hits: before: $BEFORE, after: $AFTER"
17565         fi
17566
17567         log "Read again; it should be satisfied from the cache."
17568         BEFORE=$AFTER
17569         cancel_lru_locks osc
17570         cat $file >/dev/null
17571         AFTER=$(roc_hit)
17572         if ! let "AFTER - BEFORE == CPAGES"; then
17573                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
17574         else
17575                 log "cache hits:: before: $BEFORE, after: $AFTER"
17576         fi
17577
17578         log "Turn off the read cache and turn on the write cache"
17579         set_cache read off
17580         set_cache writethrough on
17581
17582         log "Read again; it should be satisfied from the cache."
17583         BEFORE=$(roc_hit)
17584         cancel_lru_locks osc
17585         cat $file >/dev/null
17586         AFTER=$(roc_hit)
17587         if ! let "AFTER - BEFORE == CPAGES"; then
17588                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
17589         else
17590                 log "cache hits:: before: $BEFORE, after: $AFTER"
17591         fi
17592
17593         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17594                 # > 2.12.56 uses pagecache if cached
17595                 log "Read again; it should not be satisfied from the cache."
17596                 BEFORE=$AFTER
17597                 cancel_lru_locks osc
17598                 cat $file >/dev/null
17599                 AFTER=$(roc_hit)
17600                 if ! let "AFTER - BEFORE == 0"; then
17601                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
17602                 else
17603                         log "cache hits:: before: $BEFORE, after: $AFTER"
17604                 fi
17605         fi
17606
17607         log "Write data and read it back."
17608         log "Read should be satisfied from the cache."
17609         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17610         BEFORE=$(roc_hit)
17611         cancel_lru_locks osc
17612         cat $file >/dev/null
17613         AFTER=$(roc_hit)
17614         if ! let "AFTER - BEFORE == CPAGES"; then
17615                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
17616         else
17617                 log "cache hits:: before: $BEFORE, after: $AFTER"
17618         fi
17619
17620         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17621                 # > 2.12.56 uses pagecache if cached
17622                 log "Read again; it should not be satisfied from the cache."
17623                 BEFORE=$AFTER
17624                 cancel_lru_locks osc
17625                 cat $file >/dev/null
17626                 AFTER=$(roc_hit)
17627                 if ! let "AFTER - BEFORE == 0"; then
17628                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
17629                 else
17630                         log "cache hits:: before: $BEFORE, after: $AFTER"
17631                 fi
17632         fi
17633
17634         log "Turn off read and write cache"
17635         set_cache read off
17636         set_cache writethrough off
17637
17638         log "Write data and read it back"
17639         log "It should not be satisfied from the cache."
17640         rm -f $file
17641         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17642         cancel_lru_locks osc
17643         BEFORE=$(roc_hit)
17644         cat $file >/dev/null
17645         AFTER=$(roc_hit)
17646         if ! let "AFTER - BEFORE == 0"; then
17647                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
17648         else
17649                 log "cache hits:: before: $BEFORE, after: $AFTER"
17650         fi
17651
17652         log "Turn on the read cache and turn off the write cache"
17653         set_cache read on
17654         set_cache writethrough off
17655
17656         log "Write data and read it back"
17657         log "It should not be satisfied from the cache."
17658         rm -f $file
17659         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17660         BEFORE=$(roc_hit)
17661         cancel_lru_locks osc
17662         cat $file >/dev/null
17663         AFTER=$(roc_hit)
17664         if ! let "AFTER - BEFORE == 0"; then
17665                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
17666         else
17667                 log "cache hits:: before: $BEFORE, after: $AFTER"
17668         fi
17669
17670         log "Read again; it should be satisfied from the cache."
17671         BEFORE=$(roc_hit)
17672         cancel_lru_locks osc
17673         cat $file >/dev/null
17674         AFTER=$(roc_hit)
17675         if ! let "AFTER - BEFORE == CPAGES"; then
17676                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
17677         else
17678                 log "cache hits:: before: $BEFORE, after: $AFTER"
17679         fi
17680
17681         restore_lustre_params < $p
17682         rm -f $p $file
17683 }
17684 run_test 156 "Verification of tunables"
17685
17686 test_160a() {
17687         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17688         remote_mds_nodsh && skip "remote MDS with nodsh"
17689         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17690                 skip "Need MDS version at least 2.2.0"
17691
17692         changelog_register || error "changelog_register failed"
17693         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17694         changelog_users $SINGLEMDS | grep -q $cl_user ||
17695                 error "User $cl_user not found in changelog_users"
17696
17697         mkdir_on_mdt0 $DIR/$tdir
17698
17699         # change something
17700         test_mkdir -p $DIR/$tdir/pics/2008/zachy
17701         changelog_clear 0 || error "changelog_clear failed"
17702         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
17703         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
17704         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17705         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17706         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17707         rm $DIR/$tdir/pics/desktop.jpg
17708
17709         echo "verifying changelog mask"
17710         changelog_chmask "-MKDIR"
17711         changelog_chmask "-CLOSE"
17712
17713         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
17714         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
17715
17716         changelog_chmask "+MKDIR"
17717         changelog_chmask "+CLOSE"
17718
17719         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
17720         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
17721
17722         MKDIRS=$(changelog_dump | grep -c "MKDIR")
17723         CLOSES=$(changelog_dump | grep -c "CLOSE")
17724         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
17725         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
17726
17727         # verify contents
17728         echo "verifying target fid"
17729         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
17730         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
17731         [ "$fidc" == "$fidf" ] ||
17732                 error "changelog '$tfile' fid $fidc != file fid $fidf"
17733         echo "verifying parent fid"
17734         # The FID returned from the Changelog may be the directory shard on
17735         # a different MDT, and not the FID returned by path2fid on the parent.
17736         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
17737         # since this is what will matter when recreating this file in the tree.
17738         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
17739         local pathp=$($LFS fid2path $MOUNT "$fidp")
17740         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
17741                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
17742
17743         echo "getting records for $cl_user"
17744         changelog_users $SINGLEMDS
17745         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
17746         local nclr=3
17747         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
17748                 error "changelog_clear failed"
17749         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
17750         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
17751         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
17752                 error "user index expect $user_rec1 + $nclr != $user_rec2"
17753
17754         local min0_rec=$(changelog_users $SINGLEMDS |
17755                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
17756         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
17757                           awk '{ print $1; exit; }')
17758
17759         changelog_dump | tail -n 5
17760         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
17761         [ $first_rec == $((min0_rec + 1)) ] ||
17762                 error "first index should be $min0_rec + 1 not $first_rec"
17763
17764         # LU-3446 changelog index reset on MDT restart
17765         local cur_rec1=$(changelog_users $SINGLEMDS |
17766                          awk '/^current.index:/ { print $NF }')
17767         changelog_clear 0 ||
17768                 error "clear all changelog records for $cl_user failed"
17769         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
17770         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
17771                 error "Fail to start $SINGLEMDS"
17772         local cur_rec2=$(changelog_users $SINGLEMDS |
17773                          awk '/^current.index:/ { print $NF }')
17774         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
17775         [ $cur_rec1 == $cur_rec2 ] ||
17776                 error "current index should be $cur_rec1 not $cur_rec2"
17777
17778         echo "verifying users from this test are deregistered"
17779         changelog_deregister || error "changelog_deregister failed"
17780         changelog_users $SINGLEMDS | grep -q $cl_user &&
17781                 error "User '$cl_user' still in changelog_users"
17782
17783         # lctl get_param -n mdd.*.changelog_users
17784         # current_index: 144
17785         # ID    index (idle seconds)
17786         # cl3   144   (2) mask=<list>
17787         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
17788                 # this is the normal case where all users were deregistered
17789                 # make sure no new records are added when no users are present
17790                 local last_rec1=$(changelog_users $SINGLEMDS |
17791                                   awk '/^current.index:/ { print $NF }')
17792                 touch $DIR/$tdir/chloe
17793                 local last_rec2=$(changelog_users $SINGLEMDS |
17794                                   awk '/^current.index:/ { print $NF }')
17795                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
17796                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
17797         else
17798                 # any changelog users must be leftovers from a previous test
17799                 changelog_users $SINGLEMDS
17800                 echo "other changelog users; can't verify off"
17801         fi
17802 }
17803 run_test 160a "changelog sanity"
17804
17805 test_160b() { # LU-3587
17806         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17807         remote_mds_nodsh && skip "remote MDS with nodsh"
17808         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17809                 skip "Need MDS version at least 2.2.0"
17810
17811         changelog_register || error "changelog_register failed"
17812         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17813         changelog_users $SINGLEMDS | grep -q $cl_user ||
17814                 error "User '$cl_user' not found in changelog_users"
17815
17816         local longname1=$(str_repeat a 255)
17817         local longname2=$(str_repeat b 255)
17818
17819         cd $DIR
17820         echo "creating very long named file"
17821         touch $longname1 || error "create of '$longname1' failed"
17822         echo "renaming very long named file"
17823         mv $longname1 $longname2
17824
17825         changelog_dump | grep RENME | tail -n 5
17826         rm -f $longname2
17827 }
17828 run_test 160b "Verify that very long rename doesn't crash in changelog"
17829
17830 test_160c() {
17831         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17832         remote_mds_nodsh && skip "remote MDS with nodsh"
17833
17834         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
17835                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
17836                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
17837                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
17838
17839         local rc=0
17840
17841         # Registration step
17842         changelog_register || error "changelog_register failed"
17843
17844         rm -rf $DIR/$tdir
17845         mkdir -p $DIR/$tdir
17846         $MCREATE $DIR/$tdir/foo_160c
17847         changelog_chmask "-TRUNC"
17848         $TRUNCATE $DIR/$tdir/foo_160c 200
17849         changelog_chmask "+TRUNC"
17850         $TRUNCATE $DIR/$tdir/foo_160c 199
17851         changelog_dump | tail -n 5
17852         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
17853         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
17854 }
17855 run_test 160c "verify that changelog log catch the truncate event"
17856
17857 test_160d() {
17858         remote_mds_nodsh && skip "remote MDS with nodsh"
17859         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17860         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17861         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
17862                 skip "Need MDS version at least 2.7.60"
17863
17864         # Registration step
17865         changelog_register || error "changelog_register failed"
17866
17867         mkdir -p $DIR/$tdir/migrate_dir
17868         changelog_clear 0 || error "changelog_clear failed"
17869
17870         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
17871         changelog_dump | tail -n 5
17872         local migrates=$(changelog_dump | grep -c "MIGRT")
17873         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
17874 }
17875 run_test 160d "verify that changelog log catch the migrate event"
17876
17877 test_160e() {
17878         remote_mds_nodsh && skip "remote MDS with nodsh"
17879
17880         # Create a user
17881         changelog_register || error "changelog_register failed"
17882
17883         local MDT0=$(facet_svc $SINGLEMDS)
17884         local rc
17885
17886         # No user (expect fail)
17887         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
17888         rc=$?
17889         if [ $rc -eq 0 ]; then
17890                 error "Should fail without user"
17891         elif [ $rc -ne 4 ]; then
17892                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
17893         fi
17894
17895         # Delete a future user (expect fail)
17896         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
17897         rc=$?
17898         if [ $rc -eq 0 ]; then
17899                 error "Deleted non-existant user cl77"
17900         elif [ $rc -ne 2 ]; then
17901                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
17902         fi
17903
17904         # Clear to a bad index (1 billion should be safe)
17905         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
17906         rc=$?
17907
17908         if [ $rc -eq 0 ]; then
17909                 error "Successfully cleared to invalid CL index"
17910         elif [ $rc -ne 22 ]; then
17911                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
17912         fi
17913 }
17914 run_test 160e "changelog negative testing (should return errors)"
17915
17916 test_160f() {
17917         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17918         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17919                 skip "Need MDS version at least 2.10.56"
17920
17921         local mdts=$(comma_list $(mdts_nodes))
17922
17923         # Create a user
17924         changelog_register || error "first changelog_register failed"
17925         changelog_register || error "second changelog_register failed"
17926         local cl_users
17927         declare -A cl_user1
17928         declare -A cl_user2
17929         local user_rec1
17930         local user_rec2
17931         local i
17932
17933         # generate some changelog records to accumulate on each MDT
17934         # use all_char because created files should be evenly distributed
17935         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17936                 error "test_mkdir $tdir failed"
17937         log "$(date +%s): creating first files"
17938         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17939                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
17940                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
17941         done
17942
17943         # check changelogs have been generated
17944         local start=$SECONDS
17945         local idle_time=$((MDSCOUNT * 5 + 5))
17946         local nbcl=$(changelog_dump | wc -l)
17947         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17948
17949         for param in "changelog_max_idle_time=$idle_time" \
17950                      "changelog_gc=1" \
17951                      "changelog_min_gc_interval=2" \
17952                      "changelog_min_free_cat_entries=3"; do
17953                 local MDT0=$(facet_svc $SINGLEMDS)
17954                 local var="${param%=*}"
17955                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17956
17957                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17958                 do_nodes $mdts $LCTL set_param mdd.*.$param
17959         done
17960
17961         # force cl_user2 to be idle (1st part), but also cancel the
17962         # cl_user1 records so that it is not evicted later in the test.
17963         local sleep1=$((idle_time / 2))
17964         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
17965         sleep $sleep1
17966
17967         # simulate changelog catalog almost full
17968         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
17969         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
17970
17971         for i in $(seq $MDSCOUNT); do
17972                 cl_users=(${CL_USERS[mds$i]})
17973                 cl_user1[mds$i]="${cl_users[0]}"
17974                 cl_user2[mds$i]="${cl_users[1]}"
17975
17976                 [ -n "${cl_user1[mds$i]}" ] ||
17977                         error "mds$i: no user registered"
17978                 [ -n "${cl_user2[mds$i]}" ] ||
17979                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17980
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                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17985                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17986                 [ -n "$user_rec2" ] ||
17987                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17988                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17989                      "$user_rec1 + 2 == $user_rec2"
17990                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17991                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17992                               "$user_rec1 + 2, but is $user_rec2"
17993                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17994                 [ -n "$user_rec2" ] ||
17995                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17996                 [ $user_rec1 == $user_rec2 ] ||
17997                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17998                               "$user_rec1, but is $user_rec2"
17999         done
18000
18001         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
18002         local sleep2=$((idle_time - (SECONDS - start) + 1))
18003         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
18004         sleep $sleep2
18005
18006         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
18007         # cl_user1 should be OK because it recently processed records.
18008         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
18009         for ((i = 0; i < MDSCOUNT * 2; i++)); do
18010                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
18011                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
18012         done
18013
18014         # ensure gc thread is done
18015         for i in $(mdts_nodes); do
18016                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
18017                         error "$i: GC-thread not done"
18018         done
18019
18020         local first_rec
18021         for (( i = 1; i <= MDSCOUNT; i++ )); do
18022                 # check cl_user1 still registered
18023                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
18024                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18025                 # check cl_user2 unregistered
18026                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
18027                         error "mds$i: User ${cl_user2[mds$i]} still registered"
18028
18029                 # check changelogs are present and starting at $user_rec1 + 1
18030                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18031                 [ -n "$user_rec1" ] ||
18032                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18033                 first_rec=$($LFS changelog $(facet_svc mds$i) |
18034                             awk '{ print $1; exit; }')
18035
18036                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
18037                 [ $((user_rec1 + 1)) == $first_rec ] ||
18038                         error "mds$i: rec $first_rec != $user_rec1 + 1"
18039         done
18040 }
18041 run_test 160f "changelog garbage collect (timestamped users)"
18042
18043 test_160g() {
18044         remote_mds_nodsh && skip "remote MDS with nodsh"
18045         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
18046                 skip "Need MDS version at least 2.14.55"
18047
18048         local mdts=$(comma_list $(mdts_nodes))
18049
18050         # Create a user
18051         changelog_register || error "first changelog_register failed"
18052         changelog_register || error "second changelog_register failed"
18053         local cl_users
18054         declare -A cl_user1
18055         declare -A cl_user2
18056         local user_rec1
18057         local user_rec2
18058         local i
18059
18060         # generate some changelog records to accumulate on each MDT
18061         # use all_char because created files should be evenly distributed
18062         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18063                 error "test_mkdir $tdir failed"
18064         for ((i = 0; i < MDSCOUNT; i++)); do
18065                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18066                         error "create $DIR/$tdir/d$i.1 failed"
18067         done
18068
18069         # check changelogs have been generated
18070         local nbcl=$(changelog_dump | wc -l)
18071         (( $nbcl > 0 )) || error "no changelogs found"
18072
18073         # reduce the max_idle_indexes value to make sure we exceed it
18074         for param in "changelog_max_idle_indexes=2" \
18075                      "changelog_gc=1" \
18076                      "changelog_min_gc_interval=2"; do
18077                 local MDT0=$(facet_svc $SINGLEMDS)
18078                 local var="${param%=*}"
18079                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18080
18081                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18082                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
18083                         error "unable to set mdd.*.$param"
18084         done
18085
18086         local start=$SECONDS
18087         for i in $(seq $MDSCOUNT); do
18088                 cl_users=(${CL_USERS[mds$i]})
18089                 cl_user1[mds$i]="${cl_users[0]}"
18090                 cl_user2[mds$i]="${cl_users[1]}"
18091
18092                 [ -n "${cl_user1[mds$i]}" ] ||
18093                         error "mds$i: user1 is not registered"
18094                 [ -n "${cl_user2[mds$i]}" ] ||
18095                         error "mds$i: only ${cl_user1[mds$i]} is registered"
18096
18097                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18098                 [ -n "$user_rec1" ] ||
18099                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
18100                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
18101                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18102                 [ -n "$user_rec2" ] ||
18103                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
18104                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
18105                      "$user_rec1 + 2 == $user_rec2"
18106                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
18107                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
18108                               "expected $user_rec1 + 2, but is $user_rec2"
18109                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
18110                 [ -n "$user_rec2" ] ||
18111                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
18112                 [ $user_rec1 == $user_rec2 ] ||
18113                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
18114                               "expected $user_rec1, but is $user_rec2"
18115         done
18116
18117         # ensure we are past the previous changelog_min_gc_interval set above
18118         local sleep2=$((start + 2 - SECONDS))
18119         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18120         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
18121         # cl_user1 should be OK because it recently processed records.
18122         for ((i = 0; i < MDSCOUNT; i++)); do
18123                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
18124                         error "create $DIR/$tdir/d$i.3 failed"
18125         done
18126
18127         # ensure gc thread is done
18128         for i in $(mdts_nodes); do
18129                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
18130                         error "$i: GC-thread not done"
18131         done
18132
18133         local first_rec
18134         for (( i = 1; i <= MDSCOUNT; i++ )); do
18135                 # check cl_user1 still registered
18136                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
18137                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
18138                 # check cl_user2 unregistered
18139                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
18140                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
18141
18142                 # check changelogs are present and starting at $user_rec1 + 1
18143                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18144                 [ -n "$user_rec1" ] ||
18145                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
18146                 first_rec=$($LFS changelog $(facet_svc mds$i) |
18147                             awk '{ print $1; exit; }')
18148
18149                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
18150                 [ $((user_rec1 + 1)) == $first_rec ] ||
18151                         error "mds$i: rec $first_rec != $user_rec1 + 1"
18152         done
18153 }
18154 run_test 160g "changelog garbage collect on idle records"
18155
18156 test_160h() {
18157         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18158         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
18159                 skip "Need MDS version at least 2.10.56"
18160
18161         local mdts=$(comma_list $(mdts_nodes))
18162
18163         # Create a user
18164         changelog_register || error "first changelog_register failed"
18165         changelog_register || error "second changelog_register failed"
18166         local cl_users
18167         declare -A cl_user1
18168         declare -A cl_user2
18169         local user_rec1
18170         local user_rec2
18171         local i
18172
18173         # generate some changelog records to accumulate on each MDT
18174         # use all_char because created files should be evenly distributed
18175         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18176                 error "test_mkdir $tdir failed"
18177         for ((i = 0; i < MDSCOUNT; i++)); do
18178                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18179                         error "create $DIR/$tdir/d$i.1 failed"
18180         done
18181
18182         # check changelogs have been generated
18183         local nbcl=$(changelog_dump | wc -l)
18184         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18185
18186         for param in "changelog_max_idle_time=10" \
18187                      "changelog_gc=1" \
18188                      "changelog_min_gc_interval=2"; do
18189                 local MDT0=$(facet_svc $SINGLEMDS)
18190                 local var="${param%=*}"
18191                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18192
18193                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18194                 do_nodes $mdts $LCTL set_param mdd.*.$param
18195         done
18196
18197         # force cl_user2 to be idle (1st part)
18198         sleep 9
18199
18200         for i in $(seq $MDSCOUNT); do
18201                 cl_users=(${CL_USERS[mds$i]})
18202                 cl_user1[mds$i]="${cl_users[0]}"
18203                 cl_user2[mds$i]="${cl_users[1]}"
18204
18205                 [ -n "${cl_user1[mds$i]}" ] ||
18206                         error "mds$i: no user registered"
18207                 [ -n "${cl_user2[mds$i]}" ] ||
18208                         error "mds$i: only ${cl_user2[mds$i]} is registered"
18209
18210                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18211                 [ -n "$user_rec1" ] ||
18212                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18213                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
18214                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18215                 [ -n "$user_rec2" ] ||
18216                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18217                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
18218                      "$user_rec1 + 2 == $user_rec2"
18219                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
18220                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
18221                               "$user_rec1 + 2, but is $user_rec2"
18222                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
18223                 [ -n "$user_rec2" ] ||
18224                         error "mds$i: User ${cl_user2[mds$i]} not registered"
18225                 [ $user_rec1 == $user_rec2 ] ||
18226                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
18227                               "$user_rec1, but is $user_rec2"
18228         done
18229
18230         # force cl_user2 to be idle (2nd part) and to reach
18231         # changelog_max_idle_time
18232         sleep 2
18233
18234         # force each GC-thread start and block then
18235         # one per MDT/MDD, set fail_val accordingly
18236         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
18237         do_nodes $mdts $LCTL set_param fail_loc=0x1316
18238
18239         # generate more changelogs to trigger fail_loc
18240         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
18241                 error "create $DIR/$tdir/${tfile}bis failed"
18242
18243         # stop MDT to stop GC-thread, should be done in back-ground as it will
18244         # block waiting for the thread to be released and exit
18245         declare -A stop_pids
18246         for i in $(seq $MDSCOUNT); do
18247                 stop mds$i &
18248                 stop_pids[mds$i]=$!
18249         done
18250
18251         for i in $(mdts_nodes); do
18252                 local facet
18253                 local nb=0
18254                 local facets=$(facets_up_on_host $i)
18255
18256                 for facet in ${facets//,/ }; do
18257                         if [[ $facet == mds* ]]; then
18258                                 nb=$((nb + 1))
18259                         fi
18260                 done
18261                 # ensure each MDS's gc threads are still present and all in "R"
18262                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
18263                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
18264                         error "$i: expected $nb GC-thread"
18265                 wait_update $i \
18266                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
18267                         "R" 20 ||
18268                         error "$i: GC-thread not found in R-state"
18269                 # check umounts of each MDT on MDS have reached kthread_stop()
18270                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
18271                         error "$i: expected $nb umount"
18272                 wait_update $i \
18273                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
18274                         error "$i: umount not found in D-state"
18275         done
18276
18277         # release all GC-threads
18278         do_nodes $mdts $LCTL set_param fail_loc=0
18279
18280         # wait for MDT stop to complete
18281         for i in $(seq $MDSCOUNT); do
18282                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
18283         done
18284
18285         # XXX
18286         # may try to check if any orphan changelog records are present
18287         # via ldiskfs/zfs and llog_reader...
18288
18289         # re-start/mount MDTs
18290         for i in $(seq $MDSCOUNT); do
18291                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
18292                         error "Fail to start mds$i"
18293         done
18294
18295         local first_rec
18296         for i in $(seq $MDSCOUNT); do
18297                 # check cl_user1 still registered
18298                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
18299                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18300                 # check cl_user2 unregistered
18301                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
18302                         error "mds$i: User ${cl_user2[mds$i]} still registered"
18303
18304                 # check changelogs are present and starting at $user_rec1 + 1
18305                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18306                 [ -n "$user_rec1" ] ||
18307                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18308                 first_rec=$($LFS changelog $(facet_svc mds$i) |
18309                             awk '{ print $1; exit; }')
18310
18311                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
18312                 [ $((user_rec1 + 1)) == $first_rec ] ||
18313                         error "mds$i: first index should be $user_rec1 + 1, " \
18314                               "but is $first_rec"
18315         done
18316 }
18317 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
18318               "during mount"
18319
18320 test_160i() {
18321
18322         local mdts=$(comma_list $(mdts_nodes))
18323
18324         changelog_register || error "first changelog_register failed"
18325
18326         # generate some changelog records to accumulate on each MDT
18327         # use all_char because created files should be evenly distributed
18328         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18329                 error "test_mkdir $tdir failed"
18330         for ((i = 0; i < MDSCOUNT; i++)); do
18331                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18332                         error "create $DIR/$tdir/d$i.1 failed"
18333         done
18334
18335         # check changelogs have been generated
18336         local nbcl=$(changelog_dump | wc -l)
18337         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18338
18339         # simulate race between register and unregister
18340         # XXX as fail_loc is set per-MDS, with DNE configs the race
18341         # simulation will only occur for one MDT per MDS and for the
18342         # others the normal race scenario will take place
18343         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
18344         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
18345         do_nodes $mdts $LCTL set_param fail_val=1
18346
18347         # unregister 1st user
18348         changelog_deregister &
18349         local pid1=$!
18350         # wait some time for deregister work to reach race rdv
18351         sleep 2
18352         # register 2nd user
18353         changelog_register || error "2nd user register failed"
18354
18355         wait $pid1 || error "1st user deregister failed"
18356
18357         local i
18358         local last_rec
18359         declare -A LAST_REC
18360         for i in $(seq $MDSCOUNT); do
18361                 if changelog_users mds$i | grep "^cl"; then
18362                         # make sure new records are added with one user present
18363                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
18364                                           awk '/^current.index:/ { print $NF }')
18365                 else
18366                         error "mds$i has no user registered"
18367                 fi
18368         done
18369
18370         # generate more changelog records to accumulate on each MDT
18371         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
18372                 error "create $DIR/$tdir/${tfile}bis failed"
18373
18374         for i in $(seq $MDSCOUNT); do
18375                 last_rec=$(changelog_users $SINGLEMDS |
18376                            awk '/^current.index:/ { print $NF }')
18377                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
18378                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
18379                         error "changelogs are off on mds$i"
18380         done
18381 }
18382 run_test 160i "changelog user register/unregister race"
18383
18384 test_160j() {
18385         remote_mds_nodsh && skip "remote MDS with nodsh"
18386         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
18387                 skip "Need MDS version at least 2.12.56"
18388
18389         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
18390         stack_trap "umount $MOUNT2" EXIT
18391
18392         changelog_register || error "first changelog_register failed"
18393         stack_trap "changelog_deregister" EXIT
18394
18395         # generate some changelog
18396         # use all_char because created files should be evenly distributed
18397         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18398                 error "mkdir $tdir failed"
18399         for ((i = 0; i < MDSCOUNT; i++)); do
18400                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18401                         error "create $DIR/$tdir/d$i.1 failed"
18402         done
18403
18404         # open the changelog device
18405         exec 3>/dev/changelog-$FSNAME-MDT0000
18406         stack_trap "exec 3>&-" EXIT
18407         exec 4</dev/changelog-$FSNAME-MDT0000
18408         stack_trap "exec 4<&-" EXIT
18409
18410         # umount the first lustre mount
18411         umount $MOUNT
18412         stack_trap "mount_client $MOUNT" EXIT
18413
18414         # read changelog, which may or may not fail, but should not crash
18415         cat <&4 >/dev/null
18416
18417         # clear changelog
18418         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18419         changelog_users $SINGLEMDS | grep -q $cl_user ||
18420                 error "User $cl_user not found in changelog_users"
18421
18422         printf 'clear:'$cl_user':0' >&3
18423 }
18424 run_test 160j "client can be umounted while its chanangelog is being used"
18425
18426 test_160k() {
18427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18428         remote_mds_nodsh && skip "remote MDS with nodsh"
18429
18430         mkdir -p $DIR/$tdir/1/1
18431
18432         changelog_register || error "changelog_register failed"
18433         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18434
18435         changelog_users $SINGLEMDS | grep -q $cl_user ||
18436                 error "User '$cl_user' not found in changelog_users"
18437 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
18438         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
18439         rmdir $DIR/$tdir/1/1 & sleep 1
18440         mkdir $DIR/$tdir/2
18441         touch $DIR/$tdir/2/2
18442         rm -rf $DIR/$tdir/2
18443
18444         wait
18445         sleep 4
18446
18447         changelog_dump | grep rmdir || error "rmdir not recorded"
18448 }
18449 run_test 160k "Verify that changelog records are not lost"
18450
18451 # Verifies that a file passed as a parameter has recently had an operation
18452 # performed on it that has generated an MTIME changelog which contains the
18453 # correct parent FID. As files might reside on a different MDT from the
18454 # parent directory in DNE configurations, the FIDs are translated to paths
18455 # before being compared, which should be identical
18456 compare_mtime_changelog() {
18457         local file="${1}"
18458         local mdtidx
18459         local mtime
18460         local cl_fid
18461         local pdir
18462         local dir
18463
18464         mdtidx=$($LFS getstripe --mdt-index $file)
18465         mdtidx=$(printf "%04x" $mdtidx)
18466
18467         # Obtain the parent FID from the MTIME changelog
18468         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
18469         [ -z "$mtime" ] && error "MTIME changelog not recorded"
18470
18471         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
18472         [ -z "$cl_fid" ] && error "parent FID not present"
18473
18474         # Verify that the path for the parent FID is the same as the path for
18475         # the test directory
18476         pdir=$($LFS fid2path $MOUNT "$cl_fid")
18477
18478         dir=$(dirname $1)
18479
18480         [[ "${pdir%/}" == "$dir" ]] ||
18481                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
18482 }
18483
18484 test_160l() {
18485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18486
18487         remote_mds_nodsh && skip "remote MDS with nodsh"
18488         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
18489                 skip "Need MDS version at least 2.13.55"
18490
18491         local cl_user
18492
18493         changelog_register || error "changelog_register failed"
18494         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18495
18496         changelog_users $SINGLEMDS | grep -q $cl_user ||
18497                 error "User '$cl_user' not found in changelog_users"
18498
18499         # Clear some types so that MTIME changelogs are generated
18500         changelog_chmask "-CREAT"
18501         changelog_chmask "-CLOSE"
18502
18503         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
18504
18505         # Test CL_MTIME during setattr
18506         touch $DIR/$tdir/$tfile
18507         compare_mtime_changelog $DIR/$tdir/$tfile
18508
18509         # Test CL_MTIME during close
18510         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
18511         compare_mtime_changelog $DIR/$tdir/${tfile}_2
18512 }
18513 run_test 160l "Verify that MTIME changelog records contain the parent FID"
18514
18515 test_160m() {
18516         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18517         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18518                 skip "Need MDS version at least 2.14.51"
18519         local cl_users
18520         local cl_user1
18521         local cl_user2
18522         local pid1
18523
18524         # Create a user
18525         changelog_register || error "first changelog_register failed"
18526         changelog_register || error "second changelog_register failed"
18527
18528         cl_users=(${CL_USERS[mds1]})
18529         cl_user1="${cl_users[0]}"
18530         cl_user2="${cl_users[1]}"
18531         # generate some changelog records to accumulate on MDT0
18532         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18533         createmany -m $DIR/$tdir/$tfile 50 ||
18534                 error "create $DIR/$tdir/$tfile failed"
18535         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18536         rm -f $DIR/$tdir
18537
18538         # check changelogs have been generated
18539         local nbcl=$(changelog_dump | wc -l)
18540         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18541
18542 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
18543         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
18544
18545         __changelog_clear mds1 $cl_user1 +10
18546         __changelog_clear mds1 $cl_user2 0 &
18547         pid1=$!
18548         sleep 2
18549         __changelog_clear mds1 $cl_user1 0 ||
18550                 error "fail to cancel record for $cl_user1"
18551         wait $pid1
18552         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
18553 }
18554 run_test 160m "Changelog clear race"
18555
18556 test_160n() {
18557         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18558         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18559                 skip "Need MDS version at least 2.14.51"
18560         local cl_users
18561         local cl_user1
18562         local cl_user2
18563         local pid1
18564         local first_rec
18565         local last_rec=0
18566
18567         # Create a user
18568         changelog_register || error "first changelog_register failed"
18569
18570         cl_users=(${CL_USERS[mds1]})
18571         cl_user1="${cl_users[0]}"
18572
18573         # generate some changelog records to accumulate on MDT0
18574         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18575         first_rec=$(changelog_users $SINGLEMDS |
18576                         awk '/^current.index:/ { print $NF }')
18577         while (( last_rec < (( first_rec + 65000)) )); do
18578                 createmany -m $DIR/$tdir/$tfile 10000 ||
18579                         error "create $DIR/$tdir/$tfile failed"
18580
18581                 for i in $(seq 0 10000); do
18582                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
18583                                 > /dev/null
18584                 done
18585
18586                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
18587                         error "unlinkmany failed unlink"
18588                 last_rec=$(changelog_users $SINGLEMDS |
18589                         awk '/^current.index:/ { print $NF }')
18590                 echo last record $last_rec
18591                 (( last_rec == 0 )) && error "no changelog found"
18592         done
18593
18594 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
18595         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
18596
18597         __changelog_clear mds1 $cl_user1 0 &
18598         pid1=$!
18599         sleep 2
18600         __changelog_clear mds1 $cl_user1 0 ||
18601                 error "fail to cancel record for $cl_user1"
18602         wait $pid1
18603         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
18604 }
18605 run_test 160n "Changelog destroy race"
18606
18607 test_160o() {
18608         local mdt="$(facet_svc $SINGLEMDS)"
18609
18610         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18611         remote_mds_nodsh && skip "remote MDS with nodsh"
18612         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
18613                 skip "Need MDS version at least 2.14.52"
18614
18615         changelog_register --user test_160o -m unlnk+close+open ||
18616                 error "changelog_register failed"
18617
18618         do_facet $SINGLEMDS $LCTL --device $mdt \
18619                                 changelog_register -u "Tt3_-#" &&
18620                 error "bad symbols in name should fail"
18621
18622         do_facet $SINGLEMDS $LCTL --device $mdt \
18623                                 changelog_register -u test_160o &&
18624                 error "the same name registration should fail"
18625
18626         do_facet $SINGLEMDS $LCTL --device $mdt \
18627                         changelog_register -u test_160toolongname &&
18628                 error "too long name registration should fail"
18629
18630         changelog_chmask "MARK+HSM"
18631         lctl get_param mdd.*.changelog*mask
18632         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18633         changelog_users $SINGLEMDS | grep -q $cl_user ||
18634                 error "User $cl_user not found in changelog_users"
18635         #verify username
18636         echo $cl_user | grep -q test_160o ||
18637                 error "User $cl_user has no specific name 'test160o'"
18638
18639         # change something
18640         changelog_clear 0 || error "changelog_clear failed"
18641         # generate some changelog records to accumulate on MDT0
18642         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18643         touch $DIR/$tdir/$tfile                 # open 1
18644
18645         OPENS=$(changelog_dump | grep -c "OPEN")
18646         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
18647
18648         # must be no MKDIR it wasn't set as user mask
18649         MKDIR=$(changelog_dump | grep -c "MKDIR")
18650         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
18651
18652         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
18653                                 mdd.$mdt.changelog_current_mask -n)
18654         # register maskless user
18655         changelog_register || error "changelog_register failed"
18656         # effective mask should be not changed because it is not minimal
18657         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18658                                 mdd.$mdt.changelog_current_mask -n)
18659         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
18660         # set server mask to minimal value
18661         changelog_chmask "MARK"
18662         # check effective mask again, should be treated as DEFMASK now
18663         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18664                                 mdd.$mdt.changelog_current_mask -n)
18665         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18666
18667         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
18668                 # set server mask back to some value
18669                 changelog_chmask "CLOSE,UNLNK"
18670                 # check effective mask again, should not remain as DEFMASK
18671                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
18672                                 mdd.$mdt.changelog_current_mask -n)
18673                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
18674         fi
18675
18676         do_facet $SINGLEMDS $LCTL --device $mdt \
18677                                 changelog_deregister -u test_160o ||
18678                 error "cannot deregister by name"
18679 }
18680 run_test 160o "changelog user name and mask"
18681
18682 test_160p() {
18683         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18684         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18685                 skip "Need MDS version at least 2.14.51"
18686         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
18687         local cl_users
18688         local cl_user1
18689         local entry_count
18690
18691         # Create a user
18692         changelog_register || error "first changelog_register failed"
18693
18694         cl_users=(${CL_USERS[mds1]})
18695         cl_user1="${cl_users[0]}"
18696
18697         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18698         createmany -m $DIR/$tdir/$tfile 50 ||
18699                 error "create $DIR/$tdir/$tfile failed"
18700         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18701         rm -rf $DIR/$tdir
18702
18703         # check changelogs have been generated
18704         entry_count=$(changelog_dump | wc -l)
18705         ((entry_count != 0)) || error "no changelog entries found"
18706
18707         # remove changelog_users and check that orphan entries are removed
18708         stop mds1
18709         local dev=$(mdsdevname 1)
18710         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
18711         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
18712         entry_count=$(changelog_dump | wc -l)
18713         ((entry_count == 0)) ||
18714                 error "found $entry_count changelog entries, expected none"
18715 }
18716 run_test 160p "Changelog orphan cleanup with no users"
18717
18718 test_160q() {
18719         local mdt="$(facet_svc $SINGLEMDS)"
18720         local clu
18721
18722         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18723         remote_mds_nodsh && skip "remote MDS with nodsh"
18724         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
18725                 skip "Need MDS version at least 2.14.54"
18726
18727         # set server mask to minimal value like server init does
18728         changelog_chmask "MARK"
18729         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
18730                 error "changelog_register failed"
18731         # check effective mask again, should be treated as DEFMASK now
18732         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18733                                 mdd.$mdt.changelog_current_mask -n)
18734         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
18735                 error "changelog_deregister failed"
18736         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18737 }
18738 run_test 160q "changelog effective mask is DEFMASK if not set"
18739
18740 test_160s() {
18741         remote_mds_nodsh && skip "remote MDS with nodsh"
18742         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
18743                 skip "Need MDS version at least 2.14.55"
18744
18745         local mdts=$(comma_list $(mdts_nodes))
18746
18747         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
18748         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
18749                                        fail_val=$((24 * 3600 * 10))
18750
18751         # Create a user which is 10 days old
18752         changelog_register || error "first changelog_register failed"
18753         local cl_users
18754         declare -A cl_user1
18755         local i
18756
18757         # generate some changelog records to accumulate on each MDT
18758         # use all_char because created files should be evenly distributed
18759         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18760                 error "test_mkdir $tdir failed"
18761         for ((i = 0; i < MDSCOUNT; i++)); do
18762                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18763                         error "create $DIR/$tdir/d$i.1 failed"
18764         done
18765
18766         # check changelogs have been generated
18767         local nbcl=$(changelog_dump | wc -l)
18768         (( nbcl > 0 )) || error "no changelogs found"
18769
18770         # reduce the max_idle_indexes value to make sure we exceed it
18771         for param in "changelog_max_idle_indexes=2097446912" \
18772                      "changelog_max_idle_time=2592000" \
18773                      "changelog_gc=1" \
18774                      "changelog_min_gc_interval=2"; do
18775                 local MDT0=$(facet_svc $SINGLEMDS)
18776                 local var="${param%=*}"
18777                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18778
18779                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18780                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
18781                         error "unable to set mdd.*.$param"
18782         done
18783
18784         local start=$SECONDS
18785         for i in $(seq $MDSCOUNT); do
18786                 cl_users=(${CL_USERS[mds$i]})
18787                 cl_user1[mds$i]="${cl_users[0]}"
18788
18789                 [[ -n "${cl_user1[mds$i]}" ]] ||
18790                         error "mds$i: no user registered"
18791         done
18792
18793         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
18794         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
18795
18796         # ensure we are past the previous changelog_min_gc_interval set above
18797         local sleep2=$((start + 2 - SECONDS))
18798         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18799
18800         # Generate one more changelog to trigger GC
18801         for ((i = 0; i < MDSCOUNT; i++)); do
18802                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
18803                         error "create $DIR/$tdir/d$i.3 failed"
18804         done
18805
18806         # ensure gc thread is done
18807         for node in $(mdts_nodes); do
18808                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
18809                         error "$node: GC-thread not done"
18810         done
18811
18812         do_nodes $mdts $LCTL set_param fail_loc=0
18813
18814         for (( i = 1; i <= MDSCOUNT; i++ )); do
18815                 # check cl_user1 is purged
18816                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
18817                         error "mds$i: User ${cl_user1[mds$i]} is registered"
18818         done
18819         return 0
18820 }
18821 run_test 160s "changelog garbage collect on idle records * time"
18822
18823 test_160t() {
18824         remote_mds_nodsh && skip "remote MDS with nodsh"
18825         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
18826                 skip "Need MDS version at least 2.15.50"
18827
18828         local MDT0=$(facet_svc $SINGLEMDS)
18829         local cl_users
18830         local cl_user1
18831         local cl_user2
18832         local start
18833
18834         changelog_register --user user1 -m all ||
18835                 error "user1 failed to register"
18836
18837         mkdir_on_mdt0 $DIR/$tdir
18838         # create default overstripe to maximize changelog size
18839         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
18840         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
18841         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18842
18843         # user2 consumes less records so less space
18844         changelog_register --user user2 || error "user2 failed to register"
18845         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
18846         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18847
18848         # check changelogs have been generated
18849         local nbcl=$(changelog_dump | wc -l)
18850         (( nbcl > 0 )) || error "no changelogs found"
18851
18852         # reduce the changelog_min_gc_interval to force check
18853         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
18854                 local var="${param%=*}"
18855                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18856
18857                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
18858                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
18859                         error "unable to set mdd.*.$param"
18860         done
18861
18862         start=$SECONDS
18863         cl_users=(${CL_USERS[mds1]})
18864         cl_user1="${cl_users[0]}"
18865         cl_user2="${cl_users[1]}"
18866
18867         [[ -n $cl_user1 ]] ||
18868                 error "mds1: user #1 isn't registered"
18869         [[ -n $cl_user2 ]] ||
18870                 error "mds1: user #2 isn't registered"
18871
18872         # ensure we are past the previous changelog_min_gc_interval set above
18873         local sleep2=$((start + 2 - SECONDS))
18874         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18875
18876         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
18877         do_facet mds1 $LCTL set_param fail_loc=0x018c \
18878                         fail_val=$(((llog_size1 + llog_size2) / 2))
18879
18880         # Generate more changelog to trigger GC
18881         createmany -o $DIR/$tdir/u3_ 4 ||
18882                 error "create failed for more files"
18883
18884         # ensure gc thread is done
18885         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
18886                 error "mds1: GC-thread not done"
18887
18888         do_facet mds1 $LCTL set_param fail_loc=0
18889
18890         # check cl_user1 is purged
18891         changelog_users mds1 | grep -q "$cl_user1" &&
18892                 error "User $cl_user1 is registered"
18893         # check cl_user2 is not purged
18894         changelog_users mds1 | grep -q "$cl_user2" ||
18895                 error "User $cl_user2 is not registered"
18896 }
18897 run_test 160t "changelog garbage collect on lack of space"
18898
18899 test_160u() { # LU-17400
18900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18901         remote_mds_nodsh && skip "remote MDS with nodsh"
18902         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
18903                 skip "Need MDS version at least 2.2.0"
18904
18905         cd $DIR || error "cd $DIR failed"
18906
18907         # ensure changelog has a clean view if tests are run multiple times
18908         [ -d rename ] && rm -rf rename
18909
18910         changelog_register || error "changelog_register failed"
18911         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18912
18913         changelog_users $SINGLEMDS | grep -q $cl_user ||
18914                 error "User '$cl_user' not found in changelog_users"
18915
18916         local longname1=$(str_repeat a 255)
18917
18918         echo "creating simple directory tree"
18919         mkdir -p rename/a || error "create of simple directory tree failed"
18920         echo "creating rename/hw file"
18921         echo "hello world" > rename/hw || error "create of rename/hw failed"
18922         echo "creating very long named file"
18923         touch rename/$longname1 || error "create of 'rename/$longname1' failed"
18924         echo "move rename/hw to rename/a/a.hw"
18925         mv rename/hw rename/a/a.hw || error "mv failed"
18926
18927         RENME=($(changelog_dump | grep "RENME"))
18928         #declare -p RENME # for debugging captured value with indexes
18929
18930         [[ "${RENME[11]}" == "a.hw" && "${RENME[14]}" == "hw" ]] ||
18931                 error "changelog rename record type name/sname error"
18932 }
18933 run_test 160u "changelog rename record type name and sname strings are correct"
18934
18935 test_161a() {
18936         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18937
18938         test_mkdir -c1 $DIR/$tdir
18939         cp /etc/hosts $DIR/$tdir/$tfile
18940         test_mkdir -c1 $DIR/$tdir/foo1
18941         test_mkdir -c1 $DIR/$tdir/foo2
18942         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
18943         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
18944         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
18945         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
18946         local FID=$($LFS path2fid $DIR/$tdir/$tfile | 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 $DIR/$tdir/foo2/zachary
18953         # last
18954         rm $DIR/$tdir/foo2/thor
18955         # first
18956         rm $DIR/$tdir/$tfile
18957         # rename
18958         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
18959         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
18960                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
18961         rm $DIR/$tdir/foo2/maggie
18962
18963         # overflow the EA
18964         local longname=$tfile.avg_len_is_thirty_two_
18965         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
18966                 error_noexit 'failed to unlink many hardlinks'" EXIT
18967         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
18968                 error "failed to hardlink many files"
18969         links=$($LFS fid2path $DIR $FID | wc -l)
18970         echo -n "${links}/1000 links in link EA"
18971         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
18972 }
18973 run_test 161a "link ea sanity"
18974
18975 test_161b() {
18976         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18977         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
18978
18979         local MDTIDX=1
18980         local remote_dir=$DIR/$tdir/remote_dir
18981
18982         mkdir -p $DIR/$tdir
18983         $LFS mkdir -i $MDTIDX $remote_dir ||
18984                 error "create remote directory failed"
18985
18986         cp /etc/hosts $remote_dir/$tfile
18987         mkdir -p $remote_dir/foo1
18988         mkdir -p $remote_dir/foo2
18989         ln $remote_dir/$tfile $remote_dir/foo1/sofia
18990         ln $remote_dir/$tfile $remote_dir/foo2/zachary
18991         ln $remote_dir/$tfile $remote_dir/foo1/luna
18992         ln $remote_dir/$tfile $remote_dir/foo2/thor
18993
18994         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
18995                      tr -d ']')
18996         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18997                 $LFS fid2path $DIR $FID
18998                 error "bad link ea"
18999         fi
19000         # middle
19001         rm $remote_dir/foo2/zachary
19002         # last
19003         rm $remote_dir/foo2/thor
19004         # first
19005         rm $remote_dir/$tfile
19006         # rename
19007         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
19008         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
19009         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
19010                 $LFS fid2path $DIR $FID
19011                 error "bad link rename"
19012         fi
19013         rm $remote_dir/foo2/maggie
19014
19015         # overflow the EA
19016         local longname=filename_avg_len_is_thirty_two_
19017         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
19018                 error "failed to hardlink many files"
19019         links=$($LFS fid2path $DIR $FID | wc -l)
19020         echo -n "${links}/1000 links in link EA"
19021         [[ ${links} -gt 60 ]] ||
19022                 error "expected at least 60 links in link EA"
19023         unlinkmany $remote_dir/foo2/$longname 1000 ||
19024         error "failed to unlink many hardlinks"
19025 }
19026 run_test 161b "link ea sanity under remote directory"
19027
19028 test_161c() {
19029         remote_mds_nodsh && skip "remote MDS with nodsh"
19030         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19031         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
19032                 skip "Need MDS version at least 2.1.5"
19033
19034         # define CLF_RENAME_LAST 0x0001
19035         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
19036         changelog_register || error "changelog_register failed"
19037
19038         rm -rf $DIR/$tdir
19039         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
19040         touch $DIR/$tdir/foo_161c
19041         touch $DIR/$tdir/bar_161c
19042         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
19043         changelog_dump | grep RENME | tail -n 5
19044         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
19045         changelog_clear 0 || error "changelog_clear failed"
19046         if [ x$flags != "x0x1" ]; then
19047                 error "flag $flags is not 0x1"
19048         fi
19049
19050         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
19051         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
19052         touch $DIR/$tdir/foo_161c
19053         touch $DIR/$tdir/bar_161c
19054         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
19055         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
19056         changelog_dump | grep RENME | tail -n 5
19057         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
19058         changelog_clear 0 || error "changelog_clear failed"
19059         if [ x$flags != "x0x0" ]; then
19060                 error "flag $flags is not 0x0"
19061         fi
19062         echo "rename overwrite a target having nlink > 1," \
19063                 "changelog record has flags of $flags"
19064
19065         # rename doesn't overwrite a target (changelog flag 0x0)
19066         touch $DIR/$tdir/foo_161c
19067         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
19068         changelog_dump | grep RENME | tail -n 5
19069         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
19070         changelog_clear 0 || error "changelog_clear failed"
19071         if [ x$flags != "x0x0" ]; then
19072                 error "flag $flags is not 0x0"
19073         fi
19074         echo "rename doesn't overwrite a target," \
19075                 "changelog record has flags of $flags"
19076
19077         # define CLF_UNLINK_LAST 0x0001
19078         # unlink a file having nlink = 1 (changelog flag 0x1)
19079         rm -f $DIR/$tdir/foo2_161c
19080         changelog_dump | grep UNLNK | tail -n 5
19081         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
19082         changelog_clear 0 || error "changelog_clear failed"
19083         if [ x$flags != "x0x1" ]; then
19084                 error "flag $flags is not 0x1"
19085         fi
19086         echo "unlink a file having nlink = 1," \
19087                 "changelog record has flags of $flags"
19088
19089         # unlink a file having nlink > 1 (changelog flag 0x0)
19090         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
19091         rm -f $DIR/$tdir/foobar_161c
19092         changelog_dump | grep UNLNK | tail -n 5
19093         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
19094         changelog_clear 0 || error "changelog_clear failed"
19095         if [ x$flags != "x0x0" ]; then
19096                 error "flag $flags is not 0x0"
19097         fi
19098         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
19099 }
19100 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
19101
19102 test_161d() {
19103         remote_mds_nodsh && skip "remote MDS with nodsh"
19104         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
19105
19106         local pid
19107         local fid
19108
19109         changelog_register || error "changelog_register failed"
19110
19111         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
19112         # interfer with $MOUNT/.lustre/fid/ access
19113         mkdir $DIR/$tdir
19114         [[ $? -eq 0 ]] || error "mkdir failed"
19115
19116         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | CFS_FAIL_ONCE
19117         $LCTL set_param fail_loc=0x8000140c
19118         # 5s pause
19119         $LCTL set_param fail_val=5
19120
19121         # create file
19122         echo foofoo > $DIR/$tdir/$tfile &
19123         pid=$!
19124
19125         # wait for create to be delayed
19126         sleep 2
19127
19128         ps -p $pid
19129         [[ $? -eq 0 ]] || error "create should be blocked"
19130
19131         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
19132         stack_trap "rm -f $tempfile"
19133         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
19134         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
19135         # some delay may occur during ChangeLog publishing and file read just
19136         # above, that could allow file write to happen finally
19137         [[ -s $tempfile ]] && echo "file should be empty"
19138
19139         $LCTL set_param fail_loc=0
19140
19141         wait $pid
19142         [[ $? -eq 0 ]] || error "create failed"
19143 }
19144 run_test 161d "create with concurrent .lustre/fid access"
19145
19146 check_path() {
19147         local expected="$1"
19148         shift
19149         local fid="$2"
19150
19151         local path
19152         path=$($LFS fid2path "$@")
19153         local rc=$?
19154
19155         if [ $rc -ne 0 ]; then
19156                 error "path looked up of '$expected' failed: rc=$rc"
19157         elif [ "$path" != "$expected" ]; then
19158                 error "path looked up '$path' instead of '$expected'"
19159         else
19160                 echo "FID '$fid' resolves to path '$path' as expected"
19161         fi
19162 }
19163
19164 test_162a() { # was test_162
19165         test_mkdir -p -c1 $DIR/$tdir/d2
19166         touch $DIR/$tdir/d2/$tfile
19167         touch $DIR/$tdir/d2/x1
19168         touch $DIR/$tdir/d2/x2
19169         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
19170         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
19171         # regular file
19172         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
19173         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
19174
19175         # softlink
19176         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
19177         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
19178         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
19179
19180         # softlink to wrong file
19181         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
19182         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
19183         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
19184
19185         # hardlink
19186         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
19187         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
19188         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
19189         # fid2path dir/fsname should both work
19190         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
19191         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
19192
19193         # hardlink count: check that there are 2 links
19194         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
19195         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
19196
19197         # hardlink indexing: remove the first link
19198         rm $DIR/$tdir/d2/p/q/r/hlink
19199         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
19200 }
19201 run_test 162a "path lookup sanity"
19202
19203 test_162b() {
19204         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19205         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19206
19207         mkdir $DIR/$tdir
19208         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19209                                 error "create striped dir failed"
19210
19211         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
19212                                         tail -n 1 | awk '{print $2}')
19213         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
19214
19215         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
19216         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
19217
19218         # regular file
19219         for ((i=0;i<5;i++)); do
19220                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
19221                         error "get fid for f$i failed"
19222                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
19223
19224                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
19225                         error "get fid for d$i failed"
19226                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
19227         done
19228
19229         return 0
19230 }
19231 run_test 162b "striped directory path lookup sanity"
19232
19233 # LU-4239: Verify fid2path works with paths 100 or more directories deep
19234 test_162c() {
19235         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
19236                 skip "Need MDS version at least 2.7.51"
19237
19238         local lpath=$tdir.local
19239         local rpath=$tdir.remote
19240
19241         test_mkdir $DIR/$lpath
19242         test_mkdir $DIR/$rpath
19243
19244         for ((i = 0; i <= 101; i++)); do
19245                 lpath="$lpath/$i"
19246                 mkdir $DIR/$lpath
19247                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
19248                         error "get fid for local directory $DIR/$lpath failed"
19249                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
19250
19251                 rpath="$rpath/$i"
19252                 test_mkdir $DIR/$rpath
19253                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
19254                         error "get fid for remote directory $DIR/$rpath failed"
19255                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
19256         done
19257
19258         return 0
19259 }
19260 run_test 162c "fid2path works with paths 100 or more directories deep"
19261
19262 oalr_event_count() {
19263         local event="${1}"
19264         local trace="${2}"
19265
19266         awk -v name="${FSNAME}-OST0000" \
19267             -v event="${event}" \
19268             '$1 == "TRACE" && $2 == event && $3 == name' \
19269             "${trace}" |
19270         wc -l
19271 }
19272
19273 oalr_expect_event_count() {
19274         local event="${1}"
19275         local trace="${2}"
19276         local expect="${3}"
19277         local count
19278
19279         count=$(oalr_event_count "${event}" "${trace}")
19280         if ((count == expect)); then
19281                 return 0
19282         fi
19283
19284         error_noexit "${event} event count was '${count}', expected ${expect}"
19285         cat "${trace}" >&2
19286         exit 1
19287 }
19288
19289 cleanup_165() {
19290         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
19291         stop ost1
19292         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
19293 }
19294
19295 setup_165() {
19296         sync # Flush previous IOs so we can count log entries.
19297         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
19298         stack_trap cleanup_165 EXIT
19299 }
19300
19301 test_165a() {
19302         local trace="/tmp/${tfile}.trace"
19303         local rc
19304         local count
19305
19306         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19307                 skip "OFD access log unsupported"
19308
19309         setup_165
19310         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19311         sleep 5
19312
19313         do_facet ost1 ofd_access_log_reader --list
19314         stop ost1
19315
19316         do_facet ost1 killall -TERM ofd_access_log_reader
19317         wait
19318         rc=$?
19319
19320         if ((rc != 0)); then
19321                 error "ofd_access_log_reader exited with rc = '${rc}'"
19322         fi
19323
19324         # Parse trace file for discovery events:
19325         oalr_expect_event_count alr_log_add "${trace}" 1
19326         oalr_expect_event_count alr_log_eof "${trace}" 1
19327         oalr_expect_event_count alr_log_free "${trace}" 1
19328 }
19329 run_test 165a "ofd access log discovery"
19330
19331 test_165b() {
19332         local trace="/tmp/${tfile}.trace"
19333         local file="${DIR}/${tfile}"
19334         local pfid1
19335         local pfid2
19336         local -a entry
19337         local rc
19338         local count
19339         local size
19340         local flags
19341
19342         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19343                 skip "OFD access log unsupported"
19344
19345         setup_165
19346         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19347         sleep 5
19348
19349         do_facet ost1 ofd_access_log_reader --list
19350
19351         lfs setstripe -c 1 -i 0 "${file}"
19352         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19353                 error "cannot create '${file}'"
19354
19355         sleep 5
19356         do_facet ost1 killall -TERM ofd_access_log_reader
19357         wait
19358         rc=$?
19359
19360         if ((rc != 0)); then
19361                 error "ofd_access_log_reader exited with rc = '${rc}'"
19362         fi
19363
19364         oalr_expect_event_count alr_log_entry "${trace}" 1
19365
19366         pfid1=$($LFS path2fid "${file}")
19367
19368         # 1     2             3   4    5     6   7    8    9     10
19369         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
19370         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
19371
19372         echo "entry = '${entry[*]}'" >&2
19373
19374         pfid2=${entry[4]}
19375         if [[ "${pfid1}" != "${pfid2}" ]]; then
19376                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
19377         fi
19378
19379         size=${entry[8]}
19380         if ((size != 1048576)); then
19381                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
19382         fi
19383
19384         flags=${entry[10]}
19385         if [[ "${flags}" != "w" ]]; then
19386                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
19387         fi
19388
19389         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19390         sleep 5
19391
19392         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
19393                 error "cannot read '${file}'"
19394         sleep 5
19395
19396         do_facet ost1 killall -TERM ofd_access_log_reader
19397         wait
19398         rc=$?
19399
19400         if ((rc != 0)); then
19401                 error "ofd_access_log_reader exited with rc = '${rc}'"
19402         fi
19403
19404         oalr_expect_event_count alr_log_entry "${trace}" 1
19405
19406         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
19407         echo "entry = '${entry[*]}'" >&2
19408
19409         pfid2=${entry[4]}
19410         if [[ "${pfid1}" != "${pfid2}" ]]; then
19411                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
19412         fi
19413
19414         size=${entry[8]}
19415         if ((size != 524288)); then
19416                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
19417         fi
19418
19419         flags=${entry[10]}
19420         if [[ "${flags}" != "r" ]]; then
19421                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
19422         fi
19423 }
19424 run_test 165b "ofd access log entries are produced and consumed"
19425
19426 test_165c() {
19427         local trace="/tmp/${tfile}.trace"
19428         local file="${DIR}/${tdir}/${tfile}"
19429
19430         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19431                 skip "OFD access log unsupported"
19432
19433         test_mkdir "${DIR}/${tdir}"
19434
19435         setup_165
19436         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19437         sleep 5
19438
19439         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
19440
19441         # 4096 / 64 = 64. Create twice as many entries.
19442         for ((i = 0; i < 128; i++)); do
19443                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
19444                         error "cannot create file"
19445         done
19446
19447         sync
19448
19449         do_facet ost1 killall -TERM ofd_access_log_reader
19450         wait
19451         rc=$?
19452         if ((rc != 0)); then
19453                 error "ofd_access_log_reader exited with rc = '${rc}'"
19454         fi
19455
19456         unlinkmany  "${file}-%d" 128
19457 }
19458 run_test 165c "full ofd access logs do not block IOs"
19459
19460 oal_get_read_count() {
19461         local stats="$1"
19462
19463         # STATS lustre-OST0001 alr_read_count 1
19464
19465         do_facet ost1 cat "${stats}" |
19466         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
19467              END { print count; }'
19468 }
19469
19470 oal_expect_read_count() {
19471         local stats="$1"
19472         local count
19473         local expect="$2"
19474
19475         # Ask ofd_access_log_reader to write stats.
19476         do_facet ost1 killall -USR1 ofd_access_log_reader
19477
19478         # Allow some time for things to happen.
19479         sleep 1
19480
19481         count=$(oal_get_read_count "${stats}")
19482         if ((count == expect)); then
19483                 return 0
19484         fi
19485
19486         error_noexit "bad read count, got ${count}, expected ${expect}"
19487         do_facet ost1 cat "${stats}" >&2
19488         exit 1
19489 }
19490
19491 test_165d() {
19492         local stats="/tmp/${tfile}.stats"
19493         local file="${DIR}/${tdir}/${tfile}"
19494         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
19495
19496         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19497                 skip "OFD access log unsupported"
19498
19499         test_mkdir "${DIR}/${tdir}"
19500
19501         setup_165
19502         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
19503         sleep 5
19504
19505         lfs setstripe -c 1 -i 0 "${file}"
19506
19507         do_facet ost1 lctl set_param "${param}=rw"
19508         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19509                 error "cannot create '${file}'"
19510         oal_expect_read_count "${stats}" 1
19511
19512         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19513                 error "cannot read '${file}'"
19514         oal_expect_read_count "${stats}" 2
19515
19516         do_facet ost1 lctl set_param "${param}=r"
19517         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19518                 error "cannot create '${file}'"
19519         oal_expect_read_count "${stats}" 2
19520
19521         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19522                 error "cannot read '${file}'"
19523         oal_expect_read_count "${stats}" 3
19524
19525         do_facet ost1 lctl set_param "${param}=w"
19526         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19527                 error "cannot create '${file}'"
19528         oal_expect_read_count "${stats}" 4
19529
19530         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19531                 error "cannot read '${file}'"
19532         oal_expect_read_count "${stats}" 4
19533
19534         do_facet ost1 lctl set_param "${param}=0"
19535         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19536                 error "cannot create '${file}'"
19537         oal_expect_read_count "${stats}" 4
19538
19539         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19540                 error "cannot read '${file}'"
19541         oal_expect_read_count "${stats}" 4
19542
19543         do_facet ost1 killall -TERM ofd_access_log_reader
19544         wait
19545         rc=$?
19546         if ((rc != 0)); then
19547                 error "ofd_access_log_reader exited with rc = '${rc}'"
19548         fi
19549 }
19550 run_test 165d "ofd_access_log mask works"
19551
19552 test_165e() {
19553         local stats="/tmp/${tfile}.stats"
19554         local file0="${DIR}/${tdir}-0/${tfile}"
19555         local file1="${DIR}/${tdir}-1/${tfile}"
19556
19557         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19558                 skip "OFD access log unsupported"
19559
19560         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
19561
19562         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
19563         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
19564
19565         lfs setstripe -c 1 -i 0 "${file0}"
19566         lfs setstripe -c 1 -i 0 "${file1}"
19567
19568         setup_165
19569         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
19570         sleep 5
19571
19572         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
19573                 error "cannot create '${file0}'"
19574         sync
19575         oal_expect_read_count "${stats}" 0
19576
19577         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
19578                 error "cannot create '${file1}'"
19579         sync
19580         oal_expect_read_count "${stats}" 1
19581
19582         do_facet ost1 killall -TERM ofd_access_log_reader
19583         wait
19584         rc=$?
19585         if ((rc != 0)); then
19586                 error "ofd_access_log_reader exited with rc = '${rc}'"
19587         fi
19588 }
19589 run_test 165e "ofd_access_log MDT index filter works"
19590
19591 test_165f() {
19592         local trace="/tmp/${tfile}.trace"
19593         local rc
19594         local count
19595
19596         setup_165
19597         do_facet ost1 timeout 60 ofd_access_log_reader \
19598                 --exit-on-close --debug=- --trace=- > "${trace}" &
19599         sleep 5
19600         stop ost1
19601
19602         wait
19603         rc=$?
19604
19605         if ((rc != 0)); then
19606                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
19607                 cat "${trace}"
19608                 exit 1
19609         fi
19610 }
19611 run_test 165f "ofd_access_log_reader --exit-on-close works"
19612
19613 test_169() {
19614         # do directio so as not to populate the page cache
19615         log "creating a 10 Mb file"
19616         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
19617                 error "multiop failed while creating a file"
19618         log "starting reads"
19619         dd if=$DIR/$tfile of=/dev/null bs=4096 &
19620         log "truncating the file"
19621         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
19622                 error "multiop failed while truncating the file"
19623         log "killing dd"
19624         kill %+ || true # reads might have finished
19625         echo "wait until dd is finished"
19626         wait
19627         log "removing the temporary file"
19628         rm -rf $DIR/$tfile || error "tmp file removal failed"
19629 }
19630 run_test 169 "parallel read and truncate should not deadlock"
19631
19632 test_170() {
19633         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19634
19635         $LCTL clear     # bug 18514
19636         $LCTL debug_daemon start $TMP/${tfile}_log_good
19637         touch $DIR/$tfile
19638         $LCTL debug_daemon stop
19639         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
19640                 error "sed failed to read log_good"
19641
19642         $LCTL debug_daemon start $TMP/${tfile}_log_good
19643         rm -rf $DIR/$tfile
19644         $LCTL debug_daemon stop
19645
19646         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
19647                error "lctl df log_bad failed"
19648
19649         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19650         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19651
19652         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
19653         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
19654
19655         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
19656                 error "bad_line good_line1 good_line2 are empty"
19657
19658         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19659         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
19660         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19661
19662         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
19663         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19664         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19665
19666         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
19667                 error "bad_line_new good_line_new are empty"
19668
19669         local expected_good=$((good_line1 + good_line2*2))
19670
19671         rm -f $TMP/${tfile}*
19672         # LU-231, short malformed line may not be counted into bad lines
19673         if [ $bad_line -ne $bad_line_new ] &&
19674                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
19675                 error "expected $bad_line bad lines, but got $bad_line_new"
19676                 return 1
19677         fi
19678
19679         if [ $expected_good -ne $good_line_new ]; then
19680                 error "expected $expected_good good lines, but got $good_line_new"
19681                 return 2
19682         fi
19683         true
19684 }
19685 run_test 170 "test lctl df to handle corrupted log ====================="
19686
19687 test_171() { # bug20592
19688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19689
19690         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
19691         $LCTL set_param fail_loc=0x50e
19692         $LCTL set_param fail_val=3000
19693         multiop_bg_pause $DIR/$tfile O_s || true
19694         local MULTIPID=$!
19695         kill -USR1 $MULTIPID
19696         # cause log dump
19697         sleep 3
19698         wait $MULTIPID
19699         if dmesg | grep "recursive fault"; then
19700                 error "caught a recursive fault"
19701         fi
19702         $LCTL set_param fail_loc=0
19703         true
19704 }
19705 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
19706
19707 test_172() {
19708
19709         #define OBD_FAIL_OBD_CLEANUP  0x60e
19710         $LCTL set_param fail_loc=0x60e
19711         umount $MOUNT || error "umount $MOUNT failed"
19712         stack_trap "mount_client $MOUNT"
19713
19714         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
19715                 error "no client OBDs are remained"
19716
19717         $LCTL dl | while read devno state type name foo; do
19718                 case $type in
19719                 lov|osc|lmv|mdc)
19720                         $LCTL --device $name cleanup
19721                         $LCTL --device $name detach
19722                         ;;
19723                 *)
19724                         # skip server devices
19725                         ;;
19726                 esac
19727         done
19728
19729         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
19730                 $LCTL dl | egrep " osc | lov | lmv | mdc "
19731                 error "some client OBDs are still remained"
19732         fi
19733
19734 }
19735 run_test 172 "manual device removal with lctl cleanup/detach ======"
19736
19737 # it would be good to share it with obdfilter-survey/iokit-libecho code
19738 setup_obdecho_osc () {
19739         local rc=0
19740         local ost_nid=$1
19741         local obdfilter_name=$2
19742         echo "Creating new osc for $obdfilter_name on $ost_nid"
19743         # make sure we can find loopback nid
19744         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
19745
19746         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
19747                            ${obdfilter_name}_osc_UUID || rc=2; }
19748         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
19749                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
19750         return $rc
19751 }
19752
19753 cleanup_obdecho_osc () {
19754         local obdfilter_name=$1
19755         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
19756         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
19757         return 0
19758 }
19759
19760 obdecho_test() {
19761         local OBD=$1
19762         local node=$2
19763         local pages=${3:-64}
19764         local rc=0
19765         local id
19766
19767         local count=10
19768         local obd_size=$(get_obd_size $node $OBD)
19769         local page_size=$(get_page_size $node)
19770         if [[ -n "$obd_size" ]]; then
19771                 local new_count=$((obd_size / (pages * page_size / 1024)))
19772                 [[ $new_count -ge $count ]] || count=$new_count
19773         fi
19774
19775         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
19776         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
19777                            rc=2; }
19778         if [ $rc -eq 0 ]; then
19779             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
19780             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
19781         fi
19782         echo "New object id is $id"
19783         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
19784                            rc=4; }
19785         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
19786                            "test_brw $count w v $pages $id" || rc=4; }
19787         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
19788                            rc=4; }
19789         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
19790                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
19791         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
19792                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
19793         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
19794         return $rc
19795 }
19796
19797 test_180a() {
19798         skip "obdecho on osc is no longer supported"
19799 }
19800 run_test 180a "test obdecho on osc"
19801
19802 test_180b() {
19803         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19804         remote_ost_nodsh && skip "remote OST with nodsh"
19805
19806         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19807                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19808                 error "failed to load module obdecho"
19809
19810         local target=$(do_facet ost1 $LCTL dl |
19811                        awk '/obdfilter/ { print $4; exit; }')
19812
19813         if [ -n "$target" ]; then
19814                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
19815         else
19816                 do_facet ost1 $LCTL dl
19817                 error "there is no obdfilter target on ost1"
19818         fi
19819 }
19820 run_test 180b "test obdecho directly on obdfilter"
19821
19822 test_180c() { # LU-2598
19823         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19824         remote_ost_nodsh && skip "remote OST with nodsh"
19825         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
19826                 skip "Need MDS version at least 2.4.0"
19827
19828         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19829                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19830                 error "failed to load module obdecho"
19831
19832         local target=$(do_facet ost1 $LCTL dl |
19833                        awk '/obdfilter/ { print $4; exit; }')
19834
19835         if [ -n "$target" ]; then
19836                 local pages=16384 # 64MB bulk I/O RPC size
19837
19838                 obdecho_test "$target" ost1 "$pages" ||
19839                         error "obdecho_test with pages=$pages failed with $?"
19840         else
19841                 do_facet ost1 $LCTL dl
19842                 error "there is no obdfilter target on ost1"
19843         fi
19844 }
19845 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
19846
19847 test_181() { # bug 22177
19848         test_mkdir $DIR/$tdir
19849         # create enough files to index the directory
19850         createmany -o $DIR/$tdir/foobar 4000
19851         # print attributes for debug purpose
19852         lsattr -d .
19853         # open dir
19854         multiop_bg_pause $DIR/$tdir D_Sc || return 1
19855         MULTIPID=$!
19856         # remove the files & current working dir
19857         unlinkmany $DIR/$tdir/foobar 4000
19858         rmdir $DIR/$tdir
19859         kill -USR1 $MULTIPID
19860         wait $MULTIPID
19861         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
19862         return 0
19863 }
19864 run_test 181 "Test open-unlinked dir ========================"
19865
19866 test_182a() {
19867         local fcount=1000
19868         local tcount=10
19869
19870         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19871
19872         $LCTL set_param mdc.*.rpc_stats=clear
19873
19874         for (( i = 0; i < $tcount; i++ )) ; do
19875                 mkdir $DIR/$tdir/$i
19876         done
19877
19878         for (( i = 0; i < $tcount; i++ )) ; do
19879                 createmany -o $DIR/$tdir/$i/f- $fcount &
19880         done
19881         wait
19882
19883         for (( i = 0; i < $tcount; i++ )) ; do
19884                 unlinkmany $DIR/$tdir/$i/f- $fcount &
19885         done
19886         wait
19887
19888         $LCTL get_param mdc.*.rpc_stats
19889
19890         rm -rf $DIR/$tdir
19891 }
19892 run_test 182a "Test parallel modify metadata operations from mdc"
19893
19894 test_182b() {
19895         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19896         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19897         local dcount=1000
19898         local tcount=10
19899         local stime
19900         local etime
19901         local delta
19902
19903         do_facet mds1 $LCTL list_param \
19904                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
19905                 skip "MDS lacks parallel RPC handling"
19906
19907         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19908
19909         rpc_count=$(do_facet mds1 $LCTL get_param -n \
19910                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
19911
19912         stime=$(date +%s)
19913         createmany -i 0 -d $DIR/$tdir/t- $tcount
19914
19915         for (( i = 0; i < $tcount; i++ )) ; do
19916                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19917         done
19918         wait
19919         etime=$(date +%s)
19920         delta=$((etime - stime))
19921         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
19922
19923         stime=$(date +%s)
19924         for (( i = 0; i < $tcount; i++ )) ; do
19925                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
19926         done
19927         wait
19928         etime=$(date +%s)
19929         delta=$((etime - stime))
19930         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
19931
19932         rm -rf $DIR/$tdir
19933
19934         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19935
19936         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
19937
19938         stime=$(date +%s)
19939         createmany -i 0 -d $DIR/$tdir/t- $tcount
19940
19941         for (( i = 0; i < $tcount; i++ )) ; do
19942                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19943         done
19944         wait
19945         etime=$(date +%s)
19946         delta=$((etime - stime))
19947         echo "Time for file creation $delta sec for 1 RPC sent at a time"
19948
19949         stime=$(date +%s)
19950         for (( i = 0; i < $tcount; i++ )) ; do
19951                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
19952         done
19953         wait
19954         etime=$(date +%s)
19955         delta=$((etime - stime))
19956         echo "Time for file removal $delta sec for 1 RPC sent at a time"
19957
19958         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
19959 }
19960 run_test 182b "Test parallel modify metadata operations from osp"
19961
19962 test_183() { # LU-2275
19963         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19964         remote_mds_nodsh && skip "remote MDS with nodsh"
19965         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
19966                 skip "Need MDS version at least 2.3.56"
19967
19968         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19969         echo aaa > $DIR/$tdir/$tfile
19970
19971 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
19972         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
19973
19974         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
19975         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
19976
19977         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19978
19979         # Flush negative dentry cache
19980         touch $DIR/$tdir/$tfile
19981
19982         # We are not checking for any leaked references here, they'll
19983         # become evident next time we do cleanup with module unload.
19984         rm -rf $DIR/$tdir
19985 }
19986 run_test 183 "No crash or request leak in case of strange dispositions ========"
19987
19988 # test suite 184 is for LU-2016, LU-2017
19989 test_184a() {
19990         check_swap_layouts_support
19991
19992         dir0=$DIR/$tdir/$testnum
19993         test_mkdir -p -c1 $dir0
19994         ref1=/etc/passwd
19995         ref2=/etc/group
19996         file1=$dir0/f1
19997         file2=$dir0/f2
19998         $LFS setstripe -c1 $file1
19999         cp $ref1 $file1
20000         $LFS setstripe -c2 $file2
20001         cp $ref2 $file2
20002         gen1=$($LFS getstripe -g $file1)
20003         gen2=$($LFS getstripe -g $file2)
20004
20005         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
20006         gen=$($LFS getstripe -g $file1)
20007         [[ $gen1 != $gen ]] ||
20008                 error "Layout generation on $file1 does not change"
20009         gen=$($LFS getstripe -g $file2)
20010         [[ $gen2 != $gen ]] ||
20011                 error "Layout generation on $file2 does not change"
20012
20013         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
20014         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20015
20016         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
20017 }
20018 run_test 184a "Basic layout swap"
20019
20020 test_184b() {
20021         check_swap_layouts_support
20022
20023         dir0=$DIR/$tdir/$testnum
20024         mkdir -p $dir0 || error "creating dir $dir0"
20025         file1=$dir0/f1
20026         file2=$dir0/f2
20027         file3=$dir0/f3
20028         dir1=$dir0/d1
20029         dir2=$dir0/d2
20030         mkdir $dir1 $dir2
20031         $LFS setstripe -c1 $file1
20032         $LFS setstripe -c2 $file2
20033         $LFS setstripe -c1 $file3
20034         chown $RUNAS_ID $file3
20035         gen1=$($LFS getstripe -g $file1)
20036         gen2=$($LFS getstripe -g $file2)
20037
20038         $LFS swap_layouts $dir1 $dir2 &&
20039                 error "swap of directories layouts should fail"
20040         $LFS swap_layouts $dir1 $file1 &&
20041                 error "swap of directory and file layouts should fail"
20042         $RUNAS $LFS swap_layouts $file1 $file2 &&
20043                 error "swap of file we cannot write should fail"
20044         $LFS swap_layouts $file1 $file3 &&
20045                 error "swap of file with different owner should fail"
20046         /bin/true # to clear error code
20047 }
20048 run_test 184b "Forbidden layout swap (will generate errors)"
20049
20050 test_184c() {
20051         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
20052         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
20053         check_swap_layouts_support
20054         check_swap_layout_no_dom $DIR
20055
20056         local dir0=$DIR/$tdir/$testnum
20057         mkdir -p $dir0 || error "creating dir $dir0"
20058
20059         local ref1=$dir0/ref1
20060         local ref2=$dir0/ref2
20061         local file1=$dir0/file1
20062         local file2=$dir0/file2
20063         # create a file large enough for the concurrent test
20064         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
20065         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
20066         echo "ref file size: ref1($(stat -c %s $ref1))," \
20067              "ref2($(stat -c %s $ref2))"
20068
20069         cp $ref2 $file2
20070         dd if=$ref1 of=$file1 bs=16k &
20071         local DD_PID=$!
20072
20073         # Make sure dd starts to copy file, but wait at most 5 seconds
20074         local loops=0
20075         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
20076
20077         $LFS swap_layouts $file1 $file2
20078         local rc=$?
20079         wait $DD_PID
20080         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
20081         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
20082
20083         # how many bytes copied before swapping layout
20084         local copied=$(stat -c %s $file2)
20085         local remaining=$(stat -c %s $ref1)
20086         remaining=$((remaining - copied))
20087         echo "Copied $copied bytes before swapping layout..."
20088
20089         cmp -n $copied $file1 $ref2 | grep differ &&
20090                 error "Content mismatch [0, $copied) of ref2 and file1"
20091         cmp -n $copied $file2 $ref1 ||
20092                 error "Content mismatch [0, $copied) of ref1 and file2"
20093         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
20094                 error "Content mismatch [$copied, EOF) of ref1 and file1"
20095
20096         # clean up
20097         rm -f $ref1 $ref2 $file1 $file2
20098 }
20099 run_test 184c "Concurrent write and layout swap"
20100
20101 test_184d() {
20102         check_swap_layouts_support
20103         check_swap_layout_no_dom $DIR
20104         [ -z "$(which getfattr 2>/dev/null)" ] &&
20105                 skip_env "no getfattr command"
20106
20107         local file1=$DIR/$tdir/$tfile-1
20108         local file2=$DIR/$tdir/$tfile-2
20109         local file3=$DIR/$tdir/$tfile-3
20110         local lovea1
20111         local lovea2
20112
20113         mkdir -p $DIR/$tdir
20114         touch $file1 || error "create $file1 failed"
20115         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
20116                 error "create $file2 failed"
20117         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
20118                 error "create $file3 failed"
20119         lovea1=$(get_layout_param $file1)
20120
20121         $LFS swap_layouts $file2 $file3 ||
20122                 error "swap $file2 $file3 layouts failed"
20123         $LFS swap_layouts $file1 $file2 ||
20124                 error "swap $file1 $file2 layouts failed"
20125
20126         lovea2=$(get_layout_param $file2)
20127         echo "$lovea1"
20128         echo "$lovea2"
20129         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
20130
20131         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
20132         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
20133 }
20134 run_test 184d "allow stripeless layouts swap"
20135
20136 test_184e() {
20137         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
20138                 skip "Need MDS version at least 2.6.94"
20139         check_swap_layouts_support
20140         check_swap_layout_no_dom $DIR
20141         [ -z "$(which getfattr 2>/dev/null)" ] &&
20142                 skip_env "no getfattr command"
20143
20144         local file1=$DIR/$tdir/$tfile-1
20145         local file2=$DIR/$tdir/$tfile-2
20146         local file3=$DIR/$tdir/$tfile-3
20147         local lovea
20148
20149         mkdir -p $DIR/$tdir
20150         touch $file1 || error "create $file1 failed"
20151         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
20152                 error "create $file2 failed"
20153         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
20154                 error "create $file3 failed"
20155
20156         $LFS swap_layouts $file1 $file2 ||
20157                 error "swap $file1 $file2 layouts failed"
20158
20159         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
20160         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
20161
20162         echo 123 > $file1 || error "Should be able to write into $file1"
20163
20164         $LFS swap_layouts $file1 $file3 ||
20165                 error "swap $file1 $file3 layouts failed"
20166
20167         echo 123 > $file1 || error "Should be able to write into $file1"
20168
20169         rm -rf $file1 $file2 $file3
20170 }
20171 run_test 184e "Recreate layout after stripeless layout swaps"
20172
20173 test_184f() {
20174         # Create a file with name longer than sizeof(struct stat) ==
20175         # 144 to see if we can get chars from the file name to appear
20176         # in the returned striping. Note that 'f' == 0x66.
20177         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
20178
20179         mkdir -p $DIR/$tdir
20180         mcreate $DIR/$tdir/$file
20181         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
20182                 error "IOC_MDC_GETFILEINFO returned garbage striping"
20183         fi
20184 }
20185 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
20186
20187 test_185() { # LU-2441
20188         # LU-3553 - no volatile file support in old servers
20189         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
20190                 skip "Need MDS version at least 2.3.60"
20191
20192         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
20193         touch $DIR/$tdir/spoo
20194         local mtime1=$(stat -c "%Y" $DIR/$tdir)
20195         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
20196                 error "cannot create/write a volatile file"
20197         [ "$FILESET" == "" ] &&
20198         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
20199                 error "FID is still valid after close"
20200
20201         multiop_bg_pause $DIR/$tdir Vw4096_c
20202         local multi_pid=$!
20203
20204         local OLD_IFS=$IFS
20205         IFS=":"
20206         local fidv=($fid)
20207         IFS=$OLD_IFS
20208         # assume that the next FID for this client is sequential, since stdout
20209         # is unfortunately eaten by multiop_bg_pause
20210         local n=$((${fidv[1]} + 1))
20211         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
20212         if [ "$FILESET" == "" ]; then
20213                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
20214                         error "FID is missing before close"
20215         fi
20216         kill -USR1 $multi_pid
20217         # 1 second delay, so if mtime change we will see it
20218         sleep 1
20219         local mtime2=$(stat -c "%Y" $DIR/$tdir)
20220         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
20221 }
20222 run_test 185 "Volatile file support"
20223
20224 function create_check_volatile() {
20225         local idx=$1
20226         local tgt
20227
20228         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
20229         local PID=$!
20230         sleep 1
20231         local FID=$(cat /tmp/${tfile}.fid)
20232         [ "$FID" == "" ] && error "can't get FID for volatile"
20233         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
20234         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
20235         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
20236         kill -USR1 $PID
20237         wait
20238         sleep 1
20239         cancel_lru_locks mdc # flush opencache
20240         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
20241         return 0
20242 }
20243
20244 test_185a(){
20245         # LU-12516 - volatile creation via .lustre
20246         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
20247                 skip "Need MDS version at least 2.3.55"
20248
20249         create_check_volatile 0
20250         [ $MDSCOUNT -lt 2 ] && return 0
20251
20252         # DNE case
20253         create_check_volatile 1
20254
20255         return 0
20256 }
20257 run_test 185a "Volatile file creation in .lustre/fid/"
20258
20259 test_187a() {
20260         remote_mds_nodsh && skip "remote MDS with nodsh"
20261         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
20262                 skip "Need MDS version at least 2.3.0"
20263
20264         local dir0=$DIR/$tdir/$testnum
20265         mkdir -p $dir0 || error "creating dir $dir0"
20266
20267         local file=$dir0/file1
20268         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
20269         stack_trap "rm -f $file"
20270         local dv1=$($LFS data_version $file)
20271         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
20272         local dv2=$($LFS data_version $file)
20273         [[ $dv1 != $dv2 ]] ||
20274                 error "data version did not change on write $dv1 == $dv2"
20275 }
20276 run_test 187a "Test data version change"
20277
20278 test_187b() {
20279         remote_mds_nodsh && skip "remote MDS with nodsh"
20280         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
20281                 skip "Need MDS version at least 2.3.0"
20282
20283         local dir0=$DIR/$tdir/$testnum
20284         mkdir -p $dir0 || error "creating dir $dir0"
20285
20286         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
20287         [[ ${DV[0]} != ${DV[1]} ]] ||
20288                 error "data version did not change on write"\
20289                       " ${DV[0]} == ${DV[1]}"
20290
20291         # clean up
20292         rm -f $file1
20293 }
20294 run_test 187b "Test data version change on volatile file"
20295
20296 test_200() {
20297         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20298         remote_mgs_nodsh && skip "remote MGS with nodsh"
20299         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
20300
20301         local POOL=${POOL:-cea1}
20302         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
20303         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
20304         # Pool OST targets
20305         local first_ost=0
20306         local last_ost=$(($OSTCOUNT - 1))
20307         local ost_step=2
20308         local ost_list=$(seq $first_ost $ost_step $last_ost)
20309         local ost_range="$first_ost $last_ost $ost_step"
20310         local test_path=$POOL_ROOT/$POOL_DIR_NAME
20311         local file_dir=$POOL_ROOT/file_tst
20312         local subdir=$test_path/subdir
20313         local rc=0
20314
20315         while : ; do
20316                 # former test_200a test_200b
20317                 pool_add $POOL                          || { rc=$? ; break; }
20318                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
20319                 # former test_200c test_200d
20320                 mkdir -p $test_path
20321                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
20322                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
20323                 mkdir -p $subdir
20324                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
20325                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
20326                                                         || { rc=$? ; break; }
20327                 # former test_200e test_200f
20328                 local files=$((OSTCOUNT*3))
20329                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
20330                                                         || { rc=$? ; break; }
20331                 pool_create_files $POOL $file_dir $files "$ost_list" \
20332                                                         || { rc=$? ; break; }
20333                 # former test_200g test_200h
20334                 pool_lfs_df $POOL                       || { rc=$? ; break; }
20335                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
20336
20337                 # former test_201a test_201b test_201c
20338                 pool_remove_first_target $POOL          || { rc=$? ; break; }
20339
20340                 local f=$test_path/$tfile
20341                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
20342                 pool_remove $POOL $f                    || { rc=$? ; break; }
20343                 break
20344         done
20345
20346         destroy_test_pools
20347
20348         return $rc
20349 }
20350 run_test 200 "OST pools"
20351
20352 # usage: default_attr <count | size | offset>
20353 default_attr() {
20354         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
20355 }
20356
20357 # usage: check_default_stripe_attr
20358 check_default_stripe_attr() {
20359         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
20360         case $1 in
20361         --stripe-count|-c)
20362                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
20363         --stripe-size|-S)
20364                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
20365         --stripe-index|-i)
20366                 EXPECTED=-1;;
20367         *)
20368                 error "unknown getstripe attr '$1'"
20369         esac
20370
20371         [ $ACTUAL == $EXPECTED ] ||
20372                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
20373 }
20374
20375 test_204a() {
20376         test_mkdir $DIR/$tdir
20377         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
20378
20379         check_default_stripe_attr --stripe-count
20380         check_default_stripe_attr --stripe-size
20381         check_default_stripe_attr --stripe-index
20382 }
20383 run_test 204a "Print default stripe attributes"
20384
20385 test_204b() {
20386         test_mkdir $DIR/$tdir
20387         $LFS setstripe --stripe-count 1 $DIR/$tdir
20388
20389         check_default_stripe_attr --stripe-size
20390         check_default_stripe_attr --stripe-index
20391 }
20392 run_test 204b "Print default stripe size and offset"
20393
20394 test_204c() {
20395         test_mkdir $DIR/$tdir
20396         $LFS setstripe --stripe-size 65536 $DIR/$tdir
20397
20398         check_default_stripe_attr --stripe-count
20399         check_default_stripe_attr --stripe-index
20400 }
20401 run_test 204c "Print default stripe count and offset"
20402
20403 test_204d() {
20404         test_mkdir $DIR/$tdir
20405         $LFS setstripe --stripe-index 0 $DIR/$tdir
20406
20407         check_default_stripe_attr --stripe-count
20408         check_default_stripe_attr --stripe-size
20409 }
20410 run_test 204d "Print default stripe count and size"
20411
20412 test_204e() {
20413         test_mkdir $DIR/$tdir
20414         $LFS setstripe -d $DIR/$tdir
20415
20416         # LU-16904 check if root is set as PFL layout
20417         local numcomp=$($LFS getstripe --component-count $MOUNT)
20418
20419         if [[ $numcomp -gt 0 ]]; then
20420                 check_default_stripe_attr --stripe-count
20421         else
20422                 check_default_stripe_attr --stripe-count --raw
20423         fi
20424         check_default_stripe_attr --stripe-size --raw
20425         check_default_stripe_attr --stripe-index --raw
20426 }
20427 run_test 204e "Print raw stripe attributes"
20428
20429 test_204f() {
20430         test_mkdir $DIR/$tdir
20431         $LFS setstripe --stripe-count 1 $DIR/$tdir
20432
20433         check_default_stripe_attr --stripe-size --raw
20434         check_default_stripe_attr --stripe-index --raw
20435 }
20436 run_test 204f "Print raw stripe size and offset"
20437
20438 test_204g() {
20439         test_mkdir $DIR/$tdir
20440         $LFS setstripe --stripe-size 65536 $DIR/$tdir
20441
20442         check_default_stripe_attr --stripe-count --raw
20443         check_default_stripe_attr --stripe-index --raw
20444 }
20445 run_test 204g "Print raw stripe count and offset"
20446
20447 test_204h() {
20448         test_mkdir $DIR/$tdir
20449         $LFS setstripe --stripe-index 0 $DIR/$tdir
20450
20451         check_default_stripe_attr --stripe-count --raw
20452         check_default_stripe_attr --stripe-size --raw
20453 }
20454 run_test 204h "Print raw stripe count and size"
20455
20456 # Figure out which job scheduler is being used, if any,
20457 # or use a fake one
20458 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
20459         JOBENV=SLURM_JOB_ID
20460 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
20461         JOBENV=LSB_JOBID
20462 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
20463         JOBENV=PBS_JOBID
20464 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
20465         JOBENV=LOADL_STEP_ID
20466 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
20467         JOBENV=JOB_ID
20468 else
20469         $LCTL list_param jobid_name > /dev/null 2>&1
20470         if [ $? -eq 0 ]; then
20471                 JOBENV=nodelocal
20472         else
20473                 JOBENV=FAKE_JOBID
20474         fi
20475 fi
20476 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
20477
20478 verify_jobstats() {
20479         local cmd=($1)
20480         shift
20481         local facets="$@"
20482
20483 # we don't really need to clear the stats for this test to work, since each
20484 # command has a unique jobid, but it makes debugging easier if needed.
20485 #       for facet in $facets; do
20486 #               local dev=$(convert_facet2label $facet)
20487 #               # clear old jobstats
20488 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
20489 #       done
20490
20491         # use a new JobID for each test, or we might see an old one
20492         [ "$JOBENV" = "FAKE_JOBID" ] &&
20493                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
20494
20495         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
20496
20497         [ "$JOBENV" = "nodelocal" ] && {
20498                 FAKE_JOBID=id.$testnum.%e.$RANDOM
20499                 $LCTL set_param jobid_name=$FAKE_JOBID
20500                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
20501         }
20502
20503         log "Test: ${cmd[*]}"
20504         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
20505
20506         if [ $JOBENV = "FAKE_JOBID" ]; then
20507                 FAKE_JOBID=$JOBVAL ${cmd[*]}
20508         else
20509                 ${cmd[*]}
20510         fi
20511
20512         # all files are created on OST0000
20513         for facet in $facets; do
20514                 local stats="*.$(convert_facet2label $facet).job_stats"
20515
20516                 # strip out libtool wrappers for in-tree executables
20517                 if (( $(do_facet $facet lctl get_param $stats |
20518                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
20519                         do_facet $facet lctl get_param $stats
20520                         error "No jobstats for $JOBVAL found on $facet::$stats"
20521                 fi
20522         done
20523 }
20524
20525 jobstats_set() {
20526         local new_jobenv=$1
20527
20528         set_persistent_param_and_check client "jobid_var" \
20529                 "$FSNAME.sys.jobid_var" $new_jobenv
20530 }
20531
20532 test_205a() { # Job stats
20533         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20534         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
20535                 skip "Need MDS version with at least 2.7.1"
20536         remote_mgs_nodsh && skip "remote MGS with nodsh"
20537         remote_mds_nodsh && skip "remote MDS with nodsh"
20538         remote_ost_nodsh && skip "remote OST with nodsh"
20539         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
20540                 skip "Server doesn't support jobstats"
20541         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
20542
20543         local old_jobenv=$($LCTL get_param -n jobid_var)
20544         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
20545         stack_trap "jobstats_set $old_jobenv" EXIT
20546
20547         changelog_register
20548
20549         local old_jobid_name=$($LCTL get_param jobid_name)
20550         stack_trap "$LCTL set_param $old_jobid_name" EXIT
20551
20552         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
20553                                 mdt.*.job_cleanup_interval | head -n 1)
20554         local new_interval=5
20555         do_facet $SINGLEMDS \
20556                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
20557         stack_trap "do_facet $SINGLEMDS \
20558                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
20559         local start=$SECONDS
20560
20561         local cmd
20562         # mkdir
20563         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
20564         verify_jobstats "$cmd" "$SINGLEMDS"
20565         # rmdir
20566         cmd="rmdir $DIR/$tdir"
20567         verify_jobstats "$cmd" "$SINGLEMDS"
20568         # mkdir on secondary MDT
20569         if [ $MDSCOUNT -gt 1 ]; then
20570                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
20571                 verify_jobstats "$cmd" "mds2"
20572         fi
20573         # mknod
20574         cmd="mknod $DIR/$tfile c 1 3"
20575         verify_jobstats "$cmd" "$SINGLEMDS"
20576         # unlink
20577         cmd="rm -f $DIR/$tfile"
20578         verify_jobstats "$cmd" "$SINGLEMDS"
20579         # create all files on OST0000 so verify_jobstats can find OST stats
20580         # open & close
20581         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
20582         verify_jobstats "$cmd" "$SINGLEMDS"
20583         # setattr
20584         cmd="touch $DIR/$tfile"
20585         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20586         # write
20587         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
20588         verify_jobstats "$cmd" "ost1"
20589         # read
20590         cancel_lru_locks osc
20591         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
20592         verify_jobstats "$cmd" "ost1"
20593         # truncate
20594         cmd="$TRUNCATE $DIR/$tfile 0"
20595         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20596         # rename
20597         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
20598         verify_jobstats "$cmd" "$SINGLEMDS"
20599         # jobstats expiry - sleep until old stats should be expired
20600         local left=$((new_interval + 5 - (SECONDS - start)))
20601         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
20602                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
20603                         "0" $left
20604         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
20605         verify_jobstats "$cmd" "$SINGLEMDS"
20606         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
20607             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
20608
20609         # Ensure that jobid are present in changelog (if supported by MDS)
20610         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
20611                 changelog_dump | tail -10
20612                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
20613                 [ $jobids -eq 9 ] ||
20614                         error "Wrong changelog jobid count $jobids != 9"
20615
20616                 # LU-5862
20617                 JOBENV="disable"
20618                 jobstats_set $JOBENV
20619                 touch $DIR/$tfile
20620                 changelog_dump | grep $tfile
20621                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
20622                 [ $jobids -eq 0 ] ||
20623                         error "Unexpected jobids when jobid_var=$JOBENV"
20624         fi
20625
20626         # test '%j' access to environment variable - if supported
20627         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
20628                 JOBENV="JOBCOMPLEX"
20629                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20630
20631                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20632         fi
20633
20634         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
20635                 JOBENV="JOBCOMPLEX"
20636                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
20637
20638                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20639         fi
20640
20641         # test '%j' access to per-session jobid - if supported
20642         if lctl list_param jobid_this_session > /dev/null 2>&1
20643         then
20644                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
20645                 lctl set_param jobid_this_session=$USER
20646
20647                 JOBENV="JOBCOMPLEX"
20648                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20649
20650                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20651         fi
20652 }
20653 run_test 205a "Verify job stats"
20654
20655 # LU-13117, LU-13597, LU-16599
20656 test_205b() {
20657         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
20658                 skip "Need MDS version at least 2.13.54.91"
20659
20660         local job_stats="mdt.*.job_stats"
20661         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
20662
20663         do_facet mds1 $LCTL set_param $job_stats=clear
20664
20665         # Setting jobid_var to USER might not be supported
20666         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
20667         $LCTL set_param jobid_var=USER || true
20668         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
20669         $LCTL set_param jobid_name="%j.%e.%u"
20670
20671         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
20672         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
20673                 { do_facet mds1 $LCTL get_param $job_stats;
20674                   error "Unexpected jobid found"; }
20675         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
20676                 { do_facet mds1 $LCTL get_param $job_stats;
20677                   error "wrong job_stats format found"; }
20678
20679         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
20680                 echo "MDS does not yet escape jobid" && return 0
20681
20682         mkdir_on_mdt0 $DIR/$tdir
20683         $LCTL set_param jobid_var=TEST205b
20684         env -i TEST205b="has sp" touch $DIR/$tdir/$tfile.2
20685         local jobid=$(do_facet mds1 $LCTL get_param $job_stats |
20686                       awk '/has\\x20sp/ {print $3}')
20687         [[ -n "$jobid" ]] || { do_facet mds1 $LCTL get_param $job_stats;
20688                   error "jobid not escaped"; }
20689
20690         if (( $MDS1_VERSION >= $(version_code 2.15.53.139) )); then
20691                 # need to run such a command on mds1:
20692                 # lctl set_param mdt.$FSNAME-MDT0000.job_stats='"has\x20sp.touch.0"'
20693                 #
20694                 # there might be multiple MDTs on single mds server, so need to
20695                 # specifiy MDT0000. Or the command will fail due to other MDTs
20696                 do_facet_vp mds1 $LCTL set_param mdt.$FSNAME-MDT0000.job_stats=$jobid ||
20697                         error "cannot clear escaped jobid in job_stats";
20698         else
20699                 echo "MDS does not support clearing escaped jobid"
20700         fi
20701 }
20702 run_test 205b "Verify job stats jobid and output format"
20703
20704 # LU-13733
20705 test_205c() {
20706         $LCTL set_param llite.*.stats=0
20707         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
20708         $LCTL get_param llite.*.stats
20709         $LCTL get_param llite.*.stats | grep \
20710                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
20711                         error "wrong client stats format found"
20712 }
20713 run_test 205c "Verify client stats format"
20714
20715 test_205d() {
20716         local file=$DIR/$tdir/$tfile
20717
20718         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20719                 skip "need lustre >= 2.15.53 for lljobstat"
20720         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20721                 skip "need lustre >= 2.15.53 for lljobstat"
20722         verify_yaml_available || skip_env "YAML verification not installed"
20723
20724         test_mkdir -i 0 $DIR/$tdir
20725         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
20726         stack_trap "rm -rf $DIR/$tdir"
20727
20728         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
20729                 error "failed to write data to $file"
20730         mv $file $file.2
20731
20732         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
20733         echo -n 'verify rename_stats...'
20734         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
20735                 verify_yaml || error "rename_stats is not valid YAML"
20736         echo " OK"
20737
20738         echo -n 'verify mdt job_stats...'
20739         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
20740                 verify_yaml || error "job_stats on mds1 is not valid YAML"
20741         echo " OK"
20742
20743         echo -n 'verify ost job_stats...'
20744         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
20745                 verify_yaml || error "job_stats on ost1 is not valid YAML"
20746         echo " OK"
20747 }
20748 run_test 205d "verify the format of some stats files"
20749
20750 test_205e() {
20751         local ops_comma
20752         local file=$DIR/$tdir/$tfile
20753         local -a cli_params
20754
20755         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20756                 skip "need lustre >= 2.15.53 for lljobstat"
20757         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20758                 skip "need lustre >= 2.15.53 for lljobstat"
20759         verify_yaml_available || skip_env "YAML verification not installed"
20760
20761         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20762         $LCTL set_param jobid_var=nodelocal jobid_name=205e.%e.%u
20763         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20764
20765         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
20766         stack_trap "rm -rf $DIR/$tdir"
20767
20768         $LFS setstripe -E EOF -i 0 -c 1 $file ||
20769                 error "failed to create $file on ost1"
20770         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
20771                 error "failed to write data to $file"
20772
20773         do_facet mds1 "$LCTL get_param *.*.job_stats"
20774         do_facet ost1 "$LCTL get_param *.*.job_stats"
20775
20776         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
20777         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
20778                 error "The output of lljobstat is not an valid YAML"
20779
20780         # verify that job dd.0 does exist and has some ops on ost1
20781         # typically this line is like:
20782         # - 205e.dd.0:            {ops: 20, ...}
20783         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
20784                     awk '$2=="205e.dd.0:" {print $4}')
20785
20786         (( ${ops_comma%,} >= 10 )) ||
20787                 error "cannot find job 205e.dd.0 with ops >= 10"
20788 }
20789 run_test 205e "verify the output of lljobstat"
20790
20791 test_205f() {
20792         verify_yaml_available || skip_env "YAML verification not installed"
20793
20794         # check both qos_ost_weights and qos_mdt_weights
20795         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
20796         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
20797                 error "qos_ost_weights is not valid YAML"
20798 }
20799 run_test 205f "verify qos_ost_weights YAML format "
20800
20801 __test_205_jobstats_dump() {
20802         local -a pids
20803         local nbr_instance=$1
20804
20805         while true; do
20806                 if (( ${#pids[@]} >= nbr_instance )); then
20807                         wait ${pids[@]}
20808                         pids=()
20809                 fi
20810
20811                 do_facet mds1 "$LCTL get_param mdt.*.job_stats > /dev/null" &
20812                 pids+=( $! )
20813         done
20814 }
20815
20816 __test_205_cleanup() {
20817         kill $@
20818         # Clear all job entries
20819         do_facet mds1 "$LCTL set_param mdt.*.job_stats=clear"
20820 }
20821
20822 test_205g() {
20823         local -a mds1_params
20824         local -a cli_params
20825         local pids
20826         local interval=5
20827
20828         mds1_params=( $(do_facet mds1 $LCTL get_param mdt.*.job_cleanup_interval) )
20829         do_facet mds1 $LCTL set_param mdt.*.job_cleanup_interval=$interval
20830         stack_trap "do_facet mds1 $LCTL set_param ${mds1_params[*]}" EXIT
20831
20832         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20833         $LCTL set_param jobid_var=TEST205G_ID jobid_name=%j.%p
20834         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20835
20836         # start jobs loop
20837         export TEST205G_ID=205g
20838         stack_trap "unset TEST205G_ID" EXIT
20839         while true; do
20840                 printf $DIR/$tfile.{0001..1000} | xargs -P10 -n1 touch
20841         done & pids="$! "
20842
20843         __test_205_jobstats_dump 4 & pids+="$! "
20844         stack_trap "__test_205_cleanup $pids" EXIT INT
20845
20846         [[ $SLOW == "no" ]] && sleep 90 || sleep 240
20847 }
20848 run_test 205g "stress test for job_stats procfile"
20849
20850 test_205h() {
20851         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
20852                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
20853         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
20854
20855         local dir=$DIR/$tdir
20856         local f=$dir/$tfile
20857         local f2=$dir/$tfile-2
20858         local f3=$dir/$tfile-3
20859         local subdir=$DIR/dir
20860         local val
20861
20862         local mdts=$(comma_list $(mdts_nodes))
20863         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20864         local client_saved=$($LCTL get_param -n jobid_var)
20865
20866         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20867         stack_trap "$LCTL set_param jobid_var=$client_saved" EXIT
20868
20869         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job ||
20870                 error "failed to set job_xattr parameter to user.job"
20871         $LCTL set_param jobid_var=procname.uid ||
20872                 error "failed to set jobid_var parameter"
20873
20874         test_mkdir $dir
20875
20876         touch $f
20877         val=$(getfattr -n user.job $f | grep user.job)
20878         [[ $val = user.job=\"touch.0\" ]] ||
20879                 error "expected user.job=\"touch.0\", got '$val'"
20880
20881         mkdir $subdir
20882         val=$(getfattr -n user.job $subdir | grep user.job)
20883         [[ $val = user.job=\"mkdir.0\" ]] ||
20884                 error "expected user.job=\"mkdir.0\", got '$val'"
20885
20886         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE ||
20887                 error "failed to set job_xattr parameter to NONE"
20888
20889         touch $f2
20890         val=$(getfattr -d $f2)
20891         [[ -z $val ]] ||
20892                 error "expected no user xattr, got '$val'"
20893
20894         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=trusted.job ||
20895                 error "failed to set job_xattr parameter to trusted.job"
20896
20897         touch $f3
20898         val=$(getfattr -n trusted.job $f3 | grep trusted.job)
20899         [[ $val = trusted.job=\"touch.0\" ]] ||
20900                 error "expected trusted.job=\"touch.0\", got '$val'"
20901 }
20902 run_test 205h "check jobid xattr is stored correctly"
20903
20904 test_205i() {
20905         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
20906                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
20907
20908         local mdts=$(comma_list $(mdts_nodes))
20909         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20910
20911         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20912
20913         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.1234567 ||
20914                 error "failed to set mdt.*.job_xattr to user.1234567"
20915
20916         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.12345678 &&
20917                 error "failed to reject too long job_xattr name"
20918
20919         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=userjob &&
20920                 error "failed to reject job_xattr name in bad format"
20921
20922         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job/ &&
20923                 error "failed to reject job_xattr name with invalid character"
20924
20925         do_nodes $mdts "printf 'mdt.*.job_xattr=user.job\x80' |
20926                         xargs $LCTL set_param" &&
20927                 error "failed to reject job_xattr name with non-ascii character"
20928
20929         return 0
20930 }
20931 run_test 205i "check job_xattr parameter accepts and rejects values correctly"
20932
20933 # LU-1480, LU-1773 and LU-1657
20934 test_206() {
20935         mkdir -p $DIR/$tdir
20936         $LFS setstripe -c -1 $DIR/$tdir
20937 #define OBD_FAIL_LOV_INIT 0x1403
20938         $LCTL set_param fail_loc=0xa0001403
20939         $LCTL set_param fail_val=1
20940         touch $DIR/$tdir/$tfile || true
20941 }
20942 run_test 206 "fail lov_init_raid0() doesn't lbug"
20943
20944 test_207a() {
20945         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20946         local fsz=`stat -c %s $DIR/$tfile`
20947         cancel_lru_locks mdc
20948
20949         # do not return layout in getattr intent
20950 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
20951         $LCTL set_param fail_loc=0x170
20952         local sz=`stat -c %s $DIR/$tfile`
20953
20954         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
20955
20956         rm -rf $DIR/$tfile
20957 }
20958 run_test 207a "can refresh layout at glimpse"
20959
20960 test_207b() {
20961         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20962         local cksum=`md5sum $DIR/$tfile`
20963         local fsz=`stat -c %s $DIR/$tfile`
20964         cancel_lru_locks mdc
20965         cancel_lru_locks osc
20966
20967         # do not return layout in getattr intent
20968 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
20969         $LCTL set_param fail_loc=0x171
20970
20971         # it will refresh layout after the file is opened but before read issues
20972         echo checksum is "$cksum"
20973         echo "$cksum" |md5sum -c --quiet || error "file differs"
20974
20975         rm -rf $DIR/$tfile
20976 }
20977 run_test 207b "can refresh layout at open"
20978
20979 test_208() {
20980         # FIXME: in this test suite, only RD lease is used. This is okay
20981         # for now as only exclusive open is supported. After generic lease
20982         # is done, this test suite should be revised. - Jinshan
20983
20984         remote_mds_nodsh && skip "remote MDS with nodsh"
20985         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
20986                 skip "Need MDS version at least 2.4.52"
20987
20988         echo "==== test 1: verify get lease work"
20989         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
20990
20991         echo "==== test 2: verify lease can be broken by upcoming open"
20992         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20993         local PID=$!
20994         sleep 2
20995
20996         $MULTIOP $DIR/$tfile oO_RDWR:c
20997         kill -USR1 $PID && wait $PID || error "break lease error"
20998
20999         echo "==== test 3: verify lease can't be granted if an open already exists"
21000         $MULTIOP $DIR/$tfile oO_RDWR:_c &
21001         local PID=$!
21002         sleep 2
21003
21004         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
21005         kill -USR1 $PID && wait $PID || error "open file error"
21006
21007         echo "==== test 4: lease can sustain over recovery"
21008         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
21009         PID=$!
21010         sleep 2
21011
21012         fail mds1
21013
21014         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
21015
21016         echo "==== test 5: lease broken can't be regained by replay"
21017         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
21018         PID=$!
21019         sleep 2
21020
21021         # open file to break lease and then recovery
21022         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
21023         fail mds1
21024
21025         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
21026
21027         rm -f $DIR/$tfile
21028 }
21029 run_test 208 "Exclusive open"
21030
21031 test_209() {
21032         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
21033                 skip_env "must have disp_stripe"
21034
21035         touch $DIR/$tfile
21036         sync; sleep 5; sync;
21037
21038         echo 3 > /proc/sys/vm/drop_caches
21039         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
21040                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
21041         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
21042
21043         # open/close 500 times
21044         for i in $(seq 500); do
21045                 cat $DIR/$tfile
21046         done
21047
21048         echo 3 > /proc/sys/vm/drop_caches
21049         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
21050                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
21051         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
21052
21053         echo "before: $req_before, after: $req_after"
21054         [ $((req_after - req_before)) -ge 300 ] &&
21055                 error "open/close requests are not freed"
21056         return 0
21057 }
21058 run_test 209 "read-only open/close requests should be freed promptly"
21059
21060 test_210() {
21061         local pid
21062
21063         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
21064         pid=$!
21065         sleep 1
21066
21067         $LFS getstripe $DIR/$tfile
21068         kill -USR1 $pid
21069         wait $pid || error "multiop failed"
21070
21071         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
21072         pid=$!
21073         sleep 1
21074
21075         $LFS getstripe $DIR/$tfile
21076         kill -USR1 $pid
21077         wait $pid || error "multiop failed"
21078 }
21079 run_test 210 "lfs getstripe does not break leases"
21080
21081 function test_211() {
21082         local PID
21083         local id
21084         local rc
21085
21086         stack_trap "rm -f $DIR/$tfile" EXIT
21087         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=10 oflag=direct ||
21088                 error "can't create file"
21089         $LFS mirror extend -N $DIR/$tfile ||
21090                 error "can't create a replica"
21091         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
21092         $LFS getstripe $DIR/$tfile
21093         stale=$($LFS getstripe $DIR/$tfile | grep stale | wc -l)
21094         (( $stale != 1 )) && error "expected 1 stale, found $stale"
21095
21096         $MULTIOP $DIR/$tfile OeW_E+eUc &
21097         PID=$!
21098         sleep 0.3
21099
21100         id=$($LFS getstripe $DIR/$tfile |
21101                 awk '/lcme_mirror_id:/{id=$2}/lcme_flags.*init$/{print id}')
21102         $LFS mirror split -d --mirror-id $id $DIR/$tfile &&
21103                 error "removed last in-sync replica?"
21104
21105         kill -USR1 $PID
21106         wait $PID
21107         (( $? == 0 )) || error "failed split broke the lease"
21108 }
21109 run_test 211 "failed mirror split doesn't break write lease"
21110
21111 test_212() {
21112         size=`date +%s`
21113         size=$((size % 8192 + 1))
21114         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
21115         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
21116         rm -f $DIR/f212 $DIR/f212.xyz
21117 }
21118 run_test 212 "Sendfile test ============================================"
21119
21120 test_213() {
21121         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
21122         cancel_lru_locks osc
21123         lctl set_param fail_loc=0x8000040f
21124         # generate a read lock
21125         cat $DIR/$tfile > /dev/null
21126         # write to the file, it will try to cancel the above read lock.
21127         cat /etc/hosts >> $DIR/$tfile
21128 }
21129 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
21130
21131 test_214() { # for bug 20133
21132         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
21133         for (( i=0; i < 340; i++ )) ; do
21134                 touch $DIR/$tdir/d214c/a$i
21135         done
21136
21137         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
21138         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
21139         ls $DIR/d214c || error "ls $DIR/d214c failed"
21140         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
21141         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
21142 }
21143 run_test 214 "hash-indexed directory test - bug 20133"
21144
21145 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
21146 create_lnet_proc_files() {
21147         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
21148 }
21149
21150 # counterpart of create_lnet_proc_files
21151 remove_lnet_proc_files() {
21152         rm -f $TMP/lnet_$1.sys
21153 }
21154
21155 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
21156 # 3rd arg as regexp for body
21157 check_lnet_proc_stats() {
21158         local l=$(cat "$TMP/lnet_$1" |wc -l)
21159         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
21160
21161         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
21162 }
21163
21164 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
21165 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
21166 # optional and can be regexp for 2nd line (lnet.routes case)
21167 check_lnet_proc_entry() {
21168         local blp=2          # blp stands for 'position of 1st line of body'
21169         [ -z "$5" ] || blp=3 # lnet.routes case
21170
21171         local l=$(cat "$TMP/lnet_$1" |wc -l)
21172         # subtracting one from $blp because the body can be empty
21173         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
21174
21175         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
21176                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
21177
21178         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
21179                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
21180
21181         # bail out if any unexpected line happened
21182         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
21183         [ "$?" != 0 ] || error "$2 misformatted"
21184 }
21185
21186 test_215() { # for bugs 18102, 21079, 21517
21187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21188
21189         local N='(0|[1-9][0-9]*)'       # non-negative numeric
21190         local P='[1-9][0-9]*'           # positive numeric
21191         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
21192         local NET='[a-z][a-z0-9]*'      # LNet net like o2ib2
21193         local ADDR='[0-9.]+'            # LNet addr like 10.0.0.1
21194         local ADDR6='([0-9a-f]{0,4}:){2,7}[0-9a-f]{0,4}' # IPv6 LNet addr
21195         local NID="$ADDR@$NET"          # LNet nid like 10.0.0.1@o2ib2
21196         local NID6="$ADDR6@$NET"        # LNet nid like 2601:8c1:c180::cbdd@tcp
21197
21198         local L1 # regexp for 1st line
21199         local L2 # regexp for 2nd line (optional)
21200         local BR # regexp for the rest (body)
21201
21202         # lnet.stats should look as 11 space-separated non-negative numerics
21203         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
21204         create_lnet_proc_files "stats"
21205         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
21206         remove_lnet_proc_files "stats"
21207
21208         # lnet.routes should look like this:
21209         # Routing disabled/enabled
21210         # net hops priority state router
21211         # where net is a string like tcp0, hops > 0, priority >= 0,
21212         # state is up/down,
21213         # router is a string like 192.168.1.1@tcp2
21214         L1="^Routing (disabled|enabled)$"
21215         L2="^net +hops +priority +state +router$"
21216         BR="^$NET +$N +(0|1) +(up|down) +($NID|$NID6)$"
21217         create_lnet_proc_files "routes"
21218         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
21219         remove_lnet_proc_files "routes"
21220
21221         # lnet.routers should look like this:
21222         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
21223         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
21224         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
21225         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
21226         L1="^ref +rtr_ref +alive +router$"
21227         BR="^$P +$P +(up|down) +($NID|$NID6)$"
21228         create_lnet_proc_files "routers"
21229         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
21230         remove_lnet_proc_files "routers"
21231
21232         # lnet.peers should look like this:
21233         # nid refs state last max rtr min tx min queue
21234         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
21235         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
21236         # numeric (0 or >0 or <0), queue >= 0.
21237         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
21238         BR="^($NID|$NID6) +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
21239         create_lnet_proc_files "peers"
21240         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
21241         remove_lnet_proc_files "peers"
21242
21243         # lnet.buffers  should look like this:
21244         # pages count credits min
21245         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
21246         L1="^pages +count +credits +min$"
21247         BR="^ +$N +$N +$I +$I$"
21248         create_lnet_proc_files "buffers"
21249         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
21250         remove_lnet_proc_files "buffers"
21251
21252         # lnet.nis should look like this:
21253         # nid status alive refs peer rtr max tx min
21254         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
21255         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
21256         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
21257         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
21258         BR="^($NID|$NID6) +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
21259         create_lnet_proc_files "nis"
21260         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
21261         remove_lnet_proc_files "nis"
21262
21263         # can we successfully write to lnet.stats?
21264         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
21265 }
21266 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
21267
21268 test_216() { # bug 20317
21269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21270         remote_ost_nodsh && skip "remote OST with nodsh"
21271
21272         local node
21273         local facets=$(get_facets OST)
21274         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
21275
21276         save_lustre_params client "osc.*.contention_seconds" > $p
21277         save_lustre_params $facets \
21278                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
21279         save_lustre_params $facets \
21280                 "ldlm.namespaces.filter-*.contended_locks" >> $p
21281         save_lustre_params $facets \
21282                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
21283         clear_stats osc.*.osc_stats
21284
21285         # agressive lockless i/o settings
21286         do_nodes $(comma_list $(osts_nodes)) \
21287                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
21288                         ldlm.namespaces.filter-*.contended_locks=0 \
21289                         ldlm.namespaces.filter-*.contention_seconds=60"
21290         lctl set_param -n osc.*.contention_seconds=60
21291
21292         $DIRECTIO write $DIR/$tfile 0 10 4096
21293         $CHECKSTAT -s 40960 $DIR/$tfile
21294
21295         # disable lockless i/o
21296         do_nodes $(comma_list $(osts_nodes)) \
21297                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
21298                         ldlm.namespaces.filter-*.contended_locks=32 \
21299                         ldlm.namespaces.filter-*.contention_seconds=0"
21300         lctl set_param -n osc.*.contention_seconds=0
21301         clear_stats osc.*.osc_stats
21302
21303         dd if=/dev/zero of=$DIR/$tfile count=0
21304         $CHECKSTAT -s 0 $DIR/$tfile
21305
21306         restore_lustre_params <$p
21307         rm -f $p
21308         rm $DIR/$tfile
21309 }
21310 run_test 216 "check lockless direct write updates file size and kms correctly"
21311
21312 test_217() { # bug 22430
21313         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21314
21315         local node
21316
21317         for node in $(nodes_list); do
21318                 local nid=$(host_nids_address $node $NETTYPE)
21319                 local node_ip=$(do_node $node getent ahostsv4 $node |
21320                                 awk '{ print $1; exit; }')
21321
21322                 echo "node: '$node', nid: '$nid', node_ip='$node_ip'"
21323                 # if hostname matches any NID, use hostname for better testing
21324                 if [[ -z "$nid" || "$nid" =~ "$node_ip" ]]; then
21325                         echo "lctl ping node $node@$NETTYPE"
21326                         lctl ping $node@$NETTYPE ||
21327                                 error "ping $node@$NETTYPE failed rc=$?"
21328                 else # otherwise, at least test 'lctl ping' is working
21329                         echo "lctl ping nid $(h2nettype $nid)"
21330                         lctl ping $(h2nettype $nid) ||
21331                                 error "ping $(h2nettype $nid) failed rc=$?"
21332                         echo "skipping $node (no hyphen detected)"
21333                 fi
21334         done
21335
21336         return 0
21337 }
21338 run_test 217 "check lctl ping for hostnames with embedded hyphen ('-')"
21339
21340 test_218() {
21341         # do directio so as not to populate the page cache
21342         log "creating a 10 Mb file"
21343         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
21344                 error "multiop failed while creating a file"
21345         log "starting reads"
21346         dd if=$DIR/$tfile of=/dev/null bs=4096 &
21347         log "truncating the file"
21348         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
21349                 error "multiop failed while truncating the file"
21350         log "killing dd"
21351         kill %+ || true # reads might have finished
21352         echo "wait until dd is finished"
21353         wait
21354         log "removing the temporary file"
21355         rm -rf $DIR/$tfile || error "tmp file removal failed"
21356 }
21357 run_test 218 "parallel read and truncate should not deadlock"
21358
21359 test_219() {
21360         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21361
21362         # write one partial page
21363         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
21364         # set no grant so vvp_io_commit_write will do sync write
21365         $LCTL set_param fail_loc=0x411
21366         # write a full page at the end of file
21367         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
21368
21369         $LCTL set_param fail_loc=0
21370         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
21371         $LCTL set_param fail_loc=0x411
21372         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
21373
21374         # LU-4201
21375         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
21376         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
21377 }
21378 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
21379
21380 test_220() { #LU-325
21381         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21382         remote_ost_nodsh && skip "remote OST with nodsh"
21383         remote_mds_nodsh && skip "remote MDS with nodsh"
21384         remote_mgs_nodsh && skip "remote MGS with nodsh"
21385
21386         local OSTIDX=0
21387
21388         # create on MDT0000 so the last_id and next_id are correct
21389         mkdir_on_mdt0 $DIR/$tdir
21390         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
21391         OST=${OST%_UUID}
21392
21393         # on the mdt's osc
21394         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
21395         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
21396                         osp.$mdtosc_proc1.prealloc_last_id)
21397         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
21398                         osp.$mdtosc_proc1.prealloc_next_id)
21399
21400         $LFS df -i
21401
21402         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
21403         #define OBD_FAIL_OST_ENOINO              0x229
21404         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
21405         create_pool $FSNAME.$TESTNAME || return 1
21406         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
21407
21408         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
21409
21410         MDSOBJS=$((last_id - next_id))
21411         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
21412
21413         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
21414         echo "OST still has $count kbytes free"
21415
21416         echo "create $MDSOBJS files @next_id..."
21417         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
21418
21419         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
21420                         osp.$mdtosc_proc1.prealloc_last_id)
21421         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
21422                         osp.$mdtosc_proc1.prealloc_next_id)
21423
21424         echo "after creation, last_id=$last_id2, next_id=$next_id2"
21425         $LFS df -i
21426
21427         echo "cleanup..."
21428
21429         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
21430         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
21431
21432         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
21433                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
21434         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
21435                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
21436         echo "unlink $MDSOBJS files @$next_id..."
21437         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
21438 }
21439 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
21440
21441 test_221() {
21442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21443
21444         dd if=`which date` of=$MOUNT/date oflag=sync
21445         chmod +x $MOUNT/date
21446
21447         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
21448         $LCTL set_param fail_loc=0x80001401
21449
21450         $MOUNT/date > /dev/null
21451         rm -f $MOUNT/date
21452 }
21453 run_test 221 "make sure fault and truncate race to not cause OOM"
21454
21455 test_222a () {
21456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21457
21458         rm -rf $DIR/$tdir
21459         test_mkdir $DIR/$tdir
21460         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21461         createmany -o $DIR/$tdir/$tfile 10
21462         cancel_lru_locks mdc
21463         cancel_lru_locks osc
21464         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21465         $LCTL set_param fail_loc=0x31a
21466         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
21467         $LCTL set_param fail_loc=0
21468         rm -r $DIR/$tdir
21469 }
21470 run_test 222a "AGL for ls should not trigger CLIO lock failure"
21471
21472 test_222b () {
21473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21474
21475         rm -rf $DIR/$tdir
21476         test_mkdir $DIR/$tdir
21477         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21478         createmany -o $DIR/$tdir/$tfile 10
21479         cancel_lru_locks mdc
21480         cancel_lru_locks osc
21481         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21482         $LCTL set_param fail_loc=0x31a
21483         rm -r $DIR/$tdir || error "AGL for rmdir failed"
21484         $LCTL set_param fail_loc=0
21485 }
21486 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
21487
21488 test_223 () {
21489         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21490
21491         rm -rf $DIR/$tdir
21492         test_mkdir $DIR/$tdir
21493         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21494         createmany -o $DIR/$tdir/$tfile 10
21495         cancel_lru_locks mdc
21496         cancel_lru_locks osc
21497         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
21498         $LCTL set_param fail_loc=0x31b
21499         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
21500         $LCTL set_param fail_loc=0
21501         rm -r $DIR/$tdir
21502 }
21503 run_test 223 "osc reenqueue if without AGL lock granted ======================="
21504
21505 test_224a() { # LU-1039, MRP-303
21506         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21507         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
21508         $LCTL set_param fail_loc=0x508
21509         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
21510         $LCTL set_param fail_loc=0
21511         df $DIR
21512 }
21513 run_test 224a "Don't panic on bulk IO failure"
21514
21515 test_224bd_sub() { # LU-1039, MRP-303
21516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21517         local timeout=$1
21518
21519         shift
21520         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
21521
21522         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21523
21524         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
21525         cancel_lru_locks osc
21526         set_checksums 0
21527         stack_trap "set_checksums $ORIG_CSUM" EXIT
21528         local at_max_saved=0
21529
21530         # adaptive timeouts may prevent seeing the issue
21531         if at_is_enabled; then
21532                 at_max_saved=$(at_max_get mds)
21533                 at_max_set 0 mds client
21534                 stack_trap "at_max_set $at_max_saved mds client" EXIT
21535         fi
21536
21537         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
21538         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
21539         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
21540
21541         do_facet ost1 $LCTL set_param fail_loc=0
21542         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
21543         df $DIR
21544 }
21545
21546 test_224b() {
21547         test_224bd_sub 3 error "dd failed"
21548 }
21549 run_test 224b "Don't panic on bulk IO failure"
21550
21551 test_224c() { # LU-6441
21552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21553         remote_mds_nodsh && skip "remote MDS with nodsh"
21554
21555         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
21556         save_writethrough $p
21557         set_cache writethrough on
21558
21559         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
21560         local at_max=$($LCTL get_param -n at_max)
21561         local timeout=$($LCTL get_param -n timeout)
21562         local test_at="at_max"
21563         local param_at="$FSNAME.sys.at_max"
21564         local test_timeout="timeout"
21565         local param_timeout="$FSNAME.sys.timeout"
21566
21567         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
21568
21569         set_persistent_param_and_check client "$test_at" "$param_at" 0
21570         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
21571
21572         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
21573         do_facet ost1 "$LCTL set_param fail_loc=0x520"
21574         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21575         stack_trap "rm -f $DIR/$tfile"
21576         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
21577         sync
21578         do_facet ost1 "$LCTL set_param fail_loc=0"
21579
21580         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
21581         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
21582                 $timeout
21583
21584         $LCTL set_param -n $pages_per_rpc
21585         restore_lustre_params < $p
21586         rm -f $p
21587 }
21588 run_test 224c "Don't hang if one of md lost during large bulk RPC"
21589
21590 test_224d() { # LU-11169
21591         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
21592 }
21593 run_test 224d "Don't corrupt data on bulk IO timeout"
21594
21595 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
21596 test_225a () {
21597         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21598         if [ -z ${MDSSURVEY} ]; then
21599                 skip_env "mds-survey not found"
21600         fi
21601         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21602                 skip "Need MDS version at least 2.2.51"
21603
21604         local mds=$(facet_host $SINGLEMDS)
21605         local target=$(do_nodes $mds 'lctl dl' |
21606                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21607
21608         local cmd1="file_count=1000 thrhi=4"
21609         local cmd2="dir_count=2 layer=mdd stripe_count=0"
21610         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21611         local cmd="$cmd1 $cmd2 $cmd3"
21612
21613         rm -f ${TMP}/mds_survey*
21614         echo + $cmd
21615         eval $cmd || error "mds-survey with zero-stripe failed"
21616         cat ${TMP}/mds_survey*
21617         rm -f ${TMP}/mds_survey*
21618 }
21619 run_test 225a "Metadata survey sanity with zero-stripe"
21620
21621 test_225b () {
21622         if [ -z ${MDSSURVEY} ]; then
21623                 skip_env "mds-survey not found"
21624         fi
21625         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21626                 skip "Need MDS version at least 2.2.51"
21627         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21628         remote_mds_nodsh && skip "remote MDS with nodsh"
21629         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
21630                 skip_env "Need to mount OST to test"
21631         fi
21632
21633         local mds=$(facet_host $SINGLEMDS)
21634         local target=$(do_nodes $mds 'lctl dl' |
21635                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21636
21637         local cmd1="file_count=1000 thrhi=4"
21638         local cmd2="dir_count=2 layer=mdd stripe_count=1"
21639         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21640         local cmd="$cmd1 $cmd2 $cmd3"
21641
21642         rm -f ${TMP}/mds_survey*
21643         echo + $cmd
21644         eval $cmd || error "mds-survey with stripe_count failed"
21645         cat ${TMP}/mds_survey*
21646         rm -f ${TMP}/mds_survey*
21647 }
21648 run_test 225b "Metadata survey sanity with stripe_count = 1"
21649
21650 mcreate_path2fid () {
21651         local mode=$1
21652         local major=$2
21653         local minor=$3
21654         local name=$4
21655         local desc=$5
21656         local path=$DIR/$tdir/$name
21657         local fid
21658         local rc
21659         local fid_path
21660
21661         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
21662                 error "cannot create $desc"
21663
21664         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
21665         rc=$?
21666         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
21667
21668         fid_path=$($LFS fid2path $MOUNT $fid)
21669         rc=$?
21670         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
21671
21672         [ "$path" == "$fid_path" ] ||
21673                 error "fid2path returned $fid_path, expected $path"
21674
21675         echo "pass with $path and $fid"
21676 }
21677
21678 test_226a () {
21679         rm -rf $DIR/$tdir
21680         mkdir -p $DIR/$tdir
21681
21682         mcreate_path2fid 0010666 0 0 fifo "FIFO"
21683         mcreate_path2fid 0020666 1 3 null "character special file (null)"
21684         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
21685         mcreate_path2fid 0040666 0 0 dir "directory"
21686         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
21687         mcreate_path2fid 0100666 0 0 file "regular file"
21688         mcreate_path2fid 0120666 0 0 link "symbolic link"
21689         mcreate_path2fid 0140666 0 0 sock "socket"
21690 }
21691 run_test 226a "call path2fid and fid2path on files of all type"
21692
21693 test_226b () {
21694         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21695
21696         local MDTIDX=1
21697
21698         rm -rf $DIR/$tdir
21699         mkdir -p $DIR/$tdir
21700         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
21701                 error "create remote directory failed"
21702         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
21703         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
21704                                 "character special file (null)"
21705         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
21706                                 "character special file (no device)"
21707         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
21708         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
21709                                 "block special file (loop)"
21710         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
21711         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
21712         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
21713 }
21714 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
21715
21716 test_226c () {
21717         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21718         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
21719                 skip "Need MDS version at least 2.13.55"
21720
21721         local submnt=/mnt/submnt
21722         local srcfile=/etc/passwd
21723         local dstfile=$submnt/passwd
21724         local path
21725         local fid
21726
21727         rm -rf $DIR/$tdir
21728         rm -rf $submnt
21729         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
21730                 error "create remote directory failed"
21731         mkdir -p $submnt || error "create $submnt failed"
21732         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
21733                 error "mount $submnt failed"
21734         stack_trap "umount $submnt" EXIT
21735
21736         cp $srcfile $dstfile
21737         fid=$($LFS path2fid $dstfile)
21738         path=$($LFS fid2path $submnt "$fid")
21739         [ "$path" = "$dstfile" ] ||
21740                 error "fid2path $submnt $fid failed ($path != $dstfile)"
21741 }
21742 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
21743
21744 test_226d () {
21745         (( $CLIENT_VERSION >= $(version_code 2.15.57) )) ||
21746                 skip "Need client at least version 2.15.57"
21747
21748         # Define First test dataset
21749         local testdirs_01=$DIR/$tdir
21750         local testdata_01=$testdirs_01/${tdir}_01
21751         local testresult_01=${tdir}_01
21752         # Define Second test dataset
21753         local testdirs_02=$DIR/$tdir/$tdir
21754         local testdata_02=$testdirs_02/${tdir}_02
21755         local testresult_02=${tdir}_02
21756         # Define third test dataset (top level)
21757         local testdata_03=$DIR/${tdir}_03
21758         local testresult_03=${tdir}_03
21759
21760         # Create first test dataset
21761         mkdir -p $testdirs_01 || error "cannot create dir $testdirs_01"
21762         touch $testdata_01 || error "cannot create file $testdata_01"
21763
21764         # Create second test dataset
21765         mkdir -p $testdirs_02 || error "cannot create dir $testdirs_02"
21766         touch $testdata_02 || error "cannot create file $testdata_02"
21767
21768         # Create third test dataset
21769         touch $testdata_03 || error "cannot create file $testdata_03"
21770
21771         local fid01=$($LFS getstripe -F "$testdata_01") ||
21772                 error "getstripe failed on $testdata_01"
21773         local fid02=$($LFS getstripe -F "$testdata_02") ||
21774                 error "getstripe failed on $testdata_01"
21775         local fid03=$($LFS getstripe -F "$testdata_03") ||
21776                 error "getstripe failed on $testdata_03"
21777
21778         # Verify only -n option
21779         local out1=$($LFS fid2path -n $DIR $fid01) ||
21780                 error "fid2path failed on $fid01"
21781         local out2=$($LFS fid2path -n $DIR $fid02) ||
21782                 error "fid2path failed on $fid02"
21783         local out3=$($LFS fid2path -n $DIR $fid03) ||
21784                 error "fid2path failed on $fid03"
21785
21786         [[ "$out1" == "$testresult_01" ]] ||
21787                 error "fid2path failed: Expected $testresult_01 got $out1"
21788         [[ "$out2" == "$testresult_02" ]] ||
21789                 error "fid2path failed: Expected $testresult_02 got $out2"
21790         [[ "$out3" == "$testresult_03" ]] ||
21791                 error "fid2path failed: Expected $testresult_03 got $out3"
21792
21793         # Verify with option -fn together
21794         out1=$($LFS fid2path -fn $DIR $fid01) ||
21795                 error "fid2path -fn failed on $fid01"
21796         out2=$($LFS fid2path -fn $DIR $fid02) ||
21797                 error "fid2path -fn failed on $fid02"
21798         out3=$($LFS fid2path -fn $DIR $fid03) ||
21799                 error "fid2path -fn failed on $fid03"
21800
21801         local tmpout=$(echo $out1 | cut -d" " -f2)
21802         [[ "$tmpout" == "$testresult_01" ]] ||
21803                 error "fid2path -fn failed: Expected $testresult_01 got $out1"
21804
21805         tmpout=$(echo $out2 | cut -d" " -f2)
21806         [[ "$tmpout" == "$testresult_02" ]] ||
21807                 error "fid2path -fn failed: Expected $testresult_02 got $out2"
21808
21809         tmpout=$(echo $out3 | cut -d" " -f2)
21810         [[ "$tmpout" == "$testresult_03" ]] ||
21811                 error "fid2path -fn failed: Expected $testresult_03 got $out3"
21812 }
21813 run_test 226d "verify fid2path with -n and -fn option"
21814
21815 test_226e () {
21816         (( $CLIENT_VERSION >= $(version_code 2.15.56) )) ||
21817                 skip "Need client at least version 2.15.56"
21818
21819         # Define filename with 'newline' and a space
21820         local testfile="Test"$'\n'"file 01"
21821         # Define link name with multiple 'newline' and a space
21822         local linkfile="Link"$'\n'"file "$'\n'"01"
21823         # Remove prior hard link
21824         rm -f $DIR/"$linkfile"
21825
21826         # Create file
21827         touch $DIR/"$testfile"
21828         # Create link
21829         ln $DIR/"$testfile" $DIR/"$linkfile"
21830
21831         local fid=$($LFS getstripe -F "$DIR/$testfile") ||
21832                 error "getstripe failed on $DIR/$testfile"
21833
21834         # Call with -0 option
21835         local out1=$($LFS fid2path -0 $DIR $fid | xargs --null -n1 \
21836                 echo "FILE:" | grep -c "FILE:")
21837
21838         # With -0 option the output should be exactly 2 lines.
21839         (( $out1 == 2 )) || error "fid2path -0 failed on $fid, $out1"
21840 }
21841 run_test 226e "Verify path2fid -0 option with newline and space"
21842
21843 # LU-1299 Executing or running ldd on a truncated executable does not
21844 # cause an out-of-memory condition.
21845 test_227() {
21846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21847         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
21848
21849         dd if=$(which date) of=$MOUNT/date bs=1k count=1
21850         chmod +x $MOUNT/date
21851
21852         $MOUNT/date > /dev/null
21853         ldd $MOUNT/date > /dev/null
21854         rm -f $MOUNT/date
21855 }
21856 run_test 227 "running truncated executable does not cause OOM"
21857
21858 # LU-1512 try to reuse idle OI blocks
21859 test_228a() {
21860         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21861         remote_mds_nodsh && skip "remote MDS with nodsh"
21862         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21863
21864         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21865         local myDIR=$DIR/$tdir
21866
21867         mkdir -p $myDIR
21868         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21869         $LCTL set_param fail_loc=0x80001002
21870         createmany -o $myDIR/t- 10000
21871         $LCTL set_param fail_loc=0
21872         # The guard is current the largest FID holder
21873         touch $myDIR/guard
21874         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21875                     tr -d '[')
21876         local IDX=$(($SEQ % 64))
21877
21878         do_facet $SINGLEMDS sync
21879         # Make sure journal flushed.
21880         sleep 6
21881         local blk1=$(do_facet $SINGLEMDS \
21882                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21883                      grep Blockcount | awk '{print $4}')
21884
21885         # Remove old files, some OI blocks will become idle.
21886         unlinkmany $myDIR/t- 10000
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 228a "try to reuse idle OI blocks"
21899
21900 test_228b() {
21901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21902         remote_mds_nodsh && skip "remote MDS with nodsh"
21903         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21904
21905         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21906         local myDIR=$DIR/$tdir
21907
21908         mkdir -p $myDIR
21909         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21910         $LCTL set_param fail_loc=0x80001002
21911         createmany -o $myDIR/t- 10000
21912         $LCTL set_param fail_loc=0
21913         # The guard is current the largest FID holder
21914         touch $myDIR/guard
21915         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21916                     tr -d '[')
21917         local IDX=$(($SEQ % 64))
21918
21919         do_facet $SINGLEMDS sync
21920         # Make sure journal flushed.
21921         sleep 6
21922         local blk1=$(do_facet $SINGLEMDS \
21923                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21924                      grep Blockcount | awk '{print $4}')
21925
21926         # Remove old files, some OI blocks will become idle.
21927         unlinkmany $myDIR/t- 10000
21928
21929         # stop the MDT
21930         stop $SINGLEMDS || error "Fail to stop MDT."
21931         # remount the MDT
21932         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
21933                 error "Fail to start MDT."
21934
21935         client_up || error "Fail to df."
21936         # Create new files, idle OI blocks should be reused.
21937         createmany -o $myDIR/t- 2000
21938         do_facet $SINGLEMDS sync
21939         # Make sure journal flushed.
21940         sleep 6
21941         local blk2=$(do_facet $SINGLEMDS \
21942                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21943                      grep Blockcount | awk '{print $4}')
21944
21945         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21946 }
21947 run_test 228b "idle OI blocks can be reused after MDT restart"
21948
21949 #LU-1881
21950 test_228c() {
21951         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21952         remote_mds_nodsh && skip "remote MDS with nodsh"
21953         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21954
21955         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21956         local myDIR=$DIR/$tdir
21957
21958         mkdir -p $myDIR
21959         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21960         $LCTL set_param fail_loc=0x80001002
21961         # 20000 files can guarantee there are index nodes in the OI file
21962         createmany -o $myDIR/t- 20000
21963         $LCTL set_param fail_loc=0
21964         # The guard is current the largest FID holder
21965         touch $myDIR/guard
21966         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21967                     tr -d '[')
21968         local IDX=$(($SEQ % 64))
21969
21970         do_facet $SINGLEMDS sync
21971         # Make sure journal flushed.
21972         sleep 6
21973         local blk1=$(do_facet $SINGLEMDS \
21974                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21975                      grep Blockcount | awk '{print $4}')
21976
21977         # Remove old files, some OI blocks will become idle.
21978         unlinkmany $myDIR/t- 20000
21979         rm -f $myDIR/guard
21980         # The OI file should become empty now
21981
21982         # Create new files, idle OI blocks should be reused.
21983         createmany -o $myDIR/t- 2000
21984         do_facet $SINGLEMDS sync
21985         # Make sure journal flushed.
21986         sleep 6
21987         local blk2=$(do_facet $SINGLEMDS \
21988                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21989                      grep Blockcount | awk '{print $4}')
21990
21991         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21992 }
21993 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
21994
21995 test_229() { # LU-2482, LU-3448
21996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21997         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
21998         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
21999                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
22000
22001         rm -f $DIR/$tfile
22002
22003         # Create a file with a released layout and stripe count 2.
22004         $MULTIOP $DIR/$tfile H2c ||
22005                 error "failed to create file with released layout"
22006
22007         $LFS getstripe -v $DIR/$tfile
22008
22009         local pattern=$($LFS getstripe -L $DIR/$tfile)
22010         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
22011
22012         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
22013                 error "getstripe"
22014         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
22015         stat $DIR/$tfile || error "failed to stat released file"
22016
22017         chown $RUNAS_ID $DIR/$tfile ||
22018                 error "chown $RUNAS_ID $DIR/$tfile failed"
22019
22020         chgrp $RUNAS_ID $DIR/$tfile ||
22021                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
22022
22023         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
22024         rm $DIR/$tfile || error "failed to remove released file"
22025 }
22026 run_test 229 "getstripe/stat/rm/attr changes work on released files"
22027
22028 test_230a() {
22029         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22030         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22031         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22032                 skip "Need MDS version at least 2.11.52"
22033
22034         local MDTIDX=1
22035
22036         test_mkdir $DIR/$tdir
22037         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
22038         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
22039         [ $mdt_idx -ne 0 ] &&
22040                 error "create local directory on wrong MDT $mdt_idx"
22041
22042         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
22043                         error "create remote directory failed"
22044         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
22045         [ $mdt_idx -ne $MDTIDX ] &&
22046                 error "create remote directory on wrong MDT $mdt_idx"
22047
22048         createmany -o $DIR/$tdir/test_230/t- 10 ||
22049                 error "create files on remote directory failed"
22050         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
22051         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
22052         rm -r $DIR/$tdir || error "unlink remote directory failed"
22053 }
22054 run_test 230a "Create remote directory and files under the remote directory"
22055
22056 test_230b() {
22057         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22058         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22059         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22060                 skip "Need MDS version at least 2.11.52"
22061
22062         local MDTIDX=1
22063         local mdt_index
22064         local i
22065         local file
22066         local pid
22067         local stripe_count
22068         local migrate_dir=$DIR/$tdir/migrate_dir
22069         local other_dir=$DIR/$tdir/other_dir
22070
22071         test_mkdir $DIR/$tdir
22072         test_mkdir -i0 -c1 $migrate_dir
22073         test_mkdir -i0 -c1 $other_dir
22074         for ((i=0; i<10; i++)); do
22075                 mkdir -p $migrate_dir/dir_${i}
22076                 createmany -o $migrate_dir/dir_${i}/f 10 ||
22077                         error "create files under remote dir failed $i"
22078         done
22079
22080         cp /etc/passwd $migrate_dir/$tfile
22081         cp /etc/passwd $other_dir/$tfile
22082         chattr +SAD $migrate_dir
22083         chattr +SAD $migrate_dir/$tfile
22084
22085         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
22086         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
22087         local old_dir_mode=$(stat -c%f $migrate_dir)
22088         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
22089
22090         mkdir -p $migrate_dir/dir_default_stripe2
22091         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
22092         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
22093
22094         mkdir -p $other_dir
22095         ln $migrate_dir/$tfile $other_dir/luna
22096         ln $migrate_dir/$tfile $migrate_dir/sofia
22097         ln $other_dir/$tfile $migrate_dir/david
22098         ln -s $migrate_dir/$tfile $other_dir/zachary
22099         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
22100         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
22101
22102         local len
22103         local lnktgt
22104
22105         # inline symlink
22106         for len in 58 59 60; do
22107                 lnktgt=$(str_repeat 'l' $len)
22108                 touch $migrate_dir/$lnktgt
22109                 ln -s $lnktgt $migrate_dir/${len}char_ln
22110         done
22111
22112         # PATH_MAX
22113         for len in 4094 4095; do
22114                 lnktgt=$(str_repeat 'l' $len)
22115                 ln -s $lnktgt $migrate_dir/${len}char_ln
22116         done
22117
22118         # NAME_MAX
22119         for len in 254 255; do
22120                 touch $migrate_dir/$(str_repeat 'l' $len)
22121         done
22122
22123         $LFS migrate -m $MDTIDX $migrate_dir ||
22124                 error "fails on migrating remote dir to MDT1"
22125
22126         echo "migratate to MDT1, then checking.."
22127         for ((i = 0; i < 10; i++)); do
22128                 for file in $(find $migrate_dir/dir_${i}); do
22129                         mdt_index=$($LFS getstripe -m $file)
22130                         # broken symlink getstripe will fail
22131                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
22132                                 error "$file is not on MDT${MDTIDX}"
22133                 done
22134         done
22135
22136         # the multiple link file should still in MDT0
22137         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
22138         [ $mdt_index == 0 ] ||
22139                 error "$file is not on MDT${MDTIDX}"
22140
22141         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
22142         [ "$old_dir_flag" = "$new_dir_flag" ] ||
22143                 error " expect $old_dir_flag get $new_dir_flag"
22144
22145         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
22146         [ "$old_file_flag" = "$new_file_flag" ] ||
22147                 error " expect $old_file_flag get $new_file_flag"
22148
22149         local new_dir_mode=$(stat -c%f $migrate_dir)
22150         [ "$old_dir_mode" = "$new_dir_mode" ] ||
22151                 error "expect mode $old_dir_mode get $new_dir_mode"
22152
22153         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
22154         [ "$old_file_mode" = "$new_file_mode" ] ||
22155                 error "expect mode $old_file_mode get $new_file_mode"
22156
22157         diff /etc/passwd $migrate_dir/$tfile ||
22158                 error "$tfile different after migration"
22159
22160         diff /etc/passwd $other_dir/luna ||
22161                 error "luna different after migration"
22162
22163         diff /etc/passwd $migrate_dir/sofia ||
22164                 error "sofia different after migration"
22165
22166         diff /etc/passwd $migrate_dir/david ||
22167                 error "david different after migration"
22168
22169         diff /etc/passwd $other_dir/zachary ||
22170                 error "zachary different after migration"
22171
22172         diff /etc/passwd $migrate_dir/${tfile}_ln ||
22173                 error "${tfile}_ln different after migration"
22174
22175         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
22176                 error "${tfile}_ln_other different after migration"
22177
22178         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
22179         [ $stripe_count = 2 ] ||
22180                 error "dir strpe_count $d != 2 after migration."
22181
22182         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
22183         [ $stripe_count = 2 ] ||
22184                 error "file strpe_count $d != 2 after migration."
22185
22186         #migrate back to MDT0
22187         MDTIDX=0
22188
22189         $LFS migrate -m $MDTIDX $migrate_dir ||
22190                 error "fails on migrating remote dir to MDT0"
22191
22192         echo "migrate back to MDT0, checking.."
22193         for file in $(find $migrate_dir); do
22194                 mdt_index=$($LFS getstripe -m $file)
22195                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
22196                         error "$file is not on MDT${MDTIDX}"
22197         done
22198
22199         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
22200         [ "$old_dir_flag" = "$new_dir_flag" ] ||
22201                 error " expect $old_dir_flag get $new_dir_flag"
22202
22203         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
22204         [ "$old_file_flag" = "$new_file_flag" ] ||
22205                 error " expect $old_file_flag get $new_file_flag"
22206
22207         local new_dir_mode=$(stat -c%f $migrate_dir)
22208         [ "$old_dir_mode" = "$new_dir_mode" ] ||
22209                 error "expect mode $old_dir_mode get $new_dir_mode"
22210
22211         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
22212         [ "$old_file_mode" = "$new_file_mode" ] ||
22213                 error "expect mode $old_file_mode get $new_file_mode"
22214
22215         diff /etc/passwd ${migrate_dir}/$tfile ||
22216                 error "$tfile different after migration"
22217
22218         diff /etc/passwd ${other_dir}/luna ||
22219                 error "luna different after migration"
22220
22221         diff /etc/passwd ${migrate_dir}/sofia ||
22222                 error "sofia different after migration"
22223
22224         diff /etc/passwd ${other_dir}/zachary ||
22225                 error "zachary different after migration"
22226
22227         diff /etc/passwd $migrate_dir/${tfile}_ln ||
22228                 error "${tfile}_ln different after migration"
22229
22230         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
22231                 error "${tfile}_ln_other different after migration"
22232
22233         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
22234         [ $stripe_count = 2 ] ||
22235                 error "dir strpe_count $d != 2 after migration."
22236
22237         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
22238         [ $stripe_count = 2 ] ||
22239                 error "file strpe_count $d != 2 after migration."
22240
22241         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22242 }
22243 run_test 230b "migrate directory"
22244
22245 test_230c() {
22246         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22247         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22248         remote_mds_nodsh && skip "remote MDS with nodsh"
22249         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22250                 skip "Need MDS version at least 2.11.52"
22251
22252         local MDTIDX=1
22253         local total=3
22254         local mdt_index
22255         local file
22256         local migrate_dir=$DIR/$tdir/migrate_dir
22257
22258         #If migrating directory fails in the middle, all entries of
22259         #the directory is still accessiable.
22260         test_mkdir $DIR/$tdir
22261         test_mkdir -i0 -c1 $migrate_dir
22262         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
22263         stat $migrate_dir
22264         createmany -o $migrate_dir/f $total ||
22265                 error "create files under ${migrate_dir} failed"
22266
22267         # fail after migrating top dir, and this will fail only once, so the
22268         # first sub file migration will fail (currently f3), others succeed.
22269         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
22270         do_facet mds1 lctl set_param fail_loc=0x1801
22271         local t=$(ls $migrate_dir | wc -l)
22272         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
22273                 error "migrate should fail"
22274         local u=$(ls $migrate_dir | wc -l)
22275         [ "$u" == "$t" ] || error "$u != $t during migration"
22276
22277         # add new dir/file should succeed
22278         mkdir $migrate_dir/dir ||
22279                 error "mkdir failed under migrating directory"
22280         touch $migrate_dir/file ||
22281                 error "create file failed under migrating directory"
22282
22283         # add file with existing name should fail
22284         for file in $migrate_dir/f*; do
22285                 stat $file > /dev/null || error "stat $file failed"
22286                 $OPENFILE -f O_CREAT:O_EXCL $file &&
22287                         error "open(O_CREAT|O_EXCL) $file should fail"
22288                 $MULTIOP $file m && error "create $file should fail"
22289                 touch $DIR/$tdir/remote_dir/$tfile ||
22290                         error "touch $tfile failed"
22291                 ln $DIR/$tdir/remote_dir/$tfile $file &&
22292                         error "link $file should fail"
22293                 mdt_index=$($LFS getstripe -m $file)
22294                 if [ $mdt_index == 0 ]; then
22295                         # file failed to migrate is not allowed to rename to
22296                         mv $DIR/$tdir/remote_dir/$tfile $file &&
22297                                 error "rename to $file should fail"
22298                 else
22299                         mv $DIR/$tdir/remote_dir/$tfile $file ||
22300                                 error "rename to $file failed"
22301                 fi
22302                 echo hello >> $file || error "write $file failed"
22303         done
22304
22305         # resume migration with different options should fail
22306         $LFS migrate -m 0 $migrate_dir &&
22307                 error "migrate -m 0 $migrate_dir should fail"
22308
22309         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
22310                 error "migrate -c 2 $migrate_dir should fail"
22311
22312         # resume migration should succeed
22313         $LFS migrate -m $MDTIDX $migrate_dir ||
22314                 error "migrate $migrate_dir failed"
22315
22316         echo "Finish migration, then checking.."
22317         for file in $(find $migrate_dir); do
22318                 mdt_index=$($LFS getstripe -m $file)
22319                 [ $mdt_index == $MDTIDX ] ||
22320                         error "$file is not on MDT${MDTIDX}"
22321         done
22322
22323         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22324 }
22325 run_test 230c "check directory accessiblity if migration failed"
22326
22327 test_230d() {
22328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22329         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22330         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22331                 skip "Need MDS version at least 2.11.52"
22332         # LU-11235
22333         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
22334
22335         local migrate_dir=$DIR/$tdir/migrate_dir
22336         local old_index
22337         local new_index
22338         local old_count
22339         local new_count
22340         local new_hash
22341         local mdt_index
22342         local i
22343         local j
22344
22345         old_index=$((RANDOM % MDSCOUNT))
22346         old_count=$((MDSCOUNT - old_index))
22347         new_index=$((RANDOM % MDSCOUNT))
22348         new_count=$((MDSCOUNT - new_index))
22349         new_hash=1 # for all_char
22350
22351         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
22352         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
22353
22354         test_mkdir $DIR/$tdir
22355         test_mkdir -i $old_index -c $old_count $migrate_dir
22356
22357         for ((i=0; i<100; i++)); do
22358                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
22359                 createmany -o $migrate_dir/dir_${i}/f 100 ||
22360                         error "create files under remote dir failed $i"
22361         done
22362
22363         echo -n "Migrate from MDT$old_index "
22364         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
22365         echo -n "to MDT$new_index"
22366         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
22367         echo
22368
22369         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
22370         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
22371                 error "migrate remote dir error"
22372
22373         echo "Finish migration, then checking.."
22374         for file in $(find $migrate_dir -maxdepth 1); do
22375                 mdt_index=$($LFS getstripe -m $file)
22376                 if [ $mdt_index -lt $new_index ] ||
22377                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
22378                         error "$file is on MDT$mdt_index"
22379                 fi
22380         done
22381
22382         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22383 }
22384 run_test 230d "check migrate big directory"
22385
22386 test_230e() {
22387         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22388         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22389         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22390                 skip "Need MDS version at least 2.11.52"
22391
22392         local i
22393         local j
22394         local a_fid
22395         local b_fid
22396
22397         mkdir_on_mdt0 $DIR/$tdir
22398         mkdir $DIR/$tdir/migrate_dir
22399         mkdir $DIR/$tdir/other_dir
22400         touch $DIR/$tdir/migrate_dir/a
22401         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
22402         ls $DIR/$tdir/other_dir
22403
22404         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22405                 error "migrate dir fails"
22406
22407         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
22408         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
22409
22410         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22411         [ $mdt_index == 0 ] || error "a is not on MDT0"
22412
22413         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
22414                 error "migrate dir fails"
22415
22416         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
22417         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
22418
22419         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22420         [ $mdt_index == 1 ] || error "a is not on MDT1"
22421
22422         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
22423         [ $mdt_index == 1 ] || error "b is not on MDT1"
22424
22425         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
22426         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
22427
22428         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
22429
22430         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22431 }
22432 run_test 230e "migrate mulitple local link files"
22433
22434 test_230f() {
22435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22436         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22437         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22438                 skip "Need MDS version at least 2.11.52"
22439
22440         local a_fid
22441         local ln_fid
22442
22443         mkdir -p $DIR/$tdir
22444         mkdir $DIR/$tdir/migrate_dir
22445         $LFS mkdir -i1 $DIR/$tdir/other_dir
22446         touch $DIR/$tdir/migrate_dir/a
22447         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
22448         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
22449         ls $DIR/$tdir/other_dir
22450
22451         # a should be migrated to MDT1, since no other links on MDT0
22452         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22453                 error "#1 migrate dir fails"
22454         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
22455         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
22456         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22457         [ $mdt_index == 1 ] || error "a is not on MDT1"
22458
22459         # a should stay on MDT1, because it is a mulitple link file
22460         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22461                 error "#2 migrate dir fails"
22462         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22463         [ $mdt_index == 1 ] || error "a is not on MDT1"
22464
22465         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22466                 error "#3 migrate dir fails"
22467
22468         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
22469         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
22470         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
22471
22472         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
22473         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
22474
22475         # a should be migrated to MDT0, since no other links on MDT1
22476         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22477                 error "#4 migrate dir fails"
22478         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22479         [ $mdt_index == 0 ] || error "a is not on MDT0"
22480
22481         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22482 }
22483 run_test 230f "migrate mulitple remote link files"
22484
22485 test_230g() {
22486         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22487         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22488         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22489                 skip "Need MDS version at least 2.11.52"
22490
22491         mkdir -p $DIR/$tdir/migrate_dir
22492
22493         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
22494                 error "migrating dir to non-exist MDT succeeds"
22495         true
22496 }
22497 run_test 230g "migrate dir to non-exist MDT"
22498
22499 test_230h() {
22500         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22501         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22502         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22503                 skip "Need MDS version at least 2.11.52"
22504
22505         local mdt_index
22506
22507         mkdir -p $DIR/$tdir/migrate_dir
22508
22509         $LFS migrate -m1 $DIR &&
22510                 error "migrating mountpoint1 should fail"
22511
22512         $LFS migrate -m1 $DIR/$tdir/.. &&
22513                 error "migrating mountpoint2 should fail"
22514
22515         # same as mv
22516         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
22517                 error "migrating $tdir/migrate_dir/.. should fail"
22518
22519         true
22520 }
22521 run_test 230h "migrate .. and root"
22522
22523 test_230i() {
22524         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22525         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22526         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22527                 skip "Need MDS version at least 2.11.52"
22528
22529         mkdir -p $DIR/$tdir/migrate_dir
22530
22531         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
22532                 error "migration fails with a tailing slash"
22533
22534         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
22535                 error "migration fails with two tailing slashes"
22536 }
22537 run_test 230i "lfs migrate -m tolerates trailing slashes"
22538
22539 test_230j() {
22540         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22541         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
22542                 skip "Need MDS version at least 2.11.52"
22543
22544         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22545         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
22546                 error "create $tfile failed"
22547         cat /etc/passwd > $DIR/$tdir/$tfile
22548
22549         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22550
22551         cmp /etc/passwd $DIR/$tdir/$tfile ||
22552                 error "DoM file mismatch after migration"
22553 }
22554 run_test 230j "DoM file data not changed after dir migration"
22555
22556 test_230k() {
22557         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
22558         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22559                 skip "Need MDS version at least 2.11.56"
22560
22561         local total=20
22562         local files_on_starting_mdt=0
22563
22564         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
22565         $LFS getdirstripe $DIR/$tdir
22566         for i in $(seq $total); do
22567                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
22568                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22569                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22570         done
22571
22572         echo "$files_on_starting_mdt files on MDT0"
22573
22574         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
22575         $LFS getdirstripe $DIR/$tdir
22576
22577         files_on_starting_mdt=0
22578         for i in $(seq $total); do
22579                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22580                         error "file $tfile.$i mismatch after migration"
22581                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
22582                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22583         done
22584
22585         echo "$files_on_starting_mdt files on MDT1 after migration"
22586         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
22587
22588         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
22589         $LFS getdirstripe $DIR/$tdir
22590
22591         files_on_starting_mdt=0
22592         for i in $(seq $total); do
22593                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22594                         error "file $tfile.$i mismatch after 2nd migration"
22595                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22596                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22597         done
22598
22599         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
22600         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
22601
22602         true
22603 }
22604 run_test 230k "file data not changed after dir migration"
22605
22606 test_230l() {
22607         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22608         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22609                 skip "Need MDS version at least 2.11.56"
22610
22611         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
22612         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
22613                 error "create files under remote dir failed $i"
22614         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22615 }
22616 run_test 230l "readdir between MDTs won't crash"
22617
22618 test_230m() {
22619         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22620         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22621                 skip "Need MDS version at least 2.11.56"
22622
22623         local MDTIDX=1
22624         local mig_dir=$DIR/$tdir/migrate_dir
22625         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
22626         local shortstr="b"
22627         local val
22628
22629         echo "Creating files and dirs with xattrs"
22630         test_mkdir $DIR/$tdir
22631         test_mkdir -i0 -c1 $mig_dir
22632         mkdir $mig_dir/dir
22633         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
22634                 error "cannot set xattr attr1 on dir"
22635         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
22636                 error "cannot set xattr attr2 on dir"
22637         touch $mig_dir/dir/f0
22638         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
22639                 error "cannot set xattr attr1 on file"
22640         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
22641                 error "cannot set xattr attr2 on file"
22642         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22643         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22644         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
22645         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22646         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
22647         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22648         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
22649         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22650         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
22651
22652         echo "Migrating to MDT1"
22653         $LFS migrate -m $MDTIDX $mig_dir ||
22654                 error "fails on migrating dir to MDT1"
22655
22656         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22657         echo "Checking xattrs"
22658         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22659         [ "$val" = $longstr ] ||
22660                 error "expecting xattr1 $longstr on dir, found $val"
22661         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22662         [ "$val" = $shortstr ] ||
22663                 error "expecting xattr2 $shortstr on dir, found $val"
22664         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22665         [ "$val" = $longstr ] ||
22666                 error "expecting xattr1 $longstr on file, found $val"
22667         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22668         [ "$val" = $shortstr ] ||
22669                 error "expecting xattr2 $shortstr on file, found $val"
22670 }
22671 run_test 230m "xattrs not changed after dir migration"
22672
22673 test_230n() {
22674         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22675         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22676                 skip "Need MDS version at least 2.13.53"
22677
22678         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
22679         cat /etc/hosts > $DIR/$tdir/$tfile
22680         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
22681         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
22682
22683         cmp /etc/hosts $DIR/$tdir/$tfile ||
22684                 error "File data mismatch after migration"
22685 }
22686 run_test 230n "Dir migration with mirrored file"
22687
22688 test_230o() {
22689         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
22690         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22691                 skip "Need MDS version at least 2.13.52"
22692
22693         local mdts=$(comma_list $(mdts_nodes))
22694         local timeout=100
22695         local restripe_status
22696         local delta
22697         local i
22698
22699         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22700
22701         # in case "crush" hash type is not set
22702         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22703
22704         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22705                            mdt.*MDT0000.enable_dir_restripe)
22706         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22707         stack_trap "do_nodes $mdts $LCTL set_param \
22708                     mdt.*.enable_dir_restripe=$restripe_status"
22709
22710         mkdir $DIR/$tdir
22711         createmany -m $DIR/$tdir/f 100 ||
22712                 error "create files under remote dir failed $i"
22713         createmany -d $DIR/$tdir/d 100 ||
22714                 error "create dirs under remote dir failed $i"
22715
22716         for i in $(seq 2 $MDSCOUNT); do
22717                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22718                 $LFS setdirstripe -c $i $DIR/$tdir ||
22719                         error "split -c $i $tdir failed"
22720                 wait_update $HOSTNAME \
22721                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
22722                         error "dir split not finished"
22723                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22724                         awk '/migrate/ {sum += $2} END { print sum }')
22725                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
22726                 # delta is around total_files/stripe_count
22727                 (( $delta < 200 / (i - 1) + 4 )) ||
22728                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
22729         done
22730 }
22731 run_test 230o "dir split"
22732
22733 test_230p() {
22734         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22735         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22736                 skip "Need MDS version at least 2.13.52"
22737
22738         local mdts=$(comma_list $(mdts_nodes))
22739         local timeout=100
22740         local restripe_status
22741         local delta
22742         local c
22743
22744         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22745
22746         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22747
22748         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22749                            mdt.*MDT0000.enable_dir_restripe)
22750         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22751         stack_trap "do_nodes $mdts $LCTL set_param \
22752                     mdt.*.enable_dir_restripe=$restripe_status"
22753
22754         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
22755         createmany -m $DIR/$tdir/f 100 ||
22756                 error "create files under remote dir failed"
22757         createmany -d $DIR/$tdir/d 100 ||
22758                 error "create dirs under remote dir failed"
22759
22760         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
22761                 local mdt_hash="crush"
22762
22763                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22764                 $LFS setdirstripe -c $c $DIR/$tdir ||
22765                         error "split -c $c $tdir failed"
22766                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
22767                         mdt_hash="$mdt_hash,fixed"
22768                 elif [ $c -eq 1 ]; then
22769                         mdt_hash="none"
22770                 fi
22771                 wait_update $HOSTNAME \
22772                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
22773                         error "dir merge not finished"
22774                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22775                         awk '/migrate/ {sum += $2} END { print sum }')
22776                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
22777                 # delta is around total_files/stripe_count
22778                 (( delta < 200 / c + 4 )) ||
22779                         error "$delta files migrated >= $((200 / c + 4))"
22780         done
22781 }
22782 run_test 230p "dir merge"
22783
22784 test_230q() {
22785         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
22786         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22787                 skip "Need MDS version at least 2.13.52"
22788
22789         local mdts=$(comma_list $(mdts_nodes))
22790         local saved_threshold=$(do_facet mds1 \
22791                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
22792         local saved_delta=$(do_facet mds1 \
22793                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
22794         local threshold=100
22795         local delta=2
22796         local total=0
22797         local stripe_count=0
22798         local stripe_index
22799         local nr_files
22800         local create
22801
22802         # test with fewer files on ZFS
22803         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
22804
22805         stack_trap "do_nodes $mdts $LCTL set_param \
22806                     mdt.*.dir_split_count=$saved_threshold"
22807         stack_trap "do_nodes $mdts $LCTL set_param \
22808                     mdt.*.dir_split_delta=$saved_delta"
22809         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
22810         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
22811         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
22812         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
22813         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
22814         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22815
22816         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22817         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22818
22819         create=$((threshold * 3 / 2))
22820         while [ $stripe_count -lt $MDSCOUNT ]; do
22821                 createmany -m $DIR/$tdir/f $total $create ||
22822                         error "create sub files failed"
22823                 stat $DIR/$tdir > /dev/null
22824                 total=$((total + create))
22825                 stripe_count=$((stripe_count + delta))
22826                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
22827
22828                 wait_update $HOSTNAME \
22829                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
22830                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
22831
22832                 wait_update $HOSTNAME \
22833                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
22834                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
22835
22836                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
22837                 echo "$nr_files/$total files on MDT$stripe_index after split"
22838                 # allow 10% margin of imbalance with crush hash
22839                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
22840                         error "$nr_files files on MDT$stripe_index after split"
22841
22842                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
22843                 [ $nr_files -eq $total ] ||
22844                         error "total sub files $nr_files != $total"
22845         done
22846
22847         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
22848
22849         echo "fixed layout directory won't auto split"
22850         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
22851         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
22852                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
22853         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
22854                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
22855 }
22856 run_test 230q "dir auto split"
22857
22858 test_230r() {
22859         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
22860         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
22861         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
22862                 skip "Need MDS version at least 2.13.54"
22863
22864         # maximum amount of local locks:
22865         # parent striped dir - 2 locks
22866         # new stripe in parent to migrate to - 1 lock
22867         # source and target - 2 locks
22868         # Total 5 locks for regular file
22869         mkdir -p $DIR/$tdir
22870         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
22871         touch $DIR/$tdir/dir1/eee
22872
22873         # create 4 hardlink for 4 more locks
22874         # Total: 9 locks > RS_MAX_LOCKS (8)
22875         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
22876         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
22877         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
22878         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
22879         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
22880         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
22881         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
22882         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
22883
22884         cancel_lru_locks mdc
22885
22886         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
22887                 error "migrate dir fails"
22888
22889         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22890 }
22891 run_test 230r "migrate with too many local locks"
22892
22893 test_230s() {
22894         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
22895                 skip "Need MDS version at least 2.14.52"
22896
22897         local mdts=$(comma_list $(mdts_nodes))
22898         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
22899                                 mdt.*MDT0000.enable_dir_restripe)
22900
22901         stack_trap "do_nodes $mdts $LCTL set_param \
22902                     mdt.*.enable_dir_restripe=$restripe_status"
22903
22904         local st
22905         for st in 0 1; do
22906                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
22907                 test_mkdir $DIR/$tdir
22908                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
22909                         error "$LFS mkdir should return EEXIST if target exists"
22910                 rmdir $DIR/$tdir
22911         done
22912 }
22913 run_test 230s "lfs mkdir should return -EEXIST if target exists"
22914
22915 test_230t()
22916 {
22917         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
22918         (( $MDS1_VERSION >= $(version_code 2.14.50) )) ||
22919                 skip "Need MDS version at least 2.14.50"
22920
22921         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
22922         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
22923         $LFS project -p 1 -s $DIR/$tdir ||
22924                 error "set $tdir project id failed"
22925         $LFS project -p 2 -s $DIR/$tdir/subdir ||
22926                 error "set subdir project id failed"
22927         local pbefore="$($LFS project -d $DIR/$tdir)"
22928         local sbefore="$($LFS project -d $DIR/$tdir/subdir)"
22929         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
22930
22931         local pafter="$($LFS project -d $DIR/$tdir)"
22932         local safter="$($LFS project -d $DIR/$tdir/subdir)"
22933         [[ "$pbefore" == "$pafter" ]] || error "projid '$pbefore' != '$pafter'"
22934         [[ "$sbefore" == "$safter" ]] || error "projid '$sbefore' != '$safter'"
22935
22936         (( $MDS1_VERSION >= $(version_code 2.15.59.107) )) ||
22937                 { echo "Need MDS >= 2.15.59.107 for projid rename"; return 0; }
22938
22939         # check rename works, even if source parent projid differs (LU-17016)
22940         test_mkdir $DIR/$tdir.2 || error "mkdir $tdir.2 failed"
22941         local fid_before=$($LFS path2fid $DIR/$tdir/subdir)
22942
22943         $LFS project -p 2 -s $DIR/$tdir.2 || error "set $tdir.2 projid failed"
22944         mrename $DIR/$tdir/subdir $DIR/$tdir.2/subdir ||
22945                 error "subdir failed rename for different source parent projid"
22946         local fid_after=$($LFS path2fid $DIR/$tdir.2/subdir)
22947
22948         [[ "$fid_before" == "$fid_after" ]] ||
22949                 error "fid before '$fid_before' != after '$fid_after'"
22950 }
22951 run_test 230t "migrate directory with project ID set"
22952
22953 test_230u()
22954 {
22955         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22956         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22957                 skip "Need MDS version at least 2.14.53"
22958
22959         local count
22960
22961         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22962         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22963         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
22964         for i in $(seq 0 $((MDSCOUNT - 1))); do
22965                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22966                 echo "$count dirs migrated to MDT$i"
22967         done
22968         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22969         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
22970 }
22971 run_test 230u "migrate directory by QOS"
22972
22973 test_230v()
22974 {
22975         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22976         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22977                 skip "Need MDS version at least 2.14.53"
22978
22979         local count
22980
22981         mkdir $DIR/$tdir || error "mkdir $tdir failed"
22982         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22983         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
22984         for i in $(seq 0 $((MDSCOUNT - 1))); do
22985                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22986                 echo "$count subdirs migrated to MDT$i"
22987                 (( i == 3 )) && (( count > 0 )) &&
22988                         error "subdir shouldn't be migrated to MDT3"
22989         done
22990         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22991         (( count == 3 )) || error "dirs migrated to $count MDTs"
22992 }
22993 run_test 230v "subdir migrated to the MDT where its parent is located"
22994
22995 test_230w() {
22996         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22997         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22998                 skip "Need MDS version at least 2.15.0"
22999
23000         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
23001         createmany -o $DIR/$tdir/f 10 || error "create files failed"
23002         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
23003
23004         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
23005                 error "migrate failed"
23006
23007         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
23008                 error "$tdir stripe count mismatch"
23009
23010         for i in $(seq 0 9); do
23011                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
23012                         error "d$i is striped"
23013         done
23014 }
23015 run_test 230w "non-recursive mode dir migration"
23016
23017 test_230x() {
23018         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23019         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
23020                 skip "Need MDS version at least 2.15.0"
23021
23022         mkdir -p $DIR/$tdir || error "mkdir failed"
23023         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
23024
23025         local mdt_name=$(mdtname_from_index 0)
23026         local low=$(do_facet mds2 $LCTL get_param -n \
23027                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
23028         local high=$(do_facet mds2 $LCTL get_param -n \
23029                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
23030         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
23031         local maxage=$(do_facet mds2 $LCTL get_param -n \
23032                 osp.*$mdt_name-osp-MDT0001.maxage)
23033
23034         stack_trap "do_facet mds2 $LCTL set_param -n \
23035                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
23036                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
23037         stack_trap "do_facet mds2 $LCTL set_param -n \
23038                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
23039
23040         do_facet mds2 $LCTL set_param -n \
23041                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
23042         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
23043         sleep 4
23044         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
23045                 error "migrate $tdir should fail"
23046
23047         do_facet mds2 $LCTL set_param -n \
23048                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
23049         do_facet mds2 $LCTL set_param -n \
23050                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
23051         sleep 4
23052         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
23053                 error "migrate failed"
23054         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
23055                 error "$tdir stripe count mismatch"
23056 }
23057 run_test 230x "dir migration check space"
23058
23059 test_230y() {
23060         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23061         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
23062                 skip "Need MDS version at least 2.15.55.45"
23063
23064         local pid
23065
23066         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
23067         $LFS getdirstripe $DIR/$tdir
23068         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
23069         $LFS migrate -m 1 -c 2 $DIR/$tdir &
23070         pid=$!
23071         sleep 1
23072
23073         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
23074         do_facet mds2 lctl set_param fail_loc=0x1802
23075
23076         wait $pid
23077         do_facet mds2 lctl set_param fail_loc=0
23078         $LFS getdirstripe $DIR/$tdir
23079         unlinkmany -d $DIR/$tdir/d 100 || error "unlinkmany failed"
23080         rmdir $DIR/$tdir || error "rmdir $tdir failed"
23081 }
23082 run_test 230y "unlink dir with bad hash type"
23083
23084 test_230z() {
23085         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23086         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
23087                 skip "Need MDS version at least 2.15.55.45"
23088
23089         local pid
23090
23091         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
23092         $LFS getdirstripe $DIR/$tdir
23093         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
23094         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir &
23095         pid=$!
23096         sleep 1
23097
23098         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
23099         do_facet mds2 lctl set_param fail_loc=0x1802
23100
23101         wait $pid
23102         do_facet mds2 lctl set_param fail_loc=0
23103         $LFS getdirstripe $DIR/$tdir
23104
23105         # resume migration
23106         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir ||
23107                 error "resume migration failed"
23108         $LFS getdirstripe $DIR/$tdir
23109         [ $($LFS getdirstripe -H $DIR/$tdir) == "fnv_1a_64,fixed" ] ||
23110                 error "migration is not finished"
23111 }
23112 run_test 230z "resume dir migration with bad hash type"
23113
23114 test_231a()
23115 {
23116         # For simplicity this test assumes that max_pages_per_rpc
23117         # is the same across all OSCs
23118         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
23119         local bulk_size=$((max_pages * PAGE_SIZE))
23120         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
23121                                        head -n 1)
23122
23123         mkdir -p $DIR/$tdir
23124         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
23125                 error "failed to set stripe with -S ${brw_size}M option"
23126         stack_trap "rm -rf $DIR/$tdir"
23127
23128         # clear the OSC stats
23129         $LCTL set_param osc.*.stats=0 &>/dev/null
23130         stop_writeback
23131
23132         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
23133         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
23134                 oflag=direct &>/dev/null || error "dd failed"
23135
23136         sync; sleep 1; sync # just to be safe
23137         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
23138         if [ x$nrpcs != "x1" ]; then
23139                 $LCTL get_param osc.*.stats
23140                 error "found $nrpcs ost_write RPCs, not 1 as expected"
23141         fi
23142
23143         start_writeback
23144         # Drop the OSC cache, otherwise we will read from it
23145         cancel_lru_locks osc
23146
23147         # clear the OSC stats
23148         $LCTL set_param osc.*.stats=0 &>/dev/null
23149
23150         # Client reads $bulk_size.
23151         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
23152                 iflag=direct &>/dev/null || error "dd failed"
23153
23154         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
23155         if [ x$nrpcs != "x1" ]; then
23156                 $LCTL get_param osc.*.stats
23157                 error "found $nrpcs ost_read RPCs, not 1 as expected"
23158         fi
23159 }
23160 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
23161
23162 test_231b() {
23163         mkdir -p $DIR/$tdir
23164         stack_trap "rm -rf $DIR/$tdir"
23165         local i
23166         for i in {0..1023}; do
23167                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
23168                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
23169                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
23170         done
23171         sync
23172 }
23173 run_test 231b "must not assert on fully utilized OST request buffer"
23174
23175 test_232a() {
23176         mkdir -p $DIR/$tdir
23177         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
23178
23179         #define OBD_FAIL_LDLM_OST_LVB            0x31c
23180         do_facet ost1 $LCTL set_param fail_loc=0x31c
23181
23182         # ignore dd failure
23183         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
23184         stack_trap "rm -f $DIR/$tdir/$tfile"
23185
23186         do_facet ost1 $LCTL set_param fail_loc=0
23187         umount_client $MOUNT || error "umount failed"
23188         mount_client $MOUNT || error "mount failed"
23189         stop ost1 || error "cannot stop ost1"
23190         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23191 }
23192 run_test 232a "failed lock should not block umount"
23193
23194 test_232b() {
23195         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
23196                 skip "Need MDS version at least 2.10.58"
23197
23198         mkdir -p $DIR/$tdir
23199         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
23200         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
23201         stack_trap "rm -f $DIR/$tdir/$tfile"
23202         sync
23203         cancel_lru_locks osc
23204
23205         #define OBD_FAIL_LDLM_OST_LVB            0x31c
23206         do_facet ost1 $LCTL set_param fail_loc=0x31c
23207
23208         # ignore failure
23209         $LFS data_version $DIR/$tdir/$tfile || true
23210
23211         do_facet ost1 $LCTL set_param fail_loc=0
23212         umount_client $MOUNT || error "umount failed"
23213         mount_client $MOUNT || error "mount failed"
23214         stop ost1 || error "cannot stop ost1"
23215         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23216 }
23217 run_test 232b "failed data version lock should not block umount"
23218
23219 test_233a() {
23220         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
23221                 skip "Need MDS version at least 2.3.64"
23222         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
23223
23224         local fid=$($LFS path2fid $MOUNT)
23225
23226         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23227                 error "cannot access $MOUNT using its FID '$fid'"
23228 }
23229 run_test 233a "checking that OBF of the FS root succeeds"
23230
23231 test_233b() {
23232         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
23233                 skip "Need MDS version at least 2.5.90"
23234         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
23235
23236         local fid=$($LFS path2fid $MOUNT/.lustre)
23237
23238         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23239                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
23240
23241         fid=$($LFS path2fid $MOUNT/.lustre/fid)
23242         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23243                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
23244 }
23245 run_test 233b "checking that OBF of the FS .lustre succeeds"
23246
23247 test_234() {
23248         local p="$TMP/sanityN-$TESTNAME.parameters"
23249         save_lustre_params client "llite.*.xattr_cache" > $p
23250         lctl set_param llite.*.xattr_cache 1 ||
23251                 skip_env "xattr cache is not supported"
23252
23253         mkdir -p $DIR/$tdir || error "mkdir failed"
23254         touch $DIR/$tdir/$tfile || error "touch failed"
23255         # OBD_FAIL_LLITE_XATTR_ENOMEM
23256         $LCTL set_param fail_loc=0x1405
23257         getfattr -n user.attr $DIR/$tdir/$tfile &&
23258                 error "getfattr should have failed with ENOMEM"
23259         $LCTL set_param fail_loc=0x0
23260         rm -rf $DIR/$tdir
23261
23262         restore_lustre_params < $p
23263         rm -f $p
23264 }
23265 run_test 234 "xattr cache should not crash on ENOMEM"
23266
23267 test_235() {
23268         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
23269                 skip "Need MDS version at least 2.4.52"
23270
23271         flock_deadlock $DIR/$tfile
23272         local RC=$?
23273         case $RC in
23274                 0)
23275                 ;;
23276                 124) error "process hangs on a deadlock"
23277                 ;;
23278                 *) error "error executing flock_deadlock $DIR/$tfile"
23279                 ;;
23280         esac
23281 }
23282 run_test 235 "LU-1715: flock deadlock detection does not work properly"
23283
23284 #LU-2935
23285 test_236() {
23286         check_swap_layouts_support
23287
23288         local ref1=/etc/passwd
23289         local ref2=/etc/group
23290         local file1=$DIR/$tdir/f1
23291         local file2=$DIR/$tdir/f2
23292
23293         test_mkdir -c1 $DIR/$tdir
23294         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
23295         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
23296         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
23297         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
23298         local fd=$(free_fd)
23299         local cmd="exec $fd<>$file2"
23300         eval $cmd
23301         rm $file2
23302         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
23303                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
23304         cmd="exec $fd>&-"
23305         eval $cmd
23306         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
23307
23308         #cleanup
23309         rm -rf $DIR/$tdir
23310 }
23311 run_test 236 "Layout swap on open unlinked file"
23312
23313 # LU-4659 linkea consistency
23314 test_238() {
23315         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
23316                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
23317                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
23318                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
23319
23320         touch $DIR/$tfile
23321         ln $DIR/$tfile $DIR/$tfile.lnk
23322         touch $DIR/$tfile.new
23323         mv $DIR/$tfile.new $DIR/$tfile
23324         local fid1=$($LFS path2fid $DIR/$tfile)
23325         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
23326         local path1=$($LFS fid2path $FSNAME "$fid1")
23327         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
23328         local path2=$($LFS fid2path $FSNAME "$fid2")
23329         [ $tfile.lnk == $path2 ] ||
23330                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
23331         rm -f $DIR/$tfile*
23332 }
23333 run_test 238 "Verify linkea consistency"
23334
23335 test_239A() { # was test_239
23336         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
23337                 skip "Need MDS version at least 2.5.60"
23338
23339         local list=$(comma_list $(mdts_nodes))
23340
23341         mkdir -p $DIR/$tdir
23342         createmany -o $DIR/$tdir/f- 5000
23343         unlinkmany $DIR/$tdir/f- 5000
23344         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
23345                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
23346         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
23347                         osp.*MDT*.sync_in_flight" | calc_sum)
23348         [ "$changes" -eq 0 ] || error "$changes not synced"
23349 }
23350 run_test 239A "osp_sync test"
23351
23352 test_239a() { #LU-5297
23353         remote_mds_nodsh && skip "remote MDS with nodsh"
23354
23355         touch $DIR/$tfile
23356         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
23357         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
23358         chgrp $RUNAS_GID $DIR/$tfile
23359         wait_delete_completed
23360 }
23361 run_test 239a "process invalid osp sync record correctly"
23362
23363 test_239b() { #LU-5297
23364         remote_mds_nodsh && skip "remote MDS with nodsh"
23365
23366         touch $DIR/$tfile1
23367         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
23368         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
23369         chgrp $RUNAS_GID $DIR/$tfile1
23370         wait_delete_completed
23371         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
23372         touch $DIR/$tfile2
23373         chgrp $RUNAS_GID $DIR/$tfile2
23374         wait_delete_completed
23375 }
23376 run_test 239b "process osp sync record with ENOMEM error correctly"
23377
23378 test_240() {
23379         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23380         remote_mds_nodsh && skip "remote MDS with nodsh"
23381
23382         mkdir -p $DIR/$tdir
23383
23384         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
23385                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
23386         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
23387                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
23388
23389         umount_client $MOUNT || error "umount failed"
23390         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
23391         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
23392         mount_client $MOUNT || error "failed to mount client"
23393
23394         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
23395         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
23396 }
23397 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
23398
23399 test_241_bio() {
23400         local count=$1
23401         local bsize=$2
23402
23403         for LOOP in $(seq $count); do
23404                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
23405                 cancel_lru_locks $OSC || true
23406         done
23407 }
23408
23409 test_241_dio() {
23410         local count=$1
23411         local bsize=$2
23412
23413         for LOOP in $(seq $1); do
23414                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
23415                         2>/dev/null
23416         done
23417 }
23418
23419 test_241a() { # was test_241
23420         local bsize=$PAGE_SIZE
23421
23422         (( bsize < 40960 )) && bsize=40960
23423         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
23424         ls -la $DIR/$tfile
23425         cancel_lru_locks $OSC
23426         test_241_bio 1000 $bsize &
23427         PID=$!
23428         test_241_dio 1000 $bsize
23429         wait $PID
23430 }
23431 run_test 241a "bio vs dio"
23432
23433 test_241b() {
23434         local bsize=$PAGE_SIZE
23435
23436         (( bsize < 40960 )) && bsize=40960
23437         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
23438         ls -la $DIR/$tfile
23439         test_241_dio 1000 $bsize &
23440         PID=$!
23441         test_241_dio 1000 $bsize
23442         wait $PID
23443 }
23444 run_test 241b "dio vs dio"
23445
23446 test_242() {
23447         remote_mds_nodsh && skip "remote MDS with nodsh"
23448
23449         mkdir_on_mdt0 $DIR/$tdir
23450         touch $DIR/$tdir/$tfile
23451
23452         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
23453         do_facet mds1 lctl set_param fail_loc=0x105
23454         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
23455
23456         do_facet mds1 lctl set_param fail_loc=0
23457         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
23458 }
23459 run_test 242 "mdt_readpage failure should not cause directory unreadable"
23460
23461 test_243()
23462 {
23463         test_mkdir $DIR/$tdir
23464         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
23465 }
23466 run_test 243 "various group lock tests"
23467
23468 test_244a()
23469 {
23470         test_mkdir $DIR/$tdir
23471         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
23472         sendfile_grouplock $DIR/$tdir/$tfile || \
23473                 error "sendfile+grouplock failed"
23474         rm -rf $DIR/$tdir
23475 }
23476 run_test 244a "sendfile with group lock tests"
23477
23478 test_244b()
23479 {
23480         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23481
23482         local threads=50
23483         local size=$((1024*1024))
23484
23485         test_mkdir $DIR/$tdir
23486         for i in $(seq 1 $threads); do
23487                 local file=$DIR/$tdir/file_$((i / 10))
23488                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
23489                 local pids[$i]=$!
23490         done
23491         for i in $(seq 1 $threads); do
23492                 wait ${pids[$i]}
23493         done
23494 }
23495 run_test 244b "multi-threaded write with group lock"
23496
23497 test_245a() {
23498         local flagname="multi_mod_rpcs"
23499         local connect_data_name="max_mod_rpcs"
23500         local out
23501
23502         # check if multiple modify RPCs flag is set
23503         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
23504                 grep "connect_flags:")
23505         echo "$out"
23506
23507         echo "$out" | grep -qw $flagname
23508         if [ $? -ne 0 ]; then
23509                 echo "connect flag $flagname is not set"
23510                 return
23511         fi
23512
23513         # check if multiple modify RPCs data is set
23514         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
23515         echo "$out"
23516
23517         echo "$out" | grep -qw $connect_data_name ||
23518                 error "import should have connect data $connect_data_name"
23519 }
23520 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
23521
23522 test_245b() {
23523         local flagname="multi_mod_rpcs"
23524         local connect_data_name="max_mod_rpcs"
23525         local out
23526
23527         remote_mds_nodsh && skip "remote MDS with nodsh"
23528         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
23529
23530         # check if multiple modify RPCs flag is set
23531         out=$(do_facet mds1 \
23532               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
23533               grep "connect_flags:")
23534         echo "$out"
23535
23536         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
23537
23538         # check if multiple modify RPCs data is set
23539         out=$(do_facet mds1 \
23540               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
23541
23542         [[ "$out" =~ $connect_data_name ]] ||
23543                 {
23544                         echo "$out"
23545                         error "missing connect data $connect_data_name"
23546                 }
23547 }
23548 run_test 245b "check osp connection flag/data: multiple modify RPCs"
23549
23550 cleanup_247() {
23551         local submount=$1
23552
23553         trap 0
23554         umount_client $submount
23555         rmdir $submount
23556 }
23557
23558 test_247a() {
23559         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23560                 grep -q subtree ||
23561                 skip_env "Fileset feature is not supported"
23562
23563         local submount=${MOUNT}_$tdir
23564
23565         mkdir $MOUNT/$tdir
23566         mkdir -p $submount || error "mkdir $submount failed"
23567         FILESET="$FILESET/$tdir" mount_client $submount ||
23568                 error "mount $submount failed"
23569         trap "cleanup_247 $submount" EXIT
23570         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
23571         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
23572                 error "read $MOUNT/$tdir/$tfile failed"
23573         cleanup_247 $submount
23574 }
23575 run_test 247a "mount subdir as fileset"
23576
23577 test_247b() {
23578         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23579                 skip_env "Fileset feature is not supported"
23580
23581         local submount=${MOUNT}_$tdir
23582
23583         rm -rf $MOUNT/$tdir
23584         mkdir -p $submount || error "mkdir $submount failed"
23585         SKIP_FILESET=1
23586         FILESET="$FILESET/$tdir" mount_client $submount &&
23587                 error "mount $submount should fail"
23588         rmdir $submount
23589 }
23590 run_test 247b "mount subdir that dose not exist"
23591
23592 test_247c() {
23593         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23594                 skip_env "Fileset feature is not supported"
23595
23596         local submount=${MOUNT}_$tdir
23597
23598         mkdir -p $MOUNT/$tdir/dir1
23599         mkdir -p $submount || error "mkdir $submount failed"
23600         trap "cleanup_247 $submount" EXIT
23601         FILESET="$FILESET/$tdir" mount_client $submount ||
23602                 error "mount $submount failed"
23603         local fid=$($LFS path2fid $MOUNT/)
23604         $LFS fid2path $submount $fid && error "fid2path should fail"
23605         cleanup_247 $submount
23606 }
23607 run_test 247c "running fid2path outside subdirectory root"
23608
23609 test_247d() {
23610         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23611                 skip "Fileset feature is not supported"
23612
23613         local submount=${MOUNT}_$tdir
23614
23615         mkdir -p $MOUNT/$tdir/dir1
23616         mkdir -p $submount || error "mkdir $submount failed"
23617         FILESET="$FILESET/$tdir" mount_client $submount ||
23618                 error "mount $submount failed"
23619         trap "cleanup_247 $submount" EXIT
23620
23621         local td=$submount/dir1
23622         local fid=$($LFS path2fid $td)
23623         [ -z "$fid" ] && error "path2fid unable to get $td FID"
23624
23625         # check that we get the same pathname back
23626         local rootpath
23627         local found
23628         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
23629                 echo "$rootpath $fid"
23630                 found=$($LFS fid2path $rootpath "$fid")
23631                 [ -n "$found" ] || error "fid2path should succeed"
23632                 [ "$found" == "$td" ] || error "fid2path $found != $td"
23633         done
23634         # check wrong root path format
23635         rootpath=$submount"_wrong"
23636         found=$($LFS fid2path $rootpath "$fid")
23637         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
23638
23639         cleanup_247 $submount
23640 }
23641 run_test 247d "running fid2path inside subdirectory root"
23642
23643 # LU-8037
23644 test_247e() {
23645         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23646                 grep -q subtree ||
23647                 skip "Fileset feature is not supported"
23648
23649         local submount=${MOUNT}_$tdir
23650
23651         mkdir $MOUNT/$tdir
23652         mkdir -p $submount || error "mkdir $submount failed"
23653         FILESET="$FILESET/.." mount_client $submount &&
23654                 error "mount $submount should fail"
23655         rmdir $submount
23656 }
23657 run_test 247e "mount .. as fileset"
23658
23659 test_247f() {
23660         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
23661         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
23662                 skip "Need at least version 2.14.50.162"
23663         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23664                 skip "Fileset feature is not supported"
23665
23666         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
23667         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
23668                 error "mkdir remote failed"
23669         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
23670                 error "mkdir remote/subdir failed"
23671         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
23672                 error "mkdir striped failed"
23673         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
23674
23675         local submount=${MOUNT}_$tdir
23676
23677         mkdir -p $submount || error "mkdir $submount failed"
23678         stack_trap "rmdir $submount"
23679
23680         local dir
23681         local fileset=$FILESET
23682         local mdts=$(comma_list $(mdts_nodes))
23683
23684         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
23685         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
23686                 $tdir/striped/subdir $tdir/striped/.; do
23687                 FILESET="$fileset/$dir" mount_client $submount ||
23688                         error "mount $dir failed"
23689                 umount_client $submount
23690         done
23691 }
23692 run_test 247f "mount striped or remote directory as fileset"
23693
23694 test_subdir_mount_lock()
23695 {
23696         local testdir=$1
23697         local submount=${MOUNT}_$(basename $testdir)
23698
23699         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
23700
23701         mkdir -p $submount || error "mkdir $submount failed"
23702         stack_trap "rmdir $submount"
23703
23704         FILESET="$fileset/$testdir" mount_client $submount ||
23705                 error "mount $FILESET failed"
23706         stack_trap "umount $submount"
23707
23708         local mdts=$(comma_list $(mdts_nodes))
23709
23710         local nrpcs
23711
23712         stat $submount > /dev/null || error "stat $submount failed"
23713         cancel_lru_locks $MDC
23714         stat $submount > /dev/null || error "stat $submount failed"
23715         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23716         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
23717         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23718         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
23719                 awk '/getattr/ {sum += $2} END {print sum}')
23720
23721         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
23722 }
23723
23724 test_247g() {
23725         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23726
23727         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
23728                 error "mkdir $tdir failed"
23729         test_subdir_mount_lock $tdir
23730 }
23731 run_test 247g "striped directory submount revalidate ROOT from cache"
23732
23733 test_247h() {
23734         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23735         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
23736                 skip "Need MDS version at least 2.15.51"
23737
23738         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23739         test_subdir_mount_lock $tdir
23740         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
23741         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
23742                 error "mkdir $tdir.1 failed"
23743         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
23744 }
23745 run_test 247h "remote directory submount revalidate ROOT from cache"
23746
23747 test_248a() {
23748         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
23749         [ -z "$fast_read_sav" ] && skip "no fast read support"
23750
23751         # create a large file for fast read verification
23752         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
23753
23754         # make sure the file is created correctly
23755         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
23756                 { rm -f $DIR/$tfile; skip "file creation error"; }
23757
23758         echo "Test 1: verify that fast read is 4 times faster on cache read"
23759
23760         # small read with fast read enabled
23761         $LCTL set_param -n llite.*.fast_read=1
23762         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23763                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23764                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23765         # small read with fast read disabled
23766         $LCTL set_param -n llite.*.fast_read=0
23767         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23768                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23769                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23770
23771         # verify that fast read is 4 times faster for cache read
23772         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
23773                 error_not_in_vm "fast read was not 4 times faster: " \
23774                            "$t_fast vs $t_slow"
23775
23776         echo "Test 2: verify the performance between big and small read"
23777         $LCTL set_param -n llite.*.fast_read=1
23778
23779         # 1k non-cache read
23780         cancel_lru_locks osc
23781         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23782                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23783                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23784
23785         # 1M non-cache read
23786         cancel_lru_locks osc
23787         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23788                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23789                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23790
23791         # verify that big IO is not 4 times faster than small IO
23792         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
23793                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
23794
23795         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
23796         rm -f $DIR/$tfile
23797 }
23798 run_test 248a "fast read verification"
23799
23800 test_248b() {
23801         # Default short_io_bytes=16384, try both smaller and larger sizes.
23802         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
23803         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
23804         echo "bs=53248 count=113 normal buffered write"
23805         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
23806                 error "dd of initial data file failed"
23807         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
23808
23809         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
23810         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
23811                 error "dd with sync normal writes failed"
23812         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
23813
23814         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
23815         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
23816                 error "dd with sync small writes failed"
23817         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
23818
23819         cancel_lru_locks osc
23820
23821         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
23822         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
23823         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
23824         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
23825                 iflag=direct || error "dd with O_DIRECT small read failed"
23826         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
23827         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
23828                 error "compare $TMP/$tfile.1 failed"
23829
23830         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
23831         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
23832
23833         # just to see what the maximum tunable value is, and test parsing
23834         echo "test invalid parameter 2MB"
23835         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
23836                 error "too-large short_io_bytes allowed"
23837         echo "test maximum parameter 512KB"
23838         # if we can set a larger short_io_bytes, run test regardless of version
23839         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
23840                 # older clients may not allow setting it this large, that's OK
23841                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
23842                         skip "Need at least client version 2.13.50"
23843                 error "medium short_io_bytes failed"
23844         fi
23845         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23846         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
23847
23848         echo "test large parameter 64KB"
23849         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
23850         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23851
23852         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
23853         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
23854                 error "dd with sync large writes failed"
23855         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
23856
23857         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
23858         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
23859         num=$((113 * 4096 / PAGE_SIZE))
23860         echo "bs=$size count=$num oflag=direct large write $tfile.3"
23861         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
23862                 error "dd with O_DIRECT large writes failed"
23863         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
23864                 error "compare $DIR/$tfile.3 failed"
23865
23866         cancel_lru_locks osc
23867
23868         echo "bs=$size count=$num iflag=direct large read $tfile.2"
23869         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
23870                 error "dd with O_DIRECT large read failed"
23871         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
23872                 error "compare $TMP/$tfile.2 failed"
23873
23874         echo "bs=$size count=$num iflag=direct large read $tfile.3"
23875         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
23876                 error "dd with O_DIRECT large read failed"
23877         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
23878                 error "compare $TMP/$tfile.3 failed"
23879 }
23880 run_test 248b "test short_io read and write for both small and large sizes"
23881
23882 test_248c() {
23883         $LCTL set_param llite.*.read_ahead_stats=c
23884         # This test compares whole file readahead to non-whole file readahead
23885         # The performance should be consistently slightly faster for whole file,
23886         # and the bug caused whole file readahead to be 80-100x slower, but to
23887         # account for possible test system lag, we require whole file to be
23888         # <= 1.5xnon-whole file, and require 3 failures in a row to fail the
23889         # test
23890         local time1
23891         local time2
23892         local whole_mb=$($LCTL get_param -n llite.*.max_read_ahead_whole_mb)
23893         stack_trap "$LCTL set_param llite.*.max_read_ahead_whole_mb=$whole_mb" EXIT
23894         counter=0
23895
23896         while [ $counter -lt 3 ]; do
23897                 # Increment the counter
23898                 ((counter++))
23899
23900                 $LCTL set_param llite.*.max_read_ahead_whole_mb=64
23901                 rm -f $DIR/$tfile
23902                 touch $DIR/$tfile || error "(0) failed to create file"
23903                 # 64 MiB
23904                 $TRUNCATE $DIR/$tfile 67108864 || error "(1) failed to truncate file"
23905                 time1=$(dd if=$DIR/$tfile bs=4K of=/dev/null 2>&1 | awk '/bytes/ {print $8}')
23906                 echo "whole file readahead of 64 MiB took $time1 seconds"
23907                 $LCTL get_param llite.*.read_ahead_stats
23908
23909                 $LCTL set_param llite.*.read_ahead_stats=c
23910                 $LCTL set_param llite.*.max_read_ahead_whole_mb=8
23911                 rm -f $DIR/$tfile
23912                 touch $DIR/$tfile || error "(2) failed to create file"
23913                 # 64 MiB
23914                 $TRUNCATE $DIR/$tfile 67108864 || error "(3) failed to create file"
23915                 time2=$(dd if=$DIR/$tfile bs=4K of=/dev/null 2>&1 | awk '/bytes/ {print $8}')
23916                 echo "non-whole file readahead of 64 MiB took $time2 seconds"
23917                 $LCTL get_param llite.*.read_ahead_stats
23918
23919                 # Check if time1 is not more than 1.5 times2
23920                 timecheck=$(echo "$time1 <= (1.5 * $time2)" | bc -l)
23921
23922                 if [[ $timecheck -eq 1 ]]; then
23923                         echo "Test passed on attempt $counter"
23924                         # Exit the loop
23925                         counter=4
23926                 else
23927                         echo "Attempt $counter failed: whole file readahead took: $time1, greater than non: $time2"
23928                 fi
23929         done
23930         if [ $counter -eq 3 ]; then
23931                 error "whole file readahead check failed 3 times in a row, probably not just VM lag"
23932         fi
23933
23934 }
23935 run_test 248c "verify whole file read behavior"
23936
23937 test_249() { # LU-7890
23938         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
23939                 skip "Need at least version 2.8.54"
23940
23941         rm -f $DIR/$tfile
23942         $LFS setstripe -c 1 $DIR/$tfile
23943         # Offset 2T == 4k * 512M
23944         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
23945                 error "dd to 2T offset failed"
23946 }
23947 run_test 249 "Write above 2T file size"
23948
23949 test_250() {
23950         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
23951          && skip "no 16TB file size limit on ZFS"
23952
23953         $LFS setstripe -c 1 $DIR/$tfile
23954         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
23955         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
23956         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
23957         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
23958                 conv=notrunc,fsync && error "append succeeded"
23959         return 0
23960 }
23961 run_test 250 "Write above 16T limit"
23962
23963 test_251a() {
23964         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
23965
23966         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
23967         #Skip once - writing the first stripe will succeed
23968         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23969         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
23970                 error "short write happened"
23971
23972         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23973         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
23974                 error "short read happened"
23975
23976         rm -f $DIR/$tfile
23977 }
23978 run_test 251a "Handling short read and write correctly"
23979
23980 test_251b() {
23981         dd if=/dev/zero of=$DIR/$tfile bs=1k count=4 ||
23982                 error "write $tfile failed"
23983
23984         sleep 2 && echo 12345 >> $DIR/$tfile &
23985
23986         #define OBD_FAIL_LLITE_READ_PAUSE 0x1431
23987         $LCTL set_param fail_loc=0x1431 fail_val=5
23988         # seek to 4096, 2 seconds later, file size expand to 4102, and after
23989         # 5 seconds, read 10 bytes, the short read should
23990         # report:
23991         #                start ->+ read_len -> offset_after_read read_count
23992         #     short read: 4096 ->+ 10 -> 4096 0
23993         # not:
23994         #     short read: 4096 ->+ 10 -> 4102 0
23995         local off=$($MULTIOP $DIR/$tfile oO_RDONLY:z4096r10c 2>&1 | \
23996                         awk '/short read/ { print $7 }')
23997         (( off == 4096 )) ||
23998                 error "short read should set offset at 4096, not $off"
23999 }
24000 run_test 251b "short read restore offset correctly"
24001
24002 test_252() {
24003         remote_mds_nodsh && skip "remote MDS with nodsh"
24004         remote_ost_nodsh && skip "remote OST with nodsh"
24005         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
24006                 skip_env "ldiskfs only test"
24007         fi
24008
24009         local tgt
24010         local dev
24011         local out
24012         local uuid
24013         local num
24014         local gen
24015
24016         # check lr_reader on OST0000
24017         tgt=ost1
24018         dev=$(facet_device $tgt)
24019         out=$(do_facet $tgt $LR_READER $dev)
24020         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
24021         echo "$out"
24022         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
24023         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
24024                 error "Invalid uuid returned by $LR_READER on target $tgt"
24025         echo -e "uuid returned by $LR_READER is '$uuid'\n"
24026
24027         # check lr_reader -c on MDT0000
24028         tgt=mds1
24029         dev=$(facet_device $tgt)
24030         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
24031                 skip "$LR_READER does not support additional options"
24032         fi
24033         out=$(do_facet $tgt $LR_READER -c $dev)
24034         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
24035         echo "$out"
24036         num=$(echo "$out" | grep -c "mdtlov")
24037         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
24038                 error "Invalid number of mdtlov clients returned by $LR_READER"
24039         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
24040
24041         # check lr_reader -cr on MDT0000
24042         out=$(do_facet $tgt $LR_READER -cr $dev)
24043         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
24044         echo "$out"
24045         echo "$out" | grep -q "^reply_data:$" ||
24046                 error "$LR_READER should have returned 'reply_data' section"
24047         num=$(echo "$out" | grep -c "client_generation")
24048         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
24049 }
24050 run_test 252 "check lr_reader tool"
24051
24052 test_253() {
24053         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24054         remote_mds_nodsh && skip "remote MDS with nodsh"
24055         remote_mgs_nodsh && skip "remote MGS with nodsh"
24056         check_set_fallocate_or_skip
24057
24058         local ostidx=0
24059         local rc=0
24060         local ost_name=$(ostname_from_index $ostidx)
24061
24062         # on the mdt's osc
24063         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
24064         do_facet $SINGLEMDS $LCTL get_param -n \
24065                 osp.$mdtosc_proc1.reserved_mb_high ||
24066                 skip  "remote MDS does not support reserved_mb_high"
24067
24068         rm -rf $DIR/$tdir
24069         wait_mds_ost_sync
24070         wait_delete_completed
24071         mkdir $DIR/$tdir
24072         stack_trap "rm -rf $DIR/$tdir"
24073
24074         pool_add $TESTNAME || error "Pool creation failed"
24075         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
24076
24077         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
24078                 error "Setstripe failed"
24079
24080         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
24081
24082         local wms=$(ost_watermarks_get $ostidx)
24083
24084         ost_watermarks_set $ostidx 60 50
24085         stack_trap "ost_watermarks_set $ostidx $wms"
24086
24087         local free_kb=$($LFS df $MOUNT | awk "/$ost_name/ { print \$4 }")
24088         local size=$((free_kb * 1024))
24089
24090         fallocate -l $size $DIR/$tdir/fill_ost$ostidx ||
24091                 error "fallocate failed"
24092         sleep_maxage
24093
24094         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
24095                         osp.$mdtosc_proc1.prealloc_status)
24096         echo "prealloc_status $oa_status"
24097
24098         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
24099                 error "File creation should fail"
24100
24101         #object allocation was stopped, but we still able to append files
24102         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
24103                 oflag=append || error "Append failed"
24104
24105         rm -f $DIR/$tdir/$tfile.0
24106         rm -f $DIR/$tdir/fill_ost$ostidx
24107
24108         wait_delete_completed
24109         sleep_maxage
24110
24111         for i in $(seq 10 12); do
24112                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
24113                         2>/dev/null || error "File creation failed after rm"
24114         done
24115
24116         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
24117                         osp.$mdtosc_proc1.prealloc_status)
24118         echo "prealloc_status $oa_status"
24119
24120         if (( oa_status != 0 )); then
24121                 error "Object allocation still disable after rm"
24122         fi
24123 }
24124 run_test 253 "Check object allocation limit"
24125
24126 test_254() {
24127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24128         remote_mds_nodsh && skip "remote MDS with nodsh"
24129
24130         local mdt=$(facet_svc $SINGLEMDS)
24131
24132         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
24133                 skip "MDS does not support changelog_size"
24134
24135         local cl_user
24136
24137         changelog_register || error "changelog_register failed"
24138
24139         changelog_clear 0 || error "changelog_clear failed"
24140
24141         local size1=$(do_facet $SINGLEMDS \
24142                       $LCTL get_param -n mdd.$mdt.changelog_size)
24143         echo "Changelog size $size1"
24144
24145         rm -rf $DIR/$tdir
24146         $LFS mkdir -i 0 $DIR/$tdir
24147         # change something
24148         mkdir -p $DIR/$tdir/pics/2008/zachy
24149         touch $DIR/$tdir/pics/2008/zachy/timestamp
24150         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
24151         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
24152         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
24153         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
24154         rm $DIR/$tdir/pics/desktop.jpg
24155
24156         local size2=$(do_facet $SINGLEMDS \
24157                       $LCTL get_param -n mdd.$mdt.changelog_size)
24158         echo "Changelog size after work $size2"
24159
24160         (( $size2 > $size1 )) ||
24161                 error "new Changelog size=$size2 less than old size=$size1"
24162 }
24163 run_test 254 "Check changelog size"
24164
24165 ladvise_no_type()
24166 {
24167         local type=$1
24168         local file=$2
24169
24170         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
24171                 awk -F: '{print $2}' | grep $type > /dev/null
24172         if [ $? -ne 0 ]; then
24173                 return 0
24174         fi
24175         return 1
24176 }
24177
24178 ladvise_no_ioctl()
24179 {
24180         local file=$1
24181
24182         lfs ladvise -a willread $file > /dev/null 2>&1
24183         if [ $? -eq 0 ]; then
24184                 return 1
24185         fi
24186
24187         lfs ladvise -a willread $file 2>&1 |
24188                 grep "Inappropriate ioctl for device" > /dev/null
24189         if [ $? -eq 0 ]; then
24190                 return 0
24191         fi
24192         return 1
24193 }
24194
24195 percent() {
24196         bc <<<"scale=2; ($1 - $2) * 100 / $2"
24197 }
24198
24199 # run a random read IO workload
24200 # usage: random_read_iops <filename> <filesize> <iosize>
24201 random_read_iops() {
24202         local file=$1
24203         local fsize=$2
24204         local iosize=${3:-4096}
24205
24206         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
24207                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
24208 }
24209
24210 drop_file_oss_cache() {
24211         local file="$1"
24212         local nodes="$2"
24213
24214         $LFS ladvise -a dontneed $file 2>/dev/null ||
24215                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
24216 }
24217
24218 ladvise_willread_performance()
24219 {
24220         local repeat=10
24221         local average_origin=0
24222         local average_cache=0
24223         local average_ladvise=0
24224
24225         for ((i = 1; i <= $repeat; i++)); do
24226                 echo "Iter $i/$repeat: reading without willread hint"
24227                 cancel_lru_locks osc
24228                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
24229                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
24230                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
24231                 average_origin=$(bc <<<"$average_origin + $speed_origin")
24232
24233                 cancel_lru_locks osc
24234                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
24235                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
24236                 average_cache=$(bc <<<"$average_cache + $speed_cache")
24237
24238                 cancel_lru_locks osc
24239                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
24240                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
24241                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
24242                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
24243                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
24244         done
24245         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
24246         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
24247         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
24248
24249         speedup_cache=$(percent $average_cache $average_origin)
24250         speedup_ladvise=$(percent $average_ladvise $average_origin)
24251
24252         echo "Average uncached read: $average_origin"
24253         echo "Average speedup with OSS cached read:" \
24254                 "$average_cache = +$speedup_cache%"
24255         echo "Average speedup with ladvise willread:" \
24256                 "$average_ladvise = +$speedup_ladvise%"
24257
24258         local lowest_speedup=20
24259         if (( ${speedup_cache%.*} < $lowest_speedup )); then
24260                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
24261                      "got $speedup_cache%. Skipping ladvise willread check."
24262                 return 0
24263         fi
24264
24265         # the test won't work on ZFS until it supports 'ladvise dontneed', but
24266         # it is still good to run until then to exercise 'ladvise willread'
24267         ! $LFS ladvise -a dontneed $DIR/$tfile &&
24268                 [ "$ost1_FSTYPE" = "zfs" ] &&
24269                 echo "osd-zfs does not support dontneed or drop_caches" &&
24270                 return 0
24271
24272         lowest_speedup=$(bc <<<"scale=2; $speedup_cache / 2")
24273         (( ${speedup_ladvise%.*} > ${lowest_speedup%.*} )) ||
24274                 error_not_in_vm "Speedup with willread is less than " \
24275                         "$lowest_speedup%, got $speedup_ladvise%"
24276 }
24277
24278 test_255a() {
24279         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
24280                 skip "lustre < 2.8.54 does not support ladvise "
24281         remote_ost_nodsh && skip "remote OST with nodsh"
24282
24283         stack_trap "rm -f $DIR/$tfile"
24284         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
24285
24286         ladvise_no_type willread $DIR/$tfile &&
24287                 skip "willread ladvise is not supported"
24288
24289         ladvise_no_ioctl $DIR/$tfile &&
24290                 skip "ladvise ioctl is not supported"
24291
24292         local size_mb=100
24293         local size=$((size_mb * 1048576))
24294         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
24295                 error "dd to $DIR/$tfile failed"
24296
24297         lfs ladvise -a willread $DIR/$tfile ||
24298                 error "Ladvise failed with no range argument"
24299
24300         lfs ladvise -a willread -s 0 $DIR/$tfile ||
24301                 error "Ladvise failed with no -l or -e argument"
24302
24303         lfs ladvise -a willread -e 1 $DIR/$tfile ||
24304                 error "Ladvise failed with only -e argument"
24305
24306         lfs ladvise -a willread -l 1 $DIR/$tfile ||
24307                 error "Ladvise failed with only -l argument"
24308
24309         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
24310                 error "End offset should not be smaller than start offset"
24311
24312         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
24313                 error "End offset should not be equal to start offset"
24314
24315         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
24316                 error "Ladvise failed with overflowing -s argument"
24317
24318         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
24319                 error "Ladvise failed with overflowing -e argument"
24320
24321         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
24322                 error "Ladvise failed with overflowing -l argument"
24323
24324         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
24325                 error "Ladvise succeeded with conflicting -l and -e arguments"
24326
24327         echo "Synchronous ladvise should wait"
24328         local delay=8
24329 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
24330         do_nodes $(comma_list $(osts_nodes)) \
24331                 $LCTL set_param fail_val=$delay fail_loc=0x237
24332         stack_trap "do_nodes $(comma_list $(osts_nodes)) \
24333                 $LCTL set_param fail_loc=0"
24334
24335         local start_ts=$SECONDS
24336         lfs ladvise -a willread $DIR/$tfile ||
24337                 error "Ladvise failed with no range argument"
24338         local end_ts=$SECONDS
24339         local inteval_ts=$((end_ts - start_ts))
24340
24341         if [ $inteval_ts -lt $(($delay - 1)) ]; then
24342                 error "Synchronous advice didn't wait reply"
24343         fi
24344
24345         echo "Asynchronous ladvise shouldn't wait"
24346         local start_ts=$SECONDS
24347         lfs ladvise -a willread -b $DIR/$tfile ||
24348                 error "Ladvise failed with no range argument"
24349         local end_ts=$SECONDS
24350         local inteval_ts=$((end_ts - start_ts))
24351
24352         if [ $inteval_ts -gt $(($delay / 2)) ]; then
24353                 error "Asynchronous advice blocked"
24354         fi
24355
24356         ladvise_willread_performance
24357 }
24358 run_test 255a "check 'lfs ladvise -a willread'"
24359
24360 facet_meminfo() {
24361         local facet=$1
24362         local info=$2
24363
24364         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
24365 }
24366
24367 test_255b() {
24368         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
24369                 skip "lustre < 2.8.54 does not support ladvise "
24370         remote_ost_nodsh && skip "remote OST with nodsh"
24371
24372         stack_trap "rm -f $DIR/$tfile"
24373         lfs setstripe -c 1 -i 0 $DIR/$tfile
24374
24375         ladvise_no_type dontneed $DIR/$tfile &&
24376                 skip "dontneed ladvise is not supported"
24377
24378         ladvise_no_ioctl $DIR/$tfile &&
24379                 skip "ladvise ioctl is not supported"
24380
24381         ! $LFS ladvise -a dontneed $DIR/$tfile &&
24382                 [ "$ost1_FSTYPE" = "zfs" ] &&
24383                 skip "zfs-osd does not support 'ladvise dontneed'"
24384
24385         local size_mb=100
24386         local size=$((size_mb * 1048576))
24387         # In order to prevent disturbance of other processes, only check 3/4
24388         # of the memory usage
24389         local kibibytes=$((size_mb * 1024 * 3 / 4))
24390
24391         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
24392                 error "dd to $DIR/$tfile failed"
24393
24394         #force write to complete before dropping OST cache & checking memory
24395         sync
24396
24397         local total=$(facet_meminfo ost1 MemTotal)
24398         echo "Total memory: $total KiB"
24399
24400         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
24401         local before_read=$(facet_meminfo ost1 Cached)
24402         echo "Cache used before read: $before_read KiB"
24403
24404         lfs ladvise -a willread $DIR/$tfile ||
24405                 error "Ladvise willread failed"
24406         local after_read=$(facet_meminfo ost1 Cached)
24407         echo "Cache used after read: $after_read KiB"
24408
24409         lfs ladvise -a dontneed $DIR/$tfile ||
24410                 error "Ladvise dontneed again failed"
24411         local no_read=$(facet_meminfo ost1 Cached)
24412         echo "Cache used after dontneed ladvise: $no_read KiB"
24413
24414         if [ $total -lt $((before_read + kibibytes)) ]; then
24415                 echo "Memory is too small, abort checking"
24416                 return 0
24417         fi
24418
24419         if [ $((before_read + kibibytes)) -gt $after_read ]; then
24420                 error "Ladvise willread should use more memory" \
24421                         "than $kibibytes KiB"
24422         fi
24423
24424         if [ $((no_read + kibibytes)) -gt $after_read ]; then
24425                 error "Ladvise dontneed should release more memory" \
24426                         "than $kibibytes KiB"
24427         fi
24428 }
24429 run_test 255b "check 'lfs ladvise -a dontneed'"
24430
24431 test_255c() {
24432         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
24433                 skip "lustre < 2.10.50 does not support lockahead"
24434
24435         local ost1_imp=$(get_osc_import_name client ost1)
24436         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24437                          cut -d'.' -f2)
24438         local count
24439         local new_count
24440         local difference
24441         local i
24442         local rc
24443
24444         test_mkdir -p $DIR/$tdir
24445         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24446
24447         #test 10 returns only success/failure
24448         i=10
24449         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24450         rc=$?
24451         if [ $rc -eq 255 ]; then
24452                 error "Ladvise test${i} failed, ${rc}"
24453         fi
24454
24455         #test 11 counts lock enqueue requests, all others count new locks
24456         i=11
24457         count=$(do_facet ost1 \
24458                 $LCTL get_param -n ost.OSS.ost.stats)
24459         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
24460
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         new_count=$(do_facet ost1 \
24468                 $LCTL get_param -n ost.OSS.ost.stats)
24469         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
24470                    awk '{ print $2 }')
24471
24472         difference="$((new_count - count))"
24473         if [ $difference -ne $rc ]; then
24474                 error "Ladvise test${i}, bad enqueue count, returned " \
24475                       "${rc}, actual ${difference}"
24476         fi
24477
24478         for i in $(seq 12 21); do
24479                 # If we do not do this, we run the risk of having too many
24480                 # locks and starting lock cancellation while we are checking
24481                 # lock counts.
24482                 cancel_lru_locks osc
24483
24484                 count=$($LCTL get_param -n \
24485                        ldlm.namespaces.$imp_name.lock_unused_count)
24486
24487                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
24488                 rc=$?
24489                 if [ $rc -eq 255 ]; then
24490                         error "Ladvise test ${i} failed, ${rc}"
24491                 fi
24492
24493                 new_count=$($LCTL get_param -n \
24494                        ldlm.namespaces.$imp_name.lock_unused_count)
24495                 difference="$((new_count - count))"
24496
24497                 # Test 15 output is divided by 100 to map down to valid return
24498                 if [ $i -eq 15 ]; then
24499                         rc="$((rc * 100))"
24500                 fi
24501
24502                 if [ $difference -ne $rc ]; then
24503                         error "Ladvise test ${i}, bad lock count, returned " \
24504                               "${rc}, actual ${difference}"
24505                 fi
24506         done
24507
24508         #test 22 returns only success/failure
24509         i=22
24510         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24511         rc=$?
24512         if [ $rc -eq 255 ]; then
24513                 error "Ladvise test${i} failed, ${rc}"
24514         fi
24515 }
24516 run_test 255c "suite of ladvise lockahead tests"
24517
24518 test_256() {
24519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24520         remote_mds_nodsh && skip "remote MDS with nodsh"
24521         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
24522         changelog_users $SINGLEMDS | grep "^cl" &&
24523                 skip "active changelog user"
24524
24525         local cl_user
24526         local cat_sl
24527         local mdt_dev
24528
24529         mdt_dev=$(facet_device $SINGLEMDS)
24530         echo $mdt_dev
24531
24532         changelog_register || error "changelog_register failed"
24533
24534         rm -rf $DIR/$tdir
24535         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
24536
24537         changelog_clear 0 || error "changelog_clear failed"
24538
24539         # change something
24540         touch $DIR/$tdir/{1..10}
24541
24542         # stop the MDT
24543         stop $SINGLEMDS || error "Fail to stop MDT"
24544
24545         # remount the MDT
24546         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
24547                 error "Fail to start MDT"
24548
24549         #after mount new plainllog is used
24550         touch $DIR/$tdir/{11..19}
24551         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
24552         stack_trap "rm -f $tmpfile"
24553         cat_sl=$(do_facet $SINGLEMDS "sync; \
24554                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24555                  llog_reader $tmpfile | grep -c type=1064553b")
24556         do_facet $SINGLEMDS llog_reader $tmpfile
24557
24558         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
24559
24560         changelog_clear 0 || error "changelog_clear failed"
24561
24562         cat_sl=$(do_facet $SINGLEMDS "sync; \
24563                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24564                  llog_reader $tmpfile | grep -c type=1064553b")
24565
24566         if (( cat_sl == 2 )); then
24567                 error "Empty plain llog was not deleted from changelog catalog"
24568         elif (( cat_sl != 1 )); then
24569                 error "Active plain llog shouldn't be deleted from catalog"
24570         fi
24571 }
24572 run_test 256 "Check llog delete for empty and not full state"
24573
24574 test_257() {
24575         remote_mds_nodsh && skip "remote MDS with nodsh"
24576         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
24577                 skip "Need MDS version at least 2.8.55"
24578
24579         test_mkdir $DIR/$tdir
24580
24581         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
24582                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
24583         stat $DIR/$tdir
24584
24585 #define OBD_FAIL_MDS_XATTR_REP                  0x161
24586         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
24587         local facet=mds$((mdtidx + 1))
24588         set_nodes_failloc $(facet_active_host $facet) 0x80000161
24589         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
24590
24591         stop $facet || error "stop MDS failed"
24592         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
24593                 error "start MDS fail"
24594         wait_recovery_complete $facet
24595 }
24596 run_test 257 "xattr locks are not lost"
24597
24598 # Verify we take the i_mutex when security requires it
24599 test_258a() {
24600 #define OBD_FAIL_IMUTEX_SEC 0x141c
24601         $LCTL set_param fail_loc=0x141c
24602         touch $DIR/$tfile
24603         chmod u+s $DIR/$tfile
24604         chmod a+rwx $DIR/$tfile
24605         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24606         RC=$?
24607         if [ $RC -ne 0 ]; then
24608                 error "error, failed to take i_mutex, rc=$?"
24609         fi
24610         rm -f $DIR/$tfile
24611 }
24612 run_test 258a "verify i_mutex security behavior when suid attributes is set"
24613
24614 # Verify we do NOT take the i_mutex in the normal case
24615 test_258b() {
24616 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
24617         $LCTL set_param fail_loc=0x141d
24618         touch $DIR/$tfile
24619         chmod a+rwx $DIR
24620         chmod a+rw $DIR/$tfile
24621         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24622         RC=$?
24623         if [ $RC -ne 0 ]; then
24624                 error "error, took i_mutex unnecessarily, rc=$?"
24625         fi
24626         rm -f $DIR/$tfile
24627
24628 }
24629 run_test 258b "verify i_mutex security behavior"
24630
24631 test_259() {
24632         local file=$DIR/$tfile
24633         local before
24634         local after
24635
24636         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
24637
24638         stack_trap "rm -f $file" EXIT
24639
24640         wait_delete_completed
24641         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24642         echo "before: $before"
24643
24644         $LFS setstripe -i 0 -c 1 $file
24645         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
24646         sync_all_data
24647         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24648         echo "after write: $after"
24649
24650 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
24651         do_facet ost1 $LCTL set_param fail_loc=0x2301
24652         $TRUNCATE $file 0
24653         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24654         echo "after truncate: $after"
24655
24656         stop ost1
24657         do_facet ost1 $LCTL set_param fail_loc=0
24658         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
24659         sleep 2
24660         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24661         echo "after restart: $after"
24662         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
24663                 error "missing truncate?"
24664
24665         return 0
24666 }
24667 run_test 259 "crash at delayed truncate"
24668
24669 test_260() {
24670 #define OBD_FAIL_MDC_CLOSE               0x806
24671         $LCTL set_param fail_loc=0x80000806
24672         touch $DIR/$tfile
24673
24674 }
24675 run_test 260 "Check mdc_close fail"
24676
24677 ### Data-on-MDT sanity tests ###
24678 test_270a() {
24679         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24680                 skip "Need MDS version at least 2.10.55 for DoM"
24681
24682         # create DoM file
24683         local dom=$DIR/$tdir/dom_file
24684         local tmp=$DIR/$tdir/tmp_file
24685
24686         mkdir_on_mdt0 $DIR/$tdir
24687
24688         # basic checks for DoM component creation
24689         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
24690                 error "Can set MDT layout to non-first entry"
24691
24692         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
24693                 error "Can define multiple entries as MDT layout"
24694
24695         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
24696
24697         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
24698         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
24699         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
24700
24701         local mdtidx=$($LFS getstripe -m $dom)
24702         local mdtname=MDT$(printf %04x $mdtidx)
24703         local facet=mds$((mdtidx + 1))
24704         local space_check=1
24705
24706         # Skip free space checks with ZFS
24707         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
24708
24709         # write
24710         sync
24711         local size_tmp=$((65536 * 3))
24712         local mdtfree1=$(do_facet $facet \
24713                          lctl get_param -n osd*.*$mdtname.kbytesfree)
24714
24715         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24716         # check also direct IO along write
24717         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
24718         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24719         sync
24720         cmp $tmp $dom || error "file data is different"
24721         [ $(stat -c%s $dom) == $size_tmp ] ||
24722                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24723         if [ $space_check == 1 ]; then
24724                 local mdtfree2=$(do_facet $facet \
24725                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
24726
24727                 # increase in usage from by $size_tmp
24728                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24729                         error "MDT free space wrong after write: " \
24730                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24731         fi
24732
24733         # truncate
24734         local size_dom=10000
24735
24736         $TRUNCATE $dom $size_dom
24737         [ $(stat -c%s $dom) == $size_dom ] ||
24738                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
24739         if [ $space_check == 1 ]; then
24740                 mdtfree1=$(do_facet $facet \
24741                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24742                 # decrease in usage from $size_tmp to new $size_dom
24743                 [ $(($mdtfree1 - $mdtfree2)) -ge \
24744                   $(((size_tmp - size_dom) / 1024)) ] ||
24745                         error "MDT free space is wrong after truncate: " \
24746                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
24747         fi
24748
24749         # append
24750         cat $tmp >> $dom
24751         sync
24752         size_dom=$((size_dom + size_tmp))
24753         [ $(stat -c%s $dom) == $size_dom ] ||
24754                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
24755         if [ $space_check == 1 ]; then
24756                 mdtfree2=$(do_facet $facet \
24757                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24758                 # increase in usage by $size_tmp from previous
24759                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24760                         error "MDT free space is wrong after append: " \
24761                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24762         fi
24763
24764         # delete
24765         rm $dom
24766         if [ $space_check == 1 ]; then
24767                 mdtfree1=$(do_facet $facet \
24768                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24769                 # decrease in usage by $size_dom from previous
24770                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
24771                         error "MDT free space is wrong after removal: " \
24772                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
24773         fi
24774
24775         # combined striping
24776         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
24777                 error "Can't create DoM + OST striping"
24778
24779         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
24780         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24781         # check also direct IO along write
24782         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24783         sync
24784         cmp $tmp $dom || error "file data is different"
24785         [ $(stat -c%s $dom) == $size_tmp ] ||
24786                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24787         rm $dom $tmp
24788
24789         return 0
24790 }
24791 run_test 270a "DoM: basic functionality tests"
24792
24793 test_270b() {
24794         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24795                 skip "Need MDS version at least 2.10.55"
24796
24797         local dom=$DIR/$tdir/dom_file
24798         local max_size=1048576
24799
24800         mkdir -p $DIR/$tdir
24801         $LFS setstripe -E $max_size -L mdt $dom
24802
24803         # truncate over the limit
24804         $TRUNCATE $dom $(($max_size + 1)) &&
24805                 error "successful truncate over the maximum size"
24806         # write over the limit
24807         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
24808                 error "successful write over the maximum size"
24809         # append over the limit
24810         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
24811         echo "12345" >> $dom && error "successful append over the maximum size"
24812         rm $dom
24813
24814         return 0
24815 }
24816 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
24817
24818 test_270c() {
24819         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24820                 skip "Need MDS version at least 2.10.55"
24821
24822         mkdir -p $DIR/$tdir
24823         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24824
24825         # check files inherit DoM EA
24826         touch $DIR/$tdir/first
24827         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
24828                 error "bad pattern"
24829         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
24830                 error "bad stripe count"
24831         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
24832                 error "bad stripe size"
24833
24834         # check directory inherits DoM EA and uses it as default
24835         mkdir $DIR/$tdir/subdir
24836         touch $DIR/$tdir/subdir/second
24837         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
24838                 error "bad pattern in sub-directory"
24839         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
24840                 error "bad stripe count in sub-directory"
24841         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
24842                 error "bad stripe size in sub-directory"
24843         return 0
24844 }
24845 run_test 270c "DoM: DoM EA inheritance tests"
24846
24847 test_270d() {
24848         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24849                 skip "Need MDS version at least 2.10.55"
24850
24851         mkdir -p $DIR/$tdir
24852         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24853
24854         # inherit default DoM striping
24855         mkdir $DIR/$tdir/subdir
24856         touch $DIR/$tdir/subdir/f1
24857
24858         # change default directory striping
24859         $LFS setstripe -c 1 $DIR/$tdir/subdir
24860         touch $DIR/$tdir/subdir/f2
24861         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
24862                 error "wrong default striping in file 2"
24863         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
24864                 error "bad pattern in file 2"
24865         return 0
24866 }
24867 run_test 270d "DoM: change striping from DoM to RAID0"
24868
24869 test_270e() {
24870         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24871                 skip "Need MDS version at least 2.10.55"
24872
24873         mkdir -p $DIR/$tdir/dom
24874         mkdir -p $DIR/$tdir/norm
24875         DOMFILES=20
24876         NORMFILES=10
24877         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
24878         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
24879
24880         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
24881         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
24882
24883         # find DoM files by layout
24884         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
24885         [ $NUM -eq  $DOMFILES ] ||
24886                 error "lfs find -L: found $NUM, expected $DOMFILES"
24887         echo "Test 1: lfs find 20 DOM files by layout: OK"
24888
24889         # there should be 1 dir with default DOM striping
24890         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
24891         [ $NUM -eq  1 ] ||
24892                 error "lfs find -L: found $NUM, expected 1 dir"
24893         echo "Test 2: lfs find 1 DOM dir by layout: OK"
24894
24895         # find DoM files by stripe size
24896         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
24897         [ $NUM -eq  $DOMFILES ] ||
24898                 error "lfs find -S: found $NUM, expected $DOMFILES"
24899         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
24900
24901         # find files by stripe offset except DoM files
24902         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
24903         [ $NUM -eq  $NORMFILES ] ||
24904                 error "lfs find -i: found $NUM, expected $NORMFILES"
24905         echo "Test 5: lfs find no DOM files by stripe index: OK"
24906         return 0
24907 }
24908 run_test 270e "DoM: lfs find with DoM files test"
24909
24910 test_270f() {
24911         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24912                 skip "Need MDS version at least 2.10.55"
24913
24914         local mdtname=${FSNAME}-MDT0000-mdtlov
24915         local dom=$DIR/$tdir/dom_file
24916         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
24917                                                 lod.$mdtname.dom_stripesize)
24918         local dom_limit=131072
24919
24920         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
24921         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24922                                                 lod.$mdtname.dom_stripesize)
24923         [ ${dom_limit} -eq ${dom_current} ] ||
24924                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
24925
24926         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24927         $LFS setstripe -d $DIR/$tdir
24928         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
24929                 error "Can't set directory default striping"
24930
24931         # exceed maximum stripe size
24932         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24933                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
24934         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
24935                 error "Able to create DoM component size more than LOD limit"
24936
24937         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24938         dom_current=$(do_facet mds1 $LCTL get_param -n \
24939                                                 lod.$mdtname.dom_stripesize)
24940         [ 0 -eq ${dom_current} ] ||
24941                 error "Can't set zero DoM stripe limit"
24942         rm $dom
24943
24944         # attempt to create DoM file on server with disabled DoM should
24945         # remove DoM entry from layout and be succeed
24946         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
24947                 error "Can't create DoM file (DoM is disabled)"
24948         [ $($LFS getstripe -L $dom) == "mdt" ] &&
24949                 error "File has DoM component while DoM is disabled"
24950         rm $dom
24951
24952         # attempt to create DoM file with only DoM stripe should return error
24953         $LFS setstripe -E $dom_limit -L mdt $dom &&
24954                 error "Able to create DoM-only file while DoM is disabled"
24955
24956         # too low values to be aligned with smallest stripe size 64K
24957         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
24958         dom_current=$(do_facet mds1 $LCTL get_param -n \
24959                                                 lod.$mdtname.dom_stripesize)
24960         [ 30000 -eq ${dom_current} ] &&
24961                 error "Can set too small DoM stripe limit"
24962
24963         # 64K is a minimal stripe size in Lustre, expect limit of that size
24964         [ 65536 -eq ${dom_current} ] ||
24965                 error "Limit is not set to 64K but ${dom_current}"
24966
24967         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
24968         dom_current=$(do_facet mds1 $LCTL get_param -n \
24969                                                 lod.$mdtname.dom_stripesize)
24970         echo $dom_current
24971         [ 2147483648 -eq ${dom_current} ] &&
24972                 error "Can set too large DoM stripe limit"
24973
24974         do_facet mds1 $LCTL set_param -n \
24975                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
24976         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24977                 error "Can't create DoM component size after limit change"
24978         do_facet mds1 $LCTL set_param -n \
24979                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
24980         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
24981                 error "Can't create DoM file after limit decrease"
24982         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
24983                 error "Can create big DoM component after limit decrease"
24984         touch ${dom}_def ||
24985                 error "Can't create file with old default layout"
24986
24987         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
24988         return 0
24989 }
24990 run_test 270f "DoM: maximum DoM stripe size checks"
24991
24992 test_270g() {
24993         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
24994                 skip "Need MDS version at least 2.13.52"
24995         local dom=$DIR/$tdir/$tfile
24996
24997         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24998         local lodname=${FSNAME}-MDT0000-mdtlov
24999
25000         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25001         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
25002         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
25003         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25004
25005         local dom_limit=1024
25006         local dom_threshold="50%"
25007
25008         $LFS setstripe -d $DIR/$tdir
25009         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
25010                 error "Can't set directory default striping"
25011
25012         do_facet mds1 $LCTL set_param -n \
25013                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
25014         # set 0 threshold and create DOM file to change tunable stripesize
25015         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
25016         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
25017                 error "Failed to create $dom file"
25018         # now tunable dom_cur_stripesize should reach maximum
25019         local dom_current=$(do_facet mds1 $LCTL get_param -n \
25020                                         lod.${lodname}.dom_stripesize_cur_kb)
25021         [[ $dom_current == $dom_limit ]] ||
25022                 error "Current DOM stripesize is not maximum"
25023         rm $dom
25024
25025         # set threshold for further tests
25026         do_facet mds1 $LCTL set_param -n \
25027                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
25028         echo "DOM threshold is $dom_threshold free space"
25029         local dom_def
25030         local dom_set
25031         # Spoof bfree to exceed threshold
25032         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
25033         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
25034         for spfree in 40 20 0 15 30 55; do
25035                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
25036                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
25037                         error "Failed to create $dom file"
25038                 dom_def=$(do_facet mds1 $LCTL get_param -n \
25039                                         lod.${lodname}.dom_stripesize_cur_kb)
25040                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
25041                 [[ $dom_def != $dom_current ]] ||
25042                         error "Default stripe size was not changed"
25043                 if (( spfree > 0 )) ; then
25044                         dom_set=$($LFS getstripe -S $dom)
25045                         (( dom_set == dom_def * 1024 )) ||
25046                                 error "DOM component size is still old"
25047                 else
25048                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
25049                                 error "DoM component is set with no free space"
25050                 fi
25051                 rm $dom
25052                 dom_current=$dom_def
25053         done
25054 }
25055 run_test 270g "DoM: default DoM stripe size depends on free space"
25056
25057 test_270h() {
25058         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
25059                 skip "Need MDS version at least 2.13.53"
25060
25061         local mdtname=${FSNAME}-MDT0000-mdtlov
25062         local dom=$DIR/$tdir/$tfile
25063         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25064
25065         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
25066         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25067
25068         $LFS mkdir -i 0 -c 1 $DIR/$tdir
25069         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
25070                 error "can't create OST file"
25071         # mirrored file with DOM entry in the second mirror
25072         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
25073                 error "can't create mirror with DoM component"
25074
25075         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
25076
25077         # DOM component in the middle and has other enries in the same mirror,
25078         # should succeed but lost DoM component
25079         $LFS setstripe --copy=${dom}_1 $dom ||
25080                 error "Can't create file from OST|DOM mirror layout"
25081         # check new file has no DoM layout after all
25082         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
25083                 error "File has DoM component while DoM is disabled"
25084 }
25085 run_test 270h "DoM: DoM stripe removal when disabled on server"
25086
25087 test_270i() {
25088         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
25089                 skip "Need MDS version at least 2.14.54"
25090
25091         mkdir $DIR/$tdir
25092         # DoM with plain layout
25093         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
25094                 error "default plain layout with DoM must fail"
25095         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
25096                 error "setstripe plain file layout with DoM must fail"
25097         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
25098                 error "default DoM layout with bad striping must fail"
25099         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
25100                 error "setstripe to DoM layout with bad striping must fail"
25101         return 0
25102 }
25103 run_test 270i "DoM: setting invalid DoM striping should fail"
25104
25105 test_270j() {
25106         (( $MDS1_VERSION >= $(version_code 2.15.55.203) )) ||
25107                 skip "Need MDS version at least 2.15.55.203"
25108
25109         local dom=$DIR/$tdir/$tfile
25110         local odv
25111         local ndv
25112
25113         mkdir -p $DIR/$tdir
25114
25115         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25116
25117         odv=$($LFS data_version $dom)
25118         chmod 666 $dom
25119         mv $dom ${dom}_moved
25120         link ${dom}_moved $dom
25121         setfattr -n user.attrx -v "some_attr" $dom
25122         ndv=$($LFS data_version $dom)
25123         (( $ndv == $odv )) ||
25124                 error "data version was changed by metadata operations"
25125
25126         dd if=/dev/urandom of=$dom bs=1M count=1 ||
25127                 error "failed to write data into $dom"
25128         cancel_lru_locks mdc
25129         ndv=$($LFS data_version $dom)
25130         (( $ndv != $odv )) ||
25131                 error "data version wasn't changed on write"
25132
25133         odv=$ndv
25134         $TRUNCATE $dom 1000 || error "failed to truncate $dom"
25135         ndv=$($LFS data_version $dom)
25136         (( $ndv != $odv )) ||
25137                 error "data version wasn't changed on truncate down"
25138
25139         odv=$ndv
25140         $TRUNCATE $dom 25000
25141         ndv=$($LFS data_version $dom)
25142         (( $ndv != $odv )) ||
25143                 error "data version wasn't changed on truncate up"
25144
25145         # check also fallocate for ldiskfs
25146         if [[ "$mds1_FSTYPE" == ldiskfs ]]; then
25147                 odv=$ndv
25148                 fallocate -l 1048576 $dom
25149                 ndv=$($LFS data_version $dom)
25150                 (( $ndv != $odv )) ||
25151                         error "data version wasn't changed on fallocate"
25152
25153                 odv=$ndv
25154                 fallocate -p --offset 4096 -l 4096 $dom
25155                 ndv=$($LFS data_version $dom)
25156                 (( $ndv != $odv )) ||
25157                         error "data version wasn't changed on fallocate punch"
25158         fi
25159 }
25160 run_test 270j "DoM migration: DOM file to the OST-striped file (plain)"
25161
25162 test_271a() {
25163         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25164                 skip "Need MDS version at least 2.10.55"
25165
25166         local dom=$DIR/$tdir/dom
25167
25168         mkdir -p $DIR/$tdir
25169
25170         $LFS setstripe -E 1024K -L mdt $dom
25171
25172         lctl set_param -n mdc.*.stats=clear
25173         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
25174         cat $dom > /dev/null
25175         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
25176         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
25177         ls $dom
25178         rm -f $dom
25179 }
25180 run_test 271a "DoM: data is cached for read after write"
25181
25182 test_271b() {
25183         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25184                 skip "Need MDS version at least 2.10.55"
25185
25186         local dom=$DIR/$tdir/dom
25187
25188         mkdir -p $DIR/$tdir
25189
25190         $LFS setstripe -E 1024K -L mdt -E EOF $dom
25191
25192         lctl set_param -n mdc.*.stats=clear
25193         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
25194         cancel_lru_locks mdc
25195         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
25196         # second stat to check size is cached on client
25197         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
25198         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
25199         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
25200         rm -f $dom
25201 }
25202 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
25203
25204 test_271ba() {
25205         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25206                 skip "Need MDS version at least 2.10.55"
25207
25208         local dom=$DIR/$tdir/dom
25209
25210         mkdir -p $DIR/$tdir
25211
25212         $LFS setstripe -E 1024K -L mdt -E EOF $dom
25213
25214         lctl set_param -n mdc.*.stats=clear
25215         lctl set_param -n osc.*.stats=clear
25216         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
25217         cancel_lru_locks mdc
25218         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
25219         # second stat to check size is cached on client
25220         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
25221         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
25222         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
25223         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
25224         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
25225         rm -f $dom
25226 }
25227 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
25228
25229
25230 get_mdc_stats() {
25231         local mdtidx=$1
25232         local param=$2
25233         local mdt=MDT$(printf %04x $mdtidx)
25234
25235         if [ -z $param ]; then
25236                 lctl get_param -n mdc.*$mdt*.stats
25237         else
25238                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
25239         fi
25240 }
25241
25242 test_271c() {
25243         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25244                 skip "Need MDS version at least 2.10.55"
25245
25246         local dom=$DIR/$tdir/dom
25247
25248         mkdir -p $DIR/$tdir
25249
25250         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25251
25252         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
25253         local facet=mds$((mdtidx + 1))
25254
25255         cancel_lru_locks mdc
25256         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
25257         createmany -o $dom 1000
25258         lctl set_param -n mdc.*.stats=clear
25259         smalliomany -w $dom 1000 200
25260         get_mdc_stats $mdtidx
25261         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
25262         # Each file has 1 open, 1 IO enqueues, total 2000
25263         # but now we have also +1 getxattr for security.capability, total 3000
25264         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
25265         unlinkmany $dom 1000
25266
25267         cancel_lru_locks mdc
25268         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
25269         createmany -o $dom 1000
25270         lctl set_param -n mdc.*.stats=clear
25271         smalliomany -w $dom 1000 200
25272         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
25273         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
25274         # for OPEN and IO lock.
25275         [ $((enq - enq_2)) -ge 1000 ] ||
25276                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
25277         unlinkmany $dom 1000
25278         return 0
25279 }
25280 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
25281
25282 cleanup_271def_tests() {
25283         trap 0
25284         rm -f $1
25285 }
25286
25287 test_271d() {
25288         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
25289                 skip "Need MDS version at least 2.10.57"
25290
25291         local dom=$DIR/$tdir/dom
25292         local tmp=$TMP/$tfile
25293         trap "cleanup_271def_tests $tmp" EXIT
25294
25295         mkdir -p $DIR/$tdir
25296
25297         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25298
25299         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
25300
25301         cancel_lru_locks mdc
25302         dd if=/dev/urandom of=$tmp bs=1000 count=1
25303         dd if=$tmp of=$dom bs=1000 count=1
25304         cancel_lru_locks mdc
25305
25306         cat /etc/hosts >> $tmp
25307         lctl set_param -n mdc.*.stats=clear
25308
25309         # append data to the same file it should update local page
25310         echo "Append to the same page"
25311         cat /etc/hosts >> $dom
25312         local num=$(get_mdc_stats $mdtidx ost_read)
25313         local ra=$(get_mdc_stats $mdtidx req_active)
25314         local rw=$(get_mdc_stats $mdtidx req_waittime)
25315
25316         [ -z $num ] || error "$num READ RPC occured"
25317         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25318         echo "... DONE"
25319
25320         # compare content
25321         cmp $tmp $dom || error "file miscompare"
25322
25323         cancel_lru_locks mdc
25324         lctl set_param -n mdc.*.stats=clear
25325
25326         echo "Open and read file"
25327         cat $dom > /dev/null
25328         local num=$(get_mdc_stats $mdtidx ost_read)
25329         local ra=$(get_mdc_stats $mdtidx req_active)
25330         local rw=$(get_mdc_stats $mdtidx req_waittime)
25331
25332         [ -z $num ] || error "$num READ RPC occured"
25333         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25334         echo "... DONE"
25335
25336         # compare content
25337         cmp $tmp $dom || error "file miscompare"
25338
25339         return 0
25340 }
25341 run_test 271d "DoM: read on open (1K file in reply buffer)"
25342
25343 test_271f() {
25344         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
25345                 skip "Need MDS version at least 2.10.57"
25346
25347         local dom=$DIR/$tdir/dom
25348         local tmp=$TMP/$tfile
25349         trap "cleanup_271def_tests $tmp" EXIT
25350
25351         mkdir -p $DIR/$tdir
25352
25353         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25354
25355         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
25356
25357         cancel_lru_locks mdc
25358         dd if=/dev/urandom of=$tmp bs=265000 count=1
25359         dd if=$tmp of=$dom bs=265000 count=1
25360         cancel_lru_locks mdc
25361         cat /etc/hosts >> $tmp
25362         lctl set_param -n mdc.*.stats=clear
25363
25364         echo "Append to the same page"
25365         cat /etc/hosts >> $dom
25366         local num=$(get_mdc_stats $mdtidx ost_read)
25367         local ra=$(get_mdc_stats $mdtidx req_active)
25368         local rw=$(get_mdc_stats $mdtidx req_waittime)
25369
25370         [ -z $num ] || error "$num READ RPC occured"
25371         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25372         echo "... DONE"
25373
25374         # compare content
25375         cmp $tmp $dom || error "file miscompare"
25376
25377         cancel_lru_locks mdc
25378         lctl set_param -n mdc.*.stats=clear
25379
25380         echo "Open and read file"
25381         cat $dom > /dev/null
25382         local num=$(get_mdc_stats $mdtidx ost_read)
25383         local ra=$(get_mdc_stats $mdtidx req_active)
25384         local rw=$(get_mdc_stats $mdtidx req_waittime)
25385
25386         [ -z $num ] && num=0
25387         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
25388         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25389         echo "... DONE"
25390
25391         # compare content
25392         cmp $tmp $dom || error "file miscompare"
25393
25394         return 0
25395 }
25396 run_test 271f "DoM: read on open (200K file and read tail)"
25397
25398 test_271g() {
25399         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
25400                 skip "Skipping due to old client or server version"
25401
25402         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
25403         # to get layout
25404         $CHECKSTAT -t file $DIR1/$tfile
25405
25406         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
25407         MULTIOP_PID=$!
25408         sleep 1
25409         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
25410         $LCTL set_param fail_loc=0x80000314
25411         rm $DIR1/$tfile || error "Unlink fails"
25412         RC=$?
25413         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
25414         [ $RC -eq 0 ] || error "Failed write to stale object"
25415 }
25416 run_test 271g "Discard DoM data vs client flush race"
25417
25418 test_272a() {
25419         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25420                 skip "Need MDS version at least 2.11.50"
25421
25422         local dom=$DIR/$tdir/dom
25423         mkdir -p $DIR/$tdir
25424
25425         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
25426         dd if=/dev/urandom of=$dom bs=512K count=1 ||
25427                 error "failed to write data into $dom"
25428         local old_md5=$(md5sum $dom)
25429
25430         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
25431                 error "failed to migrate to the same DoM component"
25432
25433         local new_md5=$(md5sum $dom)
25434
25435         [ "$old_md5" == "$new_md5" ] ||
25436                 error "md5sum differ: $old_md5, $new_md5"
25437
25438         [ $($LFS getstripe -c $dom) -eq 2 ] ||
25439                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
25440 }
25441 run_test 272a "DoM migration: new layout with the same DOM component"
25442
25443 test_272b() {
25444         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25445                 skip "Need MDS version at least 2.11.50"
25446
25447         local dom=$DIR/$tdir/dom
25448         mkdir -p $DIR/$tdir
25449         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25450         stack_trap "rm -rf $DIR/$tdir"
25451
25452         local mdtidx=$($LFS getstripe -m $dom)
25453         local mdtname=MDT$(printf %04x $mdtidx)
25454         local facet=mds$((mdtidx + 1))
25455
25456         local mdtfree1=$(do_facet $facet \
25457                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25458         dd if=/dev/urandom of=$dom bs=2M count=1 ||
25459                 error "failed to write data into $dom"
25460         local old_md5=$(md5sum $dom)
25461         cancel_lru_locks mdc
25462         local mdtfree1=$(do_facet $facet \
25463                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25464
25465         $LFS migrate -c2 $dom ||
25466                 error "failed to migrate to the new composite layout"
25467         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
25468                 error "MDT stripe was not removed"
25469         ! getfattr -n trusted.dataver $dom &> /dev/null ||
25470                 error "$dir1 shouldn't have DATAVER EA"
25471
25472         cancel_lru_locks mdc
25473         local new_md5=$(md5sum $dom)
25474         [ "$old_md5" == "$new_md5" ] ||
25475                 error "$old_md5 != $new_md5"
25476
25477         # Skip free space checks with ZFS
25478         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25479                 local mdtfree2=$(do_facet $facet \
25480                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25481                 [ $mdtfree2 -gt $mdtfree1 ] ||
25482                         error "MDT space is not freed after migration"
25483         fi
25484         return 0
25485 }
25486 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
25487
25488 test_272c() {
25489         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25490                 skip "Need MDS version at least 2.11.50"
25491
25492         local dom=$DIR/$tdir/$tfile
25493         mkdir -p $DIR/$tdir
25494         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25495         stack_trap "rm -rf $DIR/$tdir"
25496
25497         local mdtidx=$($LFS getstripe -m $dom)
25498         local mdtname=MDT$(printf %04x $mdtidx)
25499         local facet=mds$((mdtidx + 1))
25500
25501         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25502                 error "failed to write data into $dom"
25503         local old_md5=$(md5sum $dom)
25504         cancel_lru_locks mdc
25505         local mdtfree1=$(do_facet $facet \
25506                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25507
25508         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
25509                 error "failed to migrate to the new composite layout"
25510         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
25511                 error "MDT stripe was not removed"
25512
25513         cancel_lru_locks mdc
25514         local new_md5=$(md5sum $dom)
25515         [ "$old_md5" == "$new_md5" ] ||
25516                 error "$old_md5 != $new_md5"
25517
25518         # Skip free space checks with ZFS
25519         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25520                 local mdtfree2=$(do_facet $facet \
25521                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25522                 [ $mdtfree2 -gt $mdtfree1 ] ||
25523                         error "MDS space is not freed after migration"
25524         fi
25525         return 0
25526 }
25527 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
25528
25529 test_272d() {
25530         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25531                 skip "Need MDS version at least 2.12.55"
25532
25533         local dom=$DIR/$tdir/$tfile
25534         mkdir -p $DIR/$tdir
25535         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25536
25537         local mdtidx=$($LFS getstripe -m $dom)
25538         local mdtname=MDT$(printf %04x $mdtidx)
25539         local facet=mds$((mdtidx + 1))
25540
25541         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25542                 error "failed to write data into $dom"
25543         local old_md5=$(md5sum $dom)
25544         cancel_lru_locks mdc
25545         local mdtfree1=$(do_facet $facet \
25546                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25547
25548         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
25549                 error "failed mirroring to the new composite layout"
25550         $LFS mirror resync $dom ||
25551                 error "failed mirror resync"
25552         $LFS mirror split --mirror-id 1 -d $dom ||
25553                 error "failed mirror split"
25554
25555         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
25556                 error "MDT stripe was not removed"
25557
25558         cancel_lru_locks mdc
25559         local new_md5=$(md5sum $dom)
25560         [ "$old_md5" == "$new_md5" ] ||
25561                 error "$old_md5 != $new_md5"
25562
25563         # Skip free space checks with ZFS
25564         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25565                 local mdtfree2=$(do_facet $facet \
25566                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25567                 [ $mdtfree2 -gt $mdtfree1 ] ||
25568                         error "MDS space is not freed after DOM mirror deletion"
25569         fi
25570         return 0
25571 }
25572 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
25573
25574 test_272e() {
25575         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25576                 skip "Need MDS version at least 2.12.55"
25577
25578         local dom=$DIR/$tdir/$tfile
25579         mkdir -p $DIR/$tdir
25580         $LFS setstripe -c 2 $dom
25581
25582         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25583                 error "failed to write data into $dom"
25584         local old_md5=$(md5sum $dom)
25585         cancel_lru_locks
25586
25587         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
25588                 error "failed mirroring to the DOM layout"
25589         $LFS mirror resync $dom ||
25590                 error "failed mirror resync"
25591         $LFS mirror split --mirror-id 1 -d $dom ||
25592                 error "failed mirror split"
25593
25594         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25595                 error "MDT stripe wasn't set"
25596
25597         cancel_lru_locks
25598         local new_md5=$(md5sum $dom)
25599         [ "$old_md5" == "$new_md5" ] ||
25600                 error "$old_md5 != $new_md5"
25601
25602         return 0
25603 }
25604 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
25605
25606 test_272f() {
25607         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25608                 skip "Need MDS version at least 2.12.55"
25609
25610         local dom=$DIR/$tdir/$tfile
25611         mkdir -p $DIR/$tdir
25612         $LFS setstripe -c 2 $dom
25613
25614         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25615                 error "failed to write data into $dom"
25616         local old_md5=$(md5sum $dom)
25617         cancel_lru_locks
25618
25619         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
25620                 error "failed migrating to the DOM file"
25621
25622         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25623                 error "MDT stripe wasn't set"
25624
25625         cancel_lru_locks
25626         local new_md5=$(md5sum $dom)
25627         [ "$old_md5" != "$new_md5" ] &&
25628                 error "$old_md5 != $new_md5"
25629
25630         return 0
25631 }
25632 run_test 272f "DoM migration: OST-striped file to DOM file"
25633
25634 test_273a() {
25635         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25636                 skip "Need MDS version at least 2.11.50"
25637
25638         # Layout swap cannot be done if either file has DOM component,
25639         # this will never be supported, migration should be used instead
25640
25641         local dom=$DIR/$tdir/$tfile
25642         mkdir -p $DIR/$tdir
25643
25644         $LFS setstripe -c2 ${dom}_plain
25645         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
25646         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
25647                 error "can swap layout with DoM component"
25648         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
25649                 error "can swap layout with DoM component"
25650
25651         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
25652         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
25653                 error "can swap layout with DoM component"
25654         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
25655                 error "can swap layout with DoM component"
25656         return 0
25657 }
25658 run_test 273a "DoM: layout swapping should fail with DOM"
25659
25660 test_273b() {
25661         mkdir -p $DIR/$tdir
25662         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
25663
25664 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
25665         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
25666
25667         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25668 }
25669 run_test 273b "DoM: race writeback and object destroy"
25670
25671 test_273c() {
25672         mkdir -p $DIR/$tdir
25673         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
25674
25675         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
25676         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
25677
25678         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25679 }
25680 run_test 273c "race writeback and object destroy"
25681
25682 test_275() {
25683         remote_ost_nodsh && skip "remote OST with nodsh"
25684         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
25685                 skip "Need OST version >= 2.10.57"
25686
25687         local file=$DIR/$tfile
25688         local oss
25689
25690         oss=$(comma_list $(osts_nodes))
25691
25692         dd if=/dev/urandom of=$file bs=1M count=2 ||
25693                 error "failed to create a file"
25694         stack_trap "rm -f $file"
25695         cancel_lru_locks osc
25696
25697         #lock 1
25698         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25699                 error "failed to read a file"
25700
25701 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
25702         $LCTL set_param fail_loc=0x8000031f
25703
25704         cancel_lru_locks osc &
25705         sleep 1
25706
25707 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
25708         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
25709         #IO takes another lock, but matches the PENDING one
25710         #and places it to the IO RPC
25711         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25712                 error "failed to read a file with PENDING lock"
25713 }
25714 run_test 275 "Read on a canceled duplicate lock"
25715
25716 test_276() {
25717         remote_ost_nodsh && skip "remote OST with nodsh"
25718         local pid
25719
25720         do_facet ost1 "(while true; do \
25721                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
25722                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
25723         pid=$!
25724
25725         for LOOP in $(seq 20); do
25726                 stop ost1
25727                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
25728         done
25729         kill -9 $pid
25730         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
25731                 rm $TMP/sanity_276_pid"
25732 }
25733 run_test 276 "Race between mount and obd_statfs"
25734
25735 test_277() {
25736         $LCTL set_param ldlm.namespaces.*.lru_size=0
25737         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25738         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25739                           awk '/^used_mb/ { print $2 }')
25740         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
25741         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
25742                 oflag=direct conv=notrunc
25743         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25744                     awk '/^used_mb/ { print $2 }')
25745         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
25746 }
25747 run_test 277 "Direct IO shall drop page cache"
25748
25749 test_278() {
25750         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
25751         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25752         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
25753                 skip "needs the same host for mdt1 mdt2" && return
25754
25755         local pid1
25756         local pid2
25757
25758 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
25759         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
25760         stop mds2 &
25761         pid2=$!
25762
25763         stop mds1
25764
25765         echo "Starting MDTs"
25766         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
25767         wait $pid2
25768 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
25769 #will return NULL
25770         do_facet mds2 $LCTL set_param fail_loc=0
25771
25772         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
25773         wait_recovery_complete mds2
25774 }
25775 run_test 278 "Race starting MDS between MDTs stop/start"
25776
25777 test_280() {
25778         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
25779                 skip "Need MGS version at least 2.13.52"
25780         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25781         combined_mgs_mds || skip "needs combined MGS/MDT"
25782
25783         umount_client $MOUNT
25784 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
25785         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
25786
25787         mount_client $MOUNT &
25788         sleep 1
25789         stop mgs || error "stop mgs failed"
25790         #for a race mgs would crash
25791         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
25792         # make sure we unmount client before remounting
25793         wait
25794         umount_client $MOUNT
25795         mount_client $MOUNT || error "mount client failed"
25796 }
25797 run_test 280 "Race between MGS umount and client llog processing"
25798
25799 cleanup_test_300() {
25800         trap 0
25801         umask $SAVE_UMASK
25802 }
25803
25804 test_striped_dir() {
25805         local mdt_index=$1
25806         local stripe_count=$2
25807         local overstriping=$3
25808         local stripe_index
25809         local getstripe_count
25810
25811         mkdir -p $DIR/$tdir
25812
25813         SAVE_UMASK=$(umask)
25814         trap cleanup_test_300 RETURN EXIT
25815
25816         if [ -z $overstriping ]; then
25817                 $LFS setdirstripe -i $mdt_index -c $stripe_count -H all_char \
25818                                         -o 755 $DIR/$tdir/striped_dir ||
25819                         error "set striped dir error"
25820         else
25821                 $LFS setdirstripe -i $mdt_index -C $stripe_count -H all_char \
25822                                         -o 755 $DIR/$tdir/striped_dir ||
25823                         error "set striped dir error"
25824         fi
25825
25826         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
25827         [ "$mode" = "755" ] || error "expect 755 got $mode"
25828
25829         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
25830                 error "getdirstripe failed"
25831         getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
25832         if [ "$getstripe_count" != "$stripe_count" ]; then
25833                 error "1:stripe_count is $getstripe_count, expect $stripe_count"
25834         fi
25835         getstripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
25836         if [ "$getstripe_count" != "$stripe_count" ]; then
25837                 error "2:stripe_count is $getstripe_count, expect $stripe_count"
25838         fi
25839
25840         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
25841         if [ "$stripe_index" != "$mdt_index" ]; then
25842                 error "stripe_index is $stripe_index, expect $mdt_index"
25843         fi
25844
25845         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25846                 error "nlink error after create striped dir"
25847
25848         mkdir $DIR/$tdir/striped_dir/a
25849         mkdir $DIR/$tdir/striped_dir/b
25850
25851         stat $DIR/$tdir/striped_dir/a ||
25852                 error "create dir under striped dir failed"
25853         stat $DIR/$tdir/striped_dir/b ||
25854                 error "create dir under striped dir failed"
25855
25856         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
25857                 error "nlink error after mkdir"
25858
25859         rmdir $DIR/$tdir/striped_dir/a
25860         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
25861                 error "nlink error after rmdir"
25862
25863         rmdir $DIR/$tdir/striped_dir/b
25864         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25865                 error "nlink error after rmdir"
25866
25867         chattr +i $DIR/$tdir/striped_dir
25868         createmany -o $DIR/$tdir/striped_dir/f 10 &&
25869                 error "immutable flags not working under striped dir!"
25870         chattr -i $DIR/$tdir/striped_dir
25871
25872         rmdir $DIR/$tdir/striped_dir ||
25873                 error "rmdir striped dir error"
25874
25875         cleanup_test_300
25876
25877         true
25878 }
25879
25880 test_300a() {
25881         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25882                 skip "skipped for lustre < 2.7.0"
25883         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25884         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25885
25886         test_striped_dir 0 2 || error "failed on striped dir on MDT0"
25887         test_striped_dir 1 2 || error "failed on striped dir on MDT0"
25888 }
25889 run_test 300a "basic striped dir sanity test"
25890
25891 test_300b() {
25892         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25893                 skip "skipped for lustre < 2.7.0"
25894         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25895         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25896
25897         local i
25898         local mtime1
25899         local mtime2
25900         local mtime3
25901
25902         test_mkdir $DIR/$tdir || error "mkdir fail"
25903         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25904                 error "set striped dir error"
25905         for i in {0..9}; do
25906                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
25907                 sleep 1
25908                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
25909                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
25910                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
25911                 sleep 1
25912                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
25913                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
25914                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
25915         done
25916         true
25917 }
25918 run_test 300b "check ctime/mtime for striped dir"
25919
25920 test_300c() {
25921         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25922                 skip "skipped for lustre < 2.7.0"
25923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25924         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25925
25926         local file_count
25927
25928         mkdir_on_mdt0 $DIR/$tdir
25929         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
25930                 error "set striped dir error"
25931
25932         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
25933                 error "chown striped dir failed"
25934
25935         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
25936                 error "create 5k files failed"
25937
25938         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
25939
25940         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
25941
25942         rm -rf $DIR/$tdir
25943 }
25944 run_test 300c "chown && check ls under striped directory"
25945
25946 test_300d() {
25947         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25948                 skip "skipped for lustre < 2.7.0"
25949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25950         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25951
25952         local stripe_count
25953         local file
25954
25955         mkdir -p $DIR/$tdir
25956         $LFS setstripe -c 2 $DIR/$tdir
25957
25958         #local striped directory
25959         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25960                 error "set striped dir error"
25961         #look at the directories for debug purposes
25962         ls -l $DIR/$tdir
25963         $LFS getdirstripe $DIR/$tdir
25964         ls -l $DIR/$tdir/striped_dir
25965         $LFS getdirstripe $DIR/$tdir/striped_dir
25966         createmany -o $DIR/$tdir/striped_dir/f 10 ||
25967                 error "create 10 files failed"
25968
25969         #remote striped directory
25970         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
25971                 error "set striped dir error"
25972         #look at the directories for debug purposes
25973         ls -l $DIR/$tdir
25974         $LFS getdirstripe $DIR/$tdir
25975         ls -l $DIR/$tdir/remote_striped_dir
25976         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
25977         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
25978                 error "create 10 files failed"
25979
25980         for file in $(find $DIR/$tdir); do
25981                 stripe_count=$($LFS getstripe -c $file)
25982                 [ $stripe_count -eq 2 ] ||
25983                         error "wrong stripe $stripe_count for $file"
25984         done
25985
25986         rm -rf $DIR/$tdir
25987 }
25988 run_test 300d "check default stripe under striped directory"
25989
25990 test_300e() {
25991         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25992                 skip "Need MDS version at least 2.7.55"
25993         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25994         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25995
25996         local stripe_count
25997         local file
25998
25999         mkdir -p $DIR/$tdir
26000
26001         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
26002                 error "set striped dir error"
26003
26004         touch $DIR/$tdir/striped_dir/a
26005         touch $DIR/$tdir/striped_dir/b
26006         touch $DIR/$tdir/striped_dir/c
26007
26008         mkdir $DIR/$tdir/striped_dir/dir_a
26009         mkdir $DIR/$tdir/striped_dir/dir_b
26010         mkdir $DIR/$tdir/striped_dir/dir_c
26011
26012         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
26013                 error "set striped adir under striped dir error"
26014
26015         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
26016                 error "set striped bdir under striped dir error"
26017
26018         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
26019                 error "set striped cdir under striped dir error"
26020
26021         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
26022                 error "rename dir under striped dir fails"
26023
26024         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
26025                 error "rename dir under different stripes fails"
26026
26027         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
26028                 error "rename file under striped dir should succeed"
26029
26030         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
26031                 error "rename dir under striped dir should succeed"
26032
26033         rm -rf $DIR/$tdir
26034 }
26035 run_test 300e "check rename under striped directory"
26036
26037 test_300f() {
26038         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26039         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26040         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26041                 skip "Need MDS version at least 2.7.55"
26042
26043         local stripe_count
26044         local file
26045
26046         rm -rf $DIR/$tdir
26047         mkdir -p $DIR/$tdir
26048
26049         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
26050                 error "set striped dir error"
26051
26052         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
26053                 error "set striped dir error"
26054
26055         touch $DIR/$tdir/striped_dir/a
26056         mkdir $DIR/$tdir/striped_dir/dir_a
26057         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
26058                 error "create striped dir under striped dir fails"
26059
26060         touch $DIR/$tdir/striped_dir1/b
26061         mkdir $DIR/$tdir/striped_dir1/dir_b
26062         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
26063                 error "create striped dir under striped dir fails"
26064
26065         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
26066                 error "rename dir under different striped dir should fail"
26067
26068         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
26069                 error "rename striped dir under diff striped dir should fail"
26070
26071         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
26072                 error "rename file under diff striped dirs fails"
26073
26074         rm -rf $DIR/$tdir
26075 }
26076 run_test 300f "check rename cross striped directory"
26077
26078 test_300_check_default_striped_dir()
26079 {
26080         local dirname=$1
26081         local default_count=$2
26082         local default_index=$3
26083         local stripe_count
26084         local stripe_index
26085         local dir_stripe_index
26086         local dir
26087
26088         echo "checking $dirname $default_count $default_index"
26089         $LFS setdirstripe -D -c $default_count -i $default_index \
26090                                 -H all_char $DIR/$tdir/$dirname ||
26091                 error "set default stripe on striped dir error"
26092         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
26093         [ $stripe_count -eq $default_count ] ||
26094                 error "expect $default_count get $stripe_count for $dirname"
26095
26096         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
26097         [ $stripe_index -eq $default_index ] ||
26098                 error "expect $default_index get $stripe_index for $dirname"
26099
26100         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
26101                                                 error "create dirs failed"
26102
26103         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
26104         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
26105         for dir in $(find $DIR/$tdir/$dirname/*); do
26106                 stripe_count=$($LFS getdirstripe -c $dir)
26107                 (( $stripe_count == $default_count )) ||
26108                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
26109                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
26110                 error "stripe count $default_count != $stripe_count for $dir"
26111
26112                 stripe_index=$($LFS getdirstripe -i $dir)
26113                 [ $default_index -eq -1 ] ||
26114                         [ $stripe_index -eq $default_index ] ||
26115                         error "$stripe_index != $default_index for $dir"
26116
26117                 #check default stripe
26118                 stripe_count=$($LFS getdirstripe -D -c $dir)
26119                 [ $stripe_count -eq $default_count ] ||
26120                 error "default count $default_count != $stripe_count for $dir"
26121
26122                 stripe_index=$($LFS getdirstripe -D -i $dir)
26123                 [ $stripe_index -eq $default_index ] ||
26124                 error "default index $default_index != $stripe_index for $dir"
26125         done
26126         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
26127 }
26128
26129 test_300g() {
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         local stripe_index
26137
26138         mkdir_on_mdt0 $DIR/$tdir
26139         mkdir $DIR/$tdir/normal_dir
26140
26141         #Checking when client cache stripe index
26142         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26143         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
26144                 error "create striped_dir failed"
26145
26146         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
26147                 error "create dir0 fails"
26148         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
26149         [ $stripe_index -eq 0 ] ||
26150                 error "dir0 expect index 0 got $stripe_index"
26151
26152         mkdir $DIR/$tdir/striped_dir/dir1 ||
26153                 error "create dir1 fails"
26154         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
26155         [ $stripe_index -eq 1 ] ||
26156                 error "dir1 expect index 1 got $stripe_index"
26157
26158         #check default stripe count/stripe index
26159         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
26160         test_300_check_default_striped_dir normal_dir 1 0
26161         test_300_check_default_striped_dir normal_dir -1 1
26162         test_300_check_default_striped_dir normal_dir 2 -1
26163
26164         #delete default stripe information
26165         echo "delete default stripeEA"
26166         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
26167                 error "set default stripe on striped dir error"
26168
26169         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
26170         for dir in $(find $DIR/$tdir/normal_dir/*); do
26171                 stripe_count=$($LFS getdirstripe -c $dir)
26172                 [ $stripe_count -eq 0 ] ||
26173                         error "expect 1 get $stripe_count for $dir"
26174         done
26175 }
26176 run_test 300g "check default striped directory for normal directory"
26177
26178 test_300h() {
26179         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26180         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26181                 skip "Need MDS version at least 2.7.55"
26182
26183         local dir
26184         local stripe_count
26185
26186         mkdir $DIR/$tdir
26187         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
26188                 error "set striped dir error"
26189
26190         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
26191         test_300_check_default_striped_dir striped_dir 1 0
26192         test_300_check_default_striped_dir striped_dir -1 1
26193         test_300_check_default_striped_dir striped_dir 2 -1
26194
26195         #delete default stripe information
26196         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
26197                 error "set default stripe on striped dir error"
26198
26199         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
26200         for dir in $(find $DIR/$tdir/striped_dir/*); do
26201                 stripe_count=$($LFS getdirstripe -c $dir)
26202                 [ $stripe_count -eq 0 ] ||
26203                         error "expect 1 get $stripe_count for $dir"
26204         done
26205 }
26206 run_test 300h "check default striped directory for striped directory"
26207
26208 test_300i() {
26209         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
26210         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
26211         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
26212                 skip "Need MDS version at least 2.7.55"
26213
26214         local stripe_count
26215         local file
26216
26217         mkdir $DIR/$tdir
26218
26219         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
26220                 error "set striped dir error"
26221
26222         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
26223                 error "create files under striped dir failed"
26224
26225         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
26226                 error "set striped hashdir error"
26227
26228         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
26229                 error "create dir0 under hash dir failed"
26230         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
26231                 error "create dir1 under hash dir failed"
26232         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
26233                 error "create dir2 under hash dir failed"
26234
26235         # unfortunately, we need to umount to clear dir layout cache for now
26236         # once we fully implement dir layout, we can drop this
26237         umount_client $MOUNT || error "umount failed"
26238         mount_client $MOUNT || error "mount failed"
26239
26240         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
26241         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
26242         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
26243
26244         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
26245                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
26246                         error "create crush2 dir $tdir/hashdir/d3 failed"
26247                 $LFS find -H crush2 $DIR/$tdir/hashdir
26248                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
26249                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
26250
26251                 # mkdir with an invalid hash type (hash=fail_val) from client
26252                 # should be replaced on MDS with a valid (default) hash type
26253                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
26254                 $LCTL set_param fail_loc=0x1901 fail_val=99
26255                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
26256
26257                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
26258                 local expect=$(do_facet mds1 \
26259                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
26260                 [[ $hash == $expect ]] ||
26261                         error "d99 hash '$hash' != expected hash '$expect'"
26262         fi
26263
26264         #set the stripe to be unknown hash type on read
26265         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
26266         $LCTL set_param fail_loc=0x1901 fail_val=99
26267         for ((i = 0; i < 10; i++)); do
26268                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
26269                         error "stat f-$i failed"
26270                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
26271         done
26272
26273         touch $DIR/$tdir/striped_dir/f0 &&
26274                 error "create under striped dir with unknown hash should fail"
26275
26276         $LCTL set_param fail_loc=0
26277
26278         umount_client $MOUNT || error "umount failed"
26279         mount_client $MOUNT || error "mount failed"
26280
26281         return 0
26282 }
26283 run_test 300i "client handle unknown hash type striped directory"
26284
26285 test_300j() {
26286         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26287         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26288         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26289                 skip "Need MDS version at least 2.7.55"
26290
26291         local stripe_count
26292         local file
26293
26294         mkdir $DIR/$tdir
26295
26296         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
26297         $LCTL set_param fail_loc=0x1702
26298         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
26299                 error "set striped dir error"
26300
26301         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
26302                 error "create files under striped dir failed"
26303
26304         $LCTL set_param fail_loc=0
26305
26306         rm -rf $DIR/$tdir || error "unlink striped dir fails"
26307
26308         return 0
26309 }
26310 run_test 300j "test large update record"
26311
26312 test_300k() {
26313         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26314         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26315         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26316                 skip "Need MDS version at least 2.7.55"
26317
26318         # this test needs a huge transaction
26319         local kb
26320         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
26321              osd*.$FSNAME-MDT0000.kbytestotal")
26322         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
26323
26324         local stripe_count
26325         local file
26326
26327         mkdir $DIR/$tdir
26328
26329         #define OBD_FAIL_LARGE_STRIPE   0x1703
26330         $LCTL set_param fail_loc=0x1703
26331         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
26332                 error "set striped dir error"
26333         $LCTL set_param fail_loc=0
26334
26335         $LFS getdirstripe $DIR/$tdir/striped_dir ||
26336                 error "getstripeddir fails"
26337         rm -rf $DIR/$tdir/striped_dir ||
26338                 error "unlink striped dir fails"
26339
26340         return 0
26341 }
26342 run_test 300k "test large striped directory"
26343
26344 test_300l() {
26345         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26346         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26347         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26348                 skip "Need MDS version at least 2.7.55"
26349
26350         local stripe_index
26351
26352         test_mkdir -p $DIR/$tdir/striped_dir
26353         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
26354                         error "chown $RUNAS_ID failed"
26355         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
26356                 error "set default striped dir failed"
26357
26358         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
26359         $LCTL set_param fail_loc=0x80000158
26360         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
26361
26362         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
26363         [ $stripe_index -eq 1 ] ||
26364                 error "expect 1 get $stripe_index for $dir"
26365 }
26366 run_test 300l "non-root user to create dir under striped dir with stale layout"
26367
26368 test_300m() {
26369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26370         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
26371         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26372                 skip "Need MDS version at least 2.7.55"
26373
26374         mkdir -p $DIR/$tdir/striped_dir
26375         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
26376                 error "set default stripes dir error"
26377
26378         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
26379
26380         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
26381         [ $stripe_count -eq 0 ] ||
26382                         error "expect 0 get $stripe_count for a"
26383
26384         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
26385                 error "set default stripes dir error"
26386
26387         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
26388
26389         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
26390         [ $stripe_count -eq 0 ] ||
26391                         error "expect 0 get $stripe_count for b"
26392
26393         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
26394                 error "set default stripes dir error"
26395
26396         mkdir $DIR/$tdir/striped_dir/c &&
26397                 error "default stripe_index is invalid, mkdir c should fails"
26398
26399         rm -rf $DIR/$tdir || error "rmdir fails"
26400 }
26401 run_test 300m "setstriped directory on single MDT FS"
26402
26403 cleanup_300n() {
26404         local list=$(comma_list $(mdts_nodes))
26405
26406         trap 0
26407         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26408 }
26409
26410 test_300n() {
26411         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26412         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26413         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26414                 skip "Need MDS version at least 2.7.55"
26415         remote_mds_nodsh && skip "remote MDS with nodsh"
26416
26417         local stripe_index
26418         local list=$(comma_list $(mdts_nodes))
26419
26420         trap cleanup_300n RETURN EXIT
26421         mkdir -p $DIR/$tdir
26422         chmod 777 $DIR/$tdir
26423         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
26424                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
26425                 error "create striped dir succeeds with gid=0"
26426
26427         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
26428         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
26429                 error "create striped dir fails with gid=-1"
26430
26431         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26432         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
26433                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
26434                 error "set default striped dir succeeds with gid=0"
26435
26436
26437         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
26438         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
26439                 error "set default striped dir fails with gid=-1"
26440
26441
26442         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26443         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
26444                                         error "create test_dir fails"
26445         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
26446                                         error "create test_dir1 fails"
26447         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
26448                                         error "create test_dir2 fails"
26449         cleanup_300n
26450 }
26451 run_test 300n "non-root user to create dir under striped dir with default EA"
26452
26453 test_300o() {
26454         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26455         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26456         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26457                 skip "Need MDS version at least 2.7.55"
26458
26459         local numfree1
26460         local numfree2
26461
26462         mkdir -p $DIR/$tdir
26463
26464         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
26465         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
26466         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
26467                 skip "not enough free inodes $numfree1 $numfree2"
26468         fi
26469
26470         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
26471         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
26472         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
26473                 skip "not enough free space $numfree1 $numfree2"
26474         fi
26475
26476         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
26477                 error "setdirstripe fails"
26478
26479         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
26480                 error "create dirs fails"
26481
26482         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
26483         ls $DIR/$tdir/striped_dir > /dev/null ||
26484                 error "ls striped dir fails"
26485         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
26486                 error "unlink big striped dir fails"
26487 }
26488 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
26489
26490 test_300p() {
26491         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26492         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26493         remote_mds_nodsh && skip "remote MDS with nodsh"
26494
26495         mkdir_on_mdt0 $DIR/$tdir
26496
26497         #define OBD_FAIL_OUT_ENOSPC     0x1704
26498         do_facet mds2 lctl set_param fail_loc=0x80001704
26499         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
26500                  && error "create striped directory should fail"
26501
26502         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
26503
26504         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
26505         true
26506 }
26507 run_test 300p "create striped directory without space"
26508
26509 test_300q() {
26510         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26511         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26512
26513         local fd=$(free_fd)
26514         local cmd="exec $fd<$tdir"
26515         cd $DIR
26516         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
26517         eval $cmd
26518         cmd="exec $fd<&-"
26519         trap "eval $cmd" EXIT
26520         cd $tdir || error "cd $tdir fails"
26521         rmdir  ../$tdir || error "rmdir $tdir fails"
26522         mkdir local_dir && error "create dir succeeds"
26523         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
26524         eval $cmd
26525         return 0
26526 }
26527 run_test 300q "create remote directory under orphan directory"
26528
26529 test_300r() {
26530         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26531                 skip "Need MDS version at least 2.7.55" && return
26532         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
26533
26534         mkdir $DIR/$tdir
26535
26536         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
26537                 error "set striped dir error"
26538
26539         $LFS getdirstripe $DIR/$tdir/striped_dir ||
26540                 error "getstripeddir fails"
26541
26542         local stripe_count
26543         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
26544                       awk '/lmv_stripe_count:/ { print $2 }')
26545
26546         [ $MDSCOUNT -ne $stripe_count ] &&
26547                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
26548
26549         rm -rf $DIR/$tdir/striped_dir ||
26550                 error "unlink striped dir fails"
26551 }
26552 run_test 300r "test -1 striped directory"
26553
26554 test_300s_helper() {
26555         local count=$1
26556
26557         local stripe_dir=$DIR/$tdir/striped_dir.$count
26558
26559         $LFS mkdir -c $count $stripe_dir ||
26560                 error "lfs mkdir -c error"
26561
26562         $LFS getdirstripe $stripe_dir ||
26563                 error "lfs getdirstripe fails"
26564
26565         local stripe_count
26566         stripe_count=$($LFS getdirstripe $stripe_dir |
26567                       awk '/lmv_stripe_count:/ { print $2 }')
26568
26569         [ $count -ne $stripe_count ] &&
26570                 error_noexit "bad stripe count $stripe_count expected $count"
26571
26572         local dupe_stripes
26573         dupe_stripes=$($LFS getdirstripe $stripe_dir |
26574                 awk '/0x/ {count[$1] += 1}; END {
26575                         for (idx in count) {
26576                                 if (count[idx]>1) {
26577                                         print "index " idx " count " count[idx]
26578                                 }
26579                         }
26580                 }')
26581
26582         if [[ -n "$dupe_stripes" ]] ; then
26583                 lfs getdirstripe $stripe_dir
26584                 error_noexit "Dupe MDT above: $dupe_stripes "
26585         fi
26586
26587         rm -rf $stripe_dir ||
26588                 error_noexit "unlink $stripe_dir fails"
26589 }
26590
26591 test_300s() {
26592         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26593                 skip "Need MDS version at least 2.7.55" && return
26594         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
26595
26596         mkdir $DIR/$tdir
26597         for count in $(seq 2 $MDSCOUNT); do
26598                 test_300s_helper $count
26599         done
26600 }
26601 run_test 300s "test lfs mkdir -c without -i"
26602
26603 test_300t() {
26604         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
26605                 skip "need MDS 2.14.55 or later"
26606         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
26607
26608         local testdir="$DIR/$tdir/striped_dir"
26609         local dir1=$testdir/dir1
26610         local dir2=$testdir/dir2
26611
26612         mkdir -p $testdir
26613
26614         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
26615                 error "failed to set default stripe count for $testdir"
26616
26617         mkdir $dir1
26618         local stripe_count=$($LFS getdirstripe -c $dir1)
26619
26620         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
26621
26622         local max_count=$((MDSCOUNT - 1))
26623         local mdts=$(comma_list $(mdts_nodes))
26624
26625         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
26626         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
26627
26628         mkdir $dir2
26629         stripe_count=$($LFS getdirstripe -c $dir2)
26630
26631         (( $stripe_count == $max_count )) || error "wrong stripe count"
26632 }
26633 run_test 300t "test max_mdt_stripecount"
26634
26635 MDT_OVSTRP_VER="2.15.60"
26636 # 300u family tests MDT overstriping
26637 test_300ua() {
26638         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26639
26640         local setcount=$((MDSCOUNT * 2))
26641
26642         local expected_count
26643
26644         mkdir $DIR/$tdir
26645         $LFS setdirstripe -C $setcount $DIR/$tdir/${tdir}.0 ||
26646                 error "(0) failed basic overstriped dir creation test"
26647         local getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.0)
26648
26649         # This does a basic interop test - if the MDS does not support mdt
26650         # overstriping, we should get stripes == number of MDTs
26651         if (( $MDS1_VERSION < $(version_code $MDT_OVSTRP_VER) )); then
26652                 expected_count=$MDSCOUNT
26653         else
26654                 expected_count=$setcount
26655         fi
26656         (( getstripe_count == expected_count )) ||
26657                 error "(1) incorrect stripe count for simple overstriped dir"
26658
26659         rm -rf $DIR/$tdir/${tdir}.0 ||
26660                 error "(2) unable to rm overstriped dir"
26661
26662         # Tests after this require overstriping support
26663         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26664                 { echo "skipped for MDS < $MDT_OVSTRP_VER"; return 0; }
26665
26666         test_striped_dir 0 $setcount true ||
26667                 error "(3)failed on overstriped dir"
26668         test_striped_dir 1 $setcount true ||
26669                 error "(4)failed on overstriped dir"
26670
26671         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26672
26673         test_striped_dir 0 $setcount true ||
26674                 error "(5)failed on overstriped dir"
26675 }
26676 run_test 300ua "basic overstriped dir sanity test"
26677
26678 test_300ub() {
26679         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26680                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26681         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26682
26683         mkdir $DIR/$tdir
26684
26685         echo "Testing invalid stripe count, failure expected"
26686         local setcount=$((MDSCOUNT * 2))
26687
26688         $LFS setdirstripe -c $setcount $DIR/$tdir/${tdir}.0
26689         local getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.0)
26690
26691         (( getstripe_count <= MDSCOUNT )) ||
26692                 error "(0)stripe count ($setcount) > MDT count ($MDSCOUNT) succeeded with -c"
26693
26694         # When a user requests > LMV_MAX_STRIPES_PER_MDT, we reduce to that
26695         setcount=$((MDSCOUNT * 2 * LMV_MAX_STRIPES_PER_MDT))
26696         $LFS setdirstripe -C $setcount $DIR/$tdir/${tdir}.1
26697
26698         local maxcount=$((MDSCOUNT * LMV_MAX_STRIPES_PER_MDT))
26699
26700         getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.1)
26701         (( getstripe_count == maxcount )) ||
26702                 error "(1)stripe_count is $getstripe_count, expect $maxcount"
26703
26704         # Test specific striping with -i
26705         $LFS setdirstripe -i 0,0,0,0 $DIR/$tdir/${tdir}.2
26706
26707         getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.2)
26708         (( getstripe_count == 4 )) ||
26709                 error "(2)stripe_count is $getstripe_count, expect 4"
26710
26711         local nonzeroindices=$($LFS getdirstripe $DIR/$tdir/${tdir}.2 | grep "\[" | \
26712                                grep -v mdtidx | awk '{print $1}' | grep -c -v 0)
26713
26714         [[ -n "$nonzeroindices" ]] ||
26715                 error "(3) stripes indices not all 0: $nonzeroindices"
26716
26717         # Test specific striping with too many stripes on one MDT
26718         echo "Testing invalid striping, failure expected"
26719         $LFS setdirstripe -i 0,1,0,1,0,1,0,1,0,1,0 $DIR/$tdir/${tdir}.3
26720         $LFS getdirstripe $DIR/$tdir/${tdir}.3
26721         getstripe_count=$($LFS getdirstripe $DIR/$tdir/${tdir}.3 | grep "\[" | \
26722                           grep -v mdtidx | awk '{print $1}' | grep -c '0')
26723         echo "stripes on MDT0: $getstripe_count"
26724         (( getstripe_count <= LMV_MAX_STRIPES_PER_MDT )) ||
26725                 error "(4) setstripe with too many stripes on MDT0 succeeded"
26726
26727         setcount=$((MDSCOUNT * 2))
26728         $LFS setdirstripe -C $setcount -H all_char $DIR/${tdir}.4 ||
26729                 error "(5) can't setdirstripe with manually set hash function"
26730
26731         getstripe_count=$($LFS getdirstripe -c $DIR/${tdir}.4)
26732         (( getstripe_count == setcount )) ||
26733                 error "(6)stripe_count is $getstripe_count, expect $setcount"
26734
26735         setcount=$((MDSCOUNT * 2))
26736         mkdir $DIR/${tdir}.5
26737         $LFS setdirstripe -C $setcount -D -H crush $DIR/${tdir}.5 ||
26738                 error "(7) can't setdirstripe with manually set hash function"
26739         mkdir $DIR/${tdir}.5/${tdir}.6
26740
26741         getstripe_count=$($LFS getdirstripe -c $DIR/${tdir}.5/${tdir}.6)
26742         (( getstripe_count == setcount )) ||
26743                 error "(8)stripe_count is $getstripe_count, expect $setcount"
26744 }
26745 run_test 300ub "test MDT overstriping interface & limits"
26746
26747 test_300uc() {
26748         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26749                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26750         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26751
26752         mkdir $DIR/$tdir
26753
26754         local setcount=$((MDSCOUNT * 2))
26755
26756         $LFS setdirstripe -D -C $setcount $DIR/$tdir
26757
26758         mkdir $DIR/$tdir/${tdir}.1
26759
26760         local getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.1)
26761
26762         (( getstripe_count == setcount )) ||
26763                 error "(0)stripe_count is $getstripe_count, expect $setcount"
26764
26765         mkdir $DIR/$tdir/${tdir}.1/${tdir}.2
26766
26767         local getstripe_count=$($LFS getdirstripe -c \
26768                                 $DIR/$tdir/${tdir}.1/${tdir}.2)
26769
26770         (( getstripe_count == setcount )) ||
26771                 error "(1)stripe_count is $getstripe_count, expect $setcount"
26772 }
26773 run_test 300uc "test MDT overstriping as default & inheritance"
26774
26775 test_300ud() {
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 i
26786
26787         [[ $mds1_FSTYPE == zfs ]] && timeout=300
26788
26789         # in case "crush" hash type is not set
26790         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
26791
26792         restripe_status=$(do_facet mds1 $LCTL get_param -n \
26793                            mdt.*MDT0000.enable_dir_restripe)
26794         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
26795         stack_trap "do_nodes $mdts $LCTL set_param \
26796                     mdt.*.enable_dir_restripe=$restripe_status"
26797
26798         mkdir $DIR/$tdir
26799         createmany -m $DIR/$tdir/f $((50 * MDSCOUNT)) ||
26800                 error "create files under remote dir failed $i"
26801         createmany -d $DIR/$tdir/d $((50 * MDSCOUNT)) ||
26802                 error "create dirs under remote dir failed $i"
26803
26804         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26805
26806         (( setcount < 13 )) || setcount=12
26807         for i in $(seq 2 $setcount); do
26808                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
26809                 $LFS setdirstripe -C $i $DIR/$tdir ||
26810                         error "split -C $i $tdir failed"
26811                 wait_update $HOSTNAME \
26812                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
26813                         error "dir split not finished"
26814                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
26815                         awk '/migrate/ {sum += $2} END { print sum }')
26816                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
26817                 # delta is around total_files/stripe_count, deviation 3%
26818                 (( delta < 100 * MDSCOUNT / i + 3 * MDSCOUNT )) ||
26819                         error "$delta files migrated >= $((100 * MDSCOUNT / i + 3 * MDSCOUNT))"
26820         done
26821 }
26822 run_test 300ud "dir split"
26823
26824 test_300ue() {
26825         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26826                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26827         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26828
26829         local mdts=$(comma_list $(mdts_nodes))
26830         local timeout=100
26831
26832         local restripe_status
26833         local delta
26834         local c
26835
26836         [[ $mds1_FSTYPE == zfs ]] && timeout=300
26837
26838         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
26839
26840         restripe_status=$(do_facet mds1 $LCTL get_param -n \
26841                            mdt.*MDT0000.enable_dir_restripe)
26842         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
26843         stack_trap "do_nodes $mdts $LCTL set_param \
26844                     mdt.*.enable_dir_restripe=$restripe_status"
26845
26846         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26847
26848         (( setcount < 13 )) || setcount=12
26849         test_mkdir -C $setcount -H crush $DIR/$tdir
26850         createmany -m $DIR/$tdir/f $((50 * MDSCOUNT)) ||
26851                 error "create files under remote dir failed"
26852         createmany -d $DIR/$tdir/d $((50 * MDSCOUNT)) ||
26853                 error "create dirs under remote dir failed"
26854
26855         for c in $(seq $((setcount - 1)) -1 1); do
26856                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
26857                 $LFS setdirstripe -C $c $DIR/$tdir ||
26858                         error "split -C $c $tdir failed"
26859                 wait_update $HOSTNAME \
26860                         "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" $timeout ||
26861                         error "dir merge not finished"
26862                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
26863                         awk '/migrate/ {sum += $2} END { print sum }')
26864                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
26865                 # delta is around total_files/stripe_count, deviation 3%
26866                 (( delta < 100 * MDSCOUNT / c + 3 * MDSCOUNT )) ||
26867                         error "$delta files migrated >= $((100 * MDSCOUNT / c + 3 * MDSCOUNT))"
26868         done
26869 }
26870 run_test 300ue "dir merge"
26871
26872 test_300uf() {
26873         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26874                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26875         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26876
26877         # maximum amount of local locks:
26878         # parent striped dir - 2 locks
26879         # new stripe in parent to migrate to - 1 lock
26880         # source and target - 2 locks
26881         # Total 5 locks for regular file
26882         #
26883         # NB: Overstriping should add several extra local locks
26884         # FIXME: Remove this once understood
26885         #lctl set_param *debug=-1 debug_mb=10000
26886         lctl clear
26887         lctl mark "touch/create"
26888         mkdir -p $DIR/$tdir
26889         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26890         local setcount=$((MDSCOUNT * 5))
26891
26892         $LFS mkdir -i1 -C $setcount $DIR/$tdir/dir1
26893         touch $DIR/$tdir/dir1/eee
26894
26895         lctl mark "hardlinks"
26896         # create 4 hardlink for 4 more locks
26897         # Total: 9 locks > RS_MAX_LOCKS (8)
26898         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
26899         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
26900         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
26901         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
26902         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
26903         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
26904         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
26905         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
26906
26907         lctl mark "cancel lru"
26908         cancel_lru_locks mdc
26909
26910         lctl mark "migrate"
26911         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
26912                 error "migrate dir fails"
26913
26914         rm -rf $DIR/$tdir || error "rm dir failed after migration"
26915 }
26916 run_test 300uf "migrate with too many local locks"
26917
26918 test_300ug() {
26919         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26920                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26921         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26922
26923         mkdir -p $DIR/$tdir
26924         local migrate_dir=$DIR/$tdir/migrate_dir
26925         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26926         local setcount2=$((setcount - 2))
26927
26928         $LFS setdirstripe -c 2 $migrate_dir ||
26929                 error "(0) failed to create striped directory"
26930
26931         $LFS migrate -m 0 -C $setcount $migrate_dir ||
26932                 error "(1)failed to migrate to overstriped directory"
26933         local getstripe_count=$($LFS getdirstripe -c $migrate_dir)
26934
26935         (( getstripe_count == setcount )) ||
26936                 error "(2)stripe_count is $getstripe_count, expect $setcount"
26937         touch $DIR/$tdir/migrate_dir/$tfile ||
26938                 error "(3)failed to create file in overstriped directory"
26939         $LFS migrate -m 0 -C $setcount2 $migrate_dir ||
26940                 error "(4)failed to migrate overstriped directory"
26941         # Check stripe count after migration
26942         $LFS getdirstripe $migrate_dir
26943         getstripe_count=$($LFS getdirstripe -c $migrate_dir)
26944         (( getstripe_count == setcount2 )) ||
26945                 error "(5)stripe_count is $getstripe_count, expect $setcount2"
26946
26947         rm -rf $migrate_dir || error "(6) unable to rm overstriped dir"
26948 }
26949 run_test 300ug "migrate overstriped dirs"
26950
26951 prepare_remote_file() {
26952         mkdir $DIR/$tdir/src_dir ||
26953                 error "create remote source failed"
26954
26955         cp /etc/hosts $DIR/$tdir/src_dir/a ||
26956                  error "cp to remote source failed"
26957         touch $DIR/$tdir/src_dir/a
26958
26959         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
26960                 error "create remote target dir failed"
26961
26962         touch $DIR/$tdir/tgt_dir/b
26963
26964         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
26965                 error "rename dir cross MDT failed!"
26966
26967         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
26968                 error "src_child still exists after rename"
26969
26970         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
26971                 error "missing file(a) after rename"
26972
26973         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
26974                 error "diff after rename"
26975 }
26976
26977 test_310a() {
26978         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
26979         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26980
26981         local remote_file=$DIR/$tdir/tgt_dir/b
26982
26983         mkdir -p $DIR/$tdir
26984
26985         prepare_remote_file || error "prepare remote file failed"
26986
26987         #open-unlink file
26988         $OPENUNLINK $remote_file $remote_file ||
26989                 error "openunlink $remote_file failed"
26990         $CHECKSTAT -a $remote_file || error "$remote_file exists"
26991 }
26992 run_test 310a "open unlink remote file"
26993
26994 test_310b() {
26995         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
26996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26997
26998         local remote_file=$DIR/$tdir/tgt_dir/b
26999
27000         mkdir -p $DIR/$tdir
27001
27002         prepare_remote_file || error "prepare remote file failed"
27003
27004         ln $remote_file $DIR/$tfile || error "link failed for remote file"
27005         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
27006         $CHECKSTAT -t file $remote_file || error "check file failed"
27007 }
27008 run_test 310b "unlink remote file with multiple links while open"
27009
27010 test_310c() {
27011         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27012         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
27013
27014         local remote_file=$DIR/$tdir/tgt_dir/b
27015
27016         mkdir -p $DIR/$tdir
27017
27018         prepare_remote_file || error "prepare remote file failed"
27019
27020         ln $remote_file $DIR/$tfile || error "link failed for remote file"
27021         multiop_bg_pause $remote_file O_uc ||
27022                         error "mulitop failed for remote file"
27023         MULTIPID=$!
27024         $MULTIOP $DIR/$tfile Ouc
27025         kill -USR1 $MULTIPID
27026         wait $MULTIPID
27027 }
27028 run_test 310c "open-unlink remote file with multiple links"
27029
27030 #LU-4825
27031 test_311() {
27032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27033         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
27034         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
27035                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
27036         remote_mds_nodsh && skip "remote MDS with nodsh"
27037
27038         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
27039         local mdts=$(comma_list $(mdts_nodes))
27040
27041         mkdir -p $DIR/$tdir
27042         $LFS setstripe -i 0 -c 1 $DIR/$tdir
27043         createmany -o $DIR/$tdir/$tfile. 1000
27044
27045         # statfs data is not real time, let's just calculate it
27046         old_iused=$((old_iused + 1000))
27047
27048         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27049                         osp.*OST0000*MDT0000.create_count")
27050         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27051                                 osp.*OST0000*MDT0000.max_create_count")
27052         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
27053
27054         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
27055         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
27056         [ $index -ne 0 ] || error "$tfile stripe index is 0"
27057
27058         unlinkmany $DIR/$tdir/$tfile. 1000
27059
27060         do_nodes $mdts "$LCTL set_param -n \
27061                         osp.*OST0000*.max_create_count=$max_count"
27062         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
27063                 do_nodes $mdts "$LCTL set_param -n \
27064                                 osp.*OST0000*.create_count=$count"
27065         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
27066                         grep "=0" && error "create_count is zero"
27067
27068         local new_iused
27069         for i in $(seq 120); do
27070                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
27071                 # system may be too busy to destroy all objs in time, use
27072                 # a somewhat small value to not fail autotest
27073                 [ $((old_iused - new_iused)) -gt 400 ] && break
27074                 sleep 1
27075         done
27076
27077         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
27078         [ $((old_iused - new_iused)) -gt 400 ] ||
27079                 error "objs not destroyed after unlink"
27080 }
27081 run_test 311 "disable OSP precreate, and unlink should destroy objs"
27082
27083 zfs_get_objid()
27084 {
27085         local ost=$1
27086         local tf=$2
27087         local fid=($($LFS getstripe $tf | grep 0x))
27088         local seq=${fid[3]#0x}
27089         local objid=${fid[1]}
27090
27091         local vdevdir=$(dirname $(facet_vdevice $ost))
27092         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
27093         local zfs_zapid=$(do_facet $ost $cmd |
27094                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
27095                           awk '/Object/{getline; print $1}')
27096         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
27097                           awk "/$objid = /"'{printf $3}')
27098
27099         echo $zfs_objid
27100 }
27101
27102 zfs_object_blksz() {
27103         local ost=$1
27104         local objid=$2
27105
27106         local vdevdir=$(dirname $(facet_vdevice $ost))
27107         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
27108         local blksz=$(do_facet $ost $cmd $objid |
27109                       awk '/dblk/{getline; printf $4}')
27110
27111         case "${blksz: -1}" in
27112                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
27113                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
27114                 *) ;;
27115         esac
27116
27117         echo $blksz
27118 }
27119
27120 test_312() { # LU-4856
27121         remote_ost_nodsh && skip "remote OST with nodsh"
27122         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
27123
27124         local max_blksz=$(do_facet ost1 \
27125                           $ZFS get -p recordsize $(facet_device ost1) |
27126                           awk '!/VALUE/{print $3}')
27127         local tf=$DIR/$tfile
27128
27129         $LFS setstripe -c1 $tf
27130         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
27131
27132         # Get ZFS object id
27133         local zfs_objid=$(zfs_get_objid $facet $tf)
27134         # block size change by sequential overwrite
27135         local bs
27136
27137         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
27138                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
27139
27140                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
27141                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
27142         done
27143         rm -f $tf
27144
27145         $LFS setstripe -c1 $tf
27146         facet="ost$(($($LFS getstripe -i $tf) + 1))"
27147
27148         # block size change by sequential append write
27149         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
27150         zfs_objid=$(zfs_get_objid $facet $tf)
27151         local count
27152
27153         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
27154                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
27155                         oflag=sync conv=notrunc
27156
27157                 blksz=$(zfs_object_blksz $facet $zfs_objid)
27158                 (( $blksz == 2 * count * PAGE_SIZE )) ||
27159                         error "blksz error, actual $blksz, " \
27160                                 "expected: 2 * $count * $PAGE_SIZE"
27161         done
27162         rm -f $tf
27163
27164         # random write
27165         $LFS setstripe -c1 $tf
27166         facet="ost$(($($LFS getstripe -i $tf) + 1))"
27167         zfs_objid=$(zfs_get_objid $facet $tf)
27168
27169         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
27170         blksz=$(zfs_object_blksz $facet $zfs_objid)
27171         (( blksz == PAGE_SIZE )) ||
27172                 error "blksz error: $blksz, expected: $PAGE_SIZE"
27173
27174         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
27175         blksz=$(zfs_object_blksz $facet $zfs_objid)
27176         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
27177
27178         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
27179         blksz=$(zfs_object_blksz $facet $zfs_objid)
27180         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
27181 }
27182 run_test 312 "make sure ZFS adjusts its block size by write pattern"
27183
27184 test_313() {
27185         remote_ost_nodsh && skip "remote OST with nodsh"
27186
27187         local file=$DIR/$tfile
27188
27189         rm -f $file
27190         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
27191
27192         # define OBD_FAIL_TGT_RCVD_EIO           0x720
27193         do_facet ost1 "$LCTL set_param fail_loc=0x720"
27194         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
27195                 error "write should failed"
27196         do_facet ost1 "$LCTL set_param fail_loc=0"
27197         rm -f $file
27198 }
27199 run_test 313 "io should fail after last_rcvd update fail"
27200
27201 test_314() {
27202         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
27203
27204         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
27205         do_facet ost1 "$LCTL set_param fail_loc=0x720"
27206         rm -f $DIR/$tfile
27207         wait_delete_completed
27208         do_facet ost1 "$LCTL set_param fail_loc=0"
27209 }
27210 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
27211
27212 test_315() { # LU-618
27213         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
27214
27215         local file=$DIR/$tfile
27216         rm -f $file
27217
27218         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
27219                 error "multiop file write failed"
27220         $MULTIOP $file oO_RDONLY:r4063232_c &
27221         PID=$!
27222
27223         sleep 2
27224
27225         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
27226         kill -USR1 $PID
27227
27228         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
27229         rm -f $file
27230 }
27231 run_test 315 "read should be accounted"
27232
27233 test_316() {
27234         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
27235         large_xattr_enabled || skip "ea_inode feature disabled"
27236
27237         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27238         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
27239         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
27240         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
27241
27242         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
27243 }
27244 run_test 316 "lfs migrate of file with large_xattr enabled"
27245
27246 test_317() {
27247         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
27248                 skip "Need MDS version at least 2.11.53"
27249         if [ "$ost1_FSTYPE" == "zfs" ]; then
27250                 skip "LU-10370: no implementation for ZFS"
27251         fi
27252
27253         local trunc_sz
27254         local grant_blk_size
27255
27256         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
27257                         awk '/grant_block_size:/ { print $2; exit; }')
27258         #
27259         # Create File of size 5M. Truncate it to below size's and verify
27260         # blocks count.
27261         #
27262         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
27263                 error "Create file $DIR/$tfile failed"
27264         stack_trap "rm -f $DIR/$tfile" EXIT
27265
27266         for trunc_sz in 2097152 4097 4000 509 0; do
27267                 $TRUNCATE $DIR/$tfile $trunc_sz ||
27268                         error "truncate $tfile to $trunc_sz failed"
27269                 local sz=$(stat --format=%s $DIR/$tfile)
27270                 local blk=$(stat --format=%b $DIR/$tfile)
27271                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
27272                                      grant_blk_size) * 8))
27273
27274                 if [[ $blk -ne $trunc_blk ]]; then
27275                         $(which stat) $DIR/$tfile
27276                         error "Expected Block $trunc_blk got $blk for $tfile"
27277                 fi
27278
27279                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
27280                         error "Expected Size $trunc_sz got $sz for $tfile"
27281         done
27282
27283         #
27284         # sparse file test
27285         # Create file with a hole and write actual 65536 bytes which aligned
27286         # with 4K and 64K PAGE_SIZE. Block count must be 128.
27287         #
27288         local bs=65536
27289         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
27290                 error "Create file : $DIR/$tfile"
27291
27292         #
27293         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
27294         # blocks. The block count must drop to 8.
27295         #
27296         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
27297                 ((bs - grant_blk_size) + 1)))
27298         $TRUNCATE $DIR/$tfile $trunc_sz ||
27299                 error "truncate $tfile to $trunc_sz failed"
27300
27301         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
27302         sz=$(stat --format=%s $DIR/$tfile)
27303         blk=$(stat --format=%b $DIR/$tfile)
27304
27305         if [[ $blk -ne $trunc_bsz ]]; then
27306                 $(which stat) $DIR/$tfile
27307                 error "Expected Block $trunc_bsz got $blk for $tfile"
27308         fi
27309
27310         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
27311                 error "Expected Size $trunc_sz got $sz for $tfile"
27312 }
27313 run_test 317 "Verify blocks get correctly update after truncate"
27314
27315 test_318() {
27316         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
27317         local old_max_active=$($LCTL get_param -n \
27318                             ${llite_name}.max_read_ahead_async_active \
27319                             2>/dev/null)
27320
27321         $LCTL set_param llite.*.max_read_ahead_async_active=256
27322         local max_active=$($LCTL get_param -n \
27323                            ${llite_name}.max_read_ahead_async_active \
27324                            2>/dev/null)
27325         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
27326
27327         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
27328                 error "set max_read_ahead_async_active should succeed"
27329
27330         $LCTL set_param llite.*.max_read_ahead_async_active=512
27331         max_active=$($LCTL get_param -n \
27332                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
27333         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
27334
27335         # restore @max_active
27336         [ $old_max_active -ne 0 ] && $LCTL set_param \
27337                 llite.*.max_read_ahead_async_active=$old_max_active
27338
27339         local old_threshold=$($LCTL get_param -n \
27340                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
27341         local max_per_file_mb=$($LCTL get_param -n \
27342                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
27343
27344         local invalid=$(($max_per_file_mb + 1))
27345         $LCTL set_param \
27346                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
27347                         && error "set $invalid should fail"
27348
27349         local valid=$(($invalid - 1))
27350         $LCTL set_param \
27351                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
27352                         error "set $valid should succeed"
27353         local threshold=$($LCTL get_param -n \
27354                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
27355         [ $threshold -eq $valid ] || error \
27356                 "expect threshold $valid got $threshold"
27357         $LCTL set_param \
27358                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
27359 }
27360 run_test 318 "Verify async readahead tunables"
27361
27362 test_319() {
27363         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
27364
27365         local before=$(date +%s)
27366         local evict
27367         local mdir=$DIR/$tdir
27368         local file=$mdir/xxx
27369
27370         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
27371         touch $file
27372
27373 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
27374         $LCTL set_param fail_val=5 fail_loc=0x8000032c
27375         $LFS migrate -m1 $mdir &
27376
27377         sleep 1
27378         dd if=$file of=/dev/null
27379         wait
27380         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
27381           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
27382
27383         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
27384 }
27385 run_test 319 "lost lease lock on migrate error"
27386
27387 test_350() {
27388         local mdts=$(comma_list $(mdts_nodes))
27389
27390         mkdir $DIR/$tdir || error "mkdir $DIR/$tdir failed"
27391         stack_trap "rm -r $DIR/$tdir"
27392
27393         #force 1/100 of replies to take "NID mismatch" codepath
27394         #define CFS_FAIL_MATCH_MD_NID 0xe001  CFS_FAIL_SOME 0x10000000
27395         do_nodes $mdts $LCTL set_param fail_loc=0x1000e001 fail_val=100
27396
27397         while ls -lR $DIR/$tdir > /dev/null; do :; done &
27398         stack_trap "killall -9 ls || killall -9 ls"
27399
27400         cp -a /etc $DIR/$tdir || error "cp failed"
27401 }
27402 run_test 350 "force NID mismatch path to be exercised"
27403
27404 test_360() {
27405         (( $OST1_VERSION >= $(version_code 2.15.58.96) )) ||
27406                 skip "Need OST version at least 2.15.58.96"
27407         [[ "$ost1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
27408
27409         check_set_fallocate_or_skip
27410         local param="osd-ldiskfs.delayed_unlink_mb"
27411         local old=($(do_facet ost1 "$LCTL get_param -n $param"))
27412
27413         do_facet ost1 "$LCTL set_param $param=1MiB"
27414         stack_trap "do_facet ost1 $LCTL set_param $param=${old[0]}"
27415
27416         mkdir $DIR/$tdir/
27417         do_facet ost1 $LCTL set_param debug=+inode
27418         do_facet ost1 $LCTL clear
27419         local files=100
27420
27421         for ((i = 0; i < $files; i++)); do
27422                 fallocate -l 1280k $DIR/$tdir/$tfile.$i ||
27423                         error "fallocate 1280k $DIR/$tdir/$tfile.$i failed"
27424         done
27425         local min=$(($($LFS find $DIR/$tdir --ost 0 | wc -l) / 2))
27426
27427         for ((i = 0; i < $files; i++)); do
27428                 unlink $DIR/$tdir/$tfile.$i ||
27429                         error "unlink $DIR/$tdir/$tfile.$i failed"
27430         done
27431
27432         local count=0
27433         local loop
27434
27435         for (( loop = 0; loop < 30 && count < min; loop++)); do
27436                 sleep 1
27437                 (( count += $(do_facet ost1 $LCTL dk | grep -c "delayed iput")))
27438                 echo "Count[$loop]: $count"
27439         done
27440         (( count >= min )) || error "$count < $min delayed iput after $loop s"
27441 }
27442 run_test 360 "ldiskfs unlink in a separate thread"
27443
27444 test_398a() { # LU-4198
27445         local ost1_imp=$(get_osc_import_name client ost1)
27446         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27447                          cut -d'.' -f2)
27448
27449         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27450         stack_trap "rm -f $DIR/$tfile"
27451         $LCTL set_param ldlm.namespaces.*.lru_size=clear
27452
27453         # request a new lock on client
27454         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27455
27456         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
27457         local lock_count=$($LCTL get_param -n \
27458                            ldlm.namespaces.$imp_name.lru_size)
27459         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
27460
27461         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
27462
27463         # no lock cached, should use lockless DIO and not enqueue new lock
27464         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
27465         lock_count=$($LCTL get_param -n \
27466                      ldlm.namespaces.$imp_name.lru_size)
27467         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
27468
27469         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
27470
27471         # no lock cached, should use locked DIO append
27472         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
27473                 conv=notrunc || error "DIO append failed"
27474         lock_count=$($LCTL get_param -n \
27475                      ldlm.namespaces.$imp_name.lru_size)
27476         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
27477 }
27478 run_test 398a "direct IO should cancel lock otherwise lockless"
27479
27480 test_398b() { # LU-4198
27481         local before=$(date +%s)
27482         local njobs=4
27483         local size=48
27484
27485         which fio || skip_env "no fio installed"
27486         $LFS setstripe -c -1 -S 1M $DIR/$tfile
27487         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
27488
27489         # Single page, multiple pages, stripe size, 4*stripe size
27490         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
27491                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
27492                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
27493                         --numjobs=$njobs --fallocate=none \
27494                         --iodepth=16 --allow_file_create=0 \
27495                         --size=$((size/njobs))M \
27496                         --filename=$DIR/$tfile &
27497                 bg_pid=$!
27498
27499                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
27500                 fio --name=rand-rw --rw=randrw --bs=$bsize \
27501                         --numjobs=$njobs --fallocate=none \
27502                         --iodepth=16 --allow_file_create=0 \
27503                         --size=$((size/njobs))M \
27504                         --filename=$DIR/$tfile || true
27505                 wait $bg_pid
27506         done
27507
27508         evict=$(do_facet client $LCTL get_param \
27509                 osc.$FSNAME-OST*-osc-*/state |
27510             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
27511
27512         [ -z "$evict" ] || [[ $evict -le $before ]] ||
27513                 (do_facet client $LCTL get_param \
27514                         osc.$FSNAME-OST*-osc-*/state;
27515                     error "eviction happened: $evict before:$before")
27516
27517         rm -f $DIR/$tfile
27518 }
27519 run_test 398b "DIO and buffer IO race"
27520
27521 test_398c() { # LU-4198
27522         local ost1_imp=$(get_osc_import_name client ost1)
27523         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27524                          cut -d'.' -f2)
27525
27526         which fio || skip_env "no fio installed"
27527
27528         saved_debug=$($LCTL get_param -n debug)
27529         $LCTL set_param debug=0
27530
27531         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
27532         ((size /= 1024)) # by megabytes
27533         ((size /= 2)) # write half of the OST at most
27534         [ $size -gt 40 ] && size=40 #reduce test time anyway
27535
27536         $LFS setstripe -c 1 $DIR/$tfile
27537
27538         # it seems like ldiskfs reserves more space than necessary if the
27539         # writing blocks are not mapped, so it extends the file firstly
27540         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
27541         cancel_lru_locks osc
27542
27543         # clear and verify rpc_stats later
27544         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
27545
27546         local njobs=4
27547         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
27548         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
27549                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
27550                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
27551                 --filename=$DIR/$tfile
27552         [ $? -eq 0 ] || error "fio write error"
27553
27554         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
27555                 error "Locks were requested while doing AIO"
27556
27557         # get the percentage of 1-page I/O
27558         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
27559                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
27560                 awk '{print $7}')
27561         (( $pct <= 50 )) || {
27562                 $LCTL get_param osc.${imp_name}.rpc_stats
27563                 error "$pct% of I/O are 1-page"
27564         }
27565
27566         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
27567         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
27568                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
27569                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
27570                 --filename=$DIR/$tfile
27571         [ $? -eq 0 ] || error "fio mixed read write error"
27572
27573         echo "AIO with large block size ${size}M"
27574         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
27575                 --numjobs=1 --fallocate=none --ioengine=libaio \
27576                 --iodepth=16 --allow_file_create=0 --size=${size}M \
27577                 --filename=$DIR/$tfile
27578         [ $? -eq 0 ] || error "fio large block size failed"
27579
27580         rm -f $DIR/$tfile
27581         $LCTL set_param debug="$saved_debug"
27582 }
27583 run_test 398c "run fio to test AIO"
27584
27585 test_398d() { #  LU-13846
27586         which aiocp || skip_env "no aiocp installed"
27587         local aio_file=$DIR/$tfile.aio
27588
27589         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
27590
27591         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
27592         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
27593         stack_trap "rm -f $DIR/$tfile $aio_file"
27594
27595         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
27596
27597         # test memory unaligned aio
27598         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file ||
27599                 error "unaligned aio failed"
27600         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
27601
27602         rm -f $DIR/$tfile $aio_file
27603 }
27604 run_test 398d "run aiocp to verify block size > stripe size"
27605
27606 test_398e() {
27607         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
27608         touch $DIR/$tfile.new
27609         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
27610 }
27611 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
27612
27613 test_398f() { #  LU-14687
27614         which aiocp || skip_env "no aiocp installed"
27615         local aio_file=$DIR/$tfile.aio
27616
27617         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
27618
27619         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
27620         stack_trap "rm -f $DIR/$tfile $aio_file"
27621
27622         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
27623         $LCTL set_param fail_loc=0x1418
27624         # make sure we don't crash and fail properly
27625         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
27626                 error "aio with page allocation failure succeeded"
27627         $LCTL set_param fail_loc=0
27628         diff $DIR/$tfile $aio_file
27629         [[ $? != 0 ]] || error "no diff after failed aiocp"
27630 }
27631 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
27632
27633 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
27634 # stripe and i/o size must be > stripe size
27635 # Old style synchronous DIO waits after submitting each chunk, resulting in a
27636 # single RPC in flight.  This test shows async DIO submission is working by
27637 # showing multiple RPCs in flight.
27638 test_398g() { #  LU-13798
27639         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
27640
27641         # We need to do some i/o first to acquire enough grant to put our RPCs
27642         # in flight; otherwise a new connection may not have enough grant
27643         # available
27644         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27645                 error "parallel dio failed"
27646         stack_trap "rm -f $DIR/$tfile"
27647
27648         # Reduce RPC size to 1M to avoid combination in to larger RPCs
27649         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
27650         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
27651         stack_trap "$LCTL set_param -n $pages_per_rpc"
27652
27653         # Recreate file so it's empty
27654         rm -f $DIR/$tfile
27655         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
27656         #Pause rpc completion to guarantee we see multiple rpcs in flight
27657         #define OBD_FAIL_OST_BRW_PAUSE_BULK
27658         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
27659         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
27660
27661         # Clear rpc stats
27662         $LCTL set_param osc.*.rpc_stats=c
27663
27664         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27665                 error "parallel dio failed"
27666         stack_trap "rm -f $DIR/$tfile"
27667
27668         $LCTL get_param osc.*-OST0000-*.rpc_stats
27669         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
27670                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
27671                 grep "8:" | awk '{print $8}')
27672         # We look at the "8 rpcs in flight" field, and verify A) it is present
27673         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
27674         # as expected for an 8M DIO to a file with 1M stripes.
27675         # NB: There is occasionally a mystery extra write RPC to a different
27676         # file.  I can't identify why that's happening, so we set up a margin
27677         # of 1 RPC here, ie, 8/9 RPCs at this size, or ~88%
27678         [ $pct -gt 87 ] || error "we should see 8 RPCs in flight"
27679
27680         # Verify turning off parallel dio works as expected
27681         # Clear rpc stats
27682         $LCTL set_param osc.*.rpc_stats=c
27683         $LCTL set_param llite.*.parallel_dio=0
27684         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
27685
27686         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27687                 error "dio with parallel dio disabled failed"
27688
27689         # Ideally, we would see only one RPC in flight here, but there is an
27690         # unavoidable race between i/o completion and RPC in flight counting,
27691         # so while only 1 i/o is in flight at a time, the RPC in flight counter
27692         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
27693         # So instead we just verify it's always < 8.
27694         $LCTL get_param osc.*-OST0000-*.rpc_stats
27695         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
27696                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
27697                 grep '^$' -B1 | grep . | awk '{print $1}')
27698         [ $ret != "8:" ] ||
27699                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
27700 }
27701 run_test 398g "verify parallel dio async RPC submission"
27702
27703 test_398h() { #  LU-13798
27704         local dio_file=$DIR/$tfile.dio
27705
27706         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
27707
27708         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27709         stack_trap "rm -f $DIR/$tfile $dio_file"
27710
27711         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
27712                 error "parallel dio failed"
27713         diff $DIR/$tfile $dio_file
27714         [[ $? == 0 ]] || error "file diff after aiocp"
27715 }
27716 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
27717
27718 test_398i() { #  LU-13798
27719         local dio_file=$DIR/$tfile.dio
27720
27721         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
27722
27723         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27724         stack_trap "rm -f $DIR/$tfile $dio_file"
27725
27726         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
27727         $LCTL set_param fail_loc=0x1418
27728         # make sure we don't crash and fail properly
27729         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
27730                 error "parallel dio page allocation failure succeeded"
27731         diff $DIR/$tfile $dio_file
27732         [[ $? != 0 ]] || error "no diff after failed aiocp"
27733 }
27734 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
27735
27736 test_398j() { #  LU-13798
27737         # Stripe size > RPC size but less than i/o size tests split across
27738         # stripes and RPCs for individual i/o op
27739         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
27740
27741         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
27742         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
27743         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
27744         stack_trap "$LCTL set_param -n $pages_per_rpc"
27745
27746         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27747                 error "parallel dio write failed"
27748         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
27749
27750         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
27751                 error "parallel dio read failed"
27752         diff $DIR/$tfile $DIR/$tfile.2
27753         [[ $? == 0 ]] || error "file diff after parallel dio read"
27754 }
27755 run_test 398j "test parallel dio where stripe size > rpc_size"
27756
27757 test_398k() { #  LU-13798
27758         wait_delete_completed
27759         wait_mds_ost_sync
27760
27761         # 4 stripe file; we will cause out of space on OST0
27762         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
27763
27764         # Fill OST0 (if it's not too large)
27765         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
27766                    head -n1)
27767         if [[ $ORIGFREE -gt $MAXFREE ]]; then
27768                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
27769         fi
27770         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
27771         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
27772                 error "dd should fill OST0"
27773         stack_trap "rm -f $DIR/$tfile.1"
27774
27775         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27776         err=$?
27777
27778         ls -la $DIR/$tfile
27779         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
27780                 error "file is not 0 bytes in size"
27781
27782         # dd above should not succeed, but don't error until here so we can
27783         # get debug info above
27784         [[ $err != 0 ]] ||
27785                 error "parallel dio write with enospc succeeded"
27786         stack_trap "rm -f $DIR/$tfile"
27787 }
27788 run_test 398k "test enospc on first stripe"
27789
27790 test_398l() { #  LU-13798
27791         wait_delete_completed
27792         wait_mds_ost_sync
27793
27794         # 4 stripe file; we will cause out of space on OST0
27795         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
27796         # happens on the second i/o chunk we issue
27797         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
27798
27799         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
27800         stack_trap "rm -f $DIR/$tfile"
27801
27802         # Fill OST0 (if it's not too large)
27803         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
27804                    head -n1)
27805         if [[ $ORIGFREE -gt $MAXFREE ]]; then
27806                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
27807         fi
27808         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
27809         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
27810                 error "dd should fill OST0"
27811         stack_trap "rm -f $DIR/$tfile.1"
27812
27813         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
27814         err=$?
27815         stack_trap "rm -f $DIR/$tfile.2"
27816
27817         # Check that short write completed as expected
27818         ls -la $DIR/$tfile.2
27819         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
27820                 error "file is not 1M in size"
27821
27822         # dd above should not succeed, but don't error until here so we can
27823         # get debug info above
27824         [[ $err != 0 ]] ||
27825                 error "parallel dio write with enospc succeeded"
27826
27827         # Truncate source file to same length as output file and diff them
27828         $TRUNCATE $DIR/$tfile 1048576
27829         diff $DIR/$tfile $DIR/$tfile.2
27830         [[ $? == 0 ]] || error "data incorrect after short write"
27831 }
27832 run_test 398l "test enospc on intermediate stripe/RPC"
27833
27834 test_398m() { #  LU-13798
27835         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
27836
27837         # Set up failure on OST0, the first stripe:
27838         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
27839         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
27840         # OST0 is on ost1, OST1 is on ost2.
27841         # So this fail_val specifies OST0
27842         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
27843         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
27844
27845         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
27846                 error "parallel dio write with failure on first stripe succeeded"
27847         stack_trap "rm -f $DIR/$tfile"
27848         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
27849
27850         # Place data in file for read
27851         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27852                 error "parallel dio write failed"
27853
27854         # Fail read on OST0, first stripe
27855         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
27856         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
27857         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
27858                 error "parallel dio read with error on first stripe succeeded"
27859         rm -f $DIR/$tfile.2
27860         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
27861
27862         # Switch to testing on OST1, second stripe
27863         # Clear file contents, maintain striping
27864         echo > $DIR/$tfile
27865         # Set up failure on OST1, second stripe:
27866         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
27867         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
27868
27869         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
27870                 error "parallel dio write with failure on second stripe succeeded"
27871         stack_trap "rm -f $DIR/$tfile"
27872         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
27873
27874         # Place data in file for read
27875         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27876                 error "parallel dio write failed"
27877
27878         # Fail read on OST1, second stripe
27879         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
27880         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
27881         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
27882                 error "parallel dio read with error on second stripe succeeded"
27883         rm -f $DIR/$tfile.2
27884         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
27885 }
27886 run_test 398m "test RPC failures with parallel dio"
27887
27888 # Parallel submission of DIO should not cause problems for append, but it's
27889 # important to verify.
27890 test_398n() { #  LU-13798
27891         $LFS setstripe -C 2 -S 1M $DIR/$tfile
27892
27893         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
27894                 error "dd to create source file failed"
27895         stack_trap "rm -f $DIR/$tfile"
27896
27897         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
27898                 error "parallel dio write with failure on second stripe succeeded"
27899         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
27900         diff $DIR/$tfile $DIR/$tfile.1
27901         [[ $? == 0 ]] || error "data incorrect after append"
27902
27903 }
27904 run_test 398n "test append with parallel DIO"
27905
27906 test_398o() {
27907         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
27908 }
27909 run_test 398o "right kms with DIO"
27910
27911 test_398p()
27912 {
27913         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
27914         which aiocp || skip_env "no aiocp installed"
27915
27916         local stripe_size=$((1024 * 1024)) #1 MiB
27917         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
27918         local file_size=$((25 * stripe_size))
27919
27920         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
27921         stack_trap "rm -f $DIR/$tfile*"
27922         # Just a bit bigger than the largest size in the test set below
27923         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
27924                 error "buffered i/o to create file failed"
27925
27926         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
27927                 $((stripe_size * 4)); do
27928
27929                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
27930
27931                 echo "bs: $bs, file_size $file_size"
27932                 aiocp -a $PAGE_SIZE -b $bs -s $file_size -f O_DIRECT \
27933                         $DIR/$tfile.1 $DIR/$tfile.2 &
27934                 pid_dio1=$!
27935                 # Buffered I/O with similar but not the same block size
27936                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
27937                         conv=notrunc &
27938                 pid_bio2=$!
27939                 wait $pid_dio1
27940                 rc1=$?
27941                 wait $pid_bio2
27942                 rc2=$?
27943                 if (( rc1 != 0 )); then
27944                         error "aio copy 1 w/bsize $bs failed: $rc1"
27945                 fi
27946                 if (( rc2 != 0 )); then
27947                         error "buffered copy 2 w/bsize $bs failed: $rc2"
27948                 fi
27949
27950                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
27951                         error "size incorrect"
27952                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
27953                         error "files differ, bsize $bs"
27954                 rm -f $DIR/$tfile.2
27955         done
27956 }
27957 run_test 398p "race aio with buffered i/o"
27958
27959 test_398q()
27960 {
27961         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
27962
27963         local stripe_size=$((1024 * 1024)) #1 MiB
27964         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
27965         local file_size=$((25 * stripe_size))
27966
27967         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
27968         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
27969
27970         # Just a bit bigger than the largest size in the test set below
27971         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
27972                 error "buffered i/o to create file failed"
27973
27974         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
27975                 $((stripe_size * 4)); do
27976
27977                 echo "bs: $bs, file_size $file_size"
27978                 dd if=$DIR/$tfile.1 bs=$((bs *2 )) of=$DIR/$tfile.2 \
27979                         conv=notrunc oflag=direct iflag=direct &
27980                 pid_dio1=$!
27981                 # Buffered I/O with similar but not the same block size
27982                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
27983                         conv=notrunc &
27984                 pid_bio2=$!
27985                 wait $pid_dio1
27986                 rc1=$?
27987                 wait $pid_bio2
27988                 rc2=$?
27989                 if (( rc1 != 0 )); then
27990                         error "dio copy 1 w/bsize $bs failed: $rc1"
27991                 fi
27992                 if (( rc2 != 0 )); then
27993                         error "buffered copy 2 w/bsize $bs failed: $rc2"
27994                 fi
27995
27996                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
27997                         error "size incorrect"
27998                 diff $DIR/$tfile.1 $DIR/$tfile.2 ||
27999                         error "files differ, bsize $bs"
28000         done
28001
28002         rm -f $DIR/$tfile*
28003 }
28004 run_test 398q "race dio with buffered i/o"
28005
28006 test_fake_rw() {
28007         local read_write=$1
28008         if [ "$read_write" = "write" ]; then
28009                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
28010         elif [ "$read_write" = "read" ]; then
28011                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
28012         else
28013                 error "argument error"
28014         fi
28015
28016         # turn off debug for performance testing
28017         local saved_debug=$($LCTL get_param -n debug)
28018         $LCTL set_param debug=0
28019
28020         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28021
28022         # get ost1 size - $FSNAME-OST0000
28023         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
28024         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
28025         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
28026
28027         if [ "$read_write" = "read" ]; then
28028                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
28029         fi
28030
28031         local start_time=$(date +%s.%N)
28032         $dd_cmd bs=1M count=$blocks oflag=sync ||
28033                 error "real dd $read_write error"
28034         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
28035
28036         if [ "$read_write" = "write" ]; then
28037                 rm -f $DIR/$tfile
28038         fi
28039
28040         # define OBD_FAIL_OST_FAKE_RW           0x238
28041         do_facet ost1 $LCTL set_param fail_loc=0x238
28042
28043         local start_time=$(date +%s.%N)
28044         $dd_cmd bs=1M count=$blocks oflag=sync ||
28045                 error "fake dd $read_write error"
28046         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
28047
28048         if [ "$read_write" = "write" ]; then
28049                 # verify file size
28050                 cancel_lru_locks osc
28051                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
28052                         error "$tfile size not $blocks MB"
28053         fi
28054         do_facet ost1 $LCTL set_param fail_loc=0
28055
28056         echo "fake $read_write $duration_fake vs. normal $read_write" \
28057                 "$duration in seconds"
28058         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
28059                 error_not_in_vm "fake write is slower"
28060
28061         $LCTL set_param -n debug="$saved_debug"
28062         rm -f $DIR/$tfile
28063 }
28064 test_399a() { # LU-7655 for OST fake write
28065         remote_ost_nodsh && skip "remote OST with nodsh"
28066
28067         test_fake_rw write
28068 }
28069 run_test 399a "fake write should not be slower than normal write"
28070
28071 test_399b() { # LU-8726 for OST fake read
28072         remote_ost_nodsh && skip "remote OST with nodsh"
28073         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
28074                 skip_env "ldiskfs only test"
28075         fi
28076
28077         test_fake_rw read
28078 }
28079 run_test 399b "fake read should not be slower than normal read"
28080
28081 test_400a() { # LU-1606, was conf-sanity test_74
28082         if ! which $CC > /dev/null 2>&1; then
28083                 skip_env "$CC is not installed"
28084         fi
28085
28086         local extra_flags=''
28087         local out=$TMP/$tfile
28088         local prefix=/usr/include/lustre
28089         local prog
28090
28091         # Oleg removes .c files in his test rig so test if any c files exist
28092         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
28093                 skip_env "Needed .c test files are missing"
28094
28095         if ! [[ -d $prefix ]]; then
28096                 # Assume we're running in tree and fixup the include path.
28097                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
28098                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
28099                 extra_flags+=" -L$LUSTRE/utils/.libs"
28100         fi
28101
28102         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
28103                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
28104                         error "client api broken"
28105         done
28106         rm -f $out
28107 }
28108 run_test 400a "Lustre client api program can compile and link"
28109
28110 test_400b() { # LU-1606, LU-5011
28111         local header
28112         local out=$TMP/$tfile
28113         local prefix=/usr/include/linux/lustre
28114
28115         # We use a hard coded prefix so that this test will not fail
28116         # when run in tree. There are headers in lustre/include/lustre/
28117         # that are not packaged (like lustre_idl.h) and have more
28118         # complicated include dependencies (like config.h and lnet/types.h).
28119         # Since this test about correct packaging we just skip them when
28120         # they don't exist (see below) rather than try to fixup cppflags.
28121
28122         if ! which $CC > /dev/null 2>&1; then
28123                 skip_env "$CC is not installed"
28124         fi
28125
28126         for header in $prefix/*.h; do
28127                 if ! [[ -f "$header" ]]; then
28128                         continue
28129                 fi
28130
28131                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
28132                         continue # lustre_ioctl.h is internal header
28133                 fi
28134
28135                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
28136                         error "cannot compile '$header'"
28137         done
28138         rm -f $out
28139 }
28140 run_test 400b "packaged headers can be compiled"
28141
28142 test_401a() { #LU-7437
28143         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
28144         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
28145
28146         #count the number of parameters by "list_param -R"
28147         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
28148         #count the number of parameters by listing proc files
28149         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
28150         echo "proc_dirs='$proc_dirs'"
28151         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
28152         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
28153                       sort -u | wc -l)
28154
28155         [ $params -eq $procs ] ||
28156                 error "found $params parameters vs. $procs proc files"
28157
28158         # test the list_param -D option only returns directories
28159         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
28160         #count the number of parameters by listing proc directories
28161         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
28162                 sort -u | wc -l)
28163
28164         [ $params -eq $procs ] ||
28165                 error "found $params parameters vs. $procs proc files"
28166 }
28167 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
28168
28169 test_401b() {
28170         # jobid_var may not allow arbitrary values, so use jobid_name
28171         # if available
28172         if $LCTL list_param jobid_name > /dev/null 2>&1; then
28173                 local testname=jobid_name tmp='testing%p'
28174         else
28175                 local testname=jobid_var tmp=testing
28176         fi
28177
28178         local save=$($LCTL get_param -n $testname)
28179
28180         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
28181                 error "no error returned when setting bad parameters"
28182
28183         local jobid_new=$($LCTL get_param -n foe $testname baz)
28184         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
28185
28186         $LCTL set_param -n fog=bam $testname=$save bat=fog
28187         local jobid_old=$($LCTL get_param -n foe $testname bag)
28188         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
28189 }
28190 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
28191
28192 test_401c() {
28193         # jobid_var may not allow arbitrary values, so use jobid_name
28194         # if available
28195         if $LCTL list_param jobid_name > /dev/null 2>&1; then
28196                 local testname=jobid_name
28197         else
28198                 local testname=jobid_var
28199         fi
28200
28201         local jobid_var_old=$($LCTL get_param -n $testname)
28202         local jobid_var_new
28203
28204         $LCTL set_param $testname= &&
28205                 error "no error returned for 'set_param a='"
28206
28207         jobid_var_new=$($LCTL get_param -n $testname)
28208         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
28209                 error "$testname was changed by setting without value"
28210
28211         $LCTL set_param $testname &&
28212                 error "no error returned for 'set_param a'"
28213
28214         jobid_var_new=$($LCTL get_param -n $testname)
28215         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
28216                 error "$testname was changed by setting without value"
28217 }
28218 run_test 401c "Verify 'lctl set_param' without value fails in either format."
28219
28220 test_401d() {
28221         # jobid_var may not allow arbitrary values, so use jobid_name
28222         # if available
28223         if $LCTL list_param jobid_name > /dev/null 2>&1; then
28224                 local testname=jobid_name new_value='foo=bar%p'
28225         else
28226                 local testname=jobid_var new_valuie=foo=bar
28227         fi
28228
28229         local jobid_var_old=$($LCTL get_param -n $testname)
28230         local jobid_var_new
28231
28232         $LCTL set_param $testname=$new_value ||
28233                 error "'set_param a=b' did not accept a value containing '='"
28234
28235         jobid_var_new=$($LCTL get_param -n $testname)
28236         [[ "$jobid_var_new" == "$new_value" ]] ||
28237                 error "'set_param a=b' failed on a value containing '='"
28238
28239         # Reset the $testname to test the other format
28240         $LCTL set_param $testname=$jobid_var_old
28241         jobid_var_new=$($LCTL get_param -n $testname)
28242         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
28243                 error "failed to reset $testname"
28244
28245         $LCTL set_param $testname $new_value ||
28246                 error "'set_param a b' did not accept a value containing '='"
28247
28248         jobid_var_new=$($LCTL get_param -n $testname)
28249         [[ "$jobid_var_new" == "$new_value" ]] ||
28250                 error "'set_param a b' failed on a value containing '='"
28251
28252         $LCTL set_param $testname $jobid_var_old
28253         jobid_var_new=$($LCTL get_param -n $testname)
28254         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
28255                 error "failed to reset $testname"
28256 }
28257 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
28258
28259 test_401e() { # LU-14779
28260         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
28261                 error "lctl list_param MGC* failed"
28262         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
28263         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
28264                 error "lctl get_param lru_size failed"
28265 }
28266 run_test 401e "verify 'lctl get_param' works with NID in parameter"
28267
28268 test_402() {
28269         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
28270         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
28271                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
28272         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
28273                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
28274                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
28275         remote_mds_nodsh && skip "remote MDS with nodsh"
28276
28277         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
28278 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
28279         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
28280         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
28281                 echo "Touch failed - OK"
28282 }
28283 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
28284
28285 test_403() {
28286         local file1=$DIR/$tfile.1
28287         local file2=$DIR/$tfile.2
28288         local tfile=$TMP/$tfile
28289
28290         rm -f $file1 $file2 $tfile
28291
28292         touch $file1
28293         ln $file1 $file2
28294
28295         # 30 sec OBD_TIMEOUT in ll_getattr()
28296         # right before populating st_nlink
28297         $LCTL set_param fail_loc=0x80001409
28298         stat -c %h $file1 > $tfile &
28299
28300         # create an alias, drop all locks and reclaim the dentry
28301         < $file2
28302         cancel_lru_locks mdc
28303         cancel_lru_locks osc
28304         sysctl -w vm.drop_caches=2
28305
28306         wait
28307
28308         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
28309
28310         rm -f $tfile $file1 $file2
28311 }
28312 run_test 403 "i_nlink should not drop to zero due to aliasing"
28313
28314 test_404() { # LU-6601
28315         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
28316                 skip "Need server version newer than 2.8.52"
28317         remote_mds_nodsh && skip "remote MDS with nodsh"
28318
28319         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
28320                 awk '/osp .*-osc-MDT/ { print $4}')
28321
28322         local osp
28323         for osp in $mosps; do
28324                 echo "Deactivate: " $osp
28325                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
28326                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
28327                         awk -vp=$osp '$4 == p { print $2 }')
28328                 [ $stat = IN ] || {
28329                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
28330                         error "deactivate error"
28331                 }
28332                 echo "Activate: " $osp
28333                 do_facet $SINGLEMDS $LCTL --device %$osp activate
28334                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
28335                         awk -vp=$osp '$4 == p { print $2 }')
28336                 [ $stat = UP ] || {
28337                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
28338                         error "activate error"
28339                 }
28340         done
28341 }
28342 run_test 404 "validate manual {de}activated works properly for OSPs"
28343
28344 test_405() {
28345         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
28346         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
28347                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
28348                         skip "Layout swap lock is not supported"
28349
28350         check_swap_layouts_support
28351         check_swap_layout_no_dom $DIR
28352
28353         test_mkdir $DIR/$tdir
28354         swap_lock_test -d $DIR/$tdir ||
28355                 error "One layout swap locked test failed"
28356 }
28357 run_test 405 "Various layout swap lock tests"
28358
28359 test_406() {
28360         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
28361         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
28362         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
28363         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28364         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
28365                 skip "Need MDS version at least 2.8.50"
28366
28367         local def_stripe_size=$($LFS getstripe -S $MOUNT)
28368         local test_pool=$TESTNAME
28369
28370         pool_add $test_pool || error "pool_add failed"
28371         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
28372                 error "pool_add_targets failed"
28373
28374         save_layout_restore_at_exit $MOUNT
28375
28376         # parent set default stripe count only, child will stripe from both
28377         # parent and fs default
28378         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
28379                 error "setstripe $MOUNT failed"
28380         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
28381         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
28382         for i in $(seq 10); do
28383                 local f=$DIR/$tdir/$tfile.$i
28384                 touch $f || error "touch failed"
28385                 local count=$($LFS getstripe -c $f)
28386                 [ $count -eq $OSTCOUNT ] ||
28387                         error "$f stripe count $count != $OSTCOUNT"
28388                 local offset=$($LFS getstripe -i $f)
28389                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
28390                 local size=$($LFS getstripe -S $f)
28391                 [ $size -eq $((def_stripe_size * 2)) ] ||
28392                         error "$f stripe size $size != $((def_stripe_size * 2))"
28393                 local pool=$($LFS getstripe -p $f)
28394                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
28395         done
28396
28397         # change fs default striping, delete parent default striping, now child
28398         # will stripe from new fs default striping only
28399         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
28400                 error "change $MOUNT default stripe failed"
28401         $LFS setstripe -c 0 $DIR/$tdir ||
28402                 error "delete $tdir default stripe failed"
28403         for i in $(seq 11 20); do
28404                 local f=$DIR/$tdir/$tfile.$i
28405                 touch $f || error "touch $f failed"
28406                 local count=$($LFS getstripe -c $f)
28407                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
28408                 local offset=$($LFS getstripe -i $f)
28409                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
28410                 local size=$($LFS getstripe -S $f)
28411                 [ $size -eq $def_stripe_size ] ||
28412                         error "$f stripe size $size != $def_stripe_size"
28413                 local pool=$($LFS getstripe -p $f)
28414                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
28415         done
28416
28417         unlinkmany $DIR/$tdir/$tfile. 1 20
28418
28419         local f=$DIR/$tdir/$tfile
28420         pool_remove_all_targets $test_pool $f
28421         pool_remove $test_pool $f
28422 }
28423 run_test 406 "DNE support fs default striping"
28424
28425 test_407() {
28426         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
28427         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
28428                 skip "Need MDS version at least 2.8.55"
28429         remote_mds_nodsh && skip "remote MDS with nodsh"
28430
28431         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
28432                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
28433         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
28434                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
28435         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
28436
28437         #define OBD_FAIL_DT_TXN_STOP    0x2019
28438         for idx in $(seq $MDSCOUNT); do
28439                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
28440         done
28441         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
28442         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
28443                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
28444         true
28445 }
28446 run_test 407 "transaction fail should cause operation fail"
28447
28448 test_408() {
28449         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
28450
28451         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
28452         lctl set_param fail_loc=0x8000040a
28453         # let ll_prepare_partial_page() fail
28454         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
28455
28456         rm -f $DIR/$tfile
28457
28458         # create at least 100 unused inodes so that
28459         # shrink_icache_memory(0) should not return 0
28460         touch $DIR/$tfile-{0..100}
28461         rm -f $DIR/$tfile-{0..100}
28462         sync
28463
28464         echo 2 > /proc/sys/vm/drop_caches
28465 }
28466 run_test 408 "drop_caches should not hang due to page leaks"
28467
28468 test_409()
28469 {
28470         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28471
28472         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
28473         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
28474         touch $DIR/$tdir/guard || error "(2) Fail to create"
28475
28476         local PREFIX=$(str_repeat 'A' 128)
28477         echo "Create 1K hard links start at $(date)"
28478         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
28479                 error "(3) Fail to hard link"
28480
28481         echo "Links count should be right although linkEA overflow"
28482         stat $DIR/$tdir/guard || error "(4) Fail to stat"
28483         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
28484         [ $linkcount -eq 1001 ] ||
28485                 error "(5) Unexpected hard links count: $linkcount"
28486
28487         echo "List all links start at $(date)"
28488         ls -l $DIR/$tdir/foo > /dev/null ||
28489                 error "(6) Fail to list $DIR/$tdir/foo"
28490
28491         echo "Unlink hard links start at $(date)"
28492         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
28493                 error "(7) Fail to unlink"
28494         echo "Unlink hard links finished at $(date)"
28495 }
28496 run_test 409 "Large amount of cross-MDTs hard links on the same file"
28497
28498 test_410()
28499 {
28500         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
28501                 skip "Need client version at least 2.9.59"
28502
28503         # Create a file, and stat it from the kernel
28504         local testfile=$DIR/$tfile
28505         touch $testfile
28506
28507         local run_id=$RANDOM
28508         local my_ino=$(stat --format "%i" $testfile)
28509
28510         # Try to insert the module.
28511         load_module kunit/kinode run_id=$run_id fname=$testfile ||
28512                 error "load_module failed"
28513
28514         # Anything but success is a test failure
28515         dmesg | grep -q \
28516             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
28517             error "no inode match"
28518
28519         # Remove the test module
28520         rmmod -v kinode ||
28521                 error "rmmod failed (may trigger a failure in a later test)"
28522 }
28523 run_test 410 "Test inode number returned from kernel thread"
28524
28525 cleanup_test411_cgroup() {
28526         trap 0
28527         cat $1/memory.stat
28528         rmdir "$1"
28529 }
28530
28531 test_411a() {
28532         local cg_basedir=/sys/fs/cgroup/memory
28533         # LU-9966
28534         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
28535                 skip "no setup for cgroup"
28536
28537         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
28538                 error "test file creation failed"
28539         cancel_lru_locks osc
28540
28541         # Create a very small memory cgroup to force a slab allocation error
28542         local cgdir=$cg_basedir/osc_slab_alloc
28543         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
28544         trap "cleanup_test411_cgroup $cgdir" EXIT
28545         echo 2M > $cgdir/memory.kmem.limit_in_bytes
28546         echo 1M > $cgdir/memory.limit_in_bytes
28547
28548         # Should not LBUG, just be killed by oom-killer
28549         # dd will return 0 even allocation failure in some environment.
28550         # So don't check return value
28551         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
28552         cleanup_test411_cgroup $cgdir
28553
28554         return 0
28555 }
28556 run_test 411a "Slab allocation error with cgroup does not LBUG"
28557
28558 test_411b() {
28559         local cg_basedir=/sys/fs/cgroup/memory
28560         # LU-9966
28561         [ -e "$cg_basedir/memory.kmem.limit_in_bytes" ] ||
28562                 skip "no setup for cgroup"
28563         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
28564         # (x86) testing suggests we can't reliably avoid OOM with a 64M-256M
28565         # limit, so we have 384M in cgroup
28566         # (arm) this seems to hit OOM more often than x86, so 1024M
28567         if [[ $(uname -m) = aarch64 ]]; then
28568                 local memlimit_mb=1024
28569         else
28570                 local memlimit_mb=384
28571         fi
28572
28573         # Create a cgroup and set memory limit
28574         # (tfile is used as an easy way to get a recognizable cgroup name)
28575         local cgdir=$cg_basedir/$tfile
28576         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
28577         stack_trap "cleanup_test411_cgroup $cgdir" EXIT
28578         echo $((memlimit_mb * 1024 * 1024)) > $cgdir/memory.limit_in_bytes
28579
28580         echo "writing first file"
28581         # Write a file 4x the memory limit in size
28582         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=1M count=$((memlimit_mb * 4))" ||
28583                 error "(1) failed to write successfully"
28584
28585         sync
28586         cancel_lru_locks osc
28587
28588         rm -f $DIR/$tfile
28589         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
28590
28591         # Try writing at a larger block size
28592         # NB: if block size is >= 1/2 cgroup size, we sometimes get OOM killed
28593         # so test with 1/4 cgroup size (this seems reasonable to me - we do
28594         # need *some* memory to do IO in)
28595         echo "writing at larger block size"
28596         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=64M count=$((memlimit_mb * 4 / 128))" ||
28597                 error "(3) failed to write successfully"
28598
28599         sync
28600         cancel_lru_locks osc
28601         rm -f $DIR/$tfile
28602         $LFS setstripe -c 2 $DIR/$tfile.{1..4} || error "unable to setstripe"
28603
28604         # Try writing multiple files at once
28605         echo "writing multiple files"
28606         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.1 bs=32M count=$((memlimit_mb * 4 / 64))" &
28607         local pid1=$!
28608         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.2 bs=32M count=$((memlimit_mb * 4 / 64))" &
28609         local pid2=$!
28610         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.3 bs=32M count=$((memlimit_mb * 4 / 64))" &
28611         local pid3=$!
28612         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.4 bs=32M count=$((memlimit_mb * 4 / 64))" &
28613         local pid4=$!
28614
28615         wait $pid1
28616         local rc1=$?
28617         wait $pid2
28618         local rc2=$?
28619         wait $pid3
28620         local rc3=$?
28621         wait $pid4
28622         local rc4=$?
28623         if (( rc1 != 0)); then
28624                 error "error $rc1 writing to file from $pid1"
28625         fi
28626         if (( rc2 != 0)); then
28627                 error "error $rc2 writing to file from $pid2"
28628         fi
28629         if (( rc3 != 0)); then
28630                 error "error $rc3 writing to file from $pid3"
28631         fi
28632         if (( rc4 != 0)); then
28633                 error "error $rc4 writing to file from $pid4"
28634         fi
28635
28636         sync
28637         cancel_lru_locks osc
28638
28639         # These files can be large-ish (~1 GiB total), so delete them rather
28640         # than leave for later cleanup
28641         rm -f $DIR/$tfile.*
28642         return 0
28643 }
28644 run_test 411b "confirm Lustre can avoid OOM with reasonable cgroups limits"
28645
28646 test_412() {
28647         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
28648         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
28649                 skip "Need server version at least 2.10.55"
28650
28651         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
28652                 error "mkdir failed"
28653         $LFS getdirstripe $DIR/$tdir
28654         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
28655         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
28656                 error "expect $((MDSCOUT - 1)) get $stripe_index"
28657         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
28658         [ $stripe_count -eq 2 ] ||
28659                 error "expect 2 get $stripe_count"
28660
28661         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
28662
28663         local index
28664         local index2
28665
28666         # subdirs should be on the same MDT as parent
28667         for i in $(seq 0 $((MDSCOUNT - 1))); do
28668                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
28669                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
28670                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
28671                 (( index == i )) || error "mdt$i/sub on MDT$index"
28672         done
28673
28674         # stripe offset -1, ditto
28675         for i in {1..10}; do
28676                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
28677                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
28678                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
28679                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
28680                 (( index == index2 )) ||
28681                         error "qos$i on MDT$index, sub on MDT$index2"
28682         done
28683
28684         local testdir=$DIR/$tdir/inherit
28685
28686         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
28687         # inherit 2 levels
28688         for i in 1 2; do
28689                 testdir=$testdir/s$i
28690                 mkdir $testdir || error "mkdir $testdir failed"
28691                 index=$($LFS getstripe -m $testdir)
28692                 (( index == 1 )) ||
28693                         error "$testdir on MDT$index"
28694         done
28695
28696         # not inherit any more
28697         testdir=$testdir/s3
28698         mkdir $testdir || error "mkdir $testdir failed"
28699         getfattr -d -m dmv $testdir | grep dmv &&
28700                 error "default LMV set on $testdir" || true
28701 }
28702 run_test 412 "mkdir on specific MDTs"
28703
28704 TEST413_COUNT=${TEST413_COUNT:-200}
28705
28706 #
28707 # set_maxage() is used by test_413 only.
28708 # This is a helper function to set maxage. Does not return any value.
28709 # Input: maxage to set
28710 #
28711 set_maxage() {
28712         local lmv_qos_maxage
28713         local lod_qos_maxage
28714         local new_maxage=$1
28715
28716         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
28717         $LCTL set_param lmv.*.qos_maxage=$new_maxage
28718         stack_trap "$LCTL set_param \
28719                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
28720         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
28721                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
28722         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28723                 lod.*.mdt_qos_maxage=$new_maxage
28724         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28725                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
28726 }
28727
28728 generate_uneven_mdts() {
28729         local threshold=$1
28730         local ffree
28731         local bavail
28732         local max
28733         local min
28734         local max_index
28735         local min_index
28736         local tmp
28737         local i
28738
28739         echo
28740         echo "Check for uneven MDTs: "
28741
28742         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28743         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28744         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28745
28746         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28747         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28748         max_index=0
28749         min_index=0
28750         for ((i = 1; i < ${#ffree[@]}; i++)); do
28751                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28752                 if [ $tmp -gt $max ]; then
28753                         max=$tmp
28754                         max_index=$i
28755                 fi
28756                 if [ $tmp -lt $min ]; then
28757                         min=$tmp
28758                         min_index=$i
28759                 fi
28760         done
28761
28762         (( min > 0 )) || skip "low space on MDT$min_index"
28763         (( ${ffree[min_index]} > 0 )) ||
28764                 skip "no free files on MDT$min_index"
28765         (( ${ffree[min_index]} < 10000000 )) ||
28766                 skip "too many free files on MDT$min_index"
28767
28768         # Check if we need to generate uneven MDTs
28769         local diff=$(((max - min) * 100 / min))
28770         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
28771         local testdir # individual folder within $testdirp
28772         local start
28773         local cmd
28774
28775         # fallocate is faster to consume space on MDT, if available
28776         if check_fallocate_supported mds$((min_index + 1)); then
28777                 cmd="fallocate -l 128K "
28778         else
28779                 cmd="dd if=/dev/zero bs=128K count=1 of="
28780         fi
28781
28782         echo "using cmd $cmd"
28783         for (( i = 0; diff < threshold; i++ )); do
28784                 testdir=${testdirp}/$i
28785                 [ -d $testdir ] && continue
28786
28787                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
28788
28789                 mkdir -p $testdirp
28790                 # generate uneven MDTs, create till $threshold% diff
28791                 echo -n "weight diff=$diff% must be > $threshold% ..."
28792                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
28793                 $LFS mkdir -i $min_index $testdir ||
28794                         error "mkdir $testdir failed"
28795                 $LFS setstripe -E 1M -L mdt $testdir ||
28796                         error "setstripe $testdir failed"
28797                 start=$SECONDS
28798                 for (( f = 0; f < TEST413_COUNT; f++ )); do
28799                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
28800                 done
28801                 sync; sleep 1; sync
28802
28803                 # wait for QOS to update
28804                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
28805
28806                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
28807                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
28808                 max=$(((${ffree[max_index]} >> 8) *
28809                         (${bavail[max_index]} * bsize >> 16)))
28810                 min=$(((${ffree[min_index]} >> 8) *
28811                         (${bavail[min_index]} * bsize >> 16)))
28812                 (( min > 0 )) || skip "low space on MDT$min_index"
28813                 diff=$(((max - min) * 100 / min))
28814         done
28815
28816         echo "MDT filesfree available: ${ffree[*]}"
28817         echo "MDT blocks available: ${bavail[*]}"
28818         echo "weight diff=$diff%"
28819 }
28820
28821 test_qos_mkdir() {
28822         local mkdir_cmd=$1
28823         local stripe_count=$2
28824         local mdts=$(comma_list $(mdts_nodes))
28825
28826         local testdir
28827         local lmv_qos_prio_free
28828         local lmv_qos_threshold_rr
28829         local lod_qos_prio_free
28830         local lod_qos_threshold_rr
28831         local total
28832         local count
28833         local i
28834
28835         # @total is total directories created if it's testing plain
28836         # directories, otherwise it's total stripe object count for
28837         # striped directories test.
28838         # remote/striped directory unlinking is slow on zfs and may
28839         # timeout, test with fewer directories
28840         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
28841
28842         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
28843         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
28844         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
28845                 head -n1)
28846         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
28847         stack_trap "$LCTL set_param \
28848                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
28849         stack_trap "$LCTL set_param \
28850                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
28851
28852         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
28853                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
28854         lod_qos_prio_free=${lod_qos_prio_free%%%}
28855         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
28856                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
28857         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
28858         stack_trap "do_nodes $mdts $LCTL set_param \
28859                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
28860         stack_trap "do_nodes $mdts $LCTL set_param \
28861                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
28862
28863         # decrease statfs age, so that it can be updated in time
28864         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
28865         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
28866
28867         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
28868         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
28869
28870         testdir=$DIR/$tdir-s$stripe_count/rr
28871
28872         local stripe_index=$($LFS getstripe -m $testdir)
28873         local test_mkdir_rr=true
28874
28875         getfattr -d -m dmv -e hex $testdir | grep dmv
28876         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
28877                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
28878                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
28879                         test_mkdir_rr=false
28880         fi
28881
28882         echo
28883         $test_mkdir_rr &&
28884                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
28885                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
28886
28887         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
28888         for (( i = 0; i < total / stripe_count; i++ )); do
28889                 eval $mkdir_cmd $testdir/subdir$i ||
28890                         error "$mkdir_cmd subdir$i failed"
28891         done
28892
28893         for (( i = 0; i < $MDSCOUNT; i++ )); do
28894                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
28895                 echo "$count directories created on MDT$i"
28896                 if $test_mkdir_rr; then
28897                         (( count == total / stripe_count / MDSCOUNT )) ||
28898                                 error "subdirs are not evenly distributed"
28899                 elif (( i == stripe_index )); then
28900                         (( count == total / stripe_count )) ||
28901                                 error "$count subdirs created on MDT$i"
28902                 else
28903                         (( count == 0 )) ||
28904                                 error "$count subdirs created on MDT$i"
28905                 fi
28906
28907                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
28908                         count=$($LFS getdirstripe $testdir/* |
28909                                 grep -c -P "^\s+$i\t")
28910                         echo "$count stripes created on MDT$i"
28911                         # deviation should < 5% of average
28912                         delta=$((count - total / MDSCOUNT))
28913                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
28914                                 error "stripes are not evenly distributed"
28915                 fi
28916         done
28917
28918         echo
28919         echo "Check for uneven MDTs: "
28920
28921         local ffree
28922         local bavail
28923         local max
28924         local min
28925         local max_index
28926         local min_index
28927         local tmp
28928
28929         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28930         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28931         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28932
28933         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28934         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28935         max_index=0
28936         min_index=0
28937         for ((i = 1; i < ${#ffree[@]}; i++)); do
28938                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28939                 if [ $tmp -gt $max ]; then
28940                         max=$tmp
28941                         max_index=$i
28942                 fi
28943                 if [ $tmp -lt $min ]; then
28944                         min=$tmp
28945                         min_index=$i
28946                 fi
28947         done
28948         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
28949
28950         (( min > 0 )) || skip "low space on MDT$min_index"
28951         (( ${ffree[min_index]} < 10000000 )) ||
28952                 skip "too many free files on MDT$min_index"
28953
28954         generate_uneven_mdts 120
28955
28956         echo "MDT filesfree available: ${ffree[*]}"
28957         echo "MDT blocks available: ${bavail[*]}"
28958         echo "weight diff=$(((max - min) * 100 / min))%"
28959         echo
28960         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
28961
28962         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
28963         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
28964         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
28965         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
28966
28967         sleep 1
28968
28969         testdir=$DIR/$tdir-s$stripe_count/qos
28970
28971         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
28972         for (( i = 0; i < total / stripe_count; i++ )); do
28973                 eval $mkdir_cmd $testdir/subdir$i ||
28974                         error "$mkdir_cmd subdir$i failed"
28975         done
28976
28977         max=0
28978         for (( i = 0; i < $MDSCOUNT; i++ )); do
28979                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
28980                 (( count > max )) && max=$count
28981                 echo "$count directories created on MDT$i : curmax=$max"
28982         done
28983
28984         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
28985
28986         # D-value should > 10% of average
28987         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
28988                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
28989
28990         # ditto for stripes
28991         if (( stripe_count > 1 )); then
28992                 max=0
28993                 for (( i = 0; i < $MDSCOUNT; i++ )); do
28994                         count=$($LFS getdirstripe $testdir/* |
28995                                 grep -c -P "^\s+$i\t")
28996                         (( count > max )) && max=$count
28997                         echo "$count stripes created on MDT$i"
28998                 done
28999
29000                 min=$($LFS getdirstripe $testdir/* |
29001                         grep -c -P "^\s+$min_index\t")
29002                 (( max - min > total / MDSCOUNT / 10 )) ||
29003                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
29004         fi
29005 }
29006
29007 most_full_mdt() {
29008         local ffree
29009         local bavail
29010         local bsize
29011         local min
29012         local min_index
29013         local tmp
29014
29015         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
29016         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
29017         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
29018
29019         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
29020         min_index=0
29021         for ((i = 1; i < ${#ffree[@]}; i++)); do
29022                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
29023                 (( tmp < min )) && min=$tmp && min_index=$i
29024         done
29025
29026         echo -n $min_index
29027 }
29028
29029 test_413a() {
29030         [ $MDSCOUNT -lt 2 ] &&
29031                 skip "We need at least 2 MDTs for this test"
29032
29033         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
29034                 skip "Need server version at least 2.12.52"
29035
29036         local stripe_max=$((MDSCOUNT - 1))
29037         local stripe_count
29038
29039         # let caller set maxage for latest result
29040         set_maxage 1
29041
29042         # fill MDT unevenly
29043         generate_uneven_mdts 120
29044
29045         # test 4-stripe directory at most, otherwise it's too slow
29046         # We are being very defensive. Although Autotest uses 4 MDTs.
29047         # We make sure stripe_max does not go over 4.
29048         (( stripe_max > 4 )) && stripe_max=4
29049         # unlinking striped directory is slow on zfs, and may timeout, only test
29050         # plain directory
29051         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
29052         for stripe_count in $(seq 1 $stripe_max); do
29053                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
29054                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
29055                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
29056                         error "mkdir failed"
29057                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
29058         done
29059 }
29060 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
29061
29062 test_413b() {
29063         [ $MDSCOUNT -lt 2 ] &&
29064                 skip "We need at least 2 MDTs for this test"
29065
29066         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
29067                 skip "Need server version at least 2.12.52"
29068
29069         local stripe_max=$((MDSCOUNT - 1))
29070         local testdir
29071         local stripe_count
29072
29073         # let caller set maxage for latest result
29074         set_maxage 1
29075
29076         # fill MDT unevenly
29077         generate_uneven_mdts 120
29078
29079         # test 4-stripe directory at most, otherwise it's too slow
29080         # We are being very defensive. Although Autotest uses 4 MDTs.
29081         # We make sure stripe_max does not go over 4.
29082         (( stripe_max > 4 )) && stripe_max=4
29083         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
29084         for stripe_count in $(seq 1 $stripe_max); do
29085                 testdir=$DIR/$tdir-s$stripe_count
29086                 mkdir $testdir || error "mkdir $testdir failed"
29087                 mkdir $testdir/rr || error "mkdir rr failed"
29088                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
29089                         error "mkdir qos failed"
29090                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
29091                         $testdir/rr || error "setdirstripe rr failed"
29092                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
29093                         error "setdirstripe failed"
29094                 test_qos_mkdir "mkdir" $stripe_count
29095         done
29096 }
29097 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
29098
29099 test_413c() {
29100         (( $MDSCOUNT >= 2 )) ||
29101                 skip "We need at least 2 MDTs for this test"
29102
29103         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
29104                 skip "Need server version at least 2.14.51"
29105
29106         local testdir
29107         local inherit
29108         local inherit_rr
29109         local lmv_qos_maxage
29110         local lod_qos_maxage
29111
29112         # let caller set maxage for latest result
29113         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
29114         $LCTL set_param lmv.*.qos_maxage=1
29115         stack_trap "$LCTL set_param \
29116                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
29117         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
29118                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
29119         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
29120                 lod.*.mdt_qos_maxage=1
29121         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
29122                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
29123
29124         # fill MDT unevenly
29125         generate_uneven_mdts 120
29126
29127         testdir=$DIR/${tdir}-s1
29128         mkdir $testdir || error "mkdir $testdir failed"
29129         mkdir $testdir/rr || error "mkdir rr failed"
29130         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
29131         # default max_inherit is -1, default max_inherit_rr is 0
29132         $LFS setdirstripe -D -c 1 $testdir/rr ||
29133                 error "setdirstripe rr failed"
29134         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
29135                 error "setdirstripe qos failed"
29136         test_qos_mkdir "mkdir" 1
29137
29138         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
29139         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
29140         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
29141         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
29142         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
29143
29144         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
29145         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
29146         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
29147         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
29148         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
29149         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
29150         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
29151                 error "level2 shouldn't have default LMV" || true
29152 }
29153 run_test 413c "mkdir with default LMV max inherit rr"
29154
29155 test_413d() {
29156         (( MDSCOUNT >= 2 )) ||
29157                 skip "We need at least 2 MDTs for this test"
29158
29159         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
29160                 skip "Need server version at least 2.14.51"
29161
29162         local lmv_qos_threshold_rr
29163
29164         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
29165                 head -n1)
29166         stack_trap "$LCTL set_param \
29167                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
29168
29169         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
29170         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
29171         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
29172                 error "$tdir shouldn't have default LMV"
29173         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
29174                 error "mkdir sub failed"
29175
29176         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
29177
29178         (( count == 100 )) || error "$count subdirs on MDT0"
29179 }
29180 run_test 413d "inherit ROOT default LMV"
29181
29182 test_413e() {
29183         (( MDSCOUNT >= 2 )) ||
29184                 skip "We need at least 2 MDTs for this test"
29185         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
29186                 skip "Need server version at least 2.14.55"
29187
29188         local testdir=$DIR/$tdir
29189         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
29190         local max_inherit
29191         local sub_max_inherit
29192
29193         mkdir -p $testdir || error "failed to create $testdir"
29194
29195         # set default max-inherit to -1 if stripe count is 0 or 1
29196         $LFS setdirstripe -D -c 1 $testdir ||
29197                 error "failed to set default LMV"
29198         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
29199         (( max_inherit == -1 )) ||
29200                 error "wrong max_inherit value $max_inherit"
29201
29202         # set default max_inherit to a fixed value if stripe count is not 0 or 1
29203         $LFS setdirstripe -D -c -1 $testdir ||
29204                 error "failed to set default LMV"
29205         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
29206         (( max_inherit > 0 )) ||
29207                 error "wrong max_inherit value $max_inherit"
29208
29209         # and the subdir will decrease the max_inherit by 1
29210         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
29211         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
29212         (( sub_max_inherit == max_inherit - 1)) ||
29213                 error "wrong max-inherit of subdir $sub_max_inherit"
29214
29215         # check specified --max-inherit and warning message
29216         stack_trap "rm -f $tmpfile"
29217         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
29218                 error "failed to set default LMV"
29219         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
29220         (( max_inherit == -1 )) ||
29221                 error "wrong max_inherit value $max_inherit"
29222
29223         # check the warning messages
29224         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
29225                 error "failed to detect warning string"
29226         fi
29227 }
29228 run_test 413e "check default max-inherit value"
29229
29230 test_fs_dmv_inherit()
29231 {
29232         local testdir=$DIR/$tdir
29233
29234         local count
29235         local inherit
29236         local inherit_rr
29237
29238         for i in 1 2; do
29239                 mkdir $testdir || error "mkdir $testdir failed"
29240                 count=$($LFS getdirstripe -D -c $testdir)
29241                 (( count == 1 )) ||
29242                         error "$testdir default LMV count mismatch $count != 1"
29243                 inherit=$($LFS getdirstripe -D -X $testdir)
29244                 (( inherit == 3 - i )) ||
29245                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
29246                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
29247                 (( inherit_rr == 3 - i )) ||
29248                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
29249                 testdir=$testdir/sub
29250         done
29251
29252         mkdir $testdir || error "mkdir $testdir failed"
29253         count=$($LFS getdirstripe -D -c $testdir)
29254         (( count == 0 )) ||
29255                 error "$testdir default LMV count not zero: $count"
29256 }
29257
29258 test_413f() {
29259         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
29260
29261         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
29262                 skip "Need server version at least 2.14.55"
29263
29264         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
29265                 error "dump $DIR default LMV failed"
29266         stack_trap "setfattr --restore=$TMP/dmv.ea"
29267
29268         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
29269                 error "set $DIR default LMV failed"
29270
29271         test_fs_dmv_inherit
29272 }
29273 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
29274
29275 test_413g() {
29276         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
29277
29278         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
29279         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
29280                 error "dump $DIR default LMV failed"
29281         stack_trap "setfattr --restore=$TMP/dmv.ea"
29282
29283         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
29284                 error "set $DIR default LMV failed"
29285
29286         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
29287                 error "mount $MOUNT2 failed"
29288         stack_trap "umount_client $MOUNT2"
29289
29290         local saved_DIR=$DIR
29291
29292         export DIR=$MOUNT2
29293
29294         stack_trap "export DIR=$saved_DIR"
29295
29296         # first check filesystem-wide default LMV inheritance
29297         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
29298
29299         # then check subdirs are spread to all MDTs
29300         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
29301
29302         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
29303
29304         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
29305 }
29306 run_test 413g "enforce ROOT default LMV on subdir mount"
29307
29308 test_413h() {
29309         (( MDSCOUNT >= 2 )) ||
29310                 skip "We need at least 2 MDTs for this test"
29311
29312         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
29313                 skip "Need server version at least 2.15.50.6"
29314
29315         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
29316
29317         stack_trap "$LCTL set_param \
29318                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
29319         $LCTL set_param lmv.*.qos_maxage=1
29320
29321         local depth=5
29322         local rr_depth=4
29323         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
29324         local count=$((MDSCOUNT * 20))
29325
29326         generate_uneven_mdts 50
29327
29328         mkdir -p $dir || error "mkdir $dir failed"
29329         stack_trap "rm -rf $dir"
29330         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
29331                 --max-inherit-rr=$rr_depth $dir
29332
29333         for ((d=0; d < depth + 2; d++)); do
29334                 log "dir=$dir:"
29335                 for ((sub=0; sub < count; sub++)); do
29336                         mkdir $dir/d$sub
29337                 done
29338                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
29339                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
29340                 # subdirs within $rr_depth should be created round-robin
29341                 if (( d < rr_depth )); then
29342                         (( ${num[0]} != count )) ||
29343                                 error "all objects created on MDT ${num[1]}"
29344                 fi
29345
29346                 dir=$dir/d0
29347         done
29348 }
29349 run_test 413h "don't stick to parent for round-robin dirs"
29350
29351 test_413i() {
29352         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
29353
29354         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
29355                 skip "Need server version at least 2.14.55"
29356
29357         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
29358                 error "dump $DIR default LMV failed"
29359         stack_trap "setfattr --restore=$TMP/dmv.ea"
29360
29361         local testdir=$DIR/$tdir
29362         local def_max_rr=1
29363         local def_max=3
29364         local count
29365
29366         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
29367                 --max-inherit-rr=$def_max_rr $DIR ||
29368                 error "set $DIR default LMV failed"
29369
29370         for i in $(seq 2 3); do
29371                 def_max=$((def_max - 1))
29372                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
29373
29374                 mkdir $testdir
29375                 # RR is decremented and keeps zeroed once exhausted
29376                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
29377                 (( count == def_max_rr )) ||
29378                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
29379
29380                 # max-inherit is decremented
29381                 count=$($LFS getdirstripe -D --max-inherit $testdir)
29382                 (( count == def_max )) ||
29383                         error_noexit "$testdir: max-inherit $count != $def_max"
29384
29385                 testdir=$testdir/d$i
29386         done
29387
29388         # d3 is the last inherited from ROOT, no inheritance anymore
29389         # i.e. no the default layout anymore
29390         mkdir -p $testdir/d4/d5
29391         count=$($LFS getdirstripe -D --max-inherit $testdir)
29392         (( count == -1 )) ||
29393                 error_noexit "$testdir: max-inherit $count != -1"
29394
29395         local p_count=$($LFS getdirstripe -i $testdir)
29396
29397         for i in $(seq 4 5); do
29398                 testdir=$testdir/d$i
29399
29400                 # the root default layout is not applied once exhausted
29401                 count=$($LFS getdirstripe -i $testdir)
29402                 (( count == p_count )) ||
29403                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
29404         done
29405
29406         $LFS setdirstripe -i 0 $DIR/d2
29407         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
29408         (( count == -1 )) ||
29409                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
29410 }
29411 run_test 413i "check default layout inheritance"
29412
29413 test_413j()
29414 {
29415         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
29416
29417         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
29418         $LFS setdirstripe -D -c2 --max-inherit=2 $DIR/$tdir ||
29419                 error "setdirstripe $tdir failed"
29420
29421         local value=$(getfattr -n trusted.dmv $DIR/$tdir | \
29422                       grep "trusted.dmv" |sed -e 's/[^=]\+=//')
29423
29424         mkdir -p $DIR/$tdir/sub || error "mkdir sub failed"
29425         # setfattr dmv calls setdirstripe -D
29426         setfattr -n trusted.dmv -v $value $DIR/$tdir/sub ||
29427                 error "setfattr sub failed"
29428         local value2=$(getfattr -n trusted.dmv $DIR/$tdir/sub | \
29429                        grep "trusted.dmv" |sed -e 's/[^=]\+=//')
29430
29431         [ $value == $value2 ] || error "dmv mismatch"
29432
29433         (( MDS1_VERSION >= $(version_code 2.15.58) )) || return 0
29434
29435         # do not allow remove dmv by setfattr -x
29436         do_nodes $(comma_list $(mdts_nodes)) \
29437                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=0"
29438         setfattr -x trusted.dmv $DIR/$tdir/sub || error "setfattr sub failed"
29439         getfattr -n trusted.dmv $DIR/$tdir/sub || error "default LMV deleted"
29440
29441         # allow remove dmv by setfattr -x
29442         do_nodes $(comma_list $(mdts_nodes)) \
29443                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=1"
29444         setfattr -x trusted.dmv $DIR/$tdir/sub || error "setfattr sub failed"
29445         getfattr -n trusted.dmv $DIR/$tdir/sub && error "default LMV exists"
29446         do_nodes $(comma_list $(mdts_nodes)) \
29447                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=0"
29448 }
29449 run_test 413j "set default LMV by setxattr"
29450
29451 test_413k() {
29452         (( $MDS1_VERSION >= $(version_code 2.15.60) )) ||
29453                 skip "Need server version at least 2.15.60"
29454
29455         local index1
29456         local index2
29457         local old=$($LCTL get_param -n lmv.*.qos_exclude_prefixes)
29458         local count=$($LCTL get_param -n lmv.*.qos_exclude_prefixes | wc -l)
29459         local prefixes="abc:123:foo bar"
29460
29461         # add prefixes
29462         stack_trap "$LCTL set_param lmv.*.qos_exclude_prefixes=\"$old\""
29463         $LCTL set_param lmv.*.qos_exclude_prefixes="+$prefixes"
29464
29465         mkdir $DIR/$tdir || error "mkdir $tdir failed"
29466         index1=$($LFS getstripe -m $DIR/$tdir)
29467         for dname in _temporary _temporary.XXXXXX abc 123 "foo bar"; do
29468                 mkdir "$DIR/$tdir/$dname" || error "mkdir $dname failed"
29469                 index2=$($LFS getstripe -m "$DIR/$tdir/$dname")
29470                 ((index1 == index2)) ||
29471                         error "$tdir on MDT$index1, $dname on MDT$index2"
29472         done
29473
29474         # remove prefixes
29475         $LCTL set_param lmv.*.qos_exclude_prefixes="-$prefixes"
29476
29477         # total prefixes length > PAGE_SIZE can be printed correctly
29478         for c in {a..z}; do
29479                 prefixes=$(str_repeat $c 255)
29480                 $LCTL set_param lmv.*.qos_exclude_prefixes="+$prefixes" >/dev/null
29481         done
29482         local count2=$($LCTL get_param -n lmv.*.qos_exclude_prefixes | wc -l)
29483         ((count2 == count + 26)) ||
29484                 error "prefixes count $count2 != $((count + 26))"
29485 }
29486 run_test 413k "QoS mkdir exclude prefixes"
29487
29488 test_413z() {
29489         local pids=""
29490         local subdir
29491         local pid
29492
29493         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
29494                 unlinkmany $subdir/f. $TEST413_COUNT &
29495                 pids="$pids $!"
29496         done
29497
29498         for pid in $pids; do
29499                 wait $pid
29500         done
29501
29502         true
29503 }
29504 run_test 413z "413 test cleanup"
29505
29506 test_414() {
29507 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
29508         $LCTL set_param fail_loc=0x80000521
29509         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
29510         rm -f $DIR/$tfile
29511 }
29512 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
29513
29514 test_415() {
29515         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
29516         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
29517                 skip "Need server version at least 2.11.52"
29518
29519         # LU-11102
29520         local total=500
29521         local max=120
29522
29523         # this test may be slow on ZFS
29524         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
29525
29526         # though this test is designed for striped directory, let's test normal
29527         # directory too since lock is always saved as CoS lock.
29528         test_mkdir $DIR/$tdir || error "mkdir $tdir"
29529         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
29530         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
29531         # if looping with ONLY_REPEAT, wait for previous deletions to finish
29532         wait_delete_completed_mds
29533
29534         # run a loop without concurrent touch to measure rename duration.
29535         # only for test debug/robustness, NOT part of COS functional test.
29536         local start_time=$SECONDS
29537         for ((i = 0; i < total; i++)); do
29538                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
29539                         > /dev/null
29540         done
29541         local baseline=$((SECONDS - start_time))
29542         echo "rename $total files without 'touch' took $baseline sec"
29543
29544         (
29545                 while true; do
29546                         touch $DIR/$tdir
29547                 done
29548         ) &
29549         local setattr_pid=$!
29550
29551         # rename files back to original name so unlinkmany works
29552         start_time=$SECONDS
29553         for ((i = 0; i < total; i++)); do
29554                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
29555                         > /dev/null
29556         done
29557         local duration=$((SECONDS - start_time))
29558
29559         kill -9 $setattr_pid
29560
29561         echo "rename $total files with 'touch' took $duration sec"
29562         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
29563         (( duration <= max )) ||
29564                 error_not_in_vm "rename took $duration > $max sec"
29565 }
29566 run_test 415 "lock revoke is not missing"
29567
29568 test_416() {
29569         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
29570                 skip "Need server version at least 2.11.55"
29571
29572         # define OBD_FAIL_OSD_TXN_START    0x19a
29573         do_facet mds1 lctl set_param fail_loc=0x19a
29574
29575         lfs mkdir -c $MDSCOUNT $DIR/$tdir
29576
29577         true
29578 }
29579 run_test 416 "transaction start failure won't cause system hung"
29580
29581 cleanup_417() {
29582         trap 0
29583         do_nodes $(comma_list $(mdts_nodes)) \
29584                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
29585         do_nodes $(comma_list $(mdts_nodes)) \
29586                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
29587         do_nodes $(comma_list $(mdts_nodes)) \
29588                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
29589 }
29590
29591 test_417() {
29592         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
29593         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
29594                 skip "Need MDS version at least 2.11.56"
29595
29596         trap cleanup_417 RETURN EXIT
29597
29598         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
29599         do_nodes $(comma_list $(mdts_nodes)) \
29600                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
29601         $LFS migrate -m 0 $DIR/$tdir.1 &&
29602                 error "migrate dir $tdir.1 should fail"
29603
29604         do_nodes $(comma_list $(mdts_nodes)) \
29605                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
29606         $LFS mkdir -i 1 $DIR/$tdir.2 &&
29607                 error "create remote dir $tdir.2 should fail"
29608
29609         do_nodes $(comma_list $(mdts_nodes)) \
29610                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
29611         $LFS mkdir -c 2 $DIR/$tdir.3 &&
29612                 error "create striped dir $tdir.3 should fail"
29613         true
29614 }
29615 run_test 417 "disable remote dir, striped dir and dir migration"
29616
29617 # Checks that the outputs of df [-i] and lfs df [-i] match
29618 #
29619 # usage: check_lfs_df <blocks | inodes> <mountpoint>
29620 check_lfs_df() {
29621         local dir=$2
29622         local inodes
29623         local df_out
29624         local lfs_df_out
29625         local count
29626         local passed=false
29627
29628         # blocks or inodes
29629         [ "$1" == "blocks" ] && inodes= || inodes="-i"
29630
29631         for count in {1..100}; do
29632                 do_nodes "$CLIENTS" \
29633                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
29634                 sync; sleep 0.2
29635
29636                 # read the lines of interest
29637                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
29638                         error "df $inodes $dir | tail -n +2 failed"
29639                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
29640                         error "lfs df $inodes $dir | grep summary: failed"
29641
29642                 # skip first substrings of each output as they are different
29643                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
29644                 # compare the two outputs
29645                 passed=true
29646                 #  skip "available" on MDT until LU-13997 is fixed.
29647                 #for i in {1..5}; do
29648                 for i in 1 2 4 5; do
29649                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
29650                 done
29651                 $passed && break
29652         done
29653
29654         if ! $passed; then
29655                 df -P $inodes $dir
29656                 echo
29657                 lfs df $inodes $dir
29658                 error "df and lfs df $1 output mismatch: "      \
29659                       "df ${inodes}: ${df_out[*]}, "            \
29660                       "lfs df ${inodes}: ${lfs_df_out[*]}"
29661         fi
29662 }
29663
29664 test_418() {
29665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29666
29667         local dir=$DIR/$tdir
29668         local numfiles=$((RANDOM % 4096 + 2))
29669         local numblocks=$((RANDOM % 256 + 1))
29670
29671         wait_delete_completed
29672         test_mkdir $dir
29673
29674         # check block output
29675         check_lfs_df blocks $dir
29676         # check inode output
29677         check_lfs_df inodes $dir
29678
29679         # create a single file and retest
29680         echo "Creating a single file and testing"
29681         createmany -o $dir/$tfile- 1 &>/dev/null ||
29682                 error "creating 1 file in $dir failed"
29683         check_lfs_df blocks $dir
29684         check_lfs_df inodes $dir
29685
29686         # create a random number of files
29687         echo "Creating $((numfiles - 1)) files and testing"
29688         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
29689                 error "creating $((numfiles - 1)) files in $dir failed"
29690
29691         # write a random number of blocks to the first test file
29692         echo "Writing $numblocks 4K blocks and testing"
29693         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
29694                 count=$numblocks &>/dev/null ||
29695                 error "dd to $dir/${tfile}-0 failed"
29696
29697         # retest
29698         check_lfs_df blocks $dir
29699         check_lfs_df inodes $dir
29700
29701         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
29702                 error "unlinking $numfiles files in $dir failed"
29703 }
29704 run_test 418 "df and lfs df outputs match"
29705
29706 test_419()
29707 {
29708         local dir=$DIR/$tdir
29709
29710         mkdir -p $dir
29711         touch $dir/file
29712
29713         cancel_lru_locks mdc
29714
29715         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
29716         $LCTL set_param fail_loc=0x1410
29717         cat $dir/file
29718         $LCTL set_param fail_loc=0
29719         rm -rf $dir
29720 }
29721 run_test 419 "Verify open file by name doesn't crash kernel"
29722
29723 test_420()
29724 {
29725         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
29726                 skip "Need MDS version at least 2.12.53"
29727
29728         local SAVE_UMASK=$(umask)
29729         local dir=$DIR/$tdir
29730         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
29731
29732         mkdir -p $dir
29733         umask 0000
29734         mkdir -m03777 $dir/testdir
29735         ls -dn $dir/testdir
29736         # Need to remove trailing '.' when SELinux is enabled
29737         local dirperms=$(ls -dn $dir/testdir |
29738                          awk '{ sub(/\.$/, "", $1); print $1}')
29739         [ $dirperms == "drwxrwsrwt" ] ||
29740                 error "incorrect perms on $dir/testdir"
29741
29742         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
29743                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
29744         ls -n $dir/testdir/testfile
29745         local fileperms=$(ls -n $dir/testdir/testfile |
29746                           awk '{ sub(/\.$/, "", $1); print $1}')
29747         [ $fileperms == "-rwxr-xr-x" ] ||
29748                 error "incorrect perms on $dir/testdir/testfile"
29749
29750         umask $SAVE_UMASK
29751 }
29752 run_test 420 "clear SGID bit on non-directories for non-members"
29753
29754 test_421a() {
29755         local cnt
29756         local fid1
29757         local fid2
29758
29759         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29760                 skip "Need MDS version at least 2.12.54"
29761
29762         test_mkdir $DIR/$tdir
29763         createmany -o $DIR/$tdir/f 3
29764         cnt=$(ls -1 $DIR/$tdir | wc -l)
29765         [ $cnt != 3 ] && error "unexpected #files: $cnt"
29766
29767         fid1=$(lfs path2fid $DIR/$tdir/f1)
29768         fid2=$(lfs path2fid $DIR/$tdir/f2)
29769         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
29770
29771         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
29772         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
29773
29774         cnt=$(ls -1 $DIR/$tdir | wc -l)
29775         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
29776
29777         rm -f $DIR/$tdir/f3 || error "can't remove f3"
29778         createmany -o $DIR/$tdir/f 3
29779         cnt=$(ls -1 $DIR/$tdir | wc -l)
29780         [ $cnt != 3 ] && error "unexpected #files: $cnt"
29781
29782         fid1=$(lfs path2fid $DIR/$tdir/f1)
29783         fid2=$(lfs path2fid $DIR/$tdir/f2)
29784         echo "remove using fsname $FSNAME"
29785         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
29786
29787         cnt=$(ls -1 $DIR/$tdir | wc -l)
29788         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
29789 }
29790 run_test 421a "simple rm by fid"
29791
29792 test_421b() {
29793         local cnt
29794         local FID1
29795         local FID2
29796
29797         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29798                 skip "Need MDS version at least 2.12.54"
29799
29800         test_mkdir $DIR/$tdir
29801         createmany -o $DIR/$tdir/f 3
29802         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
29803         MULTIPID=$!
29804
29805         FID1=$(lfs path2fid $DIR/$tdir/f1)
29806         FID2=$(lfs path2fid $DIR/$tdir/f2)
29807         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
29808
29809         kill -USR1 $MULTIPID
29810         wait
29811
29812         cnt=$(ls $DIR/$tdir | wc -l)
29813         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
29814 }
29815 run_test 421b "rm by fid on open file"
29816
29817 test_421c() {
29818         local cnt
29819         local FIDS
29820
29821         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29822                 skip "Need MDS version at least 2.12.54"
29823
29824         test_mkdir $DIR/$tdir
29825         createmany -o $DIR/$tdir/f 3
29826         touch $DIR/$tdir/$tfile
29827         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
29828         cnt=$(ls -1 $DIR/$tdir | wc -l)
29829         [ $cnt != 184 ] && error "unexpected #files: $cnt"
29830
29831         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
29832         $LFS rmfid $DIR $FID1 || error "rmfid failed"
29833
29834         cnt=$(ls $DIR/$tdir | wc -l)
29835         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
29836 }
29837 run_test 421c "rm by fid against hardlinked files"
29838
29839 test_421d() {
29840         local cnt
29841         local FIDS
29842
29843         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29844                 skip "Need MDS version at least 2.12.54"
29845
29846         test_mkdir $DIR/$tdir
29847         createmany -o $DIR/$tdir/f 4097
29848         cnt=$(ls -1 $DIR/$tdir | wc -l)
29849         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
29850
29851         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
29852         $LFS rmfid $DIR $FIDS || error "rmfid failed"
29853
29854         cnt=$(ls $DIR/$tdir | wc -l)
29855         rm -rf $DIR/$tdir
29856         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
29857 }
29858 run_test 421d "rmfid en masse"
29859
29860 test_421e() {
29861         local cnt
29862         local FID
29863
29864         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
29865         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29866                 skip "Need MDS version at least 2.12.54"
29867
29868         mkdir -p $DIR/$tdir
29869         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
29870         createmany -o $DIR/$tdir/striped_dir/f 512
29871         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
29872         [ $cnt != 512 ] && error "unexpected #files: $cnt"
29873
29874         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
29875                 sed "s/[/][^:]*://g")
29876         $LFS rmfid $DIR $FIDS || error "rmfid failed"
29877
29878         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
29879         rm -rf $DIR/$tdir
29880         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
29881 }
29882 run_test 421e "rmfid in DNE"
29883
29884 test_421f() {
29885         local cnt
29886         local FID
29887
29888         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29889                 skip "Need MDS version at least 2.12.54"
29890
29891         test_mkdir $DIR/$tdir
29892         touch $DIR/$tdir/f
29893         cnt=$(ls -1 $DIR/$tdir | wc -l)
29894         [ $cnt != 1 ] && error "unexpected #files: $cnt"
29895
29896         FID=$(lfs path2fid $DIR/$tdir/f)
29897         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
29898         # rmfid should fail
29899         cnt=$(ls -1 $DIR/$tdir | wc -l)
29900         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
29901
29902         chmod a+rw $DIR/$tdir
29903         ls -la $DIR/$tdir
29904         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
29905         # rmfid should fail
29906         cnt=$(ls -1 $DIR/$tdir | wc -l)
29907         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
29908
29909         rm -f $DIR/$tdir/f
29910         $RUNAS touch $DIR/$tdir/f
29911         FID=$(lfs path2fid $DIR/$tdir/f)
29912         echo "rmfid as root"
29913         $LFS rmfid $DIR $FID || error "rmfid as root failed"
29914         cnt=$(ls -1 $DIR/$tdir | wc -l)
29915         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
29916
29917         rm -f $DIR/$tdir/f
29918         $RUNAS touch $DIR/$tdir/f
29919         cnt=$(ls -1 $DIR/$tdir | wc -l)
29920         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
29921         FID=$(lfs path2fid $DIR/$tdir/f)
29922         # rmfid w/o user_fid2path mount option should fail
29923         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
29924         cnt=$(ls -1 $DIR/$tdir | wc -l)
29925         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
29926
29927         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
29928         stack_trap "rmdir $tmpdir"
29929         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
29930                 error "failed to mount client'"
29931         stack_trap "umount_client $tmpdir"
29932
29933         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
29934         # rmfid should succeed
29935         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
29936         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
29937
29938         # rmfid shouldn't allow to remove files due to dir's permission
29939         chmod a+rwx $tmpdir/$tdir
29940         touch $tmpdir/$tdir/f
29941         ls -la $tmpdir/$tdir
29942         FID=$(lfs path2fid $tmpdir/$tdir/f)
29943         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
29944         return 0
29945 }
29946 run_test 421f "rmfid checks permissions"
29947
29948 test_421g() {
29949         local cnt
29950         local FIDS
29951
29952         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
29953         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29954                 skip "Need MDS version at least 2.12.54"
29955
29956         mkdir -p $DIR/$tdir
29957         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
29958         createmany -o $DIR/$tdir/striped_dir/f 512
29959         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
29960         [ $cnt != 512 ] && error "unexpected #files: $cnt"
29961
29962         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
29963                 sed "s/[/][^:]*://g")
29964
29965         rm -f $DIR/$tdir/striped_dir/f1*
29966         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
29967         removed=$((512 - cnt))
29968
29969         # few files have been just removed, so we expect
29970         # rmfid to fail on their fids
29971         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
29972         [ $removed != $errors ] && error "$errors != $removed"
29973
29974         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
29975         rm -rf $DIR/$tdir
29976         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
29977 }
29978 run_test 421g "rmfid to return errors properly"
29979
29980 test_421h() {
29981         local mount_other
29982         local mount_ret
29983         local rmfid_ret
29984         local old_fid
29985         local fidA
29986         local fidB
29987         local fidC
29988         local fidD
29989
29990         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
29991                 skip "Need MDS version at least 2.15.53"
29992
29993         test_mkdir $DIR/$tdir
29994         test_mkdir $DIR/$tdir/subdir
29995         touch $DIR/$tdir/subdir/file0
29996         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
29997         echo File $DIR/$tdir/subdir/file0 FID $old_fid
29998         rm -f $DIR/$tdir/subdir/file0
29999         touch $DIR/$tdir/subdir/fileA
30000         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
30001         echo File $DIR/$tdir/subdir/fileA FID $fidA
30002         touch $DIR/$tdir/subdir/fileB
30003         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
30004         echo File $DIR/$tdir/subdir/fileB FID $fidB
30005         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
30006         touch $DIR/$tdir/subdir/fileC
30007         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
30008         echo File $DIR/$tdir/subdir/fileC FID $fidC
30009         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
30010         touch $DIR/$tdir/fileD
30011         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
30012         echo File $DIR/$tdir/fileD FID $fidD
30013
30014         # mount another client mount point with subdirectory mount
30015         export FILESET=/$tdir/subdir
30016         mount_other=${MOUNT}_other
30017         mount_client $mount_other ${MOUNT_OPTS}
30018         mount_ret=$?
30019         export FILESET=""
30020         (( mount_ret == 0 )) || error "mount $mount_other failed"
30021
30022         echo Removing FIDs:
30023         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
30024         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
30025         rmfid_ret=$?
30026
30027         umount_client $mount_other || error "umount $mount_other failed"
30028
30029         (( rmfid_ret != 0 )) || error "rmfid should have failed"
30030
30031         # fileA should have been deleted
30032         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
30033
30034         # fileB should have been deleted
30035         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
30036
30037         # fileC should not have been deleted, fid also exists outside of fileset
30038         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
30039
30040         # fileD should not have been deleted, it exists outside of fileset
30041         stat $DIR/$tdir/fileD || error "fileD deleted"
30042 }
30043 run_test 421h "rmfid with fileset mount"
30044
30045 test_422() {
30046         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
30047         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
30048         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
30049         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
30050         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
30051
30052         local amc=$(at_max_get client)
30053         local amo=$(at_max_get mds1)
30054         local timeout=`lctl get_param -n timeout`
30055
30056         at_max_set 0 client
30057         at_max_set 0 mds1
30058
30059 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
30060         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
30061                         fail_val=$(((2*timeout + 10)*1000))
30062         touch $DIR/$tdir/d3/file &
30063         sleep 2
30064 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
30065         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
30066                         fail_val=$((2*timeout + 5))
30067         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
30068         local pid=$!
30069         sleep 1
30070         kill -9 $pid
30071         sleep $((2 * timeout))
30072         echo kill $pid
30073         kill -9 $pid
30074         lctl mark touch
30075         touch $DIR/$tdir/d2/file3
30076         touch $DIR/$tdir/d2/file4
30077         touch $DIR/$tdir/d2/file5
30078
30079         wait
30080         at_max_set $amc client
30081         at_max_set $amo mds1
30082
30083         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
30084         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
30085                 error "Watchdog is always throttled"
30086 }
30087 run_test 422 "kill a process with RPC in progress"
30088
30089 stat_test() {
30090     df -h $MOUNT &
30091     df -h $MOUNT &
30092     df -h $MOUNT &
30093     df -h $MOUNT &
30094     df -h $MOUNT &
30095     df -h $MOUNT &
30096 }
30097
30098 test_423() {
30099     local _stats
30100     # ensure statfs cache is expired
30101     sleep 2;
30102
30103     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
30104     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
30105
30106     return 0
30107 }
30108 run_test 423 "statfs should return a right data"
30109
30110 test_424() {
30111 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | CFS_FAIL_ONCE
30112         $LCTL set_param fail_loc=0x80000522
30113         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
30114         rm -f $DIR/$tfile
30115 }
30116 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
30117
30118 test_425() {
30119         test_mkdir -c -1 $DIR/$tdir
30120         $LFS setstripe -c -1 $DIR/$tdir
30121
30122         lru_resize_disable "" 100
30123         stack_trap "lru_resize_enable" EXIT
30124
30125         sleep 5
30126
30127         for i in $(seq $((MDSCOUNT * 125))); do
30128                 local t=$DIR/$tdir/$tfile_$i
30129
30130                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
30131                         error_noexit "Create file $t"
30132         done
30133         stack_trap "rm -rf $DIR/$tdir" EXIT
30134
30135         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
30136                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
30137                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
30138
30139                 [ $lock_count -le $lru_size ] ||
30140                         error "osc lock count $lock_count > lru size $lru_size"
30141         done
30142
30143         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
30144                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
30145                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
30146
30147                 [ $lock_count -le $lru_size ] ||
30148                         error "mdc lock count $lock_count > lru size $lru_size"
30149         done
30150 }
30151 run_test 425 "lock count should not exceed lru size"
30152
30153 test_426() {
30154         splice-test -r $DIR/$tfile
30155         splice-test -rd $DIR/$tfile
30156         splice-test $DIR/$tfile
30157         splice-test -d $DIR/$tfile
30158 }
30159 run_test 426 "splice test on Lustre"
30160
30161 test_427() {
30162         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
30163         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
30164                 skip "Need MDS version at least 2.12.4"
30165         local log
30166
30167         mkdir $DIR/$tdir
30168         mkdir $DIR/$tdir/1
30169         mkdir $DIR/$tdir/2
30170         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
30171         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
30172
30173         $LFS getdirstripe $DIR/$tdir/1/dir
30174
30175         #first setfattr for creating updatelog
30176         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
30177
30178 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
30179         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
30180         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
30181         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
30182
30183         sleep 2
30184         fail mds2
30185         wait_recovery_complete mds2 $((2*TIMEOUT))
30186
30187         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
30188         echo $log | grep "get update log failed" &&
30189                 error "update log corruption is detected" || true
30190 }
30191 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
30192
30193 test_428() {
30194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30195         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
30196                               awk '/^max_cached_mb/ { print $2 }')
30197         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
30198
30199         $LCTL set_param -n llite.*.max_cached_mb=64
30200
30201         mkdir $DIR/$tdir
30202         $LFS setstripe -c 1 $DIR/$tdir
30203         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
30204         stack_trap "rm -f $DIR/$tdir/$tfile.*"
30205         #test write
30206         for f in $(seq 4); do
30207                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
30208         done
30209         wait
30210
30211         cancel_lru_locks osc
30212         # Test read
30213         for f in $(seq 4); do
30214                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
30215         done
30216         wait
30217 }
30218 run_test 428 "large block size IO should not hang"
30219
30220 test_429() { # LU-7915 / LU-10948
30221         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
30222         local testfile=$DIR/$tfile
30223         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
30224         local new_flag=1
30225         local first_rpc
30226         local second_rpc
30227         local third_rpc
30228
30229         $LCTL get_param $ll_opencache_threshold_count ||
30230                 skip "client does not have opencache parameter"
30231
30232         set_opencache $new_flag
30233         stack_trap "restore_opencache"
30234         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
30235                 error "enable opencache failed"
30236         touch $testfile
30237         # drop MDC DLM locks
30238         cancel_lru_locks mdc
30239         # clear MDC RPC stats counters
30240         $LCTL set_param $mdc_rpcstats=clear
30241
30242         # According to the current implementation, we need to run 3 times
30243         # open & close file to verify if opencache is enabled correctly.
30244         # 1st, RPCs are sent for lookup/open and open handle is released on
30245         #      close finally.
30246         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
30247         #      so open handle won't be released thereafter.
30248         # 3rd, No RPC is sent out.
30249         $MULTIOP $testfile oc || error "multiop failed"
30250         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
30251         echo "1st: $first_rpc RPCs in flight"
30252
30253         $MULTIOP $testfile oc || error "multiop failed"
30254         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
30255         echo "2nd: $second_rpc RPCs in flight"
30256
30257         $MULTIOP $testfile oc || error "multiop failed"
30258         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
30259         echo "3rd: $third_rpc RPCs in flight"
30260
30261         #verify no MDC RPC is sent
30262         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
30263 }
30264 run_test 429 "verify if opencache flag on client side does work"
30265
30266 lseek_test_430() {
30267         local offset
30268         local file=$1
30269
30270         # data at [200K, 400K)
30271         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
30272                 error "256K->512K dd fails"
30273         # data at [2M, 3M)
30274         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
30275                 error "2M->3M dd fails"
30276         # data at [4M, 5M)
30277         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
30278                 error "4M->5M dd fails"
30279         echo "Data at 256K...512K, 2M...3M and 4M...5M"
30280         # start at first component hole #1
30281         printf "Seeking hole from 1000 ... "
30282         offset=$(lseek_test -l 1000 $file)
30283         echo $offset
30284         [[ $offset == 1000 ]] || error "offset $offset != 1000"
30285         printf "Seeking data from 1000 ... "
30286         offset=$(lseek_test -d 1000 $file)
30287         echo $offset
30288         [[ $offset == 262144 ]] || error "offset $offset != 262144"
30289
30290         # start at first component data block
30291         printf "Seeking hole from 300000 ... "
30292         offset=$(lseek_test -l 300000 $file)
30293         echo $offset
30294         [[ $offset == 524288 ]] || error "offset $offset != 524288"
30295         printf "Seeking data from 300000 ... "
30296         offset=$(lseek_test -d 300000 $file)
30297         echo $offset
30298         [[ $offset == 300000 ]] || error "offset $offset != 300000"
30299
30300         # start at the first component but beyond end of object size
30301         printf "Seeking hole from 1000000 ... "
30302         offset=$(lseek_test -l 1000000 $file)
30303         echo $offset
30304         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
30305         printf "Seeking data from 1000000 ... "
30306         offset=$(lseek_test -d 1000000 $file)
30307         echo $offset
30308         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
30309
30310         # start at second component stripe 2 (empty file)
30311         printf "Seeking hole from 1500000 ... "
30312         offset=$(lseek_test -l 1500000 $file)
30313         echo $offset
30314         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
30315         printf "Seeking data from 1500000 ... "
30316         offset=$(lseek_test -d 1500000 $file)
30317         echo $offset
30318         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
30319
30320         # start at second component stripe 1 (all data)
30321         printf "Seeking hole from 3000000 ... "
30322         offset=$(lseek_test -l 3000000 $file)
30323         echo $offset
30324         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
30325         printf "Seeking data from 3000000 ... "
30326         offset=$(lseek_test -d 3000000 $file)
30327         echo $offset
30328         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
30329
30330         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
30331                 error "2nd dd fails"
30332         echo "Add data block at 640K...1280K"
30333
30334         # start at before new data block, in hole
30335         printf "Seeking hole from 600000 ... "
30336         offset=$(lseek_test -l 600000 $file)
30337         echo $offset
30338         [[ $offset == 600000 ]] || error "offset $offset != 600000"
30339         printf "Seeking data from 600000 ... "
30340         offset=$(lseek_test -d 600000 $file)
30341         echo $offset
30342         [[ $offset == 655360 ]] || error "offset $offset != 655360"
30343
30344         # start at the first component new data block
30345         printf "Seeking hole from 1000000 ... "
30346         offset=$(lseek_test -l 1000000 $file)
30347         echo $offset
30348         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
30349         printf "Seeking data from 1000000 ... "
30350         offset=$(lseek_test -d 1000000 $file)
30351         echo $offset
30352         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
30353
30354         # start at second component stripe 2, new data
30355         printf "Seeking hole from 1200000 ... "
30356         offset=$(lseek_test -l 1200000 $file)
30357         echo $offset
30358         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
30359         printf "Seeking data from 1200000 ... "
30360         offset=$(lseek_test -d 1200000 $file)
30361         echo $offset
30362         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
30363
30364         # start beyond file end
30365         printf "Using offset > filesize ... "
30366         lseek_test -l 4000000 $file && error "lseek should fail"
30367         printf "Using offset > filesize ... "
30368         lseek_test -d 4000000 $file && error "lseek should fail"
30369
30370         printf "Done\n\n"
30371 }
30372
30373 test_430a() {
30374         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
30375                 skip "MDT does not support SEEK_HOLE"
30376
30377         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
30378                 skip "OST does not support SEEK_HOLE"
30379
30380         local file=$DIR/$tdir/$tfile
30381
30382         mkdir -p $DIR/$tdir
30383
30384         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
30385         # OST stripe #1 will have continuous data at [1M, 3M)
30386         # OST stripe #2 is empty
30387         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
30388         lseek_test_430 $file
30389         rm $file
30390         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
30391         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
30392         lseek_test_430 $file
30393         rm $file
30394         $LFS setstripe -c2 -S 512K $file
30395         echo "Two stripes, stripe size 512K"
30396         lseek_test_430 $file
30397         rm $file
30398         # FLR with stale mirror
30399         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
30400                        -N -c2 -S 1M $file
30401         echo "Mirrored file:"
30402         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
30403         echo "Plain 2 stripes 1M"
30404         lseek_test_430 $file
30405         rm $file
30406 }
30407 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
30408
30409 test_430b() {
30410         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
30411                 skip "OST does not support SEEK_HOLE"
30412
30413         local offset
30414         local file=$DIR/$tdir/$tfile
30415
30416         mkdir -p $DIR/$tdir
30417         # Empty layout lseek should fail
30418         $MCREATE $file
30419         # seek from 0
30420         printf "Seeking hole from 0 ... "
30421         lseek_test -l 0 $file && error "lseek should fail"
30422         printf "Seeking data from 0 ... "
30423         lseek_test -d 0 $file && error "lseek should fail"
30424         rm $file
30425
30426         # 1M-hole file
30427         $LFS setstripe -E 1M -c2 -E eof $file
30428         $TRUNCATE $file 1048576
30429         printf "Seeking hole from 1000000 ... "
30430         offset=$(lseek_test -l 1000000 $file)
30431         echo $offset
30432         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
30433         printf "Seeking data from 1000000 ... "
30434         lseek_test -d 1000000 $file && error "lseek should fail"
30435         rm $file
30436
30437         # full component followed by non-inited one
30438         $LFS setstripe -E 1M -c2 -E eof $file
30439         dd if=/dev/urandom of=$file bs=1M count=1
30440         printf "Seeking hole from 1000000 ... "
30441         offset=$(lseek_test -l 1000000 $file)
30442         echo $offset
30443         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
30444         printf "Seeking hole from 1048576 ... "
30445         lseek_test -l 1048576 $file && error "lseek should fail"
30446         # init second component and truncate back
30447         echo "123" >> $file
30448         $TRUNCATE $file 1048576
30449         printf "Seeking hole from 1000000 ... "
30450         offset=$(lseek_test -l 1000000 $file)
30451         echo $offset
30452         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
30453         printf "Seeking hole from 1048576 ... "
30454         lseek_test -l 1048576 $file && error "lseek should fail"
30455         # boundary checks for big values
30456         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
30457         offset=$(lseek_test -d 0 $file.10g)
30458         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
30459         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
30460         offset=$(lseek_test -d 0 $file.100g)
30461         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
30462         return 0
30463 }
30464 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
30465
30466 test_430c() {
30467         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
30468                 skip "OST does not support SEEK_HOLE"
30469
30470         local file=$DIR/$tdir/$tfile
30471         local start
30472
30473         mkdir -p $DIR/$tdir
30474         stack_trap "rm -f $file $file.tmp"
30475         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M || error "dd failed"
30476
30477         # cp version 8.33+ prefers lseek over fiemap
30478         local ver=$(cp --version | awk '{ print $4; exit; }')
30479
30480         echo "cp $ver installed"
30481         if (( $(version_code $ver) >= $(version_code 8.33) )); then
30482                 start=$SECONDS
30483                 time cp -v $file $file.tmp || error "cp $file failed"
30484                 (( SECONDS - start < 5 )) || {
30485                         strace cp $file $file.tmp |&
30486                                 grep -E "open|read|seek|FIEMAP" |
30487                                 grep -A 100 $file
30488                         error "cp: too long runtime $((SECONDS - start))"
30489                 }
30490         else
30491                 echo "cp test skipped due to $ver < 8.33"
30492         fi
30493
30494         # tar version 1.29+ supports SEEK_HOLE/DATA
30495         ver=$(tar --version | awk '{ print $4; exit; }')
30496         echo "tar $ver installed"
30497         if (( $(version_code $ver) >= $(version_code 1.29) )); then
30498                 start=$SECONDS
30499                 time tar cvf $file.tmp --sparse $file || error "tar $file error"
30500                 (( SECONDS - start < 5 )) || {
30501                         strace tar cf $file.tmp --sparse $file |&
30502                                 grep -E "open|read|seek|FIEMAP" |
30503                                 grep -A 100 $file
30504                         error "tar: too long runtime $((SECONDS - start))"
30505                 }
30506         else
30507                 echo "tar test skipped due to $ver < 1.29"
30508         fi
30509 }
30510 run_test 430c "lseek: external tools check"
30511
30512 test_431() { # LU-14187
30513         local file=$DIR/$tdir/$tfile
30514
30515         mkdir -p $DIR/$tdir
30516         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
30517         dd if=/dev/urandom of=$file bs=4k count=1
30518         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
30519         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
30520         #define OBD_FAIL_OST_RESTART_IO 0x251
30521         do_facet ost1 "$LCTL set_param fail_loc=0x251"
30522         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
30523         cp $file $file.0
30524         cancel_lru_locks
30525         sync_all_data
30526         echo 3 > /proc/sys/vm/drop_caches
30527         diff  $file $file.0 || error "data diff"
30528 }
30529 run_test 431 "Restart transaction for IO"
30530
30531 cleanup_test_432() {
30532         do_facet mgs $LCTL nodemap_activate 0
30533         wait_nm_sync active
30534 }
30535
30536 test_432() {
30537         local tmpdir=$TMP/dir432
30538
30539         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
30540                 skip "Need MDS version at least 2.14.52"
30541
30542         stack_trap cleanup_test_432 EXIT
30543         mkdir $DIR/$tdir
30544         mkdir $tmpdir
30545
30546         do_facet mgs $LCTL nodemap_activate 1
30547         wait_nm_sync active
30548         do_facet mgs $LCTL nodemap_modify --name default \
30549                 --property admin --value 1
30550         do_facet mgs $LCTL nodemap_modify --name default \
30551                 --property trusted --value 1
30552         cancel_lru_locks mdc
30553         wait_nm_sync default admin_nodemap
30554         wait_nm_sync default trusted_nodemap
30555
30556         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
30557                grep -ci "Operation not permitted") -ne 0 ]; then
30558                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
30559         fi
30560 }
30561 run_test 432 "mv dir from outside Lustre"
30562
30563 test_433() {
30564         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30565
30566         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
30567                 skip "inode cache not supported"
30568
30569         $LCTL set_param llite.*.inode_cache=0
30570         stack_trap "$LCTL set_param llite.*.inode_cache=1"
30571
30572         local count=256
30573         local before
30574         local after
30575
30576         cancel_lru_locks mdc
30577         test_mkdir $DIR/$tdir || error "mkdir $tdir"
30578         createmany -m $DIR/$tdir/f $count
30579         createmany -d $DIR/$tdir/d $count
30580         ls -l $DIR/$tdir > /dev/null
30581         stack_trap "rm -rf $DIR/$tdir"
30582
30583         before=$(num_objects)
30584         cancel_lru_locks mdc
30585         after=$(num_objects)
30586
30587         # sometimes even @before is less than 2 * count
30588         while (( before - after < count )); do
30589                 sleep 1
30590                 after=$(num_objects)
30591                 wait=$((wait + 1))
30592                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
30593                 if (( wait > 60 )); then
30594                         error "inode slab grew from $before to $after"
30595                 fi
30596         done
30597
30598         echo "lustre_inode_cache $before objs before lock cancel, $after after"
30599 }
30600 run_test 433 "ldlm lock cancel releases dentries and inodes"
30601
30602 test_434() {
30603         local file
30604         local getxattr_count
30605         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
30606         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30607
30608         [[ $(getenforce) == "Disabled" ]] ||
30609                 skip "lsm selinux module have to be disabled for this test"
30610
30611         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
30612                 error "fail to create $DIR/$tdir/ on MDT0000"
30613
30614         touch $DIR/$tdir/$tfile-{001..100}
30615
30616         # disable the xattr cache
30617         save_lustre_params client "llite.*.xattr_cache" > $p
30618         lctl set_param llite.*.xattr_cache=0
30619         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
30620
30621         # clear clients mdc stats
30622         clear_stats $mdc_stat_param ||
30623                 error "fail to clear stats on mdc MDT0000"
30624
30625         for file in $DIR/$tdir/$tfile-{001..100}; do
30626                 getfattr -n security.selinux $file |&
30627                         grep -q "Operation not supported" ||
30628                         error "getxattr on security.selinux should return EOPNOTSUPP"
30629         done
30630
30631         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
30632         (( getxattr_count < 100 )) ||
30633                 error "client sent $getxattr_count getxattr RPCs to the MDS"
30634 }
30635 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
30636
30637 test_440() {
30638         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
30639                 source $LUSTRE/scripts/bash-completion/lustre
30640         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
30641                 source /usr/share/bash-completion/completions/lustre
30642         else
30643                 skip "bash completion scripts not found"
30644         fi
30645
30646         local lctl_completions
30647         local lfs_completions
30648
30649         lctl_completions=$(_lustre_cmds lctl)
30650         if [[ ! $lctl_completions =~ "get_param" ]]; then
30651                 error "lctl bash completion failed"
30652         fi
30653
30654         lfs_completions=$(_lustre_cmds lfs)
30655         if [[ ! $lfs_completions =~ "setstripe" ]]; then
30656                 error "lfs bash completion failed"
30657         fi
30658 }
30659 run_test 440 "bash completion for lfs, lctl"
30660
30661 test_442() {
30662         local pid1
30663         local pid2
30664         mkdir -p $DIR/$tdir
30665         multiop $DIR/$tdir/$tfile.1 O_w1 & pid1=$!
30666         multiop $DIR/$tdir/$tfile.1 O_w1 & pid2=$!
30667         sleep 1
30668         touch $DIR/$tdir/$tfile.2
30669         $LFS swap_layouts -n $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
30670         $LCTL set_param fail_loc=0x1430
30671         kill -USR1 $pid1
30672         sleep 1
30673         kill -USR1 $pid2
30674         wait
30675 }
30676 run_test 442 "truncate vs read/write should not panic"
30677
30678 test_460d() {
30679         verify_yaml_available || skip_env "YAML verification not installed"
30680         $LCTL get_param -n sptlrpc.page_pools
30681         $LCTL get_param -n sptlrpc.page_pools | verify_yaml ||
30682                 error "The output of encrypt_page_pools is not an valid YAML"
30683 }
30684 run_test 460d "Check encrypt pools output"
30685
30686 prep_801() {
30687         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
30688         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
30689                 skip "Need server version at least 2.9.55"
30690
30691         start_full_debug_logging
30692 }
30693
30694 post_801() {
30695         stop_full_debug_logging
30696 }
30697
30698 barrier_stat() {
30699         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
30700                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
30701                            awk '/The barrier for/ { print $7 }')
30702                 echo $st
30703         else
30704                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
30705                 echo \'$st\'
30706         fi
30707 }
30708
30709 barrier_expired() {
30710         local expired
30711
30712         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
30713                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
30714                           awk '/will be expired/ { print $7 }')
30715         else
30716                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
30717         fi
30718
30719         echo $expired
30720 }
30721
30722 test_801a() {
30723         prep_801
30724
30725         echo "Start barrier_freeze at: $(date)"
30726         #define OBD_FAIL_BARRIER_DELAY          0x2202
30727         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
30728         # Do not reduce barrier time - See LU-11873
30729         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
30730
30731         sleep 2
30732         local b_status=$(barrier_stat)
30733         echo "Got barrier status at: $(date)"
30734         [ "$b_status" = "'freezing_p1'" ] ||
30735                 error "(1) unexpected barrier status $b_status"
30736
30737         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
30738         wait
30739         b_status=$(barrier_stat)
30740         [ "$b_status" = "'frozen'" ] ||
30741                 error "(2) unexpected barrier status $b_status"
30742
30743         local expired=$(barrier_expired)
30744         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
30745         sleep $((expired + 3))
30746
30747         b_status=$(barrier_stat)
30748         [ "$b_status" = "'expired'" ] ||
30749                 error "(3) unexpected barrier status $b_status"
30750
30751         # Do not reduce barrier time - See LU-11873
30752         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
30753                 error "(4) fail to freeze barrier"
30754
30755         b_status=$(barrier_stat)
30756         [ "$b_status" = "'frozen'" ] ||
30757                 error "(5) unexpected barrier status $b_status"
30758
30759         echo "Start barrier_thaw at: $(date)"
30760         #define OBD_FAIL_BARRIER_DELAY          0x2202
30761         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
30762         do_facet mgs $LCTL barrier_thaw $FSNAME &
30763
30764         sleep 2
30765         b_status=$(barrier_stat)
30766         echo "Got barrier status at: $(date)"
30767         [ "$b_status" = "'thawing'" ] ||
30768                 error "(6) unexpected barrier status $b_status"
30769
30770         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
30771         wait
30772         b_status=$(barrier_stat)
30773         [ "$b_status" = "'thawed'" ] ||
30774                 error "(7) unexpected barrier status $b_status"
30775
30776         #define OBD_FAIL_BARRIER_FAILURE        0x2203
30777         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
30778         do_facet mgs $LCTL barrier_freeze $FSNAME
30779
30780         b_status=$(barrier_stat)
30781         [ "$b_status" = "'failed'" ] ||
30782                 error "(8) unexpected barrier status $b_status"
30783
30784         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
30785         do_facet mgs $LCTL barrier_thaw $FSNAME
30786
30787         post_801
30788 }
30789 run_test 801a "write barrier user interfaces and stat machine"
30790
30791 test_801b() {
30792         prep_801
30793
30794         mkdir $DIR/$tdir || error "(1) fail to mkdir"
30795         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
30796         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
30797         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
30798         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
30799
30800         cancel_lru_locks mdc
30801
30802         # 180 seconds should be long enough
30803         do_facet mgs $LCTL barrier_freeze $FSNAME 180
30804
30805         local b_status=$(barrier_stat)
30806         [ "$b_status" = "'frozen'" ] ||
30807                 error "(6) unexpected barrier status $b_status"
30808
30809         mkdir $DIR/$tdir/d0/d10 &
30810         mkdir_pid=$!
30811
30812         touch $DIR/$tdir/d1/f13 &
30813         touch_pid=$!
30814
30815         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
30816         ln_pid=$!
30817
30818         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
30819         mv_pid=$!
30820
30821         rm -f $DIR/$tdir/d4/f12 &
30822         rm_pid=$!
30823
30824         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
30825
30826         # To guarantee taht the 'stat' is not blocked
30827         b_status=$(barrier_stat)
30828         [ "$b_status" = "'frozen'" ] ||
30829                 error "(8) unexpected barrier status $b_status"
30830
30831         # let above commands to run at background
30832         sleep 5
30833
30834         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
30835         ps -p $touch_pid || error "(10) touch should be blocked"
30836         ps -p $ln_pid || error "(11) link should be blocked"
30837         ps -p $mv_pid || error "(12) rename should be blocked"
30838         ps -p $rm_pid || error "(13) unlink should be blocked"
30839
30840         b_status=$(barrier_stat)
30841         [ "$b_status" = "'frozen'" ] ||
30842                 error "(14) unexpected barrier status $b_status"
30843
30844         do_facet mgs $LCTL barrier_thaw $FSNAME
30845         b_status=$(barrier_stat)
30846         [ "$b_status" = "'thawed'" ] ||
30847                 error "(15) unexpected barrier status $b_status"
30848
30849         wait $mkdir_pid || error "(16) mkdir should succeed"
30850         wait $touch_pid || error "(17) touch should succeed"
30851         wait $ln_pid || error "(18) link should succeed"
30852         wait $mv_pid || error "(19) rename should succeed"
30853         wait $rm_pid || error "(20) unlink should succeed"
30854
30855         post_801
30856 }
30857 run_test 801b "modification will be blocked by write barrier"
30858
30859 test_801c() {
30860         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30861
30862         prep_801
30863
30864         stop mds2 || error "(1) Fail to stop mds2"
30865
30866         do_facet mgs $LCTL barrier_freeze $FSNAME 30
30867
30868         local b_status=$(barrier_stat)
30869         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
30870                 do_facet mgs $LCTL barrier_thaw $FSNAME
30871                 error "(2) unexpected barrier status $b_status"
30872         }
30873
30874         do_facet mgs $LCTL barrier_rescan $FSNAME ||
30875                 error "(3) Fail to rescan barrier bitmap"
30876
30877         # Do not reduce barrier time - See LU-11873
30878         do_facet mgs $LCTL barrier_freeze $FSNAME 20
30879
30880         b_status=$(barrier_stat)
30881         [ "$b_status" = "'frozen'" ] ||
30882                 error "(4) unexpected barrier status $b_status"
30883
30884         do_facet mgs $LCTL barrier_thaw $FSNAME
30885         b_status=$(barrier_stat)
30886         [ "$b_status" = "'thawed'" ] ||
30887                 error "(5) unexpected barrier status $b_status"
30888
30889         local devname=$(mdsdevname 2)
30890
30891         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
30892
30893         do_facet mgs $LCTL barrier_rescan $FSNAME ||
30894                 error "(7) Fail to rescan barrier bitmap"
30895
30896         post_801
30897 }
30898 run_test 801c "rescan barrier bitmap"
30899
30900 test_802b() {
30901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30902         remote_mds_nodsh && skip "remote MDS with nodsh"
30903
30904         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
30905                 skip "readonly option not available"
30906
30907         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
30908
30909         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
30910                 error "(2) Fail to copy"
30911
30912         # write back all cached data before setting MDT to readonly
30913         cancel_lru_locks
30914         sync_all_data
30915
30916         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
30917         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
30918
30919         echo "Modify should be refused"
30920         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
30921
30922         echo "Read should be allowed"
30923         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
30924                 error "(7) Read should succeed under ro mode"
30925
30926         # disable readonly
30927         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
30928 }
30929 run_test 802b "be able to set MDTs to readonly"
30930
30931 test_803a() {
30932         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30933         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
30934                 skip "MDS needs to be newer than 2.10.54"
30935
30936         mkdir_on_mdt0 $DIR/$tdir
30937         # Create some objects on all MDTs to trigger related logs objects
30938         for idx in $(seq $MDSCOUNT); do
30939                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
30940                         $DIR/$tdir/dir${idx} ||
30941                         error "Fail to create $DIR/$tdir/dir${idx}"
30942         done
30943
30944         wait_delete_completed # ensure old test cleanups are finished
30945         sleep 3
30946         echo "before create:"
30947         $LFS df -i $MOUNT
30948         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
30949
30950         for i in {1..10}; do
30951                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
30952                         error "Fail to create $DIR/$tdir/foo$i"
30953         done
30954
30955         # sync ZFS-on-MDS to refresh statfs data
30956         wait_zfs_commit mds1
30957         sleep 3
30958         echo "after create:"
30959         $LFS df -i $MOUNT
30960         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
30961
30962         # allow for an llog to be cleaned up during the test
30963         [ $after_used -ge $((before_used + 10 - 1)) ] ||
30964                 error "before ($before_used) + 10 > after ($after_used)"
30965
30966         for i in {1..10}; do
30967                 rm -rf $DIR/$tdir/foo$i ||
30968                         error "Fail to remove $DIR/$tdir/foo$i"
30969         done
30970
30971         # sync ZFS-on-MDS to refresh statfs data
30972         wait_zfs_commit mds1
30973         wait_delete_completed
30974         sleep 3 # avoid MDT return cached statfs
30975         echo "after unlink:"
30976         $LFS df -i $MOUNT
30977         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
30978
30979         # allow for an llog to be created during the test
30980         [ $after_used -le $((before_used + 1)) ] ||
30981                 error "after ($after_used) > before ($before_used) + 1"
30982 }
30983 run_test 803a "verify agent object for remote object"
30984
30985 test_803b() {
30986         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30987         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
30988                 skip "MDS needs to be newer than 2.13.56"
30989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30990
30991         for i in $(seq 0 $((MDSCOUNT - 1))); do
30992                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
30993         done
30994
30995         local before=0
30996         local after=0
30997
30998         local tmp
30999
31000         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
31001         for i in $(seq 0 $((MDSCOUNT - 1))); do
31002                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
31003                         awk '/getattr/ { print $2 }')
31004                 before=$((before + tmp))
31005         done
31006         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
31007         for i in $(seq 0 $((MDSCOUNT - 1))); do
31008                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
31009                         awk '/getattr/ { print $2 }')
31010                 after=$((after + tmp))
31011         done
31012
31013         [ $before -eq $after ] || error "getattr count $before != $after"
31014 }
31015 run_test 803b "remote object can getattr from cache"
31016
31017 test_804() {
31018         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
31019         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
31020                 skip "MDS needs to be newer than 2.10.54"
31021         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
31022
31023         mkdir -p $DIR/$tdir
31024         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
31025                 error "Fail to create $DIR/$tdir/dir0"
31026
31027         local fid=$($LFS path2fid $DIR/$tdir/dir0)
31028         local dev=$(mdsdevname 2)
31029
31030         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
31031                 grep ${fid} || error "NOT found agent entry for dir0"
31032
31033         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
31034                 error "Fail to create $DIR/$tdir/dir1"
31035
31036         touch $DIR/$tdir/dir1/foo0 ||
31037                 error "Fail to create $DIR/$tdir/dir1/foo0"
31038         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
31039         local rc=0
31040
31041         for idx in $(seq $MDSCOUNT); do
31042                 dev=$(mdsdevname $idx)
31043                 do_facet mds${idx} \
31044                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
31045                         grep ${fid} && rc=$idx
31046         done
31047
31048         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
31049                 error "Fail to rename foo0 to foo1"
31050         if [ $rc -eq 0 ]; then
31051                 for idx in $(seq $MDSCOUNT); do
31052                         dev=$(mdsdevname $idx)
31053                         do_facet mds${idx} \
31054                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
31055                         grep ${fid} && rc=$idx
31056                 done
31057         fi
31058
31059         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
31060                 error "Fail to rename foo1 to foo2"
31061         if [ $rc -eq 0 ]; then
31062                 for idx in $(seq $MDSCOUNT); do
31063                         dev=$(mdsdevname $idx)
31064                         do_facet mds${idx} \
31065                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
31066                         grep ${fid} && rc=$idx
31067                 done
31068         fi
31069
31070         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
31071
31072         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
31073                 error "Fail to link to $DIR/$tdir/dir1/foo2"
31074         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
31075                 error "Fail to rename foo2 to foo0"
31076         unlink $DIR/$tdir/dir1/foo0 ||
31077                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
31078         rm -rf $DIR/$tdir/dir0 ||
31079                 error "Fail to rm $DIR/$tdir/dir0"
31080
31081         for idx in $(seq $MDSCOUNT); do
31082                 rc=0
31083
31084                 stop mds${idx}
31085                 dev=$(mdsdevname $idx)
31086                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
31087                         rc=$?
31088                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
31089                         error "mount mds$idx failed"
31090                 df $MOUNT > /dev/null 2>&1
31091
31092                 # e2fsck should not return error
31093                 [ $rc -eq 0 ] ||
31094                         error "e2fsck detected error on MDT${idx}: rc=$rc"
31095         done
31096 }
31097 run_test 804 "verify agent entry for remote entry"
31098
31099 cleanup_805() {
31100         do_facet $SINGLEMDS zfs set quota=$old $fsset
31101         unlinkmany $DIR/$tdir/f- 1000000
31102         trap 0
31103 }
31104
31105 test_805() {
31106         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
31107         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
31108         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
31109                 skip "netfree not implemented before 0.7"
31110         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
31111                 skip "Need MDS version at least 2.10.57"
31112
31113         local fsset
31114         local freekb
31115         local usedkb
31116         local old
31117         local quota
31118         local pref="osd-zfs.$FSNAME-MDT0000."
31119
31120         # limit available space on MDS dataset to meet nospace issue
31121         # quickly. then ZFS 0.7.2 can use reserved space if asked
31122         # properly (using netfree flag in osd_declare_destroy()
31123         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
31124         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
31125                 gawk '{print $3}')
31126         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
31127         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
31128         let "usedkb=usedkb-freekb"
31129         let "freekb=freekb/2"
31130         if let "freekb > 5000"; then
31131                 let "freekb=5000"
31132         fi
31133         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
31134         trap cleanup_805 EXIT
31135         mkdir_on_mdt0 $DIR/$tdir
31136         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
31137                 error "Can't set PFL layout"
31138         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
31139         rm -rf $DIR/$tdir || error "not able to remove"
31140         do_facet $SINGLEMDS zfs set quota=$old $fsset
31141         trap 0
31142 }
31143 run_test 805 "ZFS can remove from full fs"
31144
31145 # Size-on-MDS test
31146 check_lsom_data()
31147 {
31148         local file=$1
31149         local expect=$(stat -c %s $file)
31150
31151         check_lsom_size $1 $expect
31152
31153         local blocks=$($LFS getsom -b $file)
31154         expect=$(stat -c %b $file)
31155         [[ $blocks == $expect ]] ||
31156                 error "$file expected blocks: $expect, got: $blocks"
31157 }
31158
31159 check_lsom_size()
31160 {
31161         local size
31162         local expect=$2
31163
31164         cancel_lru_locks mdc
31165
31166         size=$($LFS getsom -s $1)
31167         [[ $size == $expect ]] ||
31168                 error "$file expected size: $expect, got: $size"
31169 }
31170
31171 test_806() {
31172         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
31173                 skip "Need MDS version at least 2.11.52"
31174
31175         local bs=1048576
31176
31177         $LFS setstripe -c-1 $DIR/$tfile || error "setstripe $tfile failed"
31178
31179         disable_opencache
31180         stack_trap "restore_opencache"
31181
31182         # single-threaded write
31183         echo "Test SOM for single-threaded write"
31184         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
31185                 error "write $tfile failed"
31186         check_lsom_size $DIR/$tfile $bs
31187
31188         local num=32
31189         local size=$(($num * $bs))
31190         local offset=0
31191         local i
31192
31193         echo "Test SOM for single client multi-threaded($num) write"
31194         $TRUNCATE $DIR/$tfile 0
31195         for ((i = 0; i < $num; i++)); do
31196                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31197                 local pids[$i]=$!
31198                 offset=$((offset + $bs))
31199         done
31200         for (( i=0; i < $num; i++ )); do
31201                 wait ${pids[$i]}
31202         done
31203         check_lsom_size $DIR/$tfile $size
31204
31205         $TRUNCATE $DIR/$tfile 0
31206         for ((i = 0; i < $num; i++)); do
31207                 offset=$((offset - $bs))
31208                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31209                 local pids[$i]=$!
31210         done
31211         for (( i=0; i < $num; i++ )); do
31212                 wait ${pids[$i]}
31213         done
31214         check_lsom_size $DIR/$tfile $size
31215
31216         # multi-client writes
31217         num=$(get_node_count ${CLIENTS//,/ })
31218         size=$(($num * $bs))
31219         offset=0
31220         i=0
31221
31222         echo "Test SOM for multi-client ($num) writes"
31223         $TRUNCATE $DIR/$tfile 0
31224         for client in ${CLIENTS//,/ }; do
31225                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31226                 local pids[$i]=$!
31227                 i=$((i + 1))
31228                 offset=$((offset + $bs))
31229         done
31230         for (( i=0; i < $num; i++ )); do
31231                 wait ${pids[$i]}
31232         done
31233         check_lsom_size $DIR/$tfile $offset
31234
31235         i=0
31236         $TRUNCATE $DIR/$tfile 0
31237         for client in ${CLIENTS//,/ }; do
31238                 offset=$((offset - $bs))
31239                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31240                 local pids[$i]=$!
31241                 i=$((i + 1))
31242         done
31243         for (( i=0; i < $num; i++ )); do
31244                 wait ${pids[$i]}
31245         done
31246         check_lsom_size $DIR/$tfile $size
31247
31248         # verify SOM blocks count
31249         echo "Verify SOM block count"
31250         $TRUNCATE $DIR/$tfile 0
31251         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs))YSc ||
31252                 error "failed to write file $tfile with fdatasync and fstat"
31253         check_lsom_data $DIR/$tfile
31254
31255         $TRUNCATE $DIR/$tfile 0
31256         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs * 2))Yc ||
31257                 error "failed to write file $tfile with fdatasync"
31258         check_lsom_data $DIR/$tfile
31259
31260         $TRUNCATE $DIR/$tfile 0
31261         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:O_SYNC:w$((bs * 3))c ||
31262                 error "failed to write file $tfile with sync IO"
31263         check_lsom_data $DIR/$tfile
31264
31265         # verify truncate
31266         echo "Test SOM for truncate"
31267         # use ftruncate to sync blocks on close request
31268         $MULTIOP $DIR/$tfile oO_WRONLY:T16384c
31269         check_lsom_size $DIR/$tfile 16384
31270         check_lsom_data $DIR/$tfile
31271
31272         $TRUNCATE $DIR/$tfile 1234
31273         check_lsom_size $DIR/$tfile 1234
31274         # sync blocks on the MDT
31275         $MULTIOP $DIR/$tfile oc
31276         check_lsom_data $DIR/$tfile
31277 }
31278 run_test 806 "Verify Lazy Size on MDS"
31279
31280 test_807() {
31281         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
31282         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
31283                 skip "Need MDS version at least 2.11.52"
31284
31285         # Registration step
31286         changelog_register || error "changelog_register failed"
31287         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
31288         changelog_users $SINGLEMDS | grep -q $cl_user ||
31289                 error "User $cl_user not found in changelog_users"
31290
31291         rm -rf $DIR/$tdir || error "rm $tdir failed"
31292         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
31293         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
31294         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
31295         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
31296                 error "truncate $tdir/trunc failed"
31297
31298         local bs=1048576
31299         echo "Test SOM for single-threaded write with fsync"
31300         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
31301                 error "write $tfile failed"
31302         sync;sync;sync
31303
31304         # multi-client wirtes
31305         local num=$(get_node_count ${CLIENTS//,/ })
31306         local offset=0
31307         local i=0
31308
31309         echo "Test SOM for multi-client ($num) writes"
31310         touch $DIR/$tfile || error "touch $tfile failed"
31311         $TRUNCATE $DIR/$tfile 0
31312         for client in ${CLIENTS//,/ }; do
31313                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31314                 local pids[$i]=$!
31315                 i=$((i + 1))
31316                 offset=$((offset + $bs))
31317         done
31318         for (( i=0; i < $num; i++ )); do
31319                 wait ${pids[$i]}
31320         done
31321
31322         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
31323         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
31324         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
31325         check_lsom_data $DIR/$tdir/trunc
31326         check_lsom_data $DIR/$tdir/single_dd
31327         check_lsom_data $DIR/$tfile
31328
31329         rm -rf $DIR/$tdir
31330         # Deregistration step
31331         changelog_deregister || error "changelog_deregister failed"
31332 }
31333 run_test 807 "verify LSOM syncing tool"
31334
31335 check_som_nologged()
31336 {
31337         local lines=$($LFS changelog $FSNAME-MDT0000 |
31338                 grep 'x=trusted.som' | wc -l)
31339         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
31340 }
31341
31342 test_808() {
31343         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
31344                 skip "Need MDS version at least 2.11.55"
31345
31346         # Registration step
31347         changelog_register || error "changelog_register failed"
31348
31349         touch $DIR/$tfile || error "touch $tfile failed"
31350         check_som_nologged
31351
31352         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
31353                 error "write $tfile failed"
31354         check_som_nologged
31355
31356         $TRUNCATE $DIR/$tfile 1234
31357         check_som_nologged
31358
31359         $TRUNCATE $DIR/$tfile 1048576
31360         check_som_nologged
31361
31362         # Deregistration step
31363         changelog_deregister || error "changelog_deregister failed"
31364 }
31365 run_test 808 "Check trusted.som xattr not logged in Changelogs"
31366
31367 check_som_nodata()
31368 {
31369         $LFS getsom $1
31370         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
31371 }
31372
31373 test_809() {
31374         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
31375                 skip "Need MDS version at least 2.11.56"
31376
31377         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
31378                 error "failed to create DoM-only file $DIR/$tfile"
31379         touch $DIR/$tfile || error "touch $tfile failed"
31380         check_som_nodata $DIR/$tfile
31381
31382         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
31383                 error "write $tfile failed"
31384         check_som_nodata $DIR/$tfile
31385
31386         $TRUNCATE $DIR/$tfile 1234
31387         check_som_nodata $DIR/$tfile
31388
31389         $TRUNCATE $DIR/$tfile 4097
31390         check_som_nodata $DIR/$file
31391 }
31392 run_test 809 "Verify no SOM xattr store for DoM-only files"
31393
31394 test_810() {
31395         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31396         $GSS && skip_env "could not run with gss"
31397         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
31398                 skip "OST < 2.12.58 doesn't align checksum"
31399
31400         set_checksums 1
31401         stack_trap "set_checksums $ORIG_CSUM" EXIT
31402         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
31403
31404         local csum
31405         local before
31406         local after
31407         for csum in $CKSUM_TYPES; do
31408                 #define OBD_FAIL_OSC_NO_GRANT   0x411
31409                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
31410                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
31411                         eval set -- $i
31412                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
31413                         before=$(md5sum $DIR/$tfile)
31414                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
31415                         after=$(md5sum $DIR/$tfile)
31416                         [ "$before" == "$after" ] ||
31417                                 error "$csum: $before != $after bs=$1 seek=$2"
31418                 done
31419         done
31420 }
31421 run_test 810 "partial page writes on ZFS (LU-11663)"
31422
31423 test_812a() {
31424         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
31425                 skip "OST < 2.12.51 doesn't support this fail_loc"
31426
31427         $LFS setstripe -c 1 -i 0 $DIR/$tfile
31428         # ensure ost1 is connected
31429         stat $DIR/$tfile >/dev/null || error "can't stat"
31430         wait_osc_import_state client ost1 FULL
31431         # no locks, no reqs to let the connection idle
31432         cancel_lru_locks osc
31433
31434         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
31435 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
31436         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
31437         wait_osc_import_state client ost1 CONNECTING
31438         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
31439
31440         stat $DIR/$tfile >/dev/null || error "can't stat file"
31441 }
31442 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
31443
31444 test_812b() { # LU-12378
31445         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
31446                 skip "OST < 2.12.51 doesn't support this fail_loc"
31447
31448         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
31449         # ensure ost1 is connected
31450         stat $DIR/$tfile >/dev/null || error "can't stat"
31451         wait_osc_import_state client ost1 FULL
31452         # no locks, no reqs to let the connection idle
31453         cancel_lru_locks osc
31454
31455         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
31456 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
31457         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
31458         wait_osc_import_state client ost1 CONNECTING
31459         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
31460
31461         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
31462         wait_osc_import_state client ost1 IDLE
31463 }
31464 run_test 812b "do not drop no resend request for idle connect"
31465
31466 test_812c() {
31467         local old
31468
31469         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
31470
31471         $LFS setstripe -c 1 -o 0 $DIR/$tfile
31472         $LFS getstripe $DIR/$tfile
31473         $LCTL set_param osc.*.idle_timeout=10
31474         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
31475         # ensure ost1 is connected
31476         stat $DIR/$tfile >/dev/null || error "can't stat"
31477         wait_osc_import_state client ost1 FULL
31478         # no locks, no reqs to let the connection idle
31479         cancel_lru_locks osc
31480
31481 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
31482         $LCTL set_param fail_loc=0x80000533
31483         sleep 15
31484         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
31485 }
31486 run_test 812c "idle import vs lock enqueue race"
31487
31488 test_813() {
31489         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
31490         [ -z "$file_heat_sav" ] && skip "no file heat support"
31491
31492         local readsample
31493         local writesample
31494         local readbyte
31495         local writebyte
31496         local readsample1
31497         local writesample1
31498         local readbyte1
31499         local writebyte1
31500
31501         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
31502         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
31503
31504         $LCTL set_param -n llite.*.file_heat=1
31505         echo "Turn on file heat"
31506         echo "Period second: $period_second, Decay percentage: $decay_pct"
31507
31508         echo "QQQQ" > $DIR/$tfile
31509         echo "QQQQ" > $DIR/$tfile
31510         echo "QQQQ" > $DIR/$tfile
31511         cat $DIR/$tfile > /dev/null
31512         cat $DIR/$tfile > /dev/null
31513         cat $DIR/$tfile > /dev/null
31514         cat $DIR/$tfile > /dev/null
31515
31516         local out=$($LFS heat_get $DIR/$tfile)
31517
31518         $LFS heat_get $DIR/$tfile
31519         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31520         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31521         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31522         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31523
31524         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
31525         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
31526         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
31527         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
31528
31529         sleep $((period_second + 3))
31530         echo "Sleep $((period_second + 3)) seconds..."
31531         # The recursion formula to calculate the heat of the file f is as
31532         # follow:
31533         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
31534         # Where Hi is the heat value in the period between time points i*I and
31535         # (i+1)*I; Ci is the access count in the period; the symbol P refers
31536         # to the weight of Ci.
31537         out=$($LFS heat_get $DIR/$tfile)
31538         $LFS heat_get $DIR/$tfile
31539         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31540         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31541         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31542         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31543
31544         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
31545                 error "read sample ($readsample) is wrong"
31546         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
31547                 error "write sample ($writesample) is wrong"
31548         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
31549                 error "read bytes ($readbyte) is wrong"
31550         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
31551                 error "write bytes ($writebyte) is wrong"
31552
31553         echo "QQQQ" > $DIR/$tfile
31554         echo "QQQQ" > $DIR/$tfile
31555         echo "QQQQ" > $DIR/$tfile
31556         cat $DIR/$tfile > /dev/null
31557         cat $DIR/$tfile > /dev/null
31558         cat $DIR/$tfile > /dev/null
31559         cat $DIR/$tfile > /dev/null
31560
31561         sleep $((period_second + 3))
31562         echo "Sleep $((period_second + 3)) seconds..."
31563
31564         out=$($LFS heat_get $DIR/$tfile)
31565         $LFS heat_get $DIR/$tfile
31566         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31567         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31568         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31569         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31570
31571         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
31572                 4 * $decay_pct) / 100") -eq 1 ] ||
31573                 error "read sample ($readsample1) is wrong"
31574         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
31575                 3 * $decay_pct) / 100") -eq 1 ] ||
31576                 error "write sample ($writesample1) is wrong"
31577         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
31578                 20 * $decay_pct) / 100") -eq 1 ] ||
31579                 error "read bytes ($readbyte1) is wrong"
31580         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
31581                 15 * $decay_pct) / 100") -eq 1 ] ||
31582                 error "write bytes ($writebyte1) is wrong"
31583
31584         echo "Turn off file heat for the file $DIR/$tfile"
31585         $LFS heat_set -o $DIR/$tfile
31586
31587         echo "QQQQ" > $DIR/$tfile
31588         echo "QQQQ" > $DIR/$tfile
31589         echo "QQQQ" > $DIR/$tfile
31590         cat $DIR/$tfile > /dev/null
31591         cat $DIR/$tfile > /dev/null
31592         cat $DIR/$tfile > /dev/null
31593         cat $DIR/$tfile > /dev/null
31594
31595         out=$($LFS heat_get $DIR/$tfile)
31596         $LFS heat_get $DIR/$tfile
31597         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31598         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31599         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31600         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31601
31602         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
31603         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
31604         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
31605         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
31606
31607         echo "Trun on file heat for the file $DIR/$tfile"
31608         $LFS heat_set -O $DIR/$tfile
31609
31610         echo "QQQQ" > $DIR/$tfile
31611         echo "QQQQ" > $DIR/$tfile
31612         echo "QQQQ" > $DIR/$tfile
31613         cat $DIR/$tfile > /dev/null
31614         cat $DIR/$tfile > /dev/null
31615         cat $DIR/$tfile > /dev/null
31616         cat $DIR/$tfile > /dev/null
31617
31618         out=$($LFS heat_get $DIR/$tfile)
31619         $LFS heat_get $DIR/$tfile
31620         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31621         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31622         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31623         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31624
31625         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
31626         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
31627         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
31628         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
31629
31630         $LFS heat_set -c $DIR/$tfile
31631         $LCTL set_param -n llite.*.file_heat=0
31632         echo "Turn off file heat support for the Lustre filesystem"
31633
31634         echo "QQQQ" > $DIR/$tfile
31635         echo "QQQQ" > $DIR/$tfile
31636         echo "QQQQ" > $DIR/$tfile
31637         cat $DIR/$tfile > /dev/null
31638         cat $DIR/$tfile > /dev/null
31639         cat $DIR/$tfile > /dev/null
31640         cat $DIR/$tfile > /dev/null
31641
31642         out=$($LFS heat_get $DIR/$tfile)
31643         $LFS heat_get $DIR/$tfile
31644         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31645         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31646         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31647         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31648
31649         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
31650         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
31651         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
31652         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
31653
31654         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
31655         rm -f $DIR/$tfile
31656 }
31657 run_test 813 "File heat verfication"
31658
31659 test_814()
31660 {
31661         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
31662         echo -n y >> $DIR/$tfile
31663         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
31664         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
31665 }
31666 run_test 814 "sparse cp works as expected (LU-12361)"
31667
31668 test_815()
31669 {
31670         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
31671         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
31672 }
31673 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
31674
31675 test_816() {
31676         local ost1_imp=$(get_osc_import_name client ost1)
31677         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
31678                          cut -d'.' -f2)
31679
31680         $LFS setstripe -c 1 -i 0 $DIR/$tfile
31681         # ensure ost1 is connected
31682
31683         stat $DIR/$tfile >/dev/null || error "can't stat"
31684         wait_osc_import_state client ost1 FULL
31685         # no locks, no reqs to let the connection idle
31686         cancel_lru_locks osc
31687         lru_resize_disable osc
31688         local before
31689         local now
31690         before=$($LCTL get_param -n \
31691                  ldlm.namespaces.$imp_name.lru_size)
31692
31693         wait_osc_import_state client ost1 IDLE
31694         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
31695         now=$($LCTL get_param -n \
31696               ldlm.namespaces.$imp_name.lru_size)
31697         [ $before == $now ] || error "lru_size changed $before != $now"
31698 }
31699 run_test 816 "do not reset lru_resize on idle reconnect"
31700
31701 cleanup_817() {
31702         umount $tmpdir
31703         exportfs -u localhost:$DIR/nfsexp
31704         rm -rf $DIR/nfsexp
31705 }
31706
31707 test_817() {
31708         systemctl restart nfs-server.service || skip "failed to restart nfsd"
31709
31710         mkdir -p $DIR/nfsexp
31711         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
31712                 error "failed to export nfs"
31713
31714         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
31715         stack_trap cleanup_817 EXIT
31716
31717         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
31718                 error "failed to mount nfs to $tmpdir"
31719
31720         cp /bin/true $tmpdir
31721         $DIR/nfsexp/true || error "failed to execute 'true' command"
31722 }
31723 run_test 817 "nfsd won't cache write lock for exec file"
31724
31725 test_818() {
31726         test_mkdir -i0 -c1 $DIR/$tdir
31727         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
31728         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
31729         stop $SINGLEMDS
31730
31731         # restore osp-syn threads
31732         stack_trap "fail $SINGLEMDS"
31733
31734         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
31735         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
31736         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
31737                 error "start $SINGLEMDS failed"
31738         rm -rf $DIR/$tdir
31739
31740         local testid=$(echo $TESTNAME | tr '_' ' ')
31741
31742         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
31743                 grep "run LFSCK" || error "run LFSCK is not suggested"
31744 }
31745 run_test 818 "unlink with failed llog"
31746
31747 test_819a() {
31748         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
31749         cancel_lru_locks osc
31750         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
31751         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
31752         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
31753         rm -f $TDIR/$tfile
31754 }
31755 run_test 819a "too big niobuf in read"
31756
31757 test_819b() {
31758         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
31759         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
31760         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
31761         cancel_lru_locks osc
31762         sleep 1
31763         rm -f $TDIR/$tfile
31764 }
31765 run_test 819b "too big niobuf in write"
31766
31767
31768 function test_820_start_ost() {
31769         sleep 5
31770
31771         for num in $(seq $OSTCOUNT); do
31772                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
31773         done
31774 }
31775
31776 test_820() {
31777         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
31778
31779         mkdir $DIR/$tdir
31780         umount_client $MOUNT || error "umount failed"
31781         for num in $(seq $OSTCOUNT); do
31782                 stop ost$num
31783         done
31784
31785         # mount client with no active OSTs
31786         # so that the client can't initialize max LOV EA size
31787         # from OSC notifications
31788         mount_client $MOUNT || error "mount failed"
31789         # delay OST starting to keep this 0 max EA size for a while
31790         test_820_start_ost &
31791
31792         # create a directory on MDS2
31793         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
31794                 error "Failed to create directory"
31795         # open intent should update default EA size
31796         # see mdc_update_max_ea_from_body()
31797         # notice this is the very first RPC to MDS2
31798         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
31799         ret=$?
31800         echo $out
31801         # With SSK, this situation can lead to -EPERM being returned.
31802         # In that case, simply retry.
31803         if [ $ret -ne 0 ] && $SHARED_KEY; then
31804                 if echo "$out" | grep -q "not permitted"; then
31805                         cp /etc/services $DIR/$tdir/mds2
31806                         ret=$?
31807                 fi
31808         fi
31809         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
31810 }
31811 run_test 820 "update max EA from open intent"
31812
31813 test_823() {
31814         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
31815         local OST_MAX_PRECREATE=20000
31816
31817         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
31818                 skip "Need MDS version at least 2.14.56"
31819
31820         save_lustre_params mds1 \
31821                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
31822         do_facet $SINGLEMDS "$LCTL set_param -n \
31823                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
31824         do_facet $SINGLEMDS "$LCTL set_param -n \
31825                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
31826
31827         stack_trap "restore_lustre_params < $p; rm $p"
31828
31829         do_facet $SINGLEMDS "$LCTL set_param -n \
31830                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
31831
31832         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
31833                       osp.$FSNAME-OST0000*MDT0000.create_count")
31834         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
31835                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
31836         local expect_count=$(((($max/2)/256) * 256))
31837
31838         log "setting create_count to 100200:"
31839         log " -result- count: $count with max: $max, expecting: $expect_count"
31840
31841         [[ $count -eq expect_count ]] ||
31842                 error "Create count not set to max precreate."
31843 }
31844 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
31845
31846 test_831() {
31847         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
31848                 skip "Need MDS version 2.14.56"
31849
31850         local sync_changes=$(do_facet $SINGLEMDS \
31851                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
31852
31853         [ "$sync_changes" -gt 100 ] &&
31854                 skip "Sync changes $sync_changes > 100 already"
31855
31856         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
31857
31858         $LFS mkdir -i 0 $DIR/$tdir
31859         $LFS setstripe -c 1 -i 0 $DIR/$tdir
31860
31861         save_lustre_params mds1 \
31862                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
31863         save_lustre_params mds1 \
31864                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
31865
31866         do_facet mds1 "$LCTL set_param -n \
31867                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
31868                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
31869         stack_trap "restore_lustre_params < $p" EXIT
31870
31871         createmany -o $DIR/$tdir/f- 1000
31872         unlinkmany $DIR/$tdir/f- 1000 &
31873         local UNLINK_PID=$!
31874
31875         while sleep 1; do
31876                 sync_changes=$(do_facet mds1 \
31877                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
31878                 # the check in the code is racy, fail the test
31879                 # if the value above the limit by 10.
31880                 [ $sync_changes -gt 110 ] && {
31881                         kill -2 $UNLINK_PID
31882                         wait
31883                         error "osp changes throttling failed, $sync_changes>110"
31884                 }
31885                 kill -0 $UNLINK_PID 2> /dev/null || break
31886         done
31887         wait
31888 }
31889 run_test 831 "throttling unlink/setattr queuing on OSP"
31890
31891 test_832() {
31892         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
31893         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
31894                 skip "Need MDS version 2.15.52+"
31895         is_rmentry_supported || skip "rm_entry not supported"
31896
31897         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
31898         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
31899         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
31900                 error "mkdir remote_dir failed"
31901         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
31902                 error "mkdir striped_dir failed"
31903         touch $DIR/$tdir/file || error "touch file failed"
31904         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
31905         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
31906 }
31907 run_test 832 "lfs rm_entry"
31908
31909 test_833() {
31910         local file=$DIR/$tfile
31911
31912         stack_trap "rm -f $file" EXIT
31913         dd if=/dev/zero of=$file bs=1M count=50 || error "Write $file failed"
31914
31915         local wpid
31916         local rpid
31917         local rpid2
31918
31919         # Buffered I/O write
31920         (
31921                 while [ ! -e $DIR/sanity.833.lck ]; do
31922                         dd if=/dev/zero of=$file bs=1M count=50 conv=notrunc ||
31923                                 error "failed to write $file"
31924                         sleep 0.$((RANDOM % 4 + 1))
31925                 done
31926         )&
31927         wpid=$!
31928
31929         # Buffered I/O read
31930         (
31931                 while [ ! -e $DIR/sanity.833.lck ]; do
31932                         dd if=$file of=/dev/null bs=1M count=50 ||
31933                                 error "failed to read $file"
31934                         sleep 0.$((RANDOM % 4 + 1))
31935                 done
31936         )&
31937         rpid=$!
31938
31939         # Direct I/O read
31940         (
31941                 while [ ! -e $DIR/sanity.833.lck ]; do
31942                         dd if=$file of=/dev/null bs=1M count=50 iflag=direct ||
31943                                 error "failed to read $file in direct I/O mode"
31944                         sleep 0.$((RANDOM % 4 + 1))
31945                 done
31946         )&
31947         rpid2=$!
31948
31949         sleep 30
31950         touch $DIR/sanity.833.lck
31951         wait $wpid || error "$?: buffered write failed"
31952         wait $rpid || error "$?: buffered read failed"
31953         wait $rpid2 || error "$?: direct read failed"
31954 }
31955 run_test 833 "Mixed buffered/direct read and write should not return -EIO"
31956
31957 test_850() {
31958         local dir=$DIR/$tdir
31959         local file=$dir/$tfile
31960         local statsfile=$dir/all_job_stats.txt
31961
31962         test_mkdir -p $dir || error "failed to create dir $dir"
31963         echo "abcdefg" > $file || error "failed to create file $file"
31964
31965         # read job_stats in the living system
31966         lljobstat -n 1 ||
31967                 error "failed to run lljobstat on living system"
31968
31969         $LCTL get_param *.*.job_stats > $statsfile
31970         lljobstat --statsfile=$statsfile ||
31971                 error "failed to run lljobstat on file $statsfile"
31972 }
31973 run_test 850 "lljobstat can parse living and aggregated job_stats"
31974
31975 test_851() {
31976         local dir=$DIR/$tdir
31977         local file=$dir/f_test_851_$$
31978         local report=/tmp/report_test_851_$$
31979         local fanotify_prog=monitor_lustrefs
31980         local pid
31981
31982         test_mkdir $dir || error "failed to create dir $dir"
31983
31984         $fanotify_prog $DIR > $report &
31985         pid=$!
31986
31987         sleep 1
31988         if ! kill -0 $pid; then
31989                 error "failed to start $fanoify_prog"
31990         fi
31991
31992         stack_trap "kill $pid"
31993         stack_trap "rm -f $report"
31994
31995         echo "1234567890" > $file
31996         wait_update_cond localhost "stat -c %s $report" "-gt" "0" 30 ||
31997                 error "fanotify did not report anything after 30 seconds"
31998         grep -a -E "open.*:$file:" $report ||
31999                 error "no open event for writing $file"
32000         grep -a -E "write.*:$file:" $report ||
32001                 error "no write event for writing $file"
32002         grep -a -E "close.*:$file:" $report ||
32003                 error "no close event for writing $file"
32004
32005         > $report
32006         cat $file
32007         wait_update_cond localhost "stat -c %s $report" "-gt" "0" 30 ||
32008                 error "fanotify did not report anything after 30 seconds"
32009         grep -a -E "open.*:$file:" $report ||
32010                 error "no open event for reading $file"
32011         grep -a -E "read.*:$file:" $report ||
32012                 error "no write event for reading $file"
32013         grep -a -E "close.*:$file:" $report ||
32014                 error "no close event for reading $file"
32015 }
32016 run_test 851 "fanotify can monitor open/read/write/close events for lustre fs"
32017
32018 #
32019 # tests that do cleanup/setup should be run at the end
32020 #
32021
32022 test_900() {
32023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
32024         local ls
32025
32026         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
32027         $LCTL set_param fail_loc=0x903
32028
32029         cancel_lru_locks MGC
32030
32031         FAIL_ON_ERROR=true cleanup
32032         FAIL_ON_ERROR=true setup
32033 }
32034 run_test 900 "umount should not race with any mgc requeue thread"
32035
32036 # LUS-6253/LU-11185
32037 test_901() {
32038         local old
32039         local count
32040         local oldc
32041         local newc
32042         local olds
32043         local news
32044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
32045
32046         # some get_param have a bug to handle dot in param name
32047         cancel_lru_locks MGC
32048         old=$(mount -t lustre | wc -l)
32049         # 1 config+sptlrpc
32050         # 2 params
32051         # 3 nodemap
32052         # 4 IR
32053         old=$((old * 4))
32054         oldc=0
32055         count=0
32056         while [ $old -ne $oldc ]; do
32057                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
32058                 sleep 1
32059                 ((count++))
32060                 if [ $count -ge $TIMEOUT ]; then
32061                         error "too large timeout"
32062                 fi
32063         done
32064         umount_client $MOUNT || error "umount failed"
32065         mount_client $MOUNT || error "mount failed"
32066         cancel_lru_locks MGC
32067         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
32068
32069         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
32070
32071         return 0
32072 }
32073 run_test 901 "don't leak a mgc lock on client umount"
32074
32075 # LU-13377
32076 test_902() {
32077         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
32078                 skip "client does not have LU-13377 fix"
32079         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
32080         $LCTL set_param fail_loc=0x1415
32081         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
32082         cancel_lru_locks osc
32083         rm -f $DIR/$tfile
32084 }
32085 run_test 902 "test short write doesn't hang lustre"
32086
32087 # LU-14711
32088 test_903() {
32089         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
32090         echo "blah" > $DIR/${tfile}-2
32091         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
32092         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
32093         $LCTL set_param fail_loc=0x417 fail_val=20
32094
32095         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
32096         sleep 1 # To start the destroy
32097         wait_destroy_complete 150 || error "Destroy taking too long"
32098         cat $DIR/$tfile > /dev/null || error "Evicted"
32099 }
32100 run_test 903 "Test long page discard does not cause evictions"
32101
32102 test_904() {
32103         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
32104         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
32105                 grep -q project || skip "skip project quota not supported"
32106
32107         local testfile="$DIR/$tdir/$tfile"
32108         local xattr="trusted.projid"
32109         local projid
32110         local mdts=$(comma_list $(mdts_nodes))
32111         local saved=$(do_facet mds1 $LCTL get_param -n \
32112                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
32113
32114         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
32115         stack_trap "do_nodes $mdts $LCTL set_param \
32116                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
32117
32118         mkdir -p $DIR/$tdir
32119         touch $testfile
32120         #hide projid xattr on server
32121         $LFS project -p 1 $testfile ||
32122                 error "set $testfile project id failed"
32123         getfattr -m - $testfile | grep $xattr &&
32124                 error "do not show trusted.projid when disabled on server"
32125         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
32126         #should be hidden when projid is 0
32127         $LFS project -p 0 $testfile ||
32128                 error "set $testfile project id failed"
32129         getfattr -m - $testfile | grep $xattr &&
32130                 error "do not show trusted.projid with project ID 0"
32131
32132         #still can getxattr explicitly
32133         projid=$(getfattr -n $xattr $testfile |
32134                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
32135         [ $projid == "0" ] ||
32136                 error "projid expected 0 not $projid"
32137
32138         #set the projid via setxattr
32139         setfattr -n $xattr -v "1000" $testfile ||
32140                 error "setattr failed with $?"
32141         projid=($($LFS project $testfile))
32142         [ ${projid[0]} == "1000" ] ||
32143                 error "projid expected 1000 not $projid"
32144
32145         #check the new projid via getxattr
32146         $LFS project -p 1001 $testfile ||
32147                 error "set $testfile project id failed"
32148         getfattr -m - $testfile | grep $xattr ||
32149                 error "should show trusted.projid when project ID != 0"
32150         projid=$(getfattr -n $xattr $testfile |
32151                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
32152         [ $projid == "1001" ] ||
32153                 error "projid expected 1001 not $projid"
32154
32155         #try to set invalid projid
32156         setfattr -n $xattr -v "4294967295" $testfile &&
32157                 error "set invalid projid should fail"
32158
32159         #remove the xattr means setting projid to 0
32160         setfattr -x $xattr $testfile ||
32161                 error "setfattr failed with $?"
32162         projid=($($LFS project $testfile))
32163         [ ${projid[0]} == "0" ] ||
32164                 error "projid expected 0 not $projid"
32165
32166         #should be hidden when parent has inherit flag and same projid
32167         $LFS project -srp 1002 $DIR/$tdir ||
32168                 error "set $tdir project id failed"
32169         getfattr -m - $testfile | grep $xattr &&
32170                 error "do not show trusted.projid with inherit flag"
32171
32172         #still can getxattr explicitly
32173         projid=$(getfattr -n $xattr $testfile |
32174                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
32175         [ $projid == "1002" ] ||
32176                 error "projid expected 1002 not $projid"
32177 }
32178 run_test 904 "virtual project ID xattr"
32179
32180 # LU-8582
32181 test_905() {
32182         (( $OST1_VERSION >= $(version_code 2.15.50.220) )) ||
32183                 skip "need OST version >= 2.15.50.220 for fail_loc"
32184
32185         remote_ost_nodsh && skip "remote OST with nodsh"
32186         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
32187
32188         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
32189
32190         #define OBD_FAIL_OST_OPCODE 0x253
32191         # OST_LADVISE = 21
32192         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
32193         $LFS ladvise -a willread $DIR/$tfile &&
32194                 error "unexpected success of ladvise with fault injection"
32195         $LFS ladvise -a willread $DIR/$tfile |&
32196                 grep -q "Operation not supported"
32197         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
32198 }
32199 run_test 905 "bad or new opcode should not stuck client"
32200
32201 test_906() {
32202         grep -q io_uring_setup /proc/kallsyms ||
32203                 skip "Client OS does not support io_uring I/O engine"
32204         io_uring_probe || skip "kernel does not support io_uring fully"
32205         which fio || skip_env "no fio installed"
32206         fio --enghelp | grep -q io_uring ||
32207                 skip_env "fio does not support io_uring I/O engine"
32208
32209         local file=$DIR/$tfile
32210         local ioengine="io_uring"
32211         local numjobs=2
32212         local size=50M
32213
32214         fio --name=seqwrite --ioengine=$ioengine        \
32215                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
32216                 --iodepth=64 --size=$size --filename=$file --rw=write ||
32217                 error "fio seqwrite $file failed"
32218
32219         fio --name=seqread --ioengine=$ioengine \
32220                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
32221                 --iodepth=64 --size=$size --filename=$file --rw=read ||
32222                 error "fio seqread $file failed"
32223
32224         rm -f $file || error "rm -f $file failed"
32225 }
32226 run_test 906 "Simple test for io_uring I/O engine via fio"
32227
32228 test_907() {
32229         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
32230
32231         # set stripe size to max rpc size
32232         $LFS setstripe -i 0 -c 2 -S $((max_pages * PAGE_SIZE)) $DIR/$tfile
32233         $LFS getstripe $DIR/$tfile
32234 #define OBD_FAIL_OST_EROFS               0x216
32235         do_facet ost1 "$LCTL set_param fail_val=3 fail_loc=0x80000216"
32236
32237         local bs=$((max_pages * PAGE_SIZE / 16))
32238
32239         # write full one stripe and one block
32240         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=17 || error "dd failed"
32241
32242         rm $DIR/$tfile || error "rm failed"
32243 }
32244 run_test 907 "write rpc error during unlink"
32245
32246
32247 complete_test $SECONDS
32248 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
32249 check_and_cleanup_lustre
32250 if [ "$I_MOUNTED" != "yes" ]; then
32251         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
32252 fi
32253 exit_status